ascode 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be5ffda76c2c8c88b0a89678a05730f7497fc8752208b3a41dc2523d81e62e46
4
- data.tar.gz: a510b069ecb83cf610dd696c3d3b55abf761062f4296329b1ef012a67cfa21af
3
+ metadata.gz: c5d1f71ff0d30c17ef55b8f2d4c91554b4f7363d812d29db1d113e8c88aa3d63
4
+ data.tar.gz: f3af4b019e3f8c03844a195424de19c54058e45b0375a4ea4a3079094952e982
5
5
  SHA512:
6
- metadata.gz: f18a849a4413d3182427a88f98da6736712443915a199e320ac857b79e2bb436807b977920a21cad5d527673382d8f79dc3f99df789955017a25d38e59b87214
7
- data.tar.gz: 6a10e1ef202258ebb4414e922e4a97e69d286b8524c7c46cc34000650ecb78d4a7e611079aa09ae6c7224e38fdb8d34fd0ba0b67b786a53314adf1a1b78e7e72
6
+ metadata.gz: 45d409bd132f0cfb0e28f441bf36464379289711a7688e2d627a9de310c36904c2806ffaa3329ece4ce0da561d7cf7f7f1a6f0ed98b1cd05313acc933f901278
7
+ data.tar.gz: 031ab75e57bbf8202a8a6f87605d4e08248333f10f7c8c60a152104123a23545a3ce892d510fc6ae810f46e18cb113f182139f07689656bc0377159259863063
data/README.md CHANGED
@@ -27,7 +27,8 @@ At this moment, the only way to play with `ascode` is `irb`.
27
27
  $ irb
28
28
  irb(main):001:0> require 'ascode'
29
29
  => true
30
- irb(main):002:0> Ascode.run '5*ê[Even~Odd]'
30
+ irb(main):002:0> Ascode.run 'Number:>ê[Even~Odd]>'
31
+ Number:
31
32
  10
32
33
  Even
33
34
  ```
@@ -3,7 +3,7 @@ Character|Name|`pop`s|`push`es|Description
3
3
  `>`|`output`|`a`||`a` -> `stdout`
4
4
  `<`|`input`||`a`|`stdin` -> `a`
5
5
  `^`|`pop`|`a`||
6
- `[`|`condition_begin`|`a`|| If `a` = `0`, `nil` or `false`, jump to `~`, or to `]` if `~` is not present
6
+ `[`|`condition_begin`|`a`|| If `a` = `0`, `nil` or `false`, then part after `~` is executed
7
7
  `~`|`condition_else`|||
8
8
  `]`|`condition_end`|||
9
9
  `+`|`plus`|`a`, `b`|`c`|`c` = `a` + `b`
@@ -2,23 +2,23 @@ require_relative 'converter'
2
2
 
3
3
  module Ascode
4
4
  class Interpreter
5
- def initialize(ast)
5
+ def initialize(ast, stack = [])
6
6
  @ast = ast
7
- @conditions = []
8
- @cond_positions = []
9
7
 
10
- @stack = []
8
+ @stack = stack
11
9
  end
12
10
 
13
11
  def run
14
12
  @ast.each do |action|
15
13
  name = action[:action]
16
14
 
17
- if !@conditions.empty? && !%w[condition_else condition_end].include?(name)
18
- next if @conditions[0] != @cond_positions[0]
15
+ if name == 'push'
16
+ push(action[:what])
17
+ elsif name == 'condition'
18
+ condition_begin action[:true_block], action[:false_block]
19
+ else
20
+ send(name)
19
21
  end
20
-
21
- name == 'push' ? push(action[:what]) : send(name)
22
22
  end
23
23
  end
24
24
 
@@ -44,19 +44,16 @@ module Ascode
44
44
  puts pop(false)
45
45
  end
46
46
 
47
- def condition_begin
47
+ def condition_begin(true_ast, false_ast)
48
48
  condition = pop
49
- @conditions.push(!(condition.nil? || !condition || condition.zero?))
50
- @cond_positions.push true
51
- end
49
+ ast = condition.nil? || !condition || condition.zero? ? false_ast : true_ast
52
50
 
53
- def condition_else
54
- @cond_positions[0] = false
51
+ (Interpreter.new ast, @stack).run
55
52
  end
56
53
 
57
- def condition_end
58
- @conditions.pop
59
- end
54
+ def condition_else; end
55
+
56
+ def condition_end; end
60
57
 
61
58
  def plus
62
59
  a = pop
data/lib/ascode/parser.rb CHANGED
@@ -3,18 +3,26 @@ require_relative 'converter'
3
3
 
4
4
  module Ascode
5
5
  class Parser
6
- def initialize(code)
6
+ def initialize(code, impl_o = true)
7
7
  @fun = Functions.new
8
8
  @code = code
9
+
10
+ @do_implicit_output = impl_o
9
11
  end
10
12
 
11
13
  def parse
12
14
  @ast = []
13
15
  @push_buffer = false
14
- @implicit_output = true
16
+ @skip_chars = 0
17
+ @implicit_output = @do_implicit_output
15
18
 
16
- @code.split('').to_enum.each do |char|
17
- parse_character char
19
+ @code.split('').to_enum.each_with_index do |char, index|
20
+ if @skip_chars > 0
21
+ @skip_chars -= 1
22
+ next
23
+ else
24
+ parse_character char, index
25
+ end
18
26
  end
19
27
  ast_add_buffer
20
28
 
@@ -23,8 +31,62 @@ module Ascode
23
31
  @ast
24
32
  end
25
33
 
26
- def parse_character(char)
27
- if char =~ /[\w.,:;!?]/
34
+ def parse_condition_block(begin_index)
35
+ block_code = @code[(begin_index + 1)..-1]
36
+
37
+ end_index = (find_block_end block_code) + begin_index
38
+ raise "Unmatched '[' at position #{begin_index}" if end_index == -1
39
+
40
+ block_code = @code[(begin_index + 1)..(end_index + 1)]
41
+
42
+ split_pos = find_block_split(block_code)
43
+
44
+ if split_pos == -1
45
+ true_block_ast = (Parser.new block_code).parse
46
+ false_block_ast = ''
47
+ else
48
+ true_block_ast = (Parser.new block_code[0..(split_pos - 1)], false).parse
49
+ false_block_ast = (Parser.new block_code[(split_pos + 1)..-1], false).parse
50
+ end
51
+
52
+ @ast.push(action: 'condition', true_block: true_block_ast, false_block: false_block_ast )
53
+
54
+ end_index + 2
55
+ end
56
+
57
+ def find_block_end(block)
58
+ end_index = -1
59
+ block.split('').to_enum.with_index.reverse_each do |char, index|
60
+ if char == ']'
61
+ end_index = index
62
+ break
63
+ end
64
+ end
65
+
66
+ end_index - 1
67
+ end
68
+
69
+ def find_block_split(block)
70
+ level = 0
71
+ split_pos = -1
72
+ block.split('').to_enum.each_with_index do |char, index|
73
+ if char == '['
74
+ level += 1
75
+ elsif char == ']'
76
+ level -= 1
77
+ elsif char == '~' && level.zero?
78
+ split_pos = index
79
+ end
80
+ end
81
+
82
+ split_pos
83
+ end
84
+
85
+ def parse_character(char, index)
86
+ if char == '['
87
+ end_index = parse_condition_block index
88
+ @skip_chars = end_index - index
89
+ elsif char =~ /[\w.,:;!?]/
28
90
  buffer_push char
29
91
  elsif char == ' '
30
92
  ast_add_buffer
@@ -39,7 +101,7 @@ module Ascode
39
101
  value[:short] == char
40
102
  end
41
103
 
42
- puts '[Error] Unexpected identifier: \'' + char + '\'' unless function
104
+ raise "Unexpected identifier: '#{char}'" unless function
43
105
  ast_add_action function[:long]
44
106
  end
45
107
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ascode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Artem Varaksa