loxxy 0.0.19 → 0.0.24
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 +91 -30
- data/README.md +64 -5
- data/lib/loxxy/ast/all_lox_nodes.rb +5 -0
- data/lib/loxxy/ast/ast_builder.rb +44 -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_if_stmt.rb +35 -0
- 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 -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 +30 -0
- data/lib/loxxy/datatype/builtin_datatype.rb +6 -0
- 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 +21 -19
- data/spec/interpreter_spec.rb +78 -2
- 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],
|
@@ -223,6 +230,75 @@ module Loxxy
|
|
223
230
|
end
|
224
231
|
end
|
225
232
|
|
233
|
+
it 'should evaluate an if statement' do
|
234
|
+
[
|
235
|
+
# Evaluate the 'then' expression if the condition is true.
|
236
|
+
['if (true) print "then-branch";', 'then-branch'],
|
237
|
+
['if (false) print "ignored";', ''],
|
238
|
+
# TODO: test with then block body
|
239
|
+
# TODO: test with assignment in if condition
|
240
|
+
|
241
|
+
# Evaluate the 'else' expression if the condition is false.
|
242
|
+
['if (true) print "then-branch"; else print "else-branch";', 'then-branch'],
|
243
|
+
['if (false) print "then-branch"; else print "else-branch";', 'else-branch'],
|
244
|
+
['if (0) print "then-branch"; else print "else-branch";', 'then-branch'],
|
245
|
+
['if (nil) print "then-branch"; else print "else-branch";', 'else-branch']
|
246
|
+
# TODO: test with else block body
|
247
|
+
|
248
|
+
# TODO: A dangling else binds to the right-most if.
|
249
|
+
# ['if (true) if (false) print "bad"; else print "good";', 'good'],
|
250
|
+
# ['if (false) if (true) print "bad"; else print "worse";', 'bad']
|
251
|
+
].each do |(source, predicted)|
|
252
|
+
io = StringIO.new
|
253
|
+
cfg = { ostream: io }
|
254
|
+
lox = Loxxy::Interpreter.new(cfg)
|
255
|
+
lox.evaluate(source)
|
256
|
+
expect(io.string).to eq(predicted)
|
257
|
+
end
|
258
|
+
end
|
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
|
+
|
226
302
|
it 'should print the hello world message' do
|
227
303
|
expect { subject.evaluate(hello_world) }.not_to raise_error
|
228
304
|
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.24
|
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-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -87,16 +87,25 @@ 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
|
91
92
|
- lib/loxxy/ast/lox_compound_expr.rb
|
92
93
|
- lib/loxxy/ast/lox_grouping_expr.rb
|
94
|
+
- lib/loxxy/ast/lox_if_stmt.rb
|
93
95
|
- lib/loxxy/ast/lox_literal_expr.rb
|
94
96
|
- lib/loxxy/ast/lox_logical_expr.rb
|
95
97
|
- lib/loxxy/ast/lox_node.rb
|
96
98
|
- lib/loxxy/ast/lox_noop_expr.rb
|
97
99
|
- lib/loxxy/ast/lox_print_stmt.rb
|
100
|
+
- lib/loxxy/ast/lox_seq_decl.rb
|
98
101
|
- lib/loxxy/ast/lox_unary_expr.rb
|
102
|
+
- lib/loxxy/ast/lox_var_stmt.rb
|
103
|
+
- lib/loxxy/ast/lox_variable_expr.rb
|
99
104
|
- lib/loxxy/back_end/engine.rb
|
105
|
+
- lib/loxxy/back_end/entry.rb
|
106
|
+
- lib/loxxy/back_end/environment.rb
|
107
|
+
- lib/loxxy/back_end/symbol_table.rb
|
108
|
+
- lib/loxxy/back_end/variable.rb
|
100
109
|
- lib/loxxy/datatype/all_datatypes.rb
|
101
110
|
- lib/loxxy/datatype/boolean.rb
|
102
111
|
- lib/loxxy/datatype/builtin_datatype.rb
|
@@ -114,6 +123,9 @@ files:
|
|
114
123
|
- lib/loxxy/version.rb
|
115
124
|
- loxxy.gemspec
|
116
125
|
- spec/back_end/engine_spec.rb
|
126
|
+
- spec/back_end/environment_spec.rb
|
127
|
+
- spec/back_end/symbol_table_spec.rb
|
128
|
+
- spec/back_end/variable_spec.rb
|
117
129
|
- spec/datatype/boolean_spec.rb
|
118
130
|
- spec/datatype/lx_string_spec.rb
|
119
131
|
- spec/datatype/nil_spec.rb
|
@@ -150,6 +162,9 @@ specification_version: 4
|
|
150
162
|
summary: An implementation of the Lox programming language. WIP
|
151
163
|
test_files:
|
152
164
|
- spec/back_end/engine_spec.rb
|
165
|
+
- spec/back_end/environment_spec.rb
|
166
|
+
- spec/back_end/symbol_table_spec.rb
|
167
|
+
- spec/back_end/variable_spec.rb
|
153
168
|
- spec/datatype/boolean_spec.rb
|
154
169
|
- spec/datatype/lx_string_spec.rb
|
155
170
|
- spec/datatype/nil_spec.rb
|