loxxy 0.0.18 → 0.0.23
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 +94 -30
- data/README.md +72 -4
- data/lib/loxxy/ast/all_lox_nodes.rb +5 -0
- data/lib/loxxy/ast/ast_builder.rb +49 -2
- data/lib/loxxy/ast/ast_visitor.rb +47 -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_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 +44 -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 +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 +74 -1
- 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,6 +218,72 @@ module Loxxy
|
|
211
218
|
end
|
212
219
|
end
|
213
220
|
|
221
|
+
it 'should support expressions between parentheses' do
|
222
|
+
[
|
223
|
+
['3 + 4 * 5;', 23],
|
224
|
+
['(3 + 4) * 5;', 35],
|
225
|
+
['(5 - (3 - 1)) + -(1);', 2]
|
226
|
+
].each do |(source, predicted)|
|
227
|
+
lox = Loxxy::Interpreter.new
|
228
|
+
result = lox.evaluate(source)
|
229
|
+
expect(result.value == predicted).to be_truthy
|
230
|
+
end
|
231
|
+
end
|
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 foo;
|
281
|
+
print foo; // => 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
|
+
|
214
287
|
it 'should print the hello world message' do
|
215
288
|
expect { subject.evaluate(hello_world) }.not_to raise_error
|
216
289
|
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.23
|
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
|
@@ -89,13 +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
|
93
95
|
- lib/loxxy/ast/lox_logical_expr.rb
|
94
96
|
- lib/loxxy/ast/lox_node.rb
|
95
97
|
- lib/loxxy/ast/lox_noop_expr.rb
|
96
98
|
- lib/loxxy/ast/lox_print_stmt.rb
|
99
|
+
- lib/loxxy/ast/lox_seq_decl.rb
|
97
100
|
- lib/loxxy/ast/lox_unary_expr.rb
|
101
|
+
- lib/loxxy/ast/lox_var_stmt.rb
|
102
|
+
- lib/loxxy/ast/lox_variable_expr.rb
|
98
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
|
99
108
|
- lib/loxxy/datatype/all_datatypes.rb
|
100
109
|
- lib/loxxy/datatype/boolean.rb
|
101
110
|
- lib/loxxy/datatype/builtin_datatype.rb
|
@@ -113,6 +122,9 @@ files:
|
|
113
122
|
- lib/loxxy/version.rb
|
114
123
|
- loxxy.gemspec
|
115
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
|
116
128
|
- spec/datatype/boolean_spec.rb
|
117
129
|
- spec/datatype/lx_string_spec.rb
|
118
130
|
- spec/datatype/nil_spec.rb
|
@@ -149,6 +161,9 @@ specification_version: 4
|
|
149
161
|
summary: An implementation of the Lox programming language. WIP
|
150
162
|
test_files:
|
151
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
|
152
167
|
- spec/datatype/boolean_spec.rb
|
153
168
|
- spec/datatype/lx_string_spec.rb
|
154
169
|
- spec/datatype/nil_spec.rb
|