loxxy 0.0.21 → 0.0.22
Sign up to get free protection for your applications and to get access to all the features.
- 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
|