loxxy 0.0.12 → 0.0.17

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.
@@ -22,9 +22,35 @@ module Loxxy
22
22
  end
23
23
 
24
24
  context 'Provided services:' do
25
+ it 'should compare with other Lox numbers' do
26
+ result = subject == Number.new(sample_value)
27
+ expect(result).to be_true
28
+
29
+ result = subject == Number.new(5)
30
+ expect(result).to be_false
31
+ end
32
+
33
+ it 'should compare with Ruby numbers' do
34
+ result = subject == sample_value
35
+ expect(result).to be_true
36
+
37
+ result = subject == 5
38
+ expect(result).to be_false
39
+ end
40
+
25
41
  it 'should give its display representation' do
26
42
  expect(subject.to_str).to eq(sample_value.to_s)
27
43
  end
44
+
45
+ it 'should compute the addition with another number' do
46
+ addition = subject + Number.new(10)
47
+ expect(addition == -2.34).to be_true
48
+ end
49
+
50
+ it 'should compute the subtraction with another number' do
51
+ subtraction = subject - Number.new(10)
52
+ expect(subtraction == -22.34).to be_true
53
+ end
28
54
  end
29
55
  end # describe
30
56
  end # module
@@ -64,7 +64,7 @@ module Loxxy
64
64
  it 'should parse a false literal' do
65
65
  input = 'false;'
66
66
  ptree = subject.parse(input)
67
- leaf = ptree.root.subnodes[0]
67
+ leaf = ptree.root
68
68
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
69
69
  expect(leaf.literal).to be_equal(Datatype::False.instance)
70
70
  end
@@ -72,7 +72,7 @@ module Loxxy
72
72
  it 'should parse a true literal' do
73
73
  input = 'true;'
74
74
  ptree = subject.parse(input)
75
- leaf = ptree.root.subnodes[0]
75
+ leaf = ptree.root
76
76
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
77
77
  expect(leaf.literal).to be_equal(Datatype::True.instance)
78
78
  end
@@ -81,7 +81,7 @@ module Loxxy
81
81
  inputs = %w[1234; 12.34;]
82
82
  inputs.each do |source|
83
83
  ptree = subject.parse(source)
84
- leaf = ptree.root.subnodes[0]
84
+ leaf = ptree.root
85
85
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
86
86
  expect(leaf.literal).to be_kind_of(Datatype::Number)
87
87
  expect(leaf.literal.value).to eq(source.to_f)
@@ -96,7 +96,7 @@ module Loxxy
96
96
  ]
97
97
  inputs.each do |source|
98
98
  ptree = subject.parse(source)
99
- leaf = ptree.root.subnodes[0]
99
+ leaf = ptree.root
100
100
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
101
101
  expect(leaf.literal).to be_kind_of(Datatype::LXString)
102
102
  expect(leaf.literal.value).to eq(source.gsub(/(^")|(";$)/, ''))
@@ -106,7 +106,7 @@ module Loxxy
106
106
  it 'should parse a nil literal' do
107
107
  input = 'nil;'
108
108
  ptree = subject.parse(input)
109
- leaf = ptree.root.subnodes[0]
109
+ leaf = ptree.root
110
110
  expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
111
111
  expect(leaf.literal).to be_equal(Datatype::Nil.instance)
112
112
  end
@@ -131,10 +131,7 @@ LOX_END
131
131
  it 'should parse the addition of two number literals' do
132
132
  input = '123 + 456;'
133
133
  ptree = subject.parse(input)
134
- parent = ptree.root
135
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
136
- expect(parent.symbol.name).to eq('exprStmt')
137
- expr = parent.subnodes[0]
134
+ expr = ptree.root
138
135
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
139
136
  expect(expr.operator).to eq(:+)
140
137
  expect(expr.operands[0].literal.value).to eq(123)
@@ -144,10 +141,7 @@ LOX_END
144
141
  it 'should parse the subtraction of two number literals' do
145
142
  input = '4 - 3;'
146
143
  ptree = subject.parse(input)
147
- parent = ptree.root
148
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
149
- expect(parent.symbol.name).to eq('exprStmt')
150
- expr = parent.subnodes[0]
144
+ expr = ptree.root
151
145
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
152
146
  expect(expr.operator).to eq(:-)
153
147
  expect(expr.operands[0].literal.value).to eq(4)
@@ -157,10 +151,7 @@ LOX_END
157
151
  it 'should parse multiple additive operations' do
158
152
  input = '5 + 2 - 3;'
159
153
  ptree = subject.parse(input)
160
- parent = ptree.root
161
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
162
- expect(parent.symbol.name).to eq('exprStmt')
163
- expr = parent.subnodes[0]
154
+ expr = ptree.root
164
155
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
165
156
  expect(expr.operator).to eq(:-)
166
157
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -173,10 +164,7 @@ LOX_END
173
164
  it 'should parse the division of two number literals' do
174
165
  input = '8 / 2;'
175
166
  ptree = subject.parse(input)
176
- parent = ptree.root
177
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
178
- expect(parent.symbol.name).to eq('exprStmt')
179
- expr = parent.subnodes[0]
167
+ expr = ptree.root
180
168
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
181
169
  expect(expr.operator).to eq(:/)
182
170
  expect(expr.operands[0].literal.value).to eq(8)
@@ -186,10 +174,7 @@ LOX_END
186
174
  it 'should parse the product of two number literals' do
187
175
  input = '12.34 * 0.3;'
188
176
  ptree = subject.parse(input)
189
- parent = ptree.root
190
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
191
- expect(parent.symbol.name).to eq('exprStmt')
192
- expr = parent.subnodes[0]
177
+ expr = ptree.root
193
178
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
194
179
  expect(expr.operator).to eq(:*)
195
180
  expect(expr.operands[0].literal.value).to eq(12.34)
@@ -199,10 +184,7 @@ LOX_END
199
184
  it 'should parse multiple multiplicative operations' do
200
185
  input = '5 * 2 / 3;'
201
186
  ptree = subject.parse(input)
202
- parent = ptree.root
203
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
204
- expect(parent.symbol.name).to eq('exprStmt')
205
- expr = parent.subnodes[0]
187
+ expr = ptree.root
206
188
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
207
189
  expect(expr.operator).to eq(:/)
208
190
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -215,10 +197,7 @@ LOX_END
215
197
  it 'should parse combination of terms and factors' do
216
198
  input = '5 + 2 / 3;'
217
199
  ptree = subject.parse(input)
218
- parent = ptree.root
219
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
220
- expect(parent.symbol.name).to eq('exprStmt')
221
- expr = parent.subnodes[0]
200
+ expr = ptree.root
222
201
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
223
202
  expect(expr.operator).to eq(:+)
224
203
  expect(expr.operands[0].literal.value).to eq(5)
@@ -233,10 +212,7 @@ LOX_END
233
212
  it 'should parse the concatenation of two string literals' do
234
213
  input = '"Lo" + "ve";'
235
214
  ptree = subject.parse(input)
236
- parent = ptree.root
237
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
238
- expect(parent.symbol.name).to eq('exprStmt')
239
- expr = parent.subnodes[0]
215
+ expr = ptree.root
240
216
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
241
217
  expect(expr.operator).to eq(:+)
242
218
  expect(expr.operands[0].literal.value).to eq('Lo')
@@ -249,10 +225,7 @@ LOX_END
249
225
  %w[> >= < <=].each do |predicate|
250
226
  input = "3 #{predicate} 2;"
251
227
  ptree = subject.parse(input)
252
- parent = ptree.root
253
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
254
- expect(parent.symbol.name).to eq('exprStmt')
255
- expr = parent.subnodes[0]
228
+ expr = ptree.root
256
229
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
257
230
  expect(expr.operator).to eq(predicate.to_sym)
258
231
  expect(expr.operands[0].literal.value).to eq(3)
@@ -266,10 +239,7 @@ LOX_END
266
239
  %w[!= ==].each do |predicate|
267
240
  input = "3 #{predicate} 2;"
268
241
  ptree = subject.parse(input)
269
- parent = ptree.root
270
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
271
- expect(parent.symbol.name).to eq('exprStmt')
272
- expr = parent.subnodes[0]
242
+ expr = ptree.root
273
243
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
274
244
  expect(expr.operator).to eq(predicate.to_sym)
275
245
  expect(expr.operands[0].literal.value).to eq(3)
@@ -280,10 +250,7 @@ LOX_END
280
250
  it 'should parse combination of equality expressions' do
281
251
  input = '5 != 2 == false; // A bit contrived example'
282
252
  ptree = subject.parse(input)
283
- parent = ptree.root
284
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
285
- expect(parent.symbol.name).to eq('exprStmt')
286
- expr = parent.subnodes[0]
253
+ expr = ptree.root
287
254
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
288
255
  expect(expr.operator).to eq(:==)
289
256
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -299,10 +266,7 @@ LOX_END
299
266
  %w[or and].each do |connector|
300
267
  input = "5 > 2 #{connector} 3 <= 4;"
301
268
  ptree = subject.parse(input)
302
- parent = ptree.root
303
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
304
- expect(parent.symbol.name).to eq('exprStmt')
305
- expr = parent.subnodes[0]
269
+ expr = ptree.root
306
270
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
307
271
  expect(expr.operator).to eq(connector.to_sym)
308
272
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -319,10 +283,7 @@ LOX_END
319
283
  it 'should parse a combinations of logical expressions' do
320
284
  input = '4 > 3 and 1 < 2 or 4 >= 5;'
321
285
  ptree = subject.parse(input)
322
- parent = ptree.root
323
- expect(parent).to be_kind_of(Rley::PTree::NonTerminalNode)
324
- expect(parent.symbol.name).to eq('exprStmt')
325
- expr = parent.subnodes[0]
286
+ expr = ptree.root
326
287
  expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
327
288
  expect(expr.operator).to eq(:or) # or has lower precedence than and
328
289
  expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
@@ -25,9 +25,145 @@ module Loxxy
25
25
  end
26
26
  end # context
27
27
 
28
+ context 'Evaluating arithmetic operations code:' do
29
+ it 'should evaluate an addition of two numbers' do
30
+ result = subject.evaluate('123 + 456; // => 579')
31
+ expect(result).to be_kind_of(Loxxy::Datatype::Number)
32
+ expect(result == 579).to be_true
33
+ end
34
+
35
+ it 'should evaluate a subtraction of two numbers' do
36
+ result = subject.evaluate('4 - 3; // => 1')
37
+ expect(result).to be_kind_of(Loxxy::Datatype::Number)
38
+ expect(result == 1).to be_true
39
+ end
40
+
41
+ it 'should evaluate a multiplication of two numbers' do
42
+ result = subject.evaluate('5 * 3; // => 15')
43
+ expect(result).to be_kind_of(Loxxy::Datatype::Number)
44
+ expect(result == 15).to be_true
45
+ end
46
+
47
+ it 'should evaluate a division of two numbers' do
48
+ result = subject.evaluate('8 / 2; // => 4')
49
+ expect(result).to be_kind_of(Loxxy::Datatype::Number)
50
+ expect(result == 4).to be_true
51
+ end
52
+ end # context
53
+
28
54
  context 'Evaluating Lox code:' do
29
55
  let(:hello_world) { 'print "Hello, world!";' }
30
56
 
57
+ it 'should evaluate core data types' do
58
+ result = subject.evaluate('true; // Not false')
59
+ expect(result).to be_kind_of(Loxxy::Datatype::True)
60
+ end
61
+
62
+ it 'should evaluate string concatenation' do
63
+ result = subject.evaluate('"str" + "ing"; // => "string"')
64
+ expect(result).to be_kind_of(Loxxy::Datatype::LXString)
65
+ expect(result == 'string').to be_true
66
+ end
67
+
68
+ it 'should perform the equality tests of two values' do
69
+ [
70
+ ['nil == nil;', true],
71
+ ['true == true;', true],
72
+ ['true == false;', false],
73
+ ['1 == 1;', true],
74
+ ['1 == 2;', false],
75
+ ['0 == 0;', true],
76
+ ['"str" == "str";', true],
77
+ ['"str" == "ing";', false],
78
+ ['"" == "";', true],
79
+ ['nil == false;', false],
80
+ ['false == 0;', false],
81
+ ['0 == "0";', false]
82
+ ].each do |(source, predicted)|
83
+ lox = Loxxy::Interpreter.new
84
+ result = lox.evaluate(source)
85
+ expect(result.value == predicted).to be_truthy
86
+ end
87
+ end
88
+
89
+ it 'should perform the inequality test of two values' do
90
+ [
91
+ ['nil != nil;', false],
92
+ ['true != true;', false],
93
+ ['true != false;', true],
94
+ ['1 != 1;', false],
95
+ ['1 != 2;', true],
96
+ ['0 != 0;', false],
97
+ ['"str" != "str";', false],
98
+ ['"str" != "ing";', true],
99
+ ['"" != "";', false],
100
+ ['nil != false;', true],
101
+ ['false != 0;', true],
102
+ ['0 != "0";', true]
103
+ ].each do |(source, predicted)|
104
+ lox = Loxxy::Interpreter.new
105
+ result = lox.evaluate(source)
106
+ expect(result.value == predicted).to be_truthy
107
+ end
108
+ end
109
+
110
+ it 'should evaluate a comparison of two numbers' do
111
+ [
112
+ ['1 < 2;', true],
113
+ ['2 < 2;', false],
114
+ ['2 < 1;', false],
115
+ ['1 <= 2;', true],
116
+ ['2 <= 2;', true],
117
+ ['2 <= 1;', false],
118
+ ['1 > 2;', false],
119
+ ['2 > 2;', false],
120
+ ['2 > 1;', true],
121
+ ['1 >= 2;', false],
122
+ ['2 >= 2;', true],
123
+ ['2 >= 1;', true],
124
+ ['0 < -0;', false],
125
+ ['-0 < 0;', false],
126
+ ['0 > -0;', false],
127
+ ['-0 > 0;', false],
128
+ ['0 <= -0;', true],
129
+ ['-0 <= 0;', true],
130
+ ['0 >= -0;', true],
131
+ ['-0 >= 0;', true]
132
+ ].each do |(source, predicted)|
133
+ lox = Loxxy::Interpreter.new
134
+ result = lox.evaluate(source)
135
+ expect(result.value == predicted).to be_truthy
136
+ end
137
+ end
138
+
139
+ it 'should evaluate the change sign of a number' do
140
+ [
141
+ ['- 3;', -3],
142
+ ['- - 3;', 3],
143
+ ['- - - 3;', -3]
144
+ ].each do |(source, predicted)|
145
+ lox = Loxxy::Interpreter.new
146
+ result = lox.evaluate(source)
147
+ expect(result.value == predicted).to be_truthy
148
+ end
149
+ end
150
+
151
+ it 'should evaluate the negation of an object' do
152
+ [
153
+ ['!true;', false],
154
+ ['!false;', true],
155
+ ['!!true;', true],
156
+ ['!123;', false],
157
+ ['!0;', false],
158
+ ['!nil;', true],
159
+ ['!"";', false]
160
+ ].each do |(source, predicted)|
161
+ lox = Loxxy::Interpreter.new
162
+ result = lox.evaluate(source)
163
+ expect(result.value == predicted).to be_truthy
164
+ end
165
+ end
166
+
31
167
  it 'should print the hello world message' do
32
168
  expect { subject.evaluate(hello_world) }.not_to raise_error
33
169
  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.12
4
+ version: 0.0.17
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-09 00:00:00.000000000 Z
11
+ date: 2021-01-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rley
@@ -93,6 +93,7 @@ files:
93
93
  - lib/loxxy/ast/lox_node.rb
94
94
  - lib/loxxy/ast/lox_noop_expr.rb
95
95
  - lib/loxxy/ast/lox_print_stmt.rb
96
+ - lib/loxxy/ast/lox_unary_expr.rb
96
97
  - lib/loxxy/back_end/engine.rb
97
98
  - lib/loxxy/datatype/all_datatypes.rb
98
99
  - lib/loxxy/datatype/boolean.rb