loxxy 0.0.17 → 0.0.22
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/CHANGELOG.md +61 -2
- data/README.md +164 -50
- data/lib/loxxy/ast/all_lox_nodes.rb +7 -1
- data/lib/loxxy/ast/ast_builder.rb +63 -3
- data/lib/loxxy/ast/ast_visitor.rb +68 -1
- data/lib/loxxy/ast/lox_grouping_expr.rb +23 -0
- data/lib/loxxy/ast/lox_if_stmt.rb +35 -0
- data/lib/loxxy/ast/lox_logical_expr.rb +28 -0
- data/lib/loxxy/ast/lox_seq_decl.rb +23 -0
- data/lib/loxxy/ast/lox_var_stmt.rb +28 -0
- data/lib/loxxy/ast/lox_variable_expr.rb +26 -0
- data/lib/loxxy/back_end/engine.rb +70 -1
- data/lib/loxxy/back_end/entry.rb +41 -0
- data/lib/loxxy/back_end/environment.rb +66 -0
- data/lib/loxxy/back_end/symbol_table.rb +135 -0
- data/lib/loxxy/back_end/variable.rb +25 -0
- data/lib/loxxy/datatype/builtin_datatype.rb +32 -5
- data/lib/loxxy/front_end/grammar.rb +9 -9
- data/lib/loxxy/interpreter.rb +1 -1
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/engine_spec.rb +9 -0
- data/spec/back_end/environment_spec.rb +74 -0
- data/spec/back_end/symbol_table_spec.rb +142 -0
- data/spec/back_end/variable_spec.rb +79 -0
- data/spec/front_end/parser_spec.rb +25 -23
- data/spec/interpreter_spec.rb +110 -1
- metadata +18 -2
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../spec_helper' # Use the RSpec framework
|
4
|
+
|
5
|
+
# Load the class under test
|
6
|
+
require_relative '../../lib/loxxy/back_end/variable'
|
7
|
+
|
8
|
+
|
9
|
+
module Loxxy
|
10
|
+
module BackEnd
|
11
|
+
describe Variable do
|
12
|
+
let(:sample_name) { 'iAmAVariable' }
|
13
|
+
let(:sample_value) { 'here is my value' }
|
14
|
+
subject { Variable.new(sample_name, sample_value) }
|
15
|
+
|
16
|
+
context 'Initialization:' do
|
17
|
+
it 'should be initialized with a name and a value, or...' do
|
18
|
+
expect { Variable.new(sample_name, sample_value) }.not_to raise_error
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should be initialized with just a name' do
|
22
|
+
expect { Variable.new(sample_name) }.not_to raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should know its name' do
|
26
|
+
expect(subject.name).to eq(sample_name)
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'should have a frozen name' do
|
30
|
+
expect(subject.name).to be_frozen
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'should know its value (if provided)' do
|
34
|
+
expect(subject.value).to eq(sample_value)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should have a nil value otherwise' do
|
38
|
+
instance = Variable.new(sample_name)
|
39
|
+
expect(instance.value).to eq(Datatype::Nil.instance)
|
40
|
+
end
|
41
|
+
|
42
|
+
# it 'should know its default internal name' do
|
43
|
+
# # By default: internal name == label
|
44
|
+
# expect(subject.i_name).to eq(subject.label)
|
45
|
+
# end
|
46
|
+
|
47
|
+
# it 'should have a nil suffix' do
|
48
|
+
# expect(subject.suffix).to be_nil
|
49
|
+
# end
|
50
|
+
end # context
|
51
|
+
|
52
|
+
context 'Provided service:' do
|
53
|
+
let(:sample_suffix) { 'sample-suffix' }
|
54
|
+
it 'should have a label equal to its user-defined name' do
|
55
|
+
# expect(subject.label).to eq(subject.name)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'should accept a suffix' do
|
59
|
+
# expect { subject.suffix = sample_suffix }.not_to raise_error
|
60
|
+
# expect(subject.suffix).to eq(sample_suffix)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should calculate its internal name' do
|
64
|
+
# # Rule: empty suffix => internal name == label
|
65
|
+
# subject.suffix = ''
|
66
|
+
# expect(subject.i_name).to eq(subject.label)
|
67
|
+
|
68
|
+
# # Rule: suffix starting underscore: internal name = label + suffix
|
69
|
+
# subject.suffix = '_10'
|
70
|
+
# expect(subject.i_name).to eq(subject.label + subject.suffix)
|
71
|
+
|
72
|
+
# # Rule: ... otherwise: internal name == suffix
|
73
|
+
# subject.suffix = sample_suffix
|
74
|
+
# expect(subject.i_name).to eq(subject.suffix)
|
75
|
+
end
|
76
|
+
end # context
|
77
|
+
end # describe
|
78
|
+
end # module
|
79
|
+
end # module
|
@@ -64,7 +64,8 @@ module Loxxy
|
|
64
64
|
it 'should parse a false literal' do
|
65
65
|
input = 'false;'
|
66
66
|
ptree = subject.parse(input)
|
67
|
-
|
67
|
+
expect(ptree.root).to be_kind_of(Ast::LoxSeqDecl)
|
68
|
+
leaf = ptree.root.subnodes[0]
|
68
69
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
69
70
|
expect(leaf.literal).to be_equal(Datatype::False.instance)
|
70
71
|
end
|
@@ -72,7 +73,8 @@ module Loxxy
|
|
72
73
|
it 'should parse a true literal' do
|
73
74
|
input = 'true;'
|
74
75
|
ptree = subject.parse(input)
|
75
|
-
|
76
|
+
expect(ptree.root).to be_kind_of(Ast::LoxSeqDecl)
|
77
|
+
leaf = ptree.root.subnodes[0]
|
76
78
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
77
79
|
expect(leaf.literal).to be_equal(Datatype::True.instance)
|
78
80
|
end
|
@@ -81,7 +83,7 @@ module Loxxy
|
|
81
83
|
inputs = %w[1234; 12.34;]
|
82
84
|
inputs.each do |source|
|
83
85
|
ptree = subject.parse(source)
|
84
|
-
leaf = ptree.root
|
86
|
+
leaf = ptree.root.subnodes[0]
|
85
87
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
86
88
|
expect(leaf.literal).to be_kind_of(Datatype::Number)
|
87
89
|
expect(leaf.literal.value).to eq(source.to_f)
|
@@ -96,7 +98,7 @@ module Loxxy
|
|
96
98
|
]
|
97
99
|
inputs.each do |source|
|
98
100
|
ptree = subject.parse(source)
|
99
|
-
leaf = ptree.root
|
101
|
+
leaf = ptree.root.subnodes[0]
|
100
102
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
101
103
|
expect(leaf.literal).to be_kind_of(Datatype::LXString)
|
102
104
|
expect(leaf.literal.value).to eq(source.gsub(/(^")|(";$)/, ''))
|
@@ -106,7 +108,7 @@ module Loxxy
|
|
106
108
|
it 'should parse a nil literal' do
|
107
109
|
input = 'nil;'
|
108
110
|
ptree = subject.parse(input)
|
109
|
-
leaf = ptree.root
|
111
|
+
leaf = ptree.root.subnodes[0]
|
110
112
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
111
113
|
expect(leaf.literal).to be_equal(Datatype::Nil.instance)
|
112
114
|
end
|
@@ -119,7 +121,7 @@ module Loxxy
|
|
119
121
|
print "Hello, world!";
|
120
122
|
LOX_END
|
121
123
|
ptree = subject.parse(program)
|
122
|
-
prnt_stmt = ptree.root
|
124
|
+
prnt_stmt = ptree.root.subnodes[0]
|
123
125
|
expect(prnt_stmt).to be_kind_of(Ast::LoxPrintStmt)
|
124
126
|
expect(prnt_stmt.subnodes[0]).to be_kind_of(Ast::LoxLiteralExpr)
|
125
127
|
expect(prnt_stmt.subnodes[0].literal).to be_kind_of(Loxxy::Datatype::LXString)
|
@@ -131,7 +133,7 @@ LOX_END
|
|
131
133
|
it 'should parse the addition of two number literals' do
|
132
134
|
input = '123 + 456;'
|
133
135
|
ptree = subject.parse(input)
|
134
|
-
expr = ptree.root
|
136
|
+
expr = ptree.root.subnodes[0]
|
135
137
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
136
138
|
expect(expr.operator).to eq(:+)
|
137
139
|
expect(expr.operands[0].literal.value).to eq(123)
|
@@ -141,7 +143,7 @@ LOX_END
|
|
141
143
|
it 'should parse the subtraction of two number literals' do
|
142
144
|
input = '4 - 3;'
|
143
145
|
ptree = subject.parse(input)
|
144
|
-
expr = ptree.root
|
146
|
+
expr = ptree.root.subnodes[0]
|
145
147
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
146
148
|
expect(expr.operator).to eq(:-)
|
147
149
|
expect(expr.operands[0].literal.value).to eq(4)
|
@@ -151,7 +153,7 @@ LOX_END
|
|
151
153
|
it 'should parse multiple additive operations' do
|
152
154
|
input = '5 + 2 - 3;'
|
153
155
|
ptree = subject.parse(input)
|
154
|
-
expr = ptree.root
|
156
|
+
expr = ptree.root.subnodes[0]
|
155
157
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
156
158
|
expect(expr.operator).to eq(:-)
|
157
159
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
@@ -164,7 +166,7 @@ LOX_END
|
|
164
166
|
it 'should parse the division of two number literals' do
|
165
167
|
input = '8 / 2;'
|
166
168
|
ptree = subject.parse(input)
|
167
|
-
expr = ptree.root
|
169
|
+
expr = ptree.root.subnodes[0]
|
168
170
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
169
171
|
expect(expr.operator).to eq(:/)
|
170
172
|
expect(expr.operands[0].literal.value).to eq(8)
|
@@ -174,7 +176,7 @@ LOX_END
|
|
174
176
|
it 'should parse the product of two number literals' do
|
175
177
|
input = '12.34 * 0.3;'
|
176
178
|
ptree = subject.parse(input)
|
177
|
-
expr = ptree.root
|
179
|
+
expr = ptree.root.subnodes[0]
|
178
180
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
179
181
|
expect(expr.operator).to eq(:*)
|
180
182
|
expect(expr.operands[0].literal.value).to eq(12.34)
|
@@ -184,7 +186,7 @@ LOX_END
|
|
184
186
|
it 'should parse multiple multiplicative operations' do
|
185
187
|
input = '5 * 2 / 3;'
|
186
188
|
ptree = subject.parse(input)
|
187
|
-
expr = ptree.root
|
189
|
+
expr = ptree.root.subnodes[0]
|
188
190
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
189
191
|
expect(expr.operator).to eq(:/)
|
190
192
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
@@ -197,7 +199,7 @@ LOX_END
|
|
197
199
|
it 'should parse combination of terms and factors' do
|
198
200
|
input = '5 + 2 / 3;'
|
199
201
|
ptree = subject.parse(input)
|
200
|
-
expr = ptree.root
|
202
|
+
expr = ptree.root.subnodes[0]
|
201
203
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
202
204
|
expect(expr.operator).to eq(:+)
|
203
205
|
expect(expr.operands[0].literal.value).to eq(5)
|
@@ -212,7 +214,7 @@ LOX_END
|
|
212
214
|
it 'should parse the concatenation of two string literals' do
|
213
215
|
input = '"Lo" + "ve";'
|
214
216
|
ptree = subject.parse(input)
|
215
|
-
expr = ptree.root
|
217
|
+
expr = ptree.root.subnodes[0]
|
216
218
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
217
219
|
expect(expr.operator).to eq(:+)
|
218
220
|
expect(expr.operands[0].literal.value).to eq('Lo')
|
@@ -225,7 +227,7 @@ LOX_END
|
|
225
227
|
%w[> >= < <=].each do |predicate|
|
226
228
|
input = "3 #{predicate} 2;"
|
227
229
|
ptree = subject.parse(input)
|
228
|
-
expr = ptree.root
|
230
|
+
expr = ptree.root.subnodes[0]
|
229
231
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
230
232
|
expect(expr.operator).to eq(predicate.to_sym)
|
231
233
|
expect(expr.operands[0].literal.value).to eq(3)
|
@@ -239,7 +241,7 @@ LOX_END
|
|
239
241
|
%w[!= ==].each do |predicate|
|
240
242
|
input = "3 #{predicate} 2;"
|
241
243
|
ptree = subject.parse(input)
|
242
|
-
expr = ptree.root
|
244
|
+
expr = ptree.root.subnodes[0]
|
243
245
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
244
246
|
expect(expr.operator).to eq(predicate.to_sym)
|
245
247
|
expect(expr.operands[0].literal.value).to eq(3)
|
@@ -250,7 +252,7 @@ LOX_END
|
|
250
252
|
it 'should parse combination of equality expressions' do
|
251
253
|
input = '5 != 2 == false; // A bit contrived example'
|
252
254
|
ptree = subject.parse(input)
|
253
|
-
expr = ptree.root
|
255
|
+
expr = ptree.root.subnodes[0]
|
254
256
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
255
257
|
expect(expr.operator).to eq(:==)
|
256
258
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
@@ -262,12 +264,12 @@ LOX_END
|
|
262
264
|
end # context
|
263
265
|
|
264
266
|
context 'Parsing logical expressions' do
|
265
|
-
it 'should parse the logical operations
|
267
|
+
it 'should parse the logical operations between two sub-expression' do
|
266
268
|
%w[or and].each do |connector|
|
267
269
|
input = "5 > 2 #{connector} 3 <= 4;"
|
268
270
|
ptree = subject.parse(input)
|
269
|
-
expr = ptree.root
|
270
|
-
expect(expr).to be_kind_of(Ast::
|
271
|
+
expr = ptree.root.subnodes[0]
|
272
|
+
expect(expr).to be_kind_of(Ast::LoxLogicalExpr)
|
271
273
|
expect(expr.operator).to eq(connector.to_sym)
|
272
274
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
273
275
|
expect(expr.operands[0].operator).to eq(:>)
|
@@ -283,10 +285,10 @@ LOX_END
|
|
283
285
|
it 'should parse a combinations of logical expressions' do
|
284
286
|
input = '4 > 3 and 1 < 2 or 4 >= 5;'
|
285
287
|
ptree = subject.parse(input)
|
286
|
-
expr = ptree.root
|
287
|
-
expect(expr).to be_kind_of(Ast::
|
288
|
+
expr = ptree.root.subnodes[0]
|
289
|
+
expect(expr).to be_kind_of(Ast::LoxLogicalExpr)
|
288
290
|
expect(expr.operator).to eq(:or) # or has lower precedence than and
|
289
|
-
expect(expr.operands[0]).to be_kind_of(Ast::
|
291
|
+
expect(expr.operands[0]).to be_kind_of(Ast::LoxLogicalExpr)
|
290
292
|
expect(expr.operands[0].operator).to eq(:and)
|
291
293
|
conjuncts = expr.operands[0].operands
|
292
294
|
expect(conjuncts[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
data/spec/interpreter_spec.rb
CHANGED
@@ -52,7 +52,12 @@ module Loxxy
|
|
52
52
|
end # context
|
53
53
|
|
54
54
|
context 'Evaluating Lox code:' do
|
55
|
-
let(:hello_world)
|
55
|
+
let(:hello_world) do
|
56
|
+
lox =<<-LOX_END
|
57
|
+
var greeting = "Hello"; // Declaring a variable
|
58
|
+
print greeting + ", " + "world!"; // ... Playing with concatenation
|
59
|
+
LOX_END
|
60
|
+
end
|
56
61
|
|
57
62
|
it 'should evaluate core data types' do
|
58
63
|
result = subject.evaluate('true; // Not false')
|
@@ -164,6 +169,110 @@ module Loxxy
|
|
164
169
|
end
|
165
170
|
end
|
166
171
|
|
172
|
+
it 'should evaluate the "conjunction" of two values' do
|
173
|
+
[
|
174
|
+
# Return the first falsey argument
|
175
|
+
['false and 1;', false],
|
176
|
+
['nil and 1;', nil],
|
177
|
+
['true and 1;', 1],
|
178
|
+
['1 and 2 and false;', false],
|
179
|
+
['1 and 2 and nil;', nil],
|
180
|
+
|
181
|
+
# Return the last argument if all are truthy
|
182
|
+
['1 and true;', true],
|
183
|
+
['0 and true;', true],
|
184
|
+
['"false" and 0;', 0],
|
185
|
+
['1 and 2 and 3;', 3]
|
186
|
+
|
187
|
+
# TODO test short-circuit at first false argument
|
188
|
+
].each do |(source, predicted)|
|
189
|
+
lox = Loxxy::Interpreter.new
|
190
|
+
result = lox.evaluate(source)
|
191
|
+
expect(result.value == predicted).to be_truthy
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'should evaluate the "disjunction" of two values' do
|
196
|
+
[
|
197
|
+
# Return the first truthy argument
|
198
|
+
['1 or true;', 1],
|
199
|
+
['false or 1;', 1],
|
200
|
+
['nil or 1;', 1],
|
201
|
+
['false or false or true;', true],
|
202
|
+
['1 and 2 and nil;', nil],
|
203
|
+
|
204
|
+
# Return the last argument if all are falsey
|
205
|
+
['false or false;', false],
|
206
|
+
['nil or false;', false],
|
207
|
+
['false or nil;', nil],
|
208
|
+
['false or false or false;', false],
|
209
|
+
['false or false or nil;', nil]
|
210
|
+
|
211
|
+
# TODO test short-circuit at first false argument
|
212
|
+
].each do |(source, predicted)|
|
213
|
+
lox = Loxxy::Interpreter.new
|
214
|
+
result = lox.evaluate(source)
|
215
|
+
expect(result.value == predicted).to be_truthy
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
it 'should support expressions between parentheses' do
|
220
|
+
[
|
221
|
+
['3 + 4 * 5;', 23],
|
222
|
+
['(3 + 4) * 5;', 35],
|
223
|
+
['(5 - (3 - 1)) + -(1);', 2]
|
224
|
+
].each do |(source, predicted)|
|
225
|
+
lox = Loxxy::Interpreter.new
|
226
|
+
result = lox.evaluate(source)
|
227
|
+
expect(result.value == predicted).to be_truthy
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
it 'should evaluate an if statement' do
|
232
|
+
[
|
233
|
+
# Evaluate the 'then' expression if the condition is true.
|
234
|
+
['if (true) print "then-branch";', 'then-branch'],
|
235
|
+
['if (false) print "ignored";', ''],
|
236
|
+
# TODO: test with then block body
|
237
|
+
# TODO: test with assignment in if condition
|
238
|
+
|
239
|
+
# Evaluate the 'else' expression if the condition is false.
|
240
|
+
['if (true) print "then-branch"; else print "else-branch";', 'then-branch'],
|
241
|
+
['if (false) print "then-branch"; else print "else-branch";', 'else-branch'],
|
242
|
+
['if (0) print "then-branch"; else print "else-branch";', 'then-branch'],
|
243
|
+
['if (nil) print "then-branch"; else print "else-branch";', 'else-branch'],
|
244
|
+
# TODO: test with else block body
|
245
|
+
|
246
|
+
# TODO: A dangling else binds to the right-most if.
|
247
|
+
# ['if (true) if (false) print "bad"; else print "good";', 'good'],
|
248
|
+
# ['if (false) if (true) print "bad"; else print "worse";', 'bad']
|
249
|
+
].each do |(source, predicted)|
|
250
|
+
io = StringIO.new
|
251
|
+
cfg = { ostream: io }
|
252
|
+
lox = Loxxy::Interpreter.new(cfg)
|
253
|
+
result = lox.evaluate(source)
|
254
|
+
expect(io.string).to eq(predicted)
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'should accept variable declarations' do
|
259
|
+
# Variable with initialization value
|
260
|
+
var_decl = 'var iAmAVariable = "here is my value";'
|
261
|
+
expect { subject.evaluate(var_decl) }.not_to raise_error
|
262
|
+
|
263
|
+
# Variable without initialization value
|
264
|
+
expect { subject.evaluate('var iAmNil;') }.not_to raise_error
|
265
|
+
end
|
266
|
+
|
267
|
+
it 'should accept variable mention' do
|
268
|
+
program = <<-LOX_END
|
269
|
+
var foo = "bar";
|
270
|
+
print foo;
|
271
|
+
LOX_END
|
272
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
273
|
+
expect(sample_cfg[:ostream].string).to eq('bar')
|
274
|
+
end
|
275
|
+
|
167
276
|
it 'should print the hello world message' do
|
168
277
|
expect { subject.evaluate(hello_world) }.not_to raise_error
|
169
278
|
expect(sample_cfg[:ostream].string).to eq('Hello, world!')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loxxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.22
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-01-
|
11
|
+
date: 2021-01-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -89,12 +89,22 @@ files:
|
|
89
89
|
- lib/loxxy/ast/ast_visitor.rb
|
90
90
|
- lib/loxxy/ast/lox_binary_expr.rb
|
91
91
|
- lib/loxxy/ast/lox_compound_expr.rb
|
92
|
+
- lib/loxxy/ast/lox_grouping_expr.rb
|
93
|
+
- lib/loxxy/ast/lox_if_stmt.rb
|
92
94
|
- lib/loxxy/ast/lox_literal_expr.rb
|
95
|
+
- lib/loxxy/ast/lox_logical_expr.rb
|
93
96
|
- lib/loxxy/ast/lox_node.rb
|
94
97
|
- lib/loxxy/ast/lox_noop_expr.rb
|
95
98
|
- lib/loxxy/ast/lox_print_stmt.rb
|
99
|
+
- lib/loxxy/ast/lox_seq_decl.rb
|
96
100
|
- lib/loxxy/ast/lox_unary_expr.rb
|
101
|
+
- lib/loxxy/ast/lox_var_stmt.rb
|
102
|
+
- lib/loxxy/ast/lox_variable_expr.rb
|
97
103
|
- lib/loxxy/back_end/engine.rb
|
104
|
+
- lib/loxxy/back_end/entry.rb
|
105
|
+
- lib/loxxy/back_end/environment.rb
|
106
|
+
- lib/loxxy/back_end/symbol_table.rb
|
107
|
+
- lib/loxxy/back_end/variable.rb
|
98
108
|
- lib/loxxy/datatype/all_datatypes.rb
|
99
109
|
- lib/loxxy/datatype/boolean.rb
|
100
110
|
- lib/loxxy/datatype/builtin_datatype.rb
|
@@ -112,6 +122,9 @@ files:
|
|
112
122
|
- lib/loxxy/version.rb
|
113
123
|
- loxxy.gemspec
|
114
124
|
- spec/back_end/engine_spec.rb
|
125
|
+
- spec/back_end/environment_spec.rb
|
126
|
+
- spec/back_end/symbol_table_spec.rb
|
127
|
+
- spec/back_end/variable_spec.rb
|
115
128
|
- spec/datatype/boolean_spec.rb
|
116
129
|
- spec/datatype/lx_string_spec.rb
|
117
130
|
- spec/datatype/nil_spec.rb
|
@@ -148,6 +161,9 @@ specification_version: 4
|
|
148
161
|
summary: An implementation of the Lox programming language. WIP
|
149
162
|
test_files:
|
150
163
|
- spec/back_end/engine_spec.rb
|
164
|
+
- spec/back_end/environment_spec.rb
|
165
|
+
- spec/back_end/symbol_table_spec.rb
|
166
|
+
- spec/back_end/variable_spec.rb
|
151
167
|
- spec/datatype/boolean_spec.rb
|
152
168
|
- spec/datatype/lx_string_spec.rb
|
153
169
|
- spec/datatype/nil_spec.rb
|