loxxy 0.0.21 → 0.0.26
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 +93 -33
- data/README.md +46 -11
- data/lib/loxxy/ast/all_lox_nodes.rb +5 -0
- data/lib/loxxy/ast/ast_builder.rb +35 -3
- data/lib/loxxy/ast/ast_visitor.rb +47 -1
- data/lib/loxxy/ast/lox_assign_expr.rb +27 -0
- data/lib/loxxy/ast/lox_block_stmt.rb +23 -0
- data/lib/loxxy/ast/lox_if_stmt.rb +1 -1
- data/lib/loxxy/ast/lox_seq_decl.rb +17 -0
- data/lib/loxxy/ast/lox_var_stmt.rb +1 -1
- data/lib/loxxy/ast/lox_variable_expr.rb +26 -0
- data/lib/loxxy/ast/lox_while_stmt.rb +32 -0
- data/lib/loxxy/back_end/engine.rb +48 -1
- data/lib/loxxy/back_end/entry.rb +2 -2
- data/lib/loxxy/back_end/environment.rb +3 -3
- data/lib/loxxy/back_end/symbol_table.rb +3 -3
- data/lib/loxxy/back_end/variable.rb +7 -2
- data/lib/loxxy/datatype/builtin_datatype.rb +6 -0
- data/lib/loxxy/front_end/grammar.rb +6 -6
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/engine_spec.rb +1 -0
- data/spec/back_end/environment_spec.rb +2 -2
- data/spec/back_end/symbol_table_spec.rb +3 -3
- data/spec/back_end/variable_spec.rb +4 -4
- data/spec/front_end/parser_spec.rb +21 -19
- data/spec/interpreter_spec.rb +102 -3
- metadata +7 -2
@@ -34,6 +34,7 @@ module Loxxy
|
|
34
34
|
let(:var_decl) { Ast::LoxVarStmt.new(sample_pos, 'greeting', greeting) }
|
35
35
|
let(:lit_expr) { Ast::LoxLiteralExpr.new(sample_pos, greeting) }
|
36
36
|
|
37
|
+
|
37
38
|
it "should react to 'after_var_stmt' event" do
|
38
39
|
expect { subject.after_var_stmt(var_decl) }.not_to raise_error
|
39
40
|
current_env = subject.symbol_table.current_env
|
@@ -9,7 +9,7 @@ module Loxxy
|
|
9
9
|
module BackEnd
|
10
10
|
describe Environment do
|
11
11
|
let(:foo) { Datatype::LXString.new('foo') }
|
12
|
-
let(:bar) { Datatype::LXString.new('bar') }
|
12
|
+
let(:bar) { Datatype::LXString.new('bar') }
|
13
13
|
let(:mother) { Environment.new }
|
14
14
|
subject { Environment.new(mother) }
|
15
15
|
|
@@ -32,7 +32,7 @@ module Loxxy
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it 'should know its parent (if any)' do
|
35
|
-
expect(subject.
|
35
|
+
expect(subject.enclosing).to eq(mother)
|
36
36
|
end
|
37
37
|
end # context
|
38
38
|
|
@@ -46,8 +46,8 @@ module Loxxy
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'should allow the addition of several labels for same env' do
|
49
|
-
|
50
|
-
#expect(i_name).to match(/^q_[0-9a-z]*$/)
|
49
|
+
subject.insert(var('q'))
|
50
|
+
# expect(i_name).to match(/^q_[0-9a-z]*$/)
|
51
51
|
|
52
52
|
expect { subject.insert(var('x')) }.not_to raise_error
|
53
53
|
expect(subject.name2envs['x']).to be_kind_of(Array)
|
@@ -60,7 +60,7 @@ module Loxxy
|
|
60
60
|
new_env = BackEnd::Environment.new
|
61
61
|
expect { subject.enter_environment(new_env) }.not_to raise_error
|
62
62
|
expect(subject.current_env).to eq(new_env)
|
63
|
-
expect(subject.current_env.
|
63
|
+
expect(subject.current_env.enclosing).to eq(subject.root)
|
64
64
|
expect(subject.name2envs['q']).to eq([subject.root])
|
65
65
|
end
|
66
66
|
|
@@ -17,10 +17,10 @@ module Loxxy
|
|
17
17
|
it 'should be initialized with a name and a value, or...' do
|
18
18
|
expect { Variable.new(sample_name, sample_value) }.not_to raise_error
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it 'should be initialized with just a name' do
|
22
22
|
expect { Variable.new(sample_name) }.not_to raise_error
|
23
|
-
end
|
23
|
+
end
|
24
24
|
|
25
25
|
it 'should know its name' do
|
26
26
|
expect(subject.name).to eq(sample_name)
|
@@ -29,11 +29,11 @@ module Loxxy
|
|
29
29
|
it 'should have a frozen name' do
|
30
30
|
expect(subject.name).to be_frozen
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
it 'should know its value (if provided)' do
|
34
34
|
expect(subject.value).to eq(sample_value)
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
it 'should have a nil value otherwise' do
|
38
38
|
instance = Variable.new(sample_name)
|
39
39
|
expect(instance.value).to eq(Datatype::Nil.instance)
|
@@ -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)
|
@@ -266,7 +268,7 @@ LOX_END
|
|
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
|
271
|
+
expr = ptree.root.subnodes[0]
|
270
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)
|
@@ -283,7 +285,7 @@ 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
|
288
|
+
expr = ptree.root.subnodes[0]
|
287
289
|
expect(expr).to be_kind_of(Ast::LoxLogicalExpr)
|
288
290
|
expect(expr.operator).to eq(:or) # or has lower precedence than and
|
289
291
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxLogicalExpr)
|
data/spec/interpreter_spec.rb
CHANGED
@@ -52,7 +52,14 @@ 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
|
+
|
61
|
+
lox
|
62
|
+
end
|
56
63
|
|
57
64
|
it 'should evaluate core data types' do
|
58
65
|
result = subject.evaluate('true; // Not false')
|
@@ -235,7 +242,7 @@ module Loxxy
|
|
235
242
|
['if (true) print "then-branch"; else print "else-branch";', 'then-branch'],
|
236
243
|
['if (false) print "then-branch"; else print "else-branch";', 'else-branch'],
|
237
244
|
['if (0) print "then-branch"; else print "else-branch";', 'then-branch'],
|
238
|
-
['if (nil) print "then-branch"; else print "else-branch";', 'else-branch']
|
245
|
+
['if (nil) print "then-branch"; else print "else-branch";', 'else-branch']
|
239
246
|
# TODO: test with else block body
|
240
247
|
|
241
248
|
# TODO: A dangling else binds to the right-most if.
|
@@ -245,7 +252,7 @@ module Loxxy
|
|
245
252
|
io = StringIO.new
|
246
253
|
cfg = { ostream: io }
|
247
254
|
lox = Loxxy::Interpreter.new(cfg)
|
248
|
-
|
255
|
+
lox.evaluate(source)
|
249
256
|
expect(io.string).to eq(predicted)
|
250
257
|
end
|
251
258
|
end
|
@@ -259,6 +266,98 @@ module Loxxy
|
|
259
266
|
expect { subject.evaluate('var iAmNil;') }.not_to raise_error
|
260
267
|
end
|
261
268
|
|
269
|
+
it 'should accept variable mention' do
|
270
|
+
program = <<-LOX_END
|
271
|
+
var foo = "bar";
|
272
|
+
print foo; // => bar
|
273
|
+
LOX_END
|
274
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
275
|
+
expect(sample_cfg[:ostream].string).to eq('bar')
|
276
|
+
end
|
277
|
+
|
278
|
+
it 'should set uninitialized variables to nil' do
|
279
|
+
program = <<-LOX_END
|
280
|
+
var a;
|
281
|
+
print a; // => nil
|
282
|
+
LOX_END
|
283
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
284
|
+
expect(sample_cfg[:ostream].string).to eq('nil')
|
285
|
+
end
|
286
|
+
|
287
|
+
it 'should accept assignments to a global variable' do
|
288
|
+
program = <<-LOX_END
|
289
|
+
var a = "before";
|
290
|
+
print a; // output: before
|
291
|
+
|
292
|
+
a = "after";
|
293
|
+
print a; // output: after
|
294
|
+
|
295
|
+
print a = "arg"; // output: arg
|
296
|
+
print a; // output: arg
|
297
|
+
LOX_END
|
298
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
299
|
+
expect(sample_cfg[:ostream].string).to eq('beforeafterargarg')
|
300
|
+
end
|
301
|
+
|
302
|
+
it 'should support variables local to a block' do
|
303
|
+
program = <<-LOX_END
|
304
|
+
{
|
305
|
+
var a = "first";
|
306
|
+
print a;
|
307
|
+
}
|
308
|
+
{
|
309
|
+
var a = "second";
|
310
|
+
print a;
|
311
|
+
}
|
312
|
+
LOX_END
|
313
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
314
|
+
expect(sample_cfg[:ostream].string).to eq('firstsecond')
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'should support the shadowing of variables in a block' do
|
318
|
+
program = <<-LOX_END
|
319
|
+
var a = "outer";
|
320
|
+
|
321
|
+
{
|
322
|
+
var a = "inner";
|
323
|
+
print a; // output: inner
|
324
|
+
}
|
325
|
+
|
326
|
+
print a; // output: outer
|
327
|
+
LOX_END
|
328
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
329
|
+
expect(sample_cfg[:ostream].string).to eq('innerouter')
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'should implement single statement while loops' do
|
333
|
+
program = <<-LOX_END
|
334
|
+
// Single-expression body.
|
335
|
+
var c = 0;
|
336
|
+
while (c < 3) print c = c + 1;
|
337
|
+
// output: 1
|
338
|
+
// output: 2
|
339
|
+
// output: 3
|
340
|
+
LOX_END
|
341
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
342
|
+
expect(sample_cfg[:ostream].string).to eq('123')
|
343
|
+
end
|
344
|
+
|
345
|
+
it 'should implement block body while loops' do
|
346
|
+
program = <<-LOX_END
|
347
|
+
// Block body.
|
348
|
+
var a = 0;
|
349
|
+
while (a < 3) {
|
350
|
+
print a;
|
351
|
+
a = a + 1;
|
352
|
+
}
|
353
|
+
// output: 0
|
354
|
+
// output: 1
|
355
|
+
// output: 2
|
356
|
+
LOX_END
|
357
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
358
|
+
expect(sample_cfg[:ostream].string).to eq('012')
|
359
|
+
end
|
360
|
+
|
262
361
|
it 'should print the hello world message' do
|
263
362
|
expect { subject.evaluate(hello_world) }.not_to raise_error
|
264
363
|
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.26
|
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-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -87,7 +87,9 @@ files:
|
|
87
87
|
- lib/loxxy/ast/all_lox_nodes.rb
|
88
88
|
- lib/loxxy/ast/ast_builder.rb
|
89
89
|
- lib/loxxy/ast/ast_visitor.rb
|
90
|
+
- lib/loxxy/ast/lox_assign_expr.rb
|
90
91
|
- lib/loxxy/ast/lox_binary_expr.rb
|
92
|
+
- lib/loxxy/ast/lox_block_stmt.rb
|
91
93
|
- lib/loxxy/ast/lox_compound_expr.rb
|
92
94
|
- lib/loxxy/ast/lox_grouping_expr.rb
|
93
95
|
- lib/loxxy/ast/lox_if_stmt.rb
|
@@ -96,8 +98,11 @@ files:
|
|
96
98
|
- lib/loxxy/ast/lox_node.rb
|
97
99
|
- lib/loxxy/ast/lox_noop_expr.rb
|
98
100
|
- lib/loxxy/ast/lox_print_stmt.rb
|
101
|
+
- lib/loxxy/ast/lox_seq_decl.rb
|
99
102
|
- lib/loxxy/ast/lox_unary_expr.rb
|
100
103
|
- lib/loxxy/ast/lox_var_stmt.rb
|
104
|
+
- lib/loxxy/ast/lox_variable_expr.rb
|
105
|
+
- lib/loxxy/ast/lox_while_stmt.rb
|
101
106
|
- lib/loxxy/back_end/engine.rb
|
102
107
|
- lib/loxxy/back_end/entry.rb
|
103
108
|
- lib/loxxy/back_end/environment.rb
|