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 +4 -4
- data/README.md +2 -1
- data/lib/ascode/functions.md +1 -1
- data/lib/ascode/interpreter.rb +14 -17
- data/lib/ascode/parser.rb +69 -7
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5d1f71ff0d30c17ef55b8f2d4c91554b4f7363d812d29db1d113e8c88aa3d63
|
4
|
+
data.tar.gz: f3af4b019e3f8c03844a195424de19c54058e45b0375a4ea4a3079094952e982
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 45d409bd132f0cfb0e28f441bf36464379289711a7688e2d627a9de310c36904c2806ffaa3329ece4ce0da561d7cf7f7f1a6f0ed98b1cd05313acc933f901278
|
7
|
+
data.tar.gz: 031ab75e57bbf8202a8a6f87605d4e08248333f10f7c8c60a152104123a23545a3ce892d510fc6ae810f46e18cb113f182139f07689656bc0377159259863063
|
data/README.md
CHANGED
data/lib/ascode/functions.md
CHANGED
@@ -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`,
|
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`
|
data/lib/ascode/interpreter.rb
CHANGED
@@ -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
|
18
|
-
|
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
|
-
|
50
|
-
@cond_positions.push true
|
51
|
-
end
|
49
|
+
ast = condition.nil? || !condition || condition.zero? ? false_ast : true_ast
|
52
50
|
|
53
|
-
|
54
|
-
@cond_positions[0] = false
|
51
|
+
(Interpreter.new ast, @stack).run
|
55
52
|
end
|
56
53
|
|
57
|
-
def
|
58
|
-
|
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
|
-
@
|
16
|
+
@skip_chars = 0
|
17
|
+
@implicit_output = @do_implicit_output
|
15
18
|
|
16
|
-
@code.split('').to_enum.
|
17
|
-
|
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
|
27
|
-
|
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
|
-
|
104
|
+
raise "Unexpected identifier: '#{char}'" unless function
|
43
105
|
ast_add_action function[:long]
|
44
106
|
end
|
45
107
|
|