alphalang 0.2.7 → 0.2.9
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/bin/alphalang +6 -0
- data/lib/alpha.rb +73 -30
- data/lib/nodes/basenodes.rb +27 -13
- data/lib/nodes/stmtnodes.rb +111 -11
- data/lib/rdparse.rb +38 -63
- metadata +1 -3
- data/lib/tester/assign.alpha +0 -14
- data/lib/tester/assign.alpha~ +0 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fd90e0cc81ecac899602c5a173f188110fecd877428fcab72e8bc77076e75d00
|
|
4
|
+
data.tar.gz: 1b1e538edb038c95ccffcb50fb8f48f5081977701082164da879ab848af80edb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 95e31bbc359dc485d7e5e623164f2f3c636c68975e6c7bd1c83fcfe75c11cbe8b1fe6c4d35eeefae0bfcf7c0b668f673a8649cea39d9bfe6f7319d860947e87b
|
|
7
|
+
data.tar.gz: 15cd10c8ce16fea278f3d99f3c8caecf3e811249c6a1d933360433d22ca06c0816602555a1aa314ba720a00229e6401256520de7d664da884a98e1bff2e3d24e
|
data/bin/alphalang
CHANGED
|
@@ -44,6 +44,10 @@ OptionParser.new do |opts|
|
|
|
44
44
|
opts.on('--listlocale', 'Lists all keywords from a specific locale file from your locales directory.') do
|
|
45
45
|
options[:listlocale] = true
|
|
46
46
|
end
|
|
47
|
+
|
|
48
|
+
opts.on('--printtree', 'Lists all keywords from a specific locale file from your locales directory.') do
|
|
49
|
+
options[:printtree] = true
|
|
50
|
+
end
|
|
47
51
|
end.parse!
|
|
48
52
|
|
|
49
53
|
verbose_flag = options[:verbose]
|
|
@@ -54,6 +58,8 @@ create_locale_flag = options[:createlocale]
|
|
|
54
58
|
delete_locale_flag = options[:deletelocale]
|
|
55
59
|
list_locales_flag = options[:listlocales]
|
|
56
60
|
list_locale_flag = options[:listlocale]
|
|
61
|
+
PRINT_TREE_FLAG = options[:printtree]
|
|
62
|
+
TREE_ARRAY = []
|
|
57
63
|
|
|
58
64
|
if create_locale_flag
|
|
59
65
|
require_relative '../lib/locale_creator'
|
data/lib/alpha.rb
CHANGED
|
@@ -36,31 +36,48 @@ class LangParser
|
|
|
36
36
|
match(:stmt)
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
###################### Statement Rules
|
|
40
|
+
|
|
39
41
|
rule :stmt do
|
|
40
42
|
match(:if_comp_stmt)
|
|
43
|
+
match(:loop)
|
|
44
|
+
match(:declaration)
|
|
45
|
+
match(:builtin)
|
|
46
|
+
match(:expr_stmt)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
rule :loop do
|
|
41
50
|
match(:while_stmt)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
rule :declaration do
|
|
42
54
|
match(:func_dec)
|
|
43
55
|
match(:ass_stmt)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
rule :builtin do
|
|
44
59
|
match(:pause_stmt)
|
|
45
|
-
match(:
|
|
60
|
+
match(:print_stmt)
|
|
46
61
|
end
|
|
47
62
|
|
|
63
|
+
###################### If Statement Rules
|
|
64
|
+
|
|
48
65
|
rule :if_comp_stmt do
|
|
49
66
|
match(:if_stmt, :comp_elseif, :else_stmt, :STOP) { |a, b, c| IfCompStmtNode.new(a, b, c) }
|
|
50
67
|
match(:if_stmt, :else_stmt, :STOP) { |a, b| IfCompStmtNode.new(a, b) }
|
|
51
68
|
match(:if_stmt, :STOP) { |a| IfCompStmtNode.new(a) }
|
|
52
69
|
end
|
|
53
70
|
|
|
54
|
-
rule :comp_elseif do
|
|
55
|
-
match(:elseif_stmt, :comp_elseif) { |a, b| [a, b] }
|
|
56
|
-
match(:elseif_stmt)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
71
|
rule :if_stmt do
|
|
60
72
|
match(:IF, :expr_stmt, :and, :expr_stmt, :comp_stmt) { |_, a, b, c, d| IfCompactNode.new(a, b, c, d) }
|
|
61
73
|
match(:IF, :expr_stmt, :comp_stmt) { |_, a, b| IfNode.new(a, b) }
|
|
62
74
|
end
|
|
63
75
|
|
|
76
|
+
rule :comp_elseif do
|
|
77
|
+
match(:elseif_stmt, :comp_elseif) { |a, b| [a, b] }
|
|
78
|
+
match(:elseif_stmt)
|
|
79
|
+
end
|
|
80
|
+
|
|
64
81
|
rule :elseif_stmt do
|
|
65
82
|
match(:ELSEIF, :expr_stmt, :comp_stmt) { |_, a, b| ElseifNode.new(a, b) }
|
|
66
83
|
end
|
|
@@ -69,12 +86,16 @@ class LangParser
|
|
|
69
86
|
match(:ELSE, :comp_stmt) { |_, b| ElseNode.new(b) }
|
|
70
87
|
end
|
|
71
88
|
|
|
89
|
+
###################### Loop Rules
|
|
90
|
+
|
|
72
91
|
rule :while_stmt do
|
|
73
92
|
match(:WHILE, :expr_stmt, :comp_stmt, :STOP) { |_, a, b| WhileLoopNode.new(a, b) }
|
|
74
93
|
end
|
|
75
94
|
|
|
95
|
+
###################### Variable and Function Declare Rules
|
|
96
|
+
|
|
76
97
|
rule :func_dec do
|
|
77
|
-
match(:DEF, :
|
|
98
|
+
match(:DEF, :call_member, :comp_stmt, :STOP) { |_, name, value, _| FunctionDecNode.new(name, value) }
|
|
78
99
|
end
|
|
79
100
|
|
|
80
101
|
rule :ass_stmt do
|
|
@@ -82,10 +103,18 @@ class LangParser
|
|
|
82
103
|
match(:member, '=', :array_stmt) { |var, _, value| VariableDecNode.new(var, value) }
|
|
83
104
|
end
|
|
84
105
|
|
|
106
|
+
###################### Built-In Function Rules
|
|
107
|
+
|
|
85
108
|
rule :pause_stmt do
|
|
86
109
|
match(:PAUSE, :expr) { |_, a| PauseNode.new(a) }
|
|
87
110
|
end
|
|
88
111
|
|
|
112
|
+
rule :print_stmt do
|
|
113
|
+
match(:PRINT, :expr) { |_, a| PrintNode.new(a) }
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
###################### Expression Rules
|
|
117
|
+
|
|
89
118
|
rule :expr_stmt do
|
|
90
119
|
match(:or_stmt)
|
|
91
120
|
match(:and_stmt)
|
|
@@ -105,15 +134,6 @@ class LangParser
|
|
|
105
134
|
match(:NOT, :expr_stmt) { |_, b| NotNode.new(b) }
|
|
106
135
|
end
|
|
107
136
|
|
|
108
|
-
rule :array_stmt do
|
|
109
|
-
match('[', :arg_list, ']') { |_, array, _| array }
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
rule :arg_list do
|
|
113
|
-
match(:expr, ',', :arg_list) { |a, _, b| ArrayNode.new(a, b) }
|
|
114
|
-
match(:expr) { |a| ArrayNode.new(a, NilClass) }
|
|
115
|
-
end
|
|
116
|
-
|
|
117
137
|
rule :expr do
|
|
118
138
|
match(:expr, /(<|>)/, :expr) { |a, op, b| CompareNode.new(a, op, b) }
|
|
119
139
|
match(/(<|>)/, :expr) { |op, b| CompareNode.new(nil, op, b) }
|
|
@@ -131,25 +151,46 @@ class LangParser
|
|
|
131
151
|
match(:atom)
|
|
132
152
|
end
|
|
133
153
|
|
|
154
|
+
###################### Data Types Rules
|
|
155
|
+
|
|
156
|
+
rule :array_stmt do
|
|
157
|
+
match('[', :arg_list, ']') { |_, array, _| array }
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
rule :arg_list do
|
|
161
|
+
match(:expr, ',', :arg_list) { |a, _, b| ArrayNode.new(a, b) }
|
|
162
|
+
match(:expr) { |a| ArrayNode.new(a, NilClass) }
|
|
163
|
+
end
|
|
164
|
+
|
|
134
165
|
rule :atom do
|
|
135
|
-
match(
|
|
136
|
-
match(
|
|
137
|
-
match(
|
|
138
|
-
match(
|
|
166
|
+
match(:number)
|
|
167
|
+
match(:boolean)
|
|
168
|
+
match(:call_member)
|
|
169
|
+
match(:prio_stmt)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
rule :boolean do
|
|
139
173
|
match(ScopeManager.true_value) { |a| BoolNode.new(a) }
|
|
140
174
|
match(ScopeManager.false_value) { |a| BoolNode.new(a) }
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
match(
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
rule :number do
|
|
178
|
+
match('-', /\d+/, '.', /\d+/) { |neg, a, dot, b| NumberNode.new(neg + a + dot + b) }
|
|
179
|
+
match(/\d+/, '.', /\d+/) { |a, dot, b| NumberNode.new(a + dot + b) }
|
|
180
|
+
match('-', /\d+/) { |neg, a| NumberNode.new(neg + a) }
|
|
181
|
+
match(/\d+/) { |a| NumberNode.new(a) }
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
rule :call_member do
|
|
185
|
+
match(:member, '(', :arg_list, ')') { |var, _, args, _| FuncCallNode.new(var, args) }
|
|
186
|
+
match(:member, '(', ')') { |var, _, _| FuncCallNode.new(var, NilClass) }
|
|
187
|
+
match(:member, '[', '-', /\d+/, ']') { |var, _, neg, index, _| ArrayCallNode.new(var, (neg+index)) }
|
|
188
|
+
match(:member, '[', /\d+/, ']') { |var, _, index, _| ArrayCallNode.new(var, index) }
|
|
189
|
+
match(:member) { |var| VariableCallNode.new(var) }
|
|
145
190
|
end
|
|
146
191
|
|
|
147
192
|
rule :member do
|
|
148
|
-
match(/[a-z]
|
|
149
|
-
match(/[a-z]/, '(', ')') { |var, _, _| FuncCallNode.new(var, NilClass) }
|
|
150
|
-
match(/[a-z]/, '[', '-', /\d+/, ']') { |var, _, neg, index, _| ArrayCallNode.new(var, (neg+index)) }
|
|
151
|
-
match(/[a-z]/, '[', /\d+/, ']') { |var, _, index, _| ArrayCallNode.new(var, index) }
|
|
152
|
-
match(/[a-z]/) { |var| VariableCallNode.new(var) }
|
|
193
|
+
match(/[a-z]/)
|
|
153
194
|
end
|
|
154
195
|
|
|
155
196
|
rule :prio_stmt do
|
|
@@ -161,7 +202,9 @@ class LangParser
|
|
|
161
202
|
def parse_file(filename)
|
|
162
203
|
file = File.read(filename)
|
|
163
204
|
root = @langParser.parse file
|
|
164
|
-
root.evaluate
|
|
205
|
+
root = root.evaluate
|
|
206
|
+
puts TREE_ARRAY
|
|
207
|
+
root
|
|
165
208
|
end
|
|
166
209
|
|
|
167
210
|
def calc_test(str)
|
data/lib/nodes/basenodes.rb
CHANGED
|
@@ -36,6 +36,10 @@ class BoolNode < Node
|
|
|
36
36
|
@value = false if value == ScopeManager.false_value
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
+
def to_s
|
|
40
|
+
@value.to_s
|
|
41
|
+
end
|
|
42
|
+
|
|
39
43
|
def evaluate
|
|
40
44
|
@value
|
|
41
45
|
end
|
|
@@ -53,6 +57,10 @@ class AndNode < Node
|
|
|
53
57
|
end
|
|
54
58
|
end
|
|
55
59
|
|
|
60
|
+
def to_s
|
|
61
|
+
"#{@lhs} and #{@rhs}"
|
|
62
|
+
end
|
|
63
|
+
|
|
56
64
|
def evaluate
|
|
57
65
|
@lhs.evaluate && @rhs.evaluate
|
|
58
66
|
end
|
|
@@ -68,6 +76,10 @@ class OrNode < Node
|
|
|
68
76
|
end
|
|
69
77
|
end
|
|
70
78
|
|
|
79
|
+
def to_s
|
|
80
|
+
"#{@lhs} or #{@rhs}"
|
|
81
|
+
end
|
|
82
|
+
|
|
71
83
|
def evaluate
|
|
72
84
|
@lhs.evaluate || @rhs.evaluate
|
|
73
85
|
end
|
|
@@ -78,6 +90,10 @@ class NotNode < Node
|
|
|
78
90
|
@node = node
|
|
79
91
|
end
|
|
80
92
|
|
|
93
|
+
def to_s
|
|
94
|
+
"not #{@node}"
|
|
95
|
+
end
|
|
96
|
+
|
|
81
97
|
def evaluate
|
|
82
98
|
not @node.evaluate
|
|
83
99
|
end
|
|
@@ -92,6 +108,10 @@ class CompareNode < Node
|
|
|
92
108
|
@lhs, @op, @rhs = lhs, op, rhs
|
|
93
109
|
end
|
|
94
110
|
|
|
111
|
+
def to_s
|
|
112
|
+
"#{@lhs} #{@op} #{@rhs}"
|
|
113
|
+
end
|
|
114
|
+
|
|
95
115
|
def evaluate
|
|
96
116
|
@value = @lhs.evaluate.send(@op, @rhs.evaluate)
|
|
97
117
|
end
|
|
@@ -105,21 +125,13 @@ class BinaryOperationNode < Node
|
|
|
105
125
|
@lhs, @op, @rhs = lhs, op, rhs
|
|
106
126
|
end
|
|
107
127
|
|
|
128
|
+
def to_s
|
|
129
|
+
"#{@lhs} #{@op} #{@rhs}"
|
|
130
|
+
end
|
|
131
|
+
|
|
108
132
|
def evaluate
|
|
109
133
|
if @rhs.evaluate.is_a?(ArrayNode) && @op == '+'
|
|
110
134
|
return @value = @rhs.evaluate + @lhs.evaluate
|
|
111
|
-
elsif @lhs.evaluate.is_a?(Array) && @op == '+'
|
|
112
|
-
return @value = @lhs.evaluate.append(@rhs.evaluate)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
if @rhs.evaluate.is_a?(ArrayNode) && @op == '-'
|
|
116
|
-
return @value = @rhs.evaluate - @lhs.evaluate
|
|
117
|
-
elsif @lhs.evaluate.is_a?(Array) && @op == '-'
|
|
118
|
-
return @lhs.evaluate.reject { |v| v.evaluate == @rhs.evaluate }
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
if @rhs.evaluate.is_a?(ArrayNode) or @rhs.evaluate.is_a?(Array) and @lhs.evaluate.is_a?(Numeric)
|
|
122
|
-
raise SyntaxError, "You can't subtract an array from a number! #{@lhs.evaluate} #{@op} #{@rhs.name}"
|
|
123
135
|
end
|
|
124
136
|
|
|
125
137
|
if @op == '/'
|
|
@@ -163,10 +175,12 @@ class ArrayNode < Node
|
|
|
163
175
|
|
|
164
176
|
def +(value)
|
|
165
177
|
@value.append(value)
|
|
178
|
+
self
|
|
166
179
|
end
|
|
167
180
|
|
|
168
181
|
def -(value)
|
|
169
|
-
@value.reject { |v| v.evaluate == value }
|
|
182
|
+
@value = @value.reject { |v| v.evaluate == value }
|
|
183
|
+
self
|
|
170
184
|
end
|
|
171
185
|
|
|
172
186
|
def [](index)
|
data/lib/nodes/stmtnodes.rb
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
require_relative 'basenodes'
|
|
2
2
|
|
|
3
|
+
def set_up_scope_header
|
|
4
|
+
result = "<#{ScopeManager.scope_lvl}> "
|
|
5
|
+
result += '++--++--' * (ScopeManager.scope_lvl + 1) + ' '
|
|
6
|
+
result
|
|
7
|
+
end
|
|
8
|
+
|
|
3
9
|
###################### Variable Nodes
|
|
4
10
|
|
|
5
11
|
class VariableCallNode < Node
|
|
@@ -9,8 +15,19 @@ class VariableCallNode < Node
|
|
|
9
15
|
@name = name
|
|
10
16
|
end
|
|
11
17
|
|
|
18
|
+
def create_tree_entry
|
|
19
|
+
result = set_up_scope_header
|
|
20
|
+
result += "Variable #{@name} is now #{@value}"
|
|
21
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
@name
|
|
26
|
+
end
|
|
27
|
+
|
|
12
28
|
def evaluate
|
|
13
29
|
@value = ScopeManager.lookup_var(@name)
|
|
30
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
14
31
|
return @value
|
|
15
32
|
end
|
|
16
33
|
end
|
|
@@ -23,8 +40,19 @@ class VariableDecNode < Node
|
|
|
23
40
|
@name = name
|
|
24
41
|
end
|
|
25
42
|
|
|
43
|
+
def create_tree_entry
|
|
44
|
+
result = set_up_scope_header
|
|
45
|
+
result += "Variable #{@name} is now #{@value}"
|
|
46
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def to_s
|
|
50
|
+
"#{@name} = #{@value}"
|
|
51
|
+
end
|
|
52
|
+
|
|
26
53
|
def evaluate
|
|
27
54
|
ScopeManager.add_to_current_scope(name, @value)
|
|
55
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
28
56
|
self
|
|
29
57
|
end
|
|
30
58
|
end
|
|
@@ -41,6 +69,7 @@ class ArrayCallNode < Node
|
|
|
41
69
|
raise ArgumentError, "You are trying to access an out of bounds index. Here -> #{@value}[#{@index}]"
|
|
42
70
|
end
|
|
43
71
|
@value = arr[@index]
|
|
72
|
+
@value
|
|
44
73
|
end
|
|
45
74
|
end
|
|
46
75
|
|
|
@@ -53,8 +82,19 @@ class FunctionDecNode < Node
|
|
|
53
82
|
@args = node.args
|
|
54
83
|
end
|
|
55
84
|
|
|
85
|
+
def create_tree_entry
|
|
86
|
+
result = set_up_scope_header
|
|
87
|
+
result += "Function #{@name} declared"
|
|
88
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def to_s
|
|
92
|
+
"#{@name} = #{@value}"
|
|
93
|
+
end
|
|
94
|
+
|
|
56
95
|
def evaluate
|
|
57
96
|
ScopeManager.add_func_to_global_scope(@name, @value, @args)
|
|
97
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
58
98
|
return nil
|
|
59
99
|
end
|
|
60
100
|
end
|
|
@@ -67,6 +107,20 @@ class FuncCallNode < Node
|
|
|
67
107
|
@args = args
|
|
68
108
|
end
|
|
69
109
|
|
|
110
|
+
def to_s
|
|
111
|
+
if @args == NilClass
|
|
112
|
+
"#{name}()"
|
|
113
|
+
else
|
|
114
|
+
"#{name}(#{@args})"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def create_tree_entry
|
|
119
|
+
result = set_up_scope_header
|
|
120
|
+
result += "Function #{@name} is called"
|
|
121
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
122
|
+
end
|
|
123
|
+
|
|
70
124
|
def evaluate
|
|
71
125
|
func = ScopeManager.lookup_func(@name)
|
|
72
126
|
|
|
@@ -95,6 +149,7 @@ class FuncCallNode < Node
|
|
|
95
149
|
ScopeManager.scope_lvl = old_scope_lvl
|
|
96
150
|
end
|
|
97
151
|
|
|
152
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
98
153
|
return func_return_value
|
|
99
154
|
end
|
|
100
155
|
end
|
|
@@ -108,8 +163,20 @@ class IfNode < Node
|
|
|
108
163
|
@argument, @node = argument, node
|
|
109
164
|
end
|
|
110
165
|
|
|
166
|
+
def to_s
|
|
167
|
+
"If #{argument}"
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def create_tree_entry
|
|
171
|
+
result = set_up_scope_header
|
|
172
|
+
result += "If statement #{@argument} is used"
|
|
173
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
174
|
+
end
|
|
175
|
+
|
|
111
176
|
def evaluate
|
|
112
177
|
@value = @node.evaluate
|
|
178
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
179
|
+
@value
|
|
113
180
|
end
|
|
114
181
|
end
|
|
115
182
|
|
|
@@ -120,8 +187,20 @@ class ElseifNode < Node
|
|
|
120
187
|
@argument, @node = argument, node
|
|
121
188
|
end
|
|
122
189
|
|
|
190
|
+
def to_s
|
|
191
|
+
'Else'
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def create_tree_entry
|
|
195
|
+
result = set_up_scope_header
|
|
196
|
+
result += "Elseif statement is used. #{@argument}"
|
|
197
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
198
|
+
end
|
|
199
|
+
|
|
123
200
|
def evaluate
|
|
124
201
|
@value = @node.evaluate
|
|
202
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
203
|
+
@value
|
|
125
204
|
end
|
|
126
205
|
end
|
|
127
206
|
|
|
@@ -133,8 +212,16 @@ class ElseNode < Node
|
|
|
133
212
|
@argument = BoolNode.new(ScopeManager.true_value)
|
|
134
213
|
end
|
|
135
214
|
|
|
215
|
+
def create_tree_entry
|
|
216
|
+
result = set_up_scope_header
|
|
217
|
+
result += "Else statement is used."
|
|
218
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
219
|
+
end
|
|
220
|
+
|
|
136
221
|
def evaluate
|
|
137
222
|
@value = @node.evaluate
|
|
223
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
224
|
+
@value
|
|
138
225
|
end
|
|
139
226
|
end
|
|
140
227
|
|
|
@@ -163,10 +250,19 @@ class WhileLoopNode < Node
|
|
|
163
250
|
super(statement)
|
|
164
251
|
end
|
|
165
252
|
|
|
253
|
+
def create_tree_entry
|
|
254
|
+
result = set_up_scope_header
|
|
255
|
+
result += "While Loop ran with #{@counter} iterations."
|
|
256
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
257
|
+
end
|
|
258
|
+
|
|
166
259
|
def evaluate
|
|
260
|
+
@counter = 0
|
|
167
261
|
while @condition.evaluate
|
|
168
262
|
@value.evaluate
|
|
263
|
+
@counter += 1
|
|
169
264
|
end
|
|
265
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
170
266
|
self.class
|
|
171
267
|
end
|
|
172
268
|
end
|
|
@@ -180,23 +276,20 @@ class PrintNode
|
|
|
180
276
|
@value = value
|
|
181
277
|
end
|
|
182
278
|
|
|
279
|
+
def create_tree_entry
|
|
280
|
+
result = set_up_scope_header
|
|
281
|
+
result += "Printed #{@value}."
|
|
282
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
283
|
+
end
|
|
284
|
+
|
|
183
285
|
def evaluate
|
|
184
286
|
if @value.evaluate.is_a?(ArrayNode)
|
|
185
287
|
print "Array #{@value.name}: " unless TEST_UNIT_ACTIVE
|
|
186
288
|
puts @value.evaluate unless TEST_UNIT_ACTIVE
|
|
187
|
-
elsif @value.evaluate.is_a?(Array)
|
|
188
|
-
print "Array #{@value.name}: " unless TEST_UNIT_ACTIVE
|
|
189
|
-
puts @value.evaluate.join(', ') unless TEST_UNIT_ACTIVE
|
|
190
289
|
else
|
|
191
|
-
|
|
192
|
-
if @value.value.is_a?(VariableCallNode)
|
|
193
|
-
raise SyntaxError, "You have a duplicate 'print' statement! Printing #{@value.value.name} twice."
|
|
194
|
-
else
|
|
195
|
-
raise SyntaxError, "You have a duplicate 'print' statement! Printing #{@value.value} twice."
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
puts @value.evaluate unless TEST_UNIT_ACTIVE
|
|
290
|
+
puts @value.evaluate unless TEST_UNIT_ACTIVE
|
|
199
291
|
end
|
|
292
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
200
293
|
self.class
|
|
201
294
|
end
|
|
202
295
|
end
|
|
@@ -206,8 +299,15 @@ class PauseNode < Node
|
|
|
206
299
|
super(value)
|
|
207
300
|
end
|
|
208
301
|
|
|
302
|
+
def create_tree_entry
|
|
303
|
+
result = set_up_scope_header
|
|
304
|
+
result += "Paused for #{@value} seconds."
|
|
305
|
+
TREE_ARRAY << result unless TREE_ARRAY[-1] == result
|
|
306
|
+
end
|
|
307
|
+
|
|
209
308
|
def evaluate
|
|
210
309
|
@value = 0 if @value.evaluate.negative?
|
|
310
|
+
create_tree_entry if PRINT_TREE_FLAG
|
|
211
311
|
sleep @value.evaluate
|
|
212
312
|
end
|
|
213
313
|
end
|
data/lib/rdparse.rb
CHANGED
|
@@ -187,81 +187,56 @@ class Parser
|
|
|
187
187
|
end # until
|
|
188
188
|
end
|
|
189
189
|
|
|
190
|
-
def
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
190
|
+
def convert_regex_sensitive_token(token)
|
|
191
|
+
token = @token_list['end'] if token == :STOP # fulhack pga :END påstods inte funka för länge sen
|
|
192
|
+
token = '[(]' if token == '('
|
|
193
|
+
token = '[)]' if token == ')'
|
|
194
|
+
token = '[+]' if token == '+'
|
|
195
|
+
token = '[-]' if token == '-'
|
|
196
|
+
token = '[*]' if token == '*'
|
|
197
|
+
token = '[/]' if token == '/'
|
|
198
|
+
token = "#{@token_list['(not|!)'].split('|')[0][1..]}" if token == :NOT
|
|
199
|
+
token = "#{@token_list['(and|&&)'].split('|')[0][1..]}" if token == :AND
|
|
200
|
+
token = "#{@token_list['(or|\|\|)'].split('|')[0][1..]}" if token == :OR
|
|
201
|
+
token
|
|
202
|
+
end
|
|
202
203
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
204
|
+
def translate_tokens_array(array)
|
|
205
|
+
result = []
|
|
206
|
+
array.each do |token|
|
|
207
|
+
token = convert_regex_sensitive_token(token)
|
|
208
|
+
result << token unless token.is_a?(Symbol)
|
|
209
|
+
result << @token_list[token.to_s.downcase] if token.is_a?(Symbol)
|
|
208
210
|
end
|
|
209
|
-
|
|
211
|
+
result
|
|
210
212
|
end
|
|
211
213
|
|
|
212
|
-
def
|
|
213
|
-
|
|
214
|
-
|
|
214
|
+
def find_surrounding_code(problem_pos)
|
|
215
|
+
tokens_before_problem = []
|
|
216
|
+
temp = problem_pos
|
|
217
|
+
while temp >= 0
|
|
218
|
+
tokens_before_problem << @tokens[temp]
|
|
219
|
+
temp -= 1
|
|
220
|
+
end
|
|
221
|
+
tokens_before_problem.reverse
|
|
215
222
|
end
|
|
216
223
|
|
|
217
224
|
def find_faulty_line
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
puts "Problem is in the end of the file after:\n #{@tokens[@max_pos - 3]}#{@tokens[@max_pos - 2]}#{@tokens[@max_pos - 1]}"
|
|
221
|
-
else
|
|
222
|
-
puts "Problem is right in the beginning of the file."
|
|
223
|
-
end
|
|
224
|
-
raise ParseError
|
|
225
|
-
end
|
|
226
|
-
|
|
227
|
-
problematic_token = "#{@tokens[@max_pos - 1].downcase}"
|
|
228
|
-
before_problem = "#{@tokens[@max_pos - 2].downcase}"
|
|
229
|
-
after_problem = "#{@tokens[@max_pos - 0].downcase}"
|
|
230
|
-
|
|
231
|
-
after_problem = "[" + after_problem + "]" if !after_problem.match?(/[a-z]/)
|
|
232
|
-
before_problem = "[" + before_problem + "]" if !before_problem.match?(/[a-z]/)
|
|
225
|
+
tokens_before_problem = find_surrounding_code(@max_pos - 1)
|
|
226
|
+
file_as_array_without_whitespaces = translate_tokens_array(tokens_before_problem)
|
|
233
227
|
|
|
234
|
-
|
|
228
|
+
pattern = file_as_array_without_whitespaces.join('\s*')
|
|
229
|
+
regex = Regexp.new(pattern)
|
|
235
230
|
|
|
236
|
-
|
|
237
|
-
puts "The problem is #{before_problem}#{problematic_token}#{after_problem}"
|
|
238
|
-
raise ParseError, "Faulty expression, this is not completely implemented."
|
|
239
|
-
end
|
|
231
|
+
cleaned_string = @file_string.gsub(/;;.*/, '')
|
|
240
232
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
found_end = false
|
|
244
|
-
@file_string.each_line do |line|
|
|
233
|
+
match_data = regex.match(cleaned_string)
|
|
234
|
+
num_lines = match_data[0].count("\n") + 1
|
|
245
235
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
end
|
|
236
|
+
problem = @tokens[@max_pos]
|
|
237
|
+
problem = @token_list[problem.to_s.downcase] unless @token_list[problem.to_s.downcase].is_a?(NilClass)
|
|
249
238
|
|
|
250
|
-
|
|
251
|
-
problem_match_hash[after_problem] = index
|
|
252
|
-
found_end = true
|
|
253
|
-
end
|
|
254
|
-
index += 1
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
non_empty_line_before_problem = problem_match_hash[before_problem]
|
|
258
|
-
non_empty_line_after_problem = problem_match_hash[after_problem]
|
|
259
|
-
|
|
260
|
-
unless after_problem == before_problem
|
|
261
|
-
find_faulty_expression_within_block(non_empty_line_before_problem, non_empty_line_after_problem, problematic_token)
|
|
262
|
-
else
|
|
263
|
-
find_faulty_expression_within_ends
|
|
264
|
-
end
|
|
239
|
+
raise ParseError, "There is a problem around line #{num_lines}. Found <#{problem}>"
|
|
265
240
|
end
|
|
266
241
|
|
|
267
242
|
def parse(string)
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: alphalang
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.9
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- mattias, victor
|
|
@@ -74,8 +74,6 @@ files:
|
|
|
74
74
|
- lib/nodes/scopemanager.rb
|
|
75
75
|
- lib/nodes/stmtnodes.rb
|
|
76
76
|
- lib/rdparse.rb
|
|
77
|
-
- lib/tester/assign.alpha
|
|
78
|
-
- lib/tester/assign.alpha~
|
|
79
77
|
- lib/tester/demo_de.alpha
|
|
80
78
|
- lib/tester/demo_emoji.alpha
|
|
81
79
|
- lib/tester/demo_emoji.alpha~
|
data/lib/tester/assign.alpha
DELETED