loxxy 0.0.23 → 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.
- 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
|