loxxy 0.0.23 → 0.0.24
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/README.md +7 -7
- data/lib/loxxy/ast/all_lox_nodes.rb +1 -0
- data/lib/loxxy/ast/ast_builder.rb +6 -0
- data/lib/loxxy/ast/ast_visitor.rb +9 -1
- data/lib/loxxy/ast/lox_assign_expr.rb +27 -0
- data/lib/loxxy/back_end/engine.rb +9 -0
- data/lib/loxxy/back_end/variable.rb +6 -1
- data/lib/loxxy/front_end/grammar.rb +1 -1
- data/lib/loxxy/version.rb +1 -1
- data/spec/interpreter_spec.rb +17 -2
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6085bf18afb919e5ef4d327162470c9d5ca95dde67e00dce78bb26abd6563dec
|
4
|
+
data.tar.gz: f1c7732a34b6df2721c20d82404c6ce83bdc8a75b695e4bbe13c51f62d9ac371
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7546a14b935700e5050411a7805c2b2d00ccfc99160e3241b512289a6cc1762df2f39b7c9845c6ffe7fb95f1412865ef373f5308c9cf333fd72e2025a4a17ed8
|
7
|
+
data.tar.gz: 3675956929831e52963759862e8f9d40e5ebd3df471dee87d82784c2d1230ce6057882368042c907741be1038d300b7c83c27ed4bb8d979f5efa2ac79eaa3b1a
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
## [0.0.24] - 2021-01-20
|
2
|
+
- The interpreter implements the assignment of variables.
|
3
|
+
|
4
|
+
### Added
|
5
|
+
- Class `Ast::LoxAssignExpr` a node that represents the assignment of a value to a variable
|
6
|
+
- Method `Ast::ASTBuilder#reduce_assign_expr` creates an `Ast::LoxAssignExpr` node
|
7
|
+
- Method `Ast::ASTVisitor#visit_assign_expr` for visiting an `Ast::LoxAssignExpr` node
|
8
|
+
- Method `BackEnd::Engine#after_assign_expr` implementation of the assignment
|
9
|
+
- Method `BackEnd::Variable#assign` to assign a value to a variable
|
10
|
+
|
1
11
|
## [0.0.23] - 2021-01-20
|
2
12
|
- Fix for variables without explicit initialization.
|
3
13
|
|
data/README.md
CHANGED
@@ -176,7 +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
|
+
-[Variable expressions and assignments](#variable-expressions)
|
180
180
|
|
181
181
|
-[Variable declarations](#var-statement)
|
182
182
|
-[If Statement](#if-statement)
|
@@ -259,13 +259,17 @@ print 3 + 4 * 5; // => 23
|
|
259
259
|
print (3 + 4) * 5; // => 35
|
260
260
|
```
|
261
261
|
|
262
|
-
#### Variable expressions
|
262
|
+
#### Variable expressions and assignments
|
263
263
|
In __Lox__, a variable expression is nothing than retrieving the value of a variable.
|
264
264
|
``` javascript
|
265
265
|
var foo = "bar;" // Variable declaration
|
266
|
-
foo; //
|
266
|
+
print foo; // Variable expression (= use its value)
|
267
|
+
foo = "baz"; // Variable assignment
|
268
|
+
print foo; // Output: baz
|
267
269
|
```
|
268
270
|
|
271
|
+
|
272
|
+
|
269
273
|
#### Variable declarations
|
270
274
|
``` javascript
|
271
275
|
var iAmAVariable = "my-initial-value";
|
@@ -273,10 +277,6 @@ var iAmNil; // __Lox__ initializes variables to nil by default;
|
|
273
277
|
print iAmNil; // output: nil
|
274
278
|
```
|
275
279
|
|
276
|
-
Warning: current version cannot assign a value to an existing variable.
|
277
|
-
Expect this capability to be implemented in the coming days.
|
278
|
-
|
279
|
-
|
280
280
|
#### If statement
|
281
281
|
|
282
282
|
Based on a given condition, an if statement executes one of two statements:
|
@@ -7,6 +7,7 @@ require_relative 'lox_grouping_expr'
|
|
7
7
|
require_relative 'lox_unary_expr'
|
8
8
|
require_relative 'lox_binary_expr'
|
9
9
|
require_relative 'lox_logical_expr'
|
10
|
+
require_relative 'lox_assign_expr'
|
10
11
|
require_relative 'lox_print_stmt'
|
11
12
|
require_relative 'lox_if_stmt'
|
12
13
|
require_relative 'lox_var_stmt'
|
@@ -193,6 +193,12 @@ module Loxxy
|
|
193
193
|
Ast::LoxPrintStmt.new(tokens[1].position, theChildren[1])
|
194
194
|
end
|
195
195
|
|
196
|
+
# rule('assignment' => 'owner_opt IDENTIFIER EQUAL assignment')
|
197
|
+
def reduce_assign_expr(_production, _range, tokens, theChildren)
|
198
|
+
var_name = theChildren[1].token.lexeme.dup
|
199
|
+
Ast::LoxAssignExpr.new(tokens[1].position, var_name, theChildren[3])
|
200
|
+
end
|
201
|
+
|
196
202
|
# rule('logic_or' => 'logic_and disjunct_plus')
|
197
203
|
def reduce_logic_or_plus(production, range, tokens, theChildren)
|
198
204
|
reduce_logical_expr(production, range, tokens, theChildren)
|
@@ -83,6 +83,14 @@ module Loxxy
|
|
83
83
|
broadcast(:after_print_stmt, aPrintStmt)
|
84
84
|
end
|
85
85
|
|
86
|
+
# Visit event. The visitor is visiting an assignment node
|
87
|
+
# @param aLiteralExpr [AST::LoxAssignExpr] the variable assignment node to visit.
|
88
|
+
def visit_assign_expr(anAssignExpr)
|
89
|
+
broadcast(:before_assign_expr, anAssignExpr)
|
90
|
+
traverse_subnodes(anAssignExpr)
|
91
|
+
broadcast(:after_assign_expr, anAssignExpr)
|
92
|
+
end
|
93
|
+
|
86
94
|
# Visit event. The visitor is about to visit a logical expression.
|
87
95
|
# Since logical expressions may take shorcuts by not evaluating all their
|
88
96
|
# sub-expressiosns, they are responsible for visiting or not their children.
|
@@ -129,7 +137,7 @@ module Loxxy
|
|
129
137
|
broadcast(:after_literal_expr, aLiteralExpr)
|
130
138
|
end
|
131
139
|
|
132
|
-
# Visit event. The visitor is visiting a variable
|
140
|
+
# Visit event. The visitor is visiting a variable usage node
|
133
141
|
# @param aLiteralExpr [AST::LoxVariableExpr] the variable reference node to visit.
|
134
142
|
def visit_variable_expr(aVariableExpr)
|
135
143
|
broadcast(:before_variable_expr, aVariableExpr)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lox_compound_expr'
|
4
|
+
|
5
|
+
module Loxxy
|
6
|
+
module Ast
|
7
|
+
# This AST node represents the assignment of a value to a variable
|
8
|
+
class LoxAssignExpr < LoxCompoundExpr
|
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
|
+
# @param aValue [Loxxy::Ast::LoxNode, NilClass] value to assign
|
15
|
+
def initialize(aPosition, aName, aValue)
|
16
|
+
super(aPosition, [aValue])
|
17
|
+
@name = aName
|
18
|
+
end
|
19
|
+
|
20
|
+
# Part of the 'visitee' role in Visitor design pattern.
|
21
|
+
# @param visitor [Ast::ASTVisitor] the visitor
|
22
|
+
def accept(visitor)
|
23
|
+
visitor.visit_assign_expr(self)
|
24
|
+
end
|
25
|
+
end # class
|
26
|
+
end # module
|
27
|
+
end # module
|
@@ -66,6 +66,15 @@ module Loxxy
|
|
66
66
|
@ostream.print tos.to_str
|
67
67
|
end
|
68
68
|
|
69
|
+
def after_assign_expr(anAssignExpr)
|
70
|
+
var_name = anAssignExpr.name
|
71
|
+
variable = symbol_table.lookup(var_name)
|
72
|
+
raise StandardError, "Unknown variable #{var_name}" unless variable
|
73
|
+
value = stack.pop
|
74
|
+
variable.assign(value)
|
75
|
+
stack.push value # An expression produces a value
|
76
|
+
end
|
77
|
+
|
69
78
|
def after_logical_expr(aLogicalExpr, visitor)
|
70
79
|
op = aLogicalExpr.operator
|
71
80
|
operand1 = stack.pop # only first operand was evaluated
|
@@ -11,13 +11,18 @@ module Loxxy
|
|
11
11
|
include Entry # Add expected behaviour for symbol table entries
|
12
12
|
|
13
13
|
# @return [Datatype::BuiltinDatatype] the value assigned to the variable
|
14
|
-
|
14
|
+
attr_reader :value
|
15
15
|
|
16
16
|
# Create a variable with given name and initial value
|
17
17
|
# @param aName [String] The name of the variable
|
18
18
|
# @param aValue [Datatype::BuiltinDatatype] the initial assigned value
|
19
19
|
def initialize(aName, aValue = Datatype::Nil.instance)
|
20
20
|
init_name(aName)
|
21
|
+
assign(aValue)
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param aValue [Datatype::BuiltinDatatype] the assigned value
|
25
|
+
def assign(aValue)
|
21
26
|
@value = aValue
|
22
27
|
end
|
23
28
|
end # class
|
@@ -83,7 +83,7 @@ module Loxxy
|
|
83
83
|
rule('expression_opt' => 'expression')
|
84
84
|
rule('expression_opt' => [])
|
85
85
|
rule('expression' => 'assignment')
|
86
|
-
rule('assignment' => 'owner_opt IDENTIFIER EQUAL assignment')
|
86
|
+
rule('assignment' => 'owner_opt IDENTIFIER EQUAL assignment').as 'assign_expr'
|
87
87
|
rule('assignment' => 'logic_or')
|
88
88
|
rule('owner_opt' => 'call DOT')
|
89
89
|
rule('owner_opt' => [])
|
data/lib/loxxy/version.rb
CHANGED
data/spec/interpreter_spec.rb
CHANGED
@@ -277,13 +277,28 @@ LOX_END
|
|
277
277
|
|
278
278
|
it 'should set uninitialized variables to nil' do
|
279
279
|
program = <<-LOX_END
|
280
|
-
var
|
281
|
-
print
|
280
|
+
var a;
|
281
|
+
print a; // => nil
|
282
282
|
LOX_END
|
283
283
|
expect { subject.evaluate(program) }.not_to raise_error
|
284
284
|
expect(sample_cfg[:ostream].string).to eq('nil')
|
285
285
|
end
|
286
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
|
+
|
287
302
|
it 'should print the hello world message' do
|
288
303
|
expect { subject.evaluate(hello_world) }.not_to raise_error
|
289
304
|
expect(sample_cfg[:ostream].string).to eq('Hello, world!')
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
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.24
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
@@ -87,6 +87,7 @@ 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
|