loxxy 0.0.20 → 0.0.25
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 +92 -31
- data/README.md +47 -10
- data/lib/loxxy/ast/all_lox_nodes.rb +5 -0
- data/lib/loxxy/ast/ast_builder.rb +42 -2
- data/lib/loxxy/ast/ast_visitor.rb +47 -1
- data/lib/loxxy/ast/lox_assign_expr.rb +27 -0
- data/lib/loxxy/ast/lox_block_stmt.rb +23 -0
- data/lib/loxxy/ast/lox_if_stmt.rb +1 -1
- data/lib/loxxy/ast/lox_seq_decl.rb +17 -0
- data/lib/loxxy/ast/lox_var_stmt.rb +28 -0
- data/lib/loxxy/ast/lox_variable_expr.rb +26 -0
- data/lib/loxxy/back_end/engine.rb +49 -2
- data/lib/loxxy/back_end/entry.rb +41 -0
- data/lib/loxxy/back_end/environment.rb +66 -0
- data/lib/loxxy/back_end/symbol_table.rb +135 -0
- data/lib/loxxy/back_end/variable.rb +30 -0
- data/lib/loxxy/datatype/builtin_datatype.rb +6 -0
- data/lib/loxxy/front_end/grammar.rb +7 -7
- data/lib/loxxy/interpreter.rb +1 -1
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/engine_spec.rb +9 -0
- data/spec/back_end/environment_spec.rb +74 -0
- data/spec/back_end/symbol_table_spec.rb +142 -0
- data/spec/back_end/variable_spec.rb +79 -0
- data/spec/front_end/parser_spec.rb +21 -19
- data/spec/interpreter_spec.rb +83 -4
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 15da87c78ce0d90162679c2b76478cfaff17d9f88f78d4109190b83952146956
|
4
|
+
data.tar.gz: 0c9b1834f17cc51da96ec568d0804131b65dd6b82125ace0e4c56d6062250d09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6c31994ac27f67cc461fc10453468a42a17691f1b5c3171e23d26dcf9ecd6b5f5de8ad97184037990de6268039e57f8b0d5e80e4411f9c0a1a02b5edba766e91
|
7
|
+
data.tar.gz: 15ceead67dc859d2e4d3ca3e97aaa67372b581317fdbac8a66241ffb3322acec3115a5dab619a11d0a740676734fe5e517b9b1ca3aff218800ac07d693927263
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,68 @@
|
|
1
|
+
## [0.0.25] - 2021-01-21
|
2
|
+
- The interpreter implements block of code.
|
3
|
+
|
4
|
+
### Added
|
5
|
+
- Class `Ast::LoxBlockStmt` a node that represents a block of code
|
6
|
+
- Method `Ast::ASTBuilder#reduce_block_stmt` creates an `Ast::LoxBlockStmt` node
|
7
|
+
- Method `Ast::ASTVisitor#visit_block_stmt` for visiting an `Ast::LoxBlockStmt` node
|
8
|
+
- Method `BackEnd::Engine#before_block_stmt` creates an new enclosed Environment
|
9
|
+
- Method `BackEnd::Engine#after_block_stmt` close enclosed Environment and make parent Environment the current one
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
- File `README.md` updated.
|
13
|
+
|
14
|
+
## [0.0.24] - 2021-01-20
|
15
|
+
- The interpreter implements the assignment of variables.
|
16
|
+
|
17
|
+
### Added
|
18
|
+
- Class `Ast::LoxAssignExpr` a node that represents the assignment of a value to a variable
|
19
|
+
- Method `Ast::ASTBuilder#reduce_assign_expr` creates an `Ast::LoxAssignExpr` node
|
20
|
+
- Method `Ast::ASTVisitor#visit_assign_expr` for visiting an `Ast::LoxAssignExpr` node
|
21
|
+
- Method `BackEnd::Engine#after_assign_expr` implementation of the assignment
|
22
|
+
- Method `BackEnd::Variable#assign` to assign a value to a variable
|
23
|
+
|
24
|
+
## [0.0.23] - 2021-01-20
|
25
|
+
- Fix for variables without explicit initialization.
|
26
|
+
|
27
|
+
### Added
|
28
|
+
- Method `Ast::ASTVisitor#visit_builtin` for visiting `Datatype::BuiltinDatatype` value.
|
29
|
+
- Method `BackEnd::Engine#before_visit_builtin` push the data value onto the stack.
|
30
|
+
|
31
|
+
### Fixed
|
32
|
+
- Method `Ast::LoxVarStmt#initialize`: in case no explicit value provided then use `Datatype::Nil.instance`instead of Ruby `nil`
|
33
|
+
|
34
|
+
## [0.0.22] - 2021-01-17
|
35
|
+
- The interpreter can retrieve the value of a variable.
|
36
|
+
|
37
|
+
### Added
|
38
|
+
- Method `Ast::ASTBuilder#declaration_plus_more` and `Ast::ASTBuilder#declaration_plus_end` to allow multiple expressions/statements
|
39
|
+
- Method `Ast::ASTBuilder#reduce_var_expression` creates an `Ast::LoxVariableExpr` node
|
40
|
+
- Method `Ast::ASTVisitor#visit_var_expr` for visiting `Ast::LoxVariableExpr` nodes
|
41
|
+
- Class `Ast::LoxSeqDecl` a node that represents a sequence of declarations/statements
|
42
|
+
- Class `Ast::LoxVarExpr` a node that represents a variable occurrence in an expression
|
43
|
+
- Method `Engine::after_variable_expr`: retrieve the value of variable with given name
|
44
|
+
|
45
|
+
### Changed
|
46
|
+
- Method `Ast::ASTBuilder#reduce_lox_program` to support multiple statements/declarations
|
47
|
+
- File `README.md` updated.
|
48
|
+
|
49
|
+
## [0.0.21] - 2021-01-16
|
50
|
+
- The interpreter supports the declaration global variables.
|
51
|
+
|
52
|
+
### Added
|
53
|
+
- Class `BackEnd::Entry`, mixin module for objects put in the symbol table
|
54
|
+
- Class `BackEnd::Environment` that keeps track of variables in a given context.
|
55
|
+
- Class `BackEnd::SymbolTable` that keeps track of environments.
|
56
|
+
- Class `BackEnd::Variable` internal representation of a `Lox` variable
|
57
|
+
- Method `Ast::ASTBuilder#reduce_var_declaration` and `Ast::ASTBuilder#reduce_var_declaration`
|
58
|
+
- Method `Ast::ASTVisitor#visit_var_stmt` for visiting `LoxVarStmt` nodes
|
59
|
+
- Attribute `Engine::symbol_table`for keeping track of variables
|
60
|
+
- Method `Engine::after_var_stmt` for the implementation of variable declarations
|
61
|
+
|
1
62
|
## [0.0.20] - 2021-01-15
|
2
63
|
- The interpreter supports the `if` ... `else` statement.
|
3
64
|
|
4
|
-
|
65
|
+
### Added
|
5
66
|
- Class `Ast::LoxItStmt`, AST node specific for `if` `else` statements
|
6
67
|
- Method `Ast::ASTBuilder#reduce_if_stmt` as semantic action for if ... else
|
7
68
|
- Method `Ast::ASTVisitor#visit_if_stmt` for visiting `LoxIfStmt` nodes
|
@@ -10,20 +71,20 @@
|
|
10
71
|
## [0.0.19] - 2021-01-14
|
11
72
|
- The interpreter supports expressions between parentheses (grouping).
|
12
73
|
|
13
|
-
|
74
|
+
### Added
|
14
75
|
- Class `Ast::LoxLogicalExpr`
|
15
76
|
- Method `Ast::ASTBuilder#reduce_grouping_expr` as semantic action for grouping expression
|
16
77
|
- Method `Ast::ASTVisitor#visit_grouping_expr` for visiting grouping expressions
|
17
78
|
- Method `Engine::after_grouping_expr`for the evaluation of grouping expressions
|
18
79
|
|
19
|
-
|
80
|
+
### Changed
|
20
81
|
- File `grammar.rb` rules for if ... else were given names in order to activate semantic actions.
|
21
82
|
- File `README.md` updated with little `if ... else` documentation.
|
22
83
|
|
23
84
|
## [0.0.18] - 2021-01-13
|
24
85
|
- The interpreter can evaluate `and`, `or`expressions.
|
25
86
|
|
26
|
-
|
87
|
+
### Added
|
27
88
|
- Class `Ast::LoxLogicalExpr`
|
28
89
|
- Method `Ast::ASTBuilder#reduce_logical_expr` for the semantic action require for `and`, `or`
|
29
90
|
- Method `Ast::ASTVisitor#visit_logical_expr` for visiting logical expressions
|
@@ -33,7 +94,7 @@
|
|
33
94
|
- The interpreter can evaluate all arithmetic and comparison operations.
|
34
95
|
- It implements `==`, `!=` and the unary operations `!`, `-`
|
35
96
|
|
36
|
-
|
97
|
+
### Added
|
37
98
|
- Class `Ast::LoxUnaryExpr`
|
38
99
|
- Method `Ast::ASTBuilder#reduce_unary_expr` to support the evaluation of `!` and ``-@`
|
39
100
|
- Method `Ast::ASTVisitor#visit_unnary_expr` for visiting unary expressions
|
@@ -41,14 +102,14 @@
|
|
41
102
|
- In class `Datatype::BuiltinDatatype` the methods `falsey?`, `truthy?`, `!`, `!=`
|
42
103
|
- In class `Datatype::Number`the methods `<`, `<=`, ´>´, `>=` and `-@`
|
43
104
|
|
44
|
-
|
105
|
+
### Changed
|
45
106
|
- File `README.md` updated.
|
46
107
|
|
47
108
|
## [0.0.16] - 2021-01-11
|
48
109
|
- The interpreter can evaluate product and division of two numbers.
|
49
110
|
- It also implements equality `==` and inequality `!=` operators
|
50
111
|
|
51
|
-
|
112
|
+
### Added
|
52
113
|
- Method `Datatype::False#==` for equality testing
|
53
114
|
- Method `Datatype::False#!=` for inequality testing
|
54
115
|
- Method `Datatype::LXString#==` for equality testing
|
@@ -62,17 +123,17 @@
|
|
62
123
|
- Method `Datatype::True#==` for equality testing
|
63
124
|
- Method `Datatype::True#!=` for inequality testing
|
64
125
|
|
65
|
-
|
126
|
+
### Changed
|
66
127
|
- Method `BackEnd::Engine#after_binary_expr` to allow `*`, `/`, `==`, `!=` operators
|
67
128
|
- File `README.md` updated for the newly implemented operators
|
68
129
|
|
69
130
|
## [0.0.15] - 2021-01-11
|
70
131
|
- The interpreter can evaluate substraction between two numbers.
|
71
132
|
|
72
|
-
|
133
|
+
### Added
|
73
134
|
- Method `Datatype::Number#-` implmenting the subtraction operation
|
74
135
|
|
75
|
-
|
136
|
+
### Changed
|
76
137
|
- File `README.md` minor editorial changes.
|
77
138
|
- File `lx_string_spec.rb` Added test for string concatentation
|
78
139
|
- File `number_spec.rb` Added tests for addition and subtraction operations
|
@@ -81,7 +142,7 @@
|
|
81
142
|
## [0.0.14] - 2021-01-10
|
82
143
|
- The interpreter can evaluate addition of numbers and string concatenation
|
83
144
|
|
84
|
-
|
145
|
+
### Added
|
85
146
|
- Method `Ast::ASTVisitor#visit_binary_expr` for visiting binary expressions
|
86
147
|
- Method `Ast::LoxBinaryExpr#accept` for visitor pattern
|
87
148
|
- Method `BackEnd::Engine#after_binary_expr` to trigger execution of binary operator
|
@@ -89,79 +150,79 @@
|
|
89
150
|
- Method `Datatype::LXString#+` implementation of the string concatenation
|
90
151
|
- Method `Datatype::Number#+` implementation of the addition of numbers
|
91
152
|
|
92
|
-
|
153
|
+
### Changed
|
93
154
|
- File `interpreter_spec.rb` Added tests for addition operation and string concatenation
|
94
155
|
|
95
156
|
|
96
157
|
## [0.0.13] - 2021-01-10
|
97
158
|
- The interpreter can evaluate directly simple literals.
|
98
159
|
|
99
|
-
|
160
|
+
### Changed
|
100
161
|
- Class `AST::ASTBuilder` added `reduce_exprStmt` to support the evaluation of literals.
|
101
162
|
- File `README.md` added one more example.
|
102
163
|
- File `parser_spec.rb` Updated the tests to reflect the change in the AST.
|
103
164
|
- File `interpreter_spec.rb` Added a test for literal expression.
|
104
165
|
|
105
|
-
|
166
|
+
### Fixed
|
106
167
|
- File `loxxy.rb`: shorthand method `lox_true` referenced the ... false object (oops).
|
107
168
|
|
108
169
|
## [0.0.12] - 2021-01-09
|
109
170
|
- Initial interpreter capable of evaluating a tiny subset of Lox language.
|
110
171
|
|
111
|
-
|
172
|
+
### Added
|
112
173
|
- Class `AST::LoxNoopExpr`
|
113
174
|
- Class `AST::LoxPrintStmt`
|
114
175
|
- Class `BackEnd::Engine` implementation of the print statement logic
|
115
176
|
- Class `Interpreter`
|
116
177
|
|
117
|
-
|
178
|
+
### Changed
|
118
179
|
- Class `Ast::ASTVisitor` Added visit method
|
119
180
|
- File `README.md` added Hello world example.
|
120
181
|
|
121
182
|
## [0.0.11] - 2021-01-08
|
122
183
|
- AST node generation for logical expression (and, or).
|
123
184
|
|
124
|
-
|
185
|
+
### Changed
|
125
186
|
- Class `AST::ASTBuilder` added `reduce_` methods for logical operations.
|
126
187
|
- File `grammar.rb`added name to logical expression rules
|
127
188
|
- File `README.md` added gem version and license badges, expanded roadmap section.
|
128
189
|
|
129
|
-
|
190
|
+
### Fixed
|
130
191
|
- File `grammar.rb`: a rule had incomplete non-terminal name `conjunct_` in its lhs.
|
131
192
|
|
132
193
|
|
133
194
|
## [0.0.10] - 2021-01-08
|
134
195
|
- AST node generation for equality expression.
|
135
196
|
|
136
|
-
|
197
|
+
### Changed
|
137
198
|
- Class `AST::ASTBuilder` refactoring and added `reduce_` methods for equality operations.
|
138
199
|
- File `grammar.rb`added name to equality rules
|
139
200
|
- File `README.md` added gem version and license badges, expanded roadmap section.
|
140
201
|
|
141
|
-
|
202
|
+
### Fixed
|
142
203
|
- File `grammar.rb`: a rule had still the discarded non-terminal `equalityTest_star` in its lhs.
|
143
204
|
|
144
205
|
## [0.0.9] - 2021-01-07
|
145
206
|
- AST node generation for comparison expression.
|
146
207
|
|
147
|
-
|
208
|
+
### Changed
|
148
209
|
- Class `AST::ASTBuilder` added `reduce_` methods for comparison operations.
|
149
210
|
- File `grammar.rb`added name to comparison rules
|
150
211
|
|
151
212
|
## [0.0.8] - 2021-01-07
|
152
213
|
- AST node generation for arithmetic operations of number literals.
|
153
214
|
|
154
|
-
|
215
|
+
### Changed
|
155
216
|
- Class `AST::ASTBuilder` added `reduce_` methods for arithmetic operations.
|
156
217
|
- File `grammar.rb`added name to arithmetic rules
|
157
218
|
|
158
|
-
|
219
|
+
### Fixed
|
159
220
|
- File `grammar.rb`: second rule for `factor` had a missing member in rhs.
|
160
221
|
|
161
222
|
## [0.0.7] - 2021-01-06
|
162
223
|
- Lox grammar reworked, initial AST classes created.
|
163
224
|
|
164
|
-
|
225
|
+
### Added
|
165
226
|
- Class `Parser` this one generates AST's (Abstract Syntax Tree)
|
166
227
|
- Class `AST::ASTVisitor` draft initial implementation.
|
167
228
|
- Class `AST::BinaryExpr` draft initial implementation.
|
@@ -169,7 +230,7 @@
|
|
169
230
|
- Class `AST::LiteralExpr` draft initial implementation.
|
170
231
|
- Class `AST::LoxNode` draft initial implementation.
|
171
232
|
|
172
|
-
|
233
|
+
### Changed
|
173
234
|
- File `spec_helper.rb`: removed Bundler dependency
|
174
235
|
- Class `AST::ASTBuilder` added initial `reduce_` methods.
|
175
236
|
- File `README.md` Removed example with AST generation since this is in flux.
|
@@ -177,31 +238,31 @@
|
|
177
238
|
## [0.0.6] - 2021-01-03
|
178
239
|
- First iteration of a parser with AST generation.
|
179
240
|
|
180
|
-
|
241
|
+
### Added
|
181
242
|
- Class `Parser` this one generates AST's (Abstract Syntax Tree)
|
182
243
|
- Class `AST::ASTBuilder` default code to generate an AST.
|
183
244
|
|
184
|
-
|
245
|
+
### Changed
|
185
246
|
- File `spec_helper.rb`: removed Bundler dependency
|
186
247
|
- File `README.md` Added example with AST visualization.
|
187
248
|
|
188
|
-
|
249
|
+
### Fixed
|
189
250
|
- File `grammar.rb` ensure that the constant `Grammar` is created once only.
|
190
251
|
|
191
252
|
## [0.0.5] - 2021-01-02
|
192
253
|
- Improved example in `README.md`, code re-styling to please `Rubocop` 1.7
|
193
254
|
|
194
|
-
|
255
|
+
### Changed
|
195
256
|
- Code re-styling to please `Rubocop` 1.7
|
196
257
|
- File `README.md` Improved example with better parse tree visualization.
|
197
258
|
|
198
259
|
## [0.0.4] - 2021-01-01
|
199
260
|
- A first parser implementation able to parse Lox source code.
|
200
261
|
|
201
|
-
|
262
|
+
### Added
|
202
263
|
- Method `LXString::==` equality operator.
|
203
264
|
|
204
|
-
|
265
|
+
### Changed
|
205
266
|
- class `Parser` renamed to `RawParser`
|
206
267
|
- File `README.md` Added an example showing the use of `RawParser` class.
|
207
268
|
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ a simple language used in Bob Nystrom's online book [Crafting Interpreters](http
|
|
8
8
|
|
9
9
|
### Purpose of this project:
|
10
10
|
- To deliver an open source example of a programming language fully implemented in Ruby
|
11
|
-
(from the scanner
|
11
|
+
(from the scanner and parser to an interpreter).
|
12
12
|
- The implementation should be mature enough to run [LoxLox](https://github.com/benhoyt/loxlox),
|
13
13
|
a Lox interpreter written in Lox.
|
14
14
|
|
@@ -141,7 +141,10 @@ Here are the language features currently supported by the interpreter:
|
|
141
141
|
- [Datatypes](#datatypes)
|
142
142
|
- [Statements](#statements)
|
143
143
|
-[Expressions](#expressions)
|
144
|
-
|
144
|
+
- [Variable declarations](#var-statement)
|
145
|
+
- [If Statement](#if-statement)
|
146
|
+
- [Print Statement](#print-statement)
|
147
|
+
- [Block Statement](#block-statement)
|
145
148
|
|
146
149
|
### Comments
|
147
150
|
|
@@ -168,14 +171,18 @@ loxxy supports all the standard __Lox__ datatypes:
|
|
168
171
|
### Statements
|
169
172
|
|
170
173
|
Loxxy supports the following statements:
|
171
|
-
-[Expressions](#expressions)
|
174
|
+
- [Expressions](#expressions)
|
172
175
|
-[Arithmetic expressions](#arithmetic-expressions)
|
173
176
|
-[String concatenation](#string-concatenation)
|
174
177
|
-[Comparison expressions](#comparison-expressions)
|
175
178
|
-[Logical expressions](#logical-expressions)
|
176
179
|
-[Grouping expressions](#grouping-expressions)
|
177
|
-
-[
|
178
|
-
|
180
|
+
-[Variable expressions and assignments](#variable-expressions)
|
181
|
+
|
182
|
+
-[Variable declarations](#var-statement)
|
183
|
+
-[If Statement](#if-statement)
|
184
|
+
-[Print Statement](#print-statement)
|
185
|
+
-[Block Statement](#block-statement)
|
179
186
|
|
180
187
|
#### Expressions
|
181
188
|
|
@@ -254,6 +261,22 @@ print 3 + 4 * 5; // => 23
|
|
254
261
|
print (3 + 4) * 5; // => 35
|
255
262
|
```
|
256
263
|
|
264
|
+
#### Variable expressions and assignments
|
265
|
+
In __Lox__, a variable expression is nothing than retrieving the value of a variable.
|
266
|
+
``` javascript
|
267
|
+
var foo = "bar;" // Variable declaration
|
268
|
+
print foo; // Variable expression (= use its value)
|
269
|
+
foo = "baz"; // Variable assignment
|
270
|
+
print foo; // Output: baz
|
271
|
+
```
|
272
|
+
|
273
|
+
#### Variable declarations
|
274
|
+
``` javascript
|
275
|
+
var iAmAVariable = "my-initial-value";
|
276
|
+
var iAmNil; // __Lox__ initializes variables to nil by default;
|
277
|
+
print iAmNil; // output: nil
|
278
|
+
```
|
279
|
+
|
257
280
|
#### If statement
|
258
281
|
|
259
282
|
Based on a given condition, an if statement executes one of two statements:
|
@@ -274,20 +297,21 @@ The problem in a nutshell: in a nested if ... else ... statement like this:
|
|
274
297
|
``` javascript
|
275
298
|
'if (true) if (false) print "bad"; else print "good";
|
276
299
|
```
|
277
|
-
... there is an ambiguity.
|
300
|
+
... there is an ambiguity.
|
301
|
+
Indeed, according to the __Lox__ grammar, the `else` could be bound
|
278
302
|
either to the first `if` or to the second one.
|
279
303
|
This ambiguity is usually lifted by applying an ad-hoc rule: an `else` is aways bound to the most
|
280
304
|
recent (rightmost) `if`.
|
281
|
-
Being a generic parsing library, `Rley` doesn't apply any of these supplemental rules.
|
305
|
+
Being a generic parsing library, `Rley` doesn't apply any of these supplemental rules.
|
282
306
|
As a consequence,it complains about the found ambiguity and stops the parsing...
|
283
307
|
Although `Rley` can cope with ambiguities, this requires the use of an advanced data structure
|
284
308
|
called `Shared Packed Parse Forest (SPPF)`.
|
285
|
-
SPPF are much more complex to handle than the
|
309
|
+
SPPF are much more complex to handle than the "common" parse trees present in most compiler or interpreter books.
|
286
310
|
Therefore, a future version of `Rley` will incorporate the capability to define disambuiguation rules.
|
287
311
|
|
288
312
|
In the meantime, the `Loxxy` will progress on other __Lox__ features like:
|
289
|
-
- Variables,
|
290
313
|
- Block structures...
|
314
|
+
- Iteration structures (`for` and `while` loops)
|
291
315
|
|
292
316
|
|
293
317
|
#### Print Statement
|
@@ -299,6 +323,19 @@ print "Hello, world!"; // Output: Hello, world!
|
|
299
323
|
|
300
324
|
```
|
301
325
|
|
326
|
+
#### Block Statement
|
327
|
+
__Lox__ has code blocks.
|
328
|
+
``` javascript
|
329
|
+
var a = "outer";
|
330
|
+
|
331
|
+
{
|
332
|
+
var a = "inner";
|
333
|
+
print a; // output: inner
|
334
|
+
}
|
335
|
+
|
336
|
+
print a; // output: outer
|
337
|
+
```
|
338
|
+
|
302
339
|
## Installation
|
303
340
|
|
304
341
|
Add this line to your application's Gemfile:
|
@@ -321,7 +358,7 @@ TODO: Write usage instructions here
|
|
321
358
|
|
322
359
|
## Other Lox implementations in Ruby
|
323
360
|
|
324
|
-
For Ruby, there is the [lox](https://github.com/rdodson41/ruby-lox) gem.
|
361
|
+
For Ruby, there is the [lox](https://github.com/rdodson41/ruby-lox) gem.
|
325
362
|
There are other Ruby-based projects as well:
|
326
363
|
- [SlowLox](https://github.com/ArminKleinert/SlowLox), described as a "1-to-1 conversion of JLox to Ruby"
|
327
364
|
- [rulox](https://github.com/LevitatingBusinessMan/rulox)
|
@@ -1,10 +1,15 @@
|
|
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'
|
6
7
|
require_relative 'lox_unary_expr'
|
7
8
|
require_relative 'lox_binary_expr'
|
8
9
|
require_relative 'lox_logical_expr'
|
10
|
+
require_relative 'lox_assign_expr'
|
11
|
+
require_relative 'lox_block_stmt'
|
9
12
|
require_relative 'lox_print_stmt'
|
10
13
|
require_relative 'lox_if_stmt'
|
14
|
+
require_relative 'lox_var_stmt'
|
15
|
+
require_relative 'lox_seq_decl'
|
@@ -149,8 +149,18 @@ module Loxxy
|
|
149
149
|
end
|
150
150
|
|
151
151
|
# rule('program' => 'declaration_plus EOF').as ''
|
152
|
-
def reduce_lox_program(_production,
|
153
|
-
|
152
|
+
def reduce_lox_program(_production, _range, tokens, theChildren)
|
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')
|
@@ -158,6 +168,18 @@ module Loxxy
|
|
158
168
|
return_first_child(range, tokens, theChildren) # Discard the semicolon
|
159
169
|
end
|
160
170
|
|
171
|
+
# rule('varDecl' => 'VAR IDENTIFIER SEMICOLON')
|
172
|
+
def reduce_var_declaration(_production, _range, tokens, theChildren)
|
173
|
+
var_name = theChildren[1].token.lexeme.dup
|
174
|
+
Ast::LoxVarStmt.new(tokens[1].position, var_name, nil)
|
175
|
+
end
|
176
|
+
|
177
|
+
# rule('varDecl' => 'VAR IDENTIFIER EQUAL expression SEMICOLON')
|
178
|
+
def reduce_var_initialization(_production, _range, tokens, theChildren)
|
179
|
+
var_name = theChildren[1].token.lexeme.dup
|
180
|
+
Ast::LoxVarStmt.new(tokens[1].position, var_name, theChildren[3])
|
181
|
+
end
|
182
|
+
|
161
183
|
# rule('ifStmt' => 'IF ifCondition statement elsePart_opt')
|
162
184
|
def reduce_if_stmt(_production, _range, tokens, theChildren)
|
163
185
|
condition = theChildren[1]
|
@@ -171,6 +193,18 @@ module Loxxy
|
|
171
193
|
Ast::LoxPrintStmt.new(tokens[1].position, theChildren[1])
|
172
194
|
end
|
173
195
|
|
196
|
+
# rule('block' => 'LEFT_BRACE declaration_plus RIGHT_BRACE')
|
197
|
+
def reduce_block_stmt(_production, _range, tokens, theChildren)
|
198
|
+
decls = LoxSeqDecl.new(tokens[1].position, theChildren[1])
|
199
|
+
Ast::LoxBlockStmt.new(tokens[1].position, decls)
|
200
|
+
end
|
201
|
+
|
202
|
+
# rule('assignment' => 'owner_opt IDENTIFIER EQUAL assignment')
|
203
|
+
def reduce_assign_expr(_production, _range, tokens, theChildren)
|
204
|
+
var_name = theChildren[1].token.lexeme.dup
|
205
|
+
Ast::LoxAssignExpr.new(tokens[1].position, var_name, theChildren[3])
|
206
|
+
end
|
207
|
+
|
174
208
|
# rule('logic_or' => 'logic_and disjunct_plus')
|
175
209
|
def reduce_logic_or_plus(production, range, tokens, theChildren)
|
176
210
|
reduce_logical_expr(production, range, tokens, theChildren)
|
@@ -279,6 +313,12 @@ module Loxxy
|
|
279
313
|
literal = first_child.token.value
|
280
314
|
LoxLiteralExpr.new(pos, literal)
|
281
315
|
end
|
316
|
+
|
317
|
+
# rule('primary' => 'IDENTIFIER')
|
318
|
+
def reduce_variable_expr(_production, _range, tokens, theChildren)
|
319
|
+
var_name = theChildren[0].token.lexeme
|
320
|
+
LoxVariableExpr.new(tokens[0].position, var_name)
|
321
|
+
end
|
282
322
|
end # class
|
283
323
|
end # module
|
284
324
|
end # module
|