ascode 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|