loxxy 0.0.21 → 0.0.22
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 +16 -1
- data/README.md +9 -1
- data/lib/loxxy/ast/all_lox_nodes.rb +2 -0
- data/lib/loxxy/ast/ast_builder.rb +18 -1
- data/lib/loxxy/ast/ast_visitor.rb +16 -1
- data/lib/loxxy/ast/lox_seq_decl.rb +23 -0
- data/lib/loxxy/ast/lox_variable_expr.rb +26 -0
- data/lib/loxxy/back_end/engine.rb +12 -0
- data/lib/loxxy/front_end/grammar.rb +3 -3
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/engine_spec.rb +1 -0
- data/spec/front_end/parser_spec.rb +21 -19
- data/spec/interpreter_spec.rb +15 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acd7b65477866aee4f022731a70f67cad63f482eae6ae5e3f5a35cd56c43f9b0
|
4
|
+
data.tar.gz: 4980c1dafbd83c1ed0a41cf5da09d0decba43e912722c5052fc3e4f63626d73a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8853388df750173e1a9e818e3aac92f33f98ff75cf5c575d0b583758c59938810a593823a73a6914a28413ba697d53147d7317b744484d43b4026c76a182bc4
|
7
|
+
data.tar.gz: 3426ce17792625f908f2a31c879b0a312cbefbe18c82848f769d78bcac550d3700349fc1408bbeddb7738b47735ed583fd89355636c8c377a7cde3baf2f5071f
|
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,19 @@
|
|
1
|
-
## [0.0.
|
1
|
+
## [0.0.22] - 2021-01-17
|
2
|
+
- The interpreter can retrieve the value of a variable.
|
3
|
+
|
4
|
+
## Added
|
5
|
+
- Method `Ast::ASTBuilder#declaration_plus_more` and `Ast::ASTBuilder#declaration_plus_end` to allow multiple expressions/statements
|
6
|
+
- Method `Ast::ASTBuilder#reduce_var_expression` creates an `Ast::LoxVariableExpr` node
|
7
|
+
- Method `Ast::ASTVisitor#visit_var_expr` for visiting `Ast::LoxVariableExpr` nodes
|
8
|
+
- Class `Ast::LoxSeqDecl` a node that represents a sequence of declarations/statements
|
9
|
+
- Class `Ast::LoxVarExpr` a node that represents a variable occurrence in an expression
|
10
|
+
- Method `Engine::after_variable_expr`: retrieve the value of variable with given name
|
11
|
+
|
12
|
+
## Changed
|
13
|
+
- Method `Ast::ASTBuilder#reduce_lox_program` to support multiple statements/declarations
|
14
|
+
- File `README.md` updated.
|
15
|
+
|
16
|
+
## [0.0.21] - 2021-01-16
|
2
17
|
- The interpreter supports the declaration global variables.
|
3
18
|
|
4
19
|
## Added
|
data/README.md
CHANGED
@@ -176,6 +176,7 @@ Loxxy supports the following statements:
|
|
176
176
|
-[Comparison expressions](#comparison-expressions)
|
177
177
|
-[Logical expressions](#logical-expressions)
|
178
178
|
-[Grouping expressions](#grouping-expressions)
|
179
|
+
-[Variable expressions](#variable-expressions)
|
179
180
|
|
180
181
|
-[Variable declarations](#var-statement)
|
181
182
|
-[If Statement](#if-statement)
|
@@ -258,13 +259,20 @@ print 3 + 4 * 5; // => 23
|
|
258
259
|
print (3 + 4) * 5; // => 35
|
259
260
|
```
|
260
261
|
|
262
|
+
#### Variable expressions
|
263
|
+
In __Lox__, a variable expression is nothing than retrieving the value of a variable.
|
264
|
+
``` javascript
|
265
|
+
var foo = "bar;" // Variable declaration
|
266
|
+
foo; // Varible expression (= retrieving its value)
|
267
|
+
```
|
268
|
+
|
261
269
|
#### Variable declarations
|
262
270
|
``` javascript
|
263
271
|
var iAmAVariable = "my-initial-value";
|
264
272
|
var iAmNil; // __Lox__ initializes variables to nil by default;
|
265
273
|
```
|
266
274
|
|
267
|
-
Warning: current version cannot
|
275
|
+
Warning: current version cannot assign a value to an existing variable.
|
268
276
|
Expect this capability to be implemented in the coming days.
|
269
277
|
|
270
278
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'lox_variable_expr'
|
3
4
|
require_relative 'lox_literal_expr'
|
4
5
|
require_relative 'lox_noop_expr'
|
5
6
|
require_relative 'lox_grouping_expr'
|
@@ -9,3 +10,4 @@ require_relative 'lox_logical_expr'
|
|
9
10
|
require_relative 'lox_print_stmt'
|
10
11
|
require_relative 'lox_if_stmt'
|
11
12
|
require_relative 'lox_var_stmt'
|
13
|
+
require_relative 'lox_seq_decl'
|
@@ -150,7 +150,17 @@ module Loxxy
|
|
150
150
|
|
151
151
|
# rule('program' => 'declaration_plus EOF').as ''
|
152
152
|
def reduce_lox_program(_production, range, tokens, theChildren)
|
153
|
-
|
153
|
+
LoxSeqDecl.new(tokens[0].position, theChildren[0])
|
154
|
+
end
|
155
|
+
|
156
|
+
# rule('declaration_plus' => 'declaration_plus declaration').as ''
|
157
|
+
def reduce_declaration_plus_more(_production, range, tokens, theChildren)
|
158
|
+
theChildren[0] << theChildren[1]
|
159
|
+
end
|
160
|
+
|
161
|
+
# rule('declaration_plus' => 'declaration')
|
162
|
+
def reduce_declaration_plus_end(_production, range, tokens, theChildren)
|
163
|
+
[ theChildren[0] ]
|
154
164
|
end
|
155
165
|
|
156
166
|
# rule('exprStmt' => 'expression SEMICOLON')
|
@@ -292,6 +302,13 @@ module Loxxy
|
|
292
302
|
literal = first_child.token.value
|
293
303
|
LoxLiteralExpr.new(pos, literal)
|
294
304
|
end
|
305
|
+
|
306
|
+
# rule('primary' => 'IDENTIFIER')
|
307
|
+
def reduce_variable_expr(_production, _range, tokens, theChildren)
|
308
|
+
var_name = theChildren[0].token.lexeme
|
309
|
+
LoxVariableExpr.new(tokens[0].position, var_name)
|
310
|
+
end#
|
311
|
+
|
295
312
|
end # class
|
296
313
|
end # module
|
297
314
|
end # module
|
@@ -51,6 +51,14 @@ module Loxxy
|
|
51
51
|
broadcast(:after_ptree, aParseTree)
|
52
52
|
end
|
53
53
|
|
54
|
+
# Visit event. The visitor is about to visit a variable declaration statement.
|
55
|
+
# @param aPrintStmt [AST::LOXVarStmt] the variable declaration node to visit
|
56
|
+
def visit_seq_decl(aSeqDecls)
|
57
|
+
broadcast(:before_seq_decl, aSeqDecls)
|
58
|
+
traverse_subnodes(aSeqDecls)
|
59
|
+
broadcast(:after_seq_decl, aSeqDecls)
|
60
|
+
end
|
61
|
+
|
54
62
|
# Visit event. The visitor is about to visit a variable declaration statement.
|
55
63
|
# @param aPrintStmt [AST::LOXVarStmt] the variable declaration node to visit
|
56
64
|
def visit_var_stmt(aVarStmt)
|
@@ -121,8 +129,15 @@ module Loxxy
|
|
121
129
|
broadcast(:after_literal_expr, aLiteralExpr)
|
122
130
|
end
|
123
131
|
|
132
|
+
# Visit event. The visitor is visiting a variable reference node
|
133
|
+
# @param aLiteralExpr [AST::LoxVariableExpr] the variable reference node to visit.
|
134
|
+
def visit_variable_expr(aVariableExpr)
|
135
|
+
broadcast(:before_variable_expr, aVariableExpr)
|
136
|
+
broadcast(:after_variable_expr, aVariableExpr, self)
|
137
|
+
end
|
138
|
+
|
124
139
|
# Visit event. The visitor is about to visit the given non terminal node.
|
125
|
-
# @param aNonTerminalNode [Rley::
|
140
|
+
# @param aNonTerminalNode [Rley::PTree::NonTerminalNode] the node to visit.
|
126
141
|
def visit_nonterminal(_non_terminal_node)
|
127
142
|
# Loxxy interpreter encountered a CST node (Concrete Syntax Tree)
|
128
143
|
# that it cannot handle.
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_compound_expr'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
class LoxSeqDecl < LoxCompoundExpr
|
8
|
+
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
9
|
+
# @param declarations [Arrya<Loxxy::Ast::LoxNode>]
|
10
|
+
def initialize(aPosition, declarations)
|
11
|
+
super(aPosition, declarations)
|
12
|
+
end
|
13
|
+
|
14
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
15
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
16
|
+
def accept(visitor)
|
17
|
+
visitor.visit_seq_decl(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
alias operands subnodes
|
21
|
+
end # class
|
22
|
+
end # module
|
23
|
+
end # module
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_node'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
# This AST node represents a mention of a variable
|
8
|
+
class LoxVariableExpr < LoxNode
|
9
|
+
# @return [String] variable name
|
10
|
+
attr_reader :name
|
11
|
+
|
12
|
+
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
13
|
+
# @param aName [String] name of the variable
|
14
|
+
def initialize(aPosition, aName)
|
15
|
+
super(aPosition)
|
16
|
+
@name = aName
|
17
|
+
end
|
18
|
+
|
19
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
20
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
21
|
+
def accept(visitor)
|
22
|
+
visitor.visit_variable_expr(self)
|
23
|
+
end
|
24
|
+
end # class
|
25
|
+
end # module
|
26
|
+
end # module
|
@@ -41,6 +41,11 @@ module Loxxy
|
|
41
41
|
##########################################################################
|
42
42
|
# Visit event handling
|
43
43
|
##########################################################################
|
44
|
+
|
45
|
+
def after_seq_decl(aSeqDecls)
|
46
|
+
# Do nothing, subnodes were already evaluated
|
47
|
+
end
|
48
|
+
|
44
49
|
def after_var_stmt(aVarStmt)
|
45
50
|
new_var = Variable.new(aVarStmt.name, aVarStmt.subnodes[0])
|
46
51
|
symbol_table.insert(new_var)
|
@@ -120,6 +125,13 @@ module Loxxy
|
|
120
125
|
# Do nothing: work was already done by visiting /evaluating the subexpression
|
121
126
|
end
|
122
127
|
|
128
|
+
def after_variable_expr(aVarExpr, aVisitor)
|
129
|
+
var_name = aVarExpr.name
|
130
|
+
var = symbol_table.lookup(var_name)
|
131
|
+
raise StandardError, "Unknown variable #{var_name}" unless var
|
132
|
+
var.value.accept(aVisitor) # Evaluate the variable value
|
133
|
+
end
|
134
|
+
|
123
135
|
# @param literalExpr [Ast::LoxLiteralExpr]
|
124
136
|
def before_literal_expr(literalExpr)
|
125
137
|
stack.push(literalExpr.literal)
|
@@ -30,8 +30,8 @@ module Loxxy
|
|
30
30
|
rule('program' => 'declaration_plus EOF').as 'lox_program'
|
31
31
|
|
32
32
|
# Declarations: bind an identifier to something
|
33
|
-
rule('declaration_plus' => 'declaration_plus declaration')
|
34
|
-
rule('declaration_plus' => 'declaration')
|
33
|
+
rule('declaration_plus' => 'declaration_plus declaration').as 'declaration_plus_more'
|
34
|
+
rule('declaration_plus' => 'declaration').as 'declaration_plus_end'
|
35
35
|
rule('declaration' => 'classDecl')
|
36
36
|
rule('declaration' => 'funDecl')
|
37
37
|
rule('declaration' => 'varDecl')
|
@@ -137,7 +137,7 @@ module Loxxy
|
|
137
137
|
rule('primary' => 'THIS')
|
138
138
|
rule('primary' => 'NUMBER').as 'literal_expr'
|
139
139
|
rule('primary' => 'STRING').as 'literal_expr'
|
140
|
-
rule('primary' => 'IDENTIFIER')
|
140
|
+
rule('primary' => 'IDENTIFIER').as 'variable_expr'
|
141
141
|
rule('primary' => 'LEFT_PAREN expression RIGHT_PAREN').as 'grouping_expr'
|
142
142
|
rule('primary' => 'SUPER DOT IDENTIFIER')
|
143
143
|
|
data/lib/loxxy/version.rb
CHANGED
@@ -34,6 +34,7 @@ module Loxxy
|
|
34
34
|
let(:var_decl) { Ast::LoxVarStmt.new(sample_pos, 'greeting', greeting) }
|
35
35
|
let(:lit_expr) { Ast::LoxLiteralExpr.new(sample_pos, greeting) }
|
36
36
|
|
37
|
+
|
37
38
|
it "should react to 'after_var_stmt' event" do
|
38
39
|
expect { subject.after_var_stmt(var_decl) }.not_to raise_error
|
39
40
|
current_env = subject.symbol_table.current_env
|
@@ -64,7 +64,8 @@ module Loxxy
|
|
64
64
|
it 'should parse a false literal' do
|
65
65
|
input = 'false;'
|
66
66
|
ptree = subject.parse(input)
|
67
|
-
|
67
|
+
expect(ptree.root).to be_kind_of(Ast::LoxSeqDecl)
|
68
|
+
leaf = ptree.root.subnodes[0]
|
68
69
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
69
70
|
expect(leaf.literal).to be_equal(Datatype::False.instance)
|
70
71
|
end
|
@@ -72,7 +73,8 @@ module Loxxy
|
|
72
73
|
it 'should parse a true literal' do
|
73
74
|
input = 'true;'
|
74
75
|
ptree = subject.parse(input)
|
75
|
-
|
76
|
+
expect(ptree.root).to be_kind_of(Ast::LoxSeqDecl)
|
77
|
+
leaf = ptree.root.subnodes[0]
|
76
78
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
77
79
|
expect(leaf.literal).to be_equal(Datatype::True.instance)
|
78
80
|
end
|
@@ -81,7 +83,7 @@ module Loxxy
|
|
81
83
|
inputs = %w[1234; 12.34;]
|
82
84
|
inputs.each do |source|
|
83
85
|
ptree = subject.parse(source)
|
84
|
-
leaf = ptree.root
|
86
|
+
leaf = ptree.root.subnodes[0]
|
85
87
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
86
88
|
expect(leaf.literal).to be_kind_of(Datatype::Number)
|
87
89
|
expect(leaf.literal.value).to eq(source.to_f)
|
@@ -96,7 +98,7 @@ module Loxxy
|
|
96
98
|
]
|
97
99
|
inputs.each do |source|
|
98
100
|
ptree = subject.parse(source)
|
99
|
-
leaf = ptree.root
|
101
|
+
leaf = ptree.root.subnodes[0]
|
100
102
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
101
103
|
expect(leaf.literal).to be_kind_of(Datatype::LXString)
|
102
104
|
expect(leaf.literal.value).to eq(source.gsub(/(^")|(";$)/, ''))
|
@@ -106,7 +108,7 @@ module Loxxy
|
|
106
108
|
it 'should parse a nil literal' do
|
107
109
|
input = 'nil;'
|
108
110
|
ptree = subject.parse(input)
|
109
|
-
leaf = ptree.root
|
111
|
+
leaf = ptree.root.subnodes[0]
|
110
112
|
expect(leaf).to be_kind_of(Ast::LoxLiteralExpr)
|
111
113
|
expect(leaf.literal).to be_equal(Datatype::Nil.instance)
|
112
114
|
end
|
@@ -119,7 +121,7 @@ module Loxxy
|
|
119
121
|
print "Hello, world!";
|
120
122
|
LOX_END
|
121
123
|
ptree = subject.parse(program)
|
122
|
-
prnt_stmt = ptree.root
|
124
|
+
prnt_stmt = ptree.root.subnodes[0]
|
123
125
|
expect(prnt_stmt).to be_kind_of(Ast::LoxPrintStmt)
|
124
126
|
expect(prnt_stmt.subnodes[0]).to be_kind_of(Ast::LoxLiteralExpr)
|
125
127
|
expect(prnt_stmt.subnodes[0].literal).to be_kind_of(Loxxy::Datatype::LXString)
|
@@ -131,7 +133,7 @@ LOX_END
|
|
131
133
|
it 'should parse the addition of two number literals' do
|
132
134
|
input = '123 + 456;'
|
133
135
|
ptree = subject.parse(input)
|
134
|
-
expr = ptree.root
|
136
|
+
expr = ptree.root.subnodes[0]
|
135
137
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
136
138
|
expect(expr.operator).to eq(:+)
|
137
139
|
expect(expr.operands[0].literal.value).to eq(123)
|
@@ -141,7 +143,7 @@ LOX_END
|
|
141
143
|
it 'should parse the subtraction of two number literals' do
|
142
144
|
input = '4 - 3;'
|
143
145
|
ptree = subject.parse(input)
|
144
|
-
expr = ptree.root
|
146
|
+
expr = ptree.root.subnodes[0]
|
145
147
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
146
148
|
expect(expr.operator).to eq(:-)
|
147
149
|
expect(expr.operands[0].literal.value).to eq(4)
|
@@ -151,7 +153,7 @@ LOX_END
|
|
151
153
|
it 'should parse multiple additive operations' do
|
152
154
|
input = '5 + 2 - 3;'
|
153
155
|
ptree = subject.parse(input)
|
154
|
-
expr = ptree.root
|
156
|
+
expr = ptree.root.subnodes[0]
|
155
157
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
156
158
|
expect(expr.operator).to eq(:-)
|
157
159
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
@@ -164,7 +166,7 @@ LOX_END
|
|
164
166
|
it 'should parse the division of two number literals' do
|
165
167
|
input = '8 / 2;'
|
166
168
|
ptree = subject.parse(input)
|
167
|
-
expr = ptree.root
|
169
|
+
expr = ptree.root.subnodes[0]
|
168
170
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
169
171
|
expect(expr.operator).to eq(:/)
|
170
172
|
expect(expr.operands[0].literal.value).to eq(8)
|
@@ -174,7 +176,7 @@ LOX_END
|
|
174
176
|
it 'should parse the product of two number literals' do
|
175
177
|
input = '12.34 * 0.3;'
|
176
178
|
ptree = subject.parse(input)
|
177
|
-
expr = ptree.root
|
179
|
+
expr = ptree.root.subnodes[0]
|
178
180
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
179
181
|
expect(expr.operator).to eq(:*)
|
180
182
|
expect(expr.operands[0].literal.value).to eq(12.34)
|
@@ -184,7 +186,7 @@ LOX_END
|
|
184
186
|
it 'should parse multiple multiplicative operations' do
|
185
187
|
input = '5 * 2 / 3;'
|
186
188
|
ptree = subject.parse(input)
|
187
|
-
expr = ptree.root
|
189
|
+
expr = ptree.root.subnodes[0]
|
188
190
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
189
191
|
expect(expr.operator).to eq(:/)
|
190
192
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
@@ -197,7 +199,7 @@ LOX_END
|
|
197
199
|
it 'should parse combination of terms and factors' do
|
198
200
|
input = '5 + 2 / 3;'
|
199
201
|
ptree = subject.parse(input)
|
200
|
-
expr = ptree.root
|
202
|
+
expr = ptree.root.subnodes[0]
|
201
203
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
202
204
|
expect(expr.operator).to eq(:+)
|
203
205
|
expect(expr.operands[0].literal.value).to eq(5)
|
@@ -212,7 +214,7 @@ LOX_END
|
|
212
214
|
it 'should parse the concatenation of two string literals' do
|
213
215
|
input = '"Lo" + "ve";'
|
214
216
|
ptree = subject.parse(input)
|
215
|
-
expr = ptree.root
|
217
|
+
expr = ptree.root.subnodes[0]
|
216
218
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
217
219
|
expect(expr.operator).to eq(:+)
|
218
220
|
expect(expr.operands[0].literal.value).to eq('Lo')
|
@@ -225,7 +227,7 @@ LOX_END
|
|
225
227
|
%w[> >= < <=].each do |predicate|
|
226
228
|
input = "3 #{predicate} 2;"
|
227
229
|
ptree = subject.parse(input)
|
228
|
-
expr = ptree.root
|
230
|
+
expr = ptree.root.subnodes[0]
|
229
231
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
230
232
|
expect(expr.operator).to eq(predicate.to_sym)
|
231
233
|
expect(expr.operands[0].literal.value).to eq(3)
|
@@ -239,7 +241,7 @@ LOX_END
|
|
239
241
|
%w[!= ==].each do |predicate|
|
240
242
|
input = "3 #{predicate} 2;"
|
241
243
|
ptree = subject.parse(input)
|
242
|
-
expr = ptree.root
|
244
|
+
expr = ptree.root.subnodes[0]
|
243
245
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
244
246
|
expect(expr.operator).to eq(predicate.to_sym)
|
245
247
|
expect(expr.operands[0].literal.value).to eq(3)
|
@@ -250,7 +252,7 @@ LOX_END
|
|
250
252
|
it 'should parse combination of equality expressions' do
|
251
253
|
input = '5 != 2 == false; // A bit contrived example'
|
252
254
|
ptree = subject.parse(input)
|
253
|
-
expr = ptree.root
|
255
|
+
expr = ptree.root.subnodes[0]
|
254
256
|
expect(expr).to be_kind_of(Ast::LoxBinaryExpr)
|
255
257
|
expect(expr.operator).to eq(:==)
|
256
258
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
@@ -266,7 +268,7 @@ LOX_END
|
|
266
268
|
%w[or and].each do |connector|
|
267
269
|
input = "5 > 2 #{connector} 3 <= 4;"
|
268
270
|
ptree = subject.parse(input)
|
269
|
-
expr = ptree.root
|
271
|
+
expr = ptree.root.subnodes[0]
|
270
272
|
expect(expr).to be_kind_of(Ast::LoxLogicalExpr)
|
271
273
|
expect(expr.operator).to eq(connector.to_sym)
|
272
274
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxBinaryExpr)
|
@@ -283,7 +285,7 @@ LOX_END
|
|
283
285
|
it 'should parse a combinations of logical expressions' do
|
284
286
|
input = '4 > 3 and 1 < 2 or 4 >= 5;'
|
285
287
|
ptree = subject.parse(input)
|
286
|
-
expr = ptree.root
|
288
|
+
expr = ptree.root.subnodes[0]
|
287
289
|
expect(expr).to be_kind_of(Ast::LoxLogicalExpr)
|
288
290
|
expect(expr.operator).to eq(:or) # or has lower precedence than and
|
289
291
|
expect(expr.operands[0]).to be_kind_of(Ast::LoxLogicalExpr)
|
data/spec/interpreter_spec.rb
CHANGED
@@ -52,7 +52,12 @@ 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
|
+
end
|
56
61
|
|
57
62
|
it 'should evaluate core data types' do
|
58
63
|
result = subject.evaluate('true; // Not false')
|
@@ -259,6 +264,15 @@ module Loxxy
|
|
259
264
|
expect { subject.evaluate('var iAmNil;') }.not_to raise_error
|
260
265
|
end
|
261
266
|
|
267
|
+
it 'should accept variable mention' do
|
268
|
+
program = <<-LOX_END
|
269
|
+
var foo = "bar";
|
270
|
+
print foo;
|
271
|
+
LOX_END
|
272
|
+
expect { subject.evaluate(program) }.not_to raise_error
|
273
|
+
expect(sample_cfg[:ostream].string).to eq('bar')
|
274
|
+
end
|
275
|
+
|
262
276
|
it 'should print the hello world message' do
|
263
277
|
expect { subject.evaluate(hello_world) }.not_to raise_error
|
264
278
|
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.22
|
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-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -96,8 +96,10 @@ files:
|
|
96
96
|
- lib/loxxy/ast/lox_node.rb
|
97
97
|
- lib/loxxy/ast/lox_noop_expr.rb
|
98
98
|
- lib/loxxy/ast/lox_print_stmt.rb
|
99
|
+
- lib/loxxy/ast/lox_seq_decl.rb
|
99
100
|
- lib/loxxy/ast/lox_unary_expr.rb
|
100
101
|
- lib/loxxy/ast/lox_var_stmt.rb
|
102
|
+
- lib/loxxy/ast/lox_variable_expr.rb
|
101
103
|
- lib/loxxy/back_end/engine.rb
|
102
104
|
- lib/loxxy/back_end/entry.rb
|
103
105
|
- lib/loxxy/back_end/environment.rb
|