loxxy 0.0.20 → 0.0.25
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 +92 -31
- data/README.md +47 -10
- data/lib/loxxy/ast/all_lox_nodes.rb +5 -0
- data/lib/loxxy/ast/ast_builder.rb +42 -2
- 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 +28 -0
- data/lib/loxxy/ast/lox_variable_expr.rb +26 -0
- data/lib/loxxy/back_end/engine.rb +49 -2
- 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 +30 -0
- data/lib/loxxy/datatype/builtin_datatype.rb +6 -0
- data/lib/loxxy/front_end/grammar.rb +7 -7
- 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 +21 -19
- data/spec/interpreter_spec.rb +83 -4
- metadata +17 -2
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')
|
@@ -211,7 +218,7 @@ module Loxxy
|
|
211
218
|
end
|
212
219
|
end
|
213
220
|
|
214
|
-
it 'should
|
221
|
+
it 'should support expressions between parentheses' do
|
215
222
|
[
|
216
223
|
['3 + 4 * 5;', 23],
|
217
224
|
['(3 + 4) * 5;', 35],
|
@@ -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,11 +252,83 @@ 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
|
252
259
|
|
260
|
+
it 'should accept variable declarations' do
|
261
|
+
# Variable with initialization value
|
262
|
+
var_decl = 'var iAmAVariable = "here is my value";'
|
263
|
+
expect { subject.evaluate(var_decl) }.not_to raise_error
|
264
|
+
|
265
|
+
# Variable without initialization value
|
266
|
+
expect { subject.evaluate('var iAmNil;') }.not_to raise_error
|
267
|
+
end
|
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
|
+
|
253
332
|
it 'should print the hello world message' do
|
254
333
|
expect { subject.evaluate(hello_world) }.not_to raise_error
|
255
334
|
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.25
|
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-21 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,15 @@ 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
|
103
|
+
- lib/loxxy/ast/lox_var_stmt.rb
|
104
|
+
- lib/loxxy/ast/lox_variable_expr.rb
|
100
105
|
- lib/loxxy/back_end/engine.rb
|
106
|
+
- lib/loxxy/back_end/entry.rb
|
107
|
+
- lib/loxxy/back_end/environment.rb
|
108
|
+
- lib/loxxy/back_end/symbol_table.rb
|
109
|
+
- lib/loxxy/back_end/variable.rb
|
101
110
|
- lib/loxxy/datatype/all_datatypes.rb
|
102
111
|
- lib/loxxy/datatype/boolean.rb
|
103
112
|
- lib/loxxy/datatype/builtin_datatype.rb
|
@@ -115,6 +124,9 @@ files:
|
|
115
124
|
- lib/loxxy/version.rb
|
116
125
|
- loxxy.gemspec
|
117
126
|
- spec/back_end/engine_spec.rb
|
127
|
+
- spec/back_end/environment_spec.rb
|
128
|
+
- spec/back_end/symbol_table_spec.rb
|
129
|
+
- spec/back_end/variable_spec.rb
|
118
130
|
- spec/datatype/boolean_spec.rb
|
119
131
|
- spec/datatype/lx_string_spec.rb
|
120
132
|
- spec/datatype/nil_spec.rb
|
@@ -151,6 +163,9 @@ specification_version: 4
|
|
151
163
|
summary: An implementation of the Lox programming language. WIP
|
152
164
|
test_files:
|
153
165
|
- spec/back_end/engine_spec.rb
|
166
|
+
- spec/back_end/environment_spec.rb
|
167
|
+
- spec/back_end/symbol_table_spec.rb
|
168
|
+
- spec/back_end/variable_spec.rb
|
154
169
|
- spec/datatype/boolean_spec.rb
|
155
170
|
- spec/datatype/lx_string_spec.rb
|
156
171
|
- spec/datatype/nil_spec.rb
|