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.
@@ -52,7 +52,14 @@ module Loxxy
52
52
  end # context
53
53
 
54
54
  context 'Evaluating Lox code:' do
55
- let(:hello_world) { 'print "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.18
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-13 00:00:00.000000000 Z
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