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.
@@ -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,7 +218,7 @@ module Loxxy
211
218
  end
212
219
  end
213
220
 
214
- it 'should supprt expressions between parentheses' do
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.19
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-14 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
@@ -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