loxxy 0.0.17 → 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 +61 -2
- data/README.md +164 -50
- data/lib/loxxy/ast/all_lox_nodes.rb +7 -1
- data/lib/loxxy/ast/ast_builder.rb +63 -3
- data/lib/loxxy/ast/ast_visitor.rb +68 -1
- data/lib/loxxy/ast/lox_grouping_expr.rb +23 -0
- data/lib/loxxy/ast/lox_if_stmt.rb +35 -0
- data/lib/loxxy/ast/lox_logical_expr.rb +28 -0
- data/lib/loxxy/ast/lox_seq_decl.rb +23 -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 +70 -1
- 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 +25 -0
- data/lib/loxxy/datatype/builtin_datatype.rb +32 -5
- data/lib/loxxy/front_end/grammar.rb +9 -9
- 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 +25 -23
- data/spec/interpreter_spec.rb +110 -1
- metadata +18 -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,10 +1,69 @@
|
|
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
|
17
|
+
- The interpreter supports the declaration global variables.
|
18
|
+
|
19
|
+
## Added
|
20
|
+
- Class `BackEnd::Entry`, mixin module for objects put in the symbol table
|
21
|
+
- Class `BackEnd::Environment` that keeps track of variables in a given context.
|
22
|
+
- Class `BackEnd::SymbolTable` that keeps track of environments.
|
23
|
+
- Class `BackEnd::Variable` internal representation of a `Lox` variable
|
24
|
+
- Method `Ast::ASTBuilder#reduce_var_declaration` and `Ast::ASTBuilder#reduce_var_declaration`
|
25
|
+
- Method `Ast::ASTVisitor#visit_var_stmt` for visiting `LoxVarStmt` nodes
|
26
|
+
- Attribute `Engine::symbol_table`for keeping track of variables
|
27
|
+
- Method `Engine::after_var_stmt` for the implementation of variable declarations
|
28
|
+
|
29
|
+
## [0.0.20] - 2021-01-15
|
30
|
+
- The interpreter supports the `if` ... `else` statement.
|
31
|
+
|
32
|
+
## Added
|
33
|
+
- Class `Ast::LoxItStmt`, AST node specific for `if` `else` statements
|
34
|
+
- Method `Ast::ASTBuilder#reduce_if_stmt` as semantic action for if ... else
|
35
|
+
- Method `Ast::ASTVisitor#visit_if_stmt` for visiting `LoxIfStmt` nodes
|
36
|
+
- Method `Engine::after_if_stmt` implementation of the control flow
|
37
|
+
|
38
|
+
## [0.0.19] - 2021-01-14
|
39
|
+
- The interpreter supports expressions between parentheses (grouping).
|
40
|
+
|
41
|
+
## Added
|
42
|
+
- Class `Ast::LoxLogicalExpr`
|
43
|
+
- Method `Ast::ASTBuilder#reduce_grouping_expr` as semantic action for grouping expression
|
44
|
+
- Method `Ast::ASTVisitor#visit_grouping_expr` for visiting grouping expressions
|
45
|
+
- Method `Engine::after_grouping_expr`for the evaluation of grouping expressions
|
46
|
+
|
47
|
+
## Changed
|
48
|
+
- File `grammar.rb` rules for if ... else were given names in order to activate semantic actions.
|
49
|
+
- File `README.md` updated with little `if ... else` documentation.
|
50
|
+
|
51
|
+
## [0.0.18] - 2021-01-13
|
52
|
+
- The interpreter can evaluate `and`, `or`expressions.
|
53
|
+
|
54
|
+
## Added
|
55
|
+
- Class `Ast::LoxLogicalExpr`
|
56
|
+
- Method `Ast::ASTBuilder#reduce_logical_expr` for the semantic action require for `and`, `or`
|
57
|
+
- Method `Ast::ASTVisitor#visit_logical_expr` for visiting logical expressions
|
58
|
+
- Method `Backend::Engine#after_logical_expr` implements the evaluation of the logical expressions
|
59
|
+
|
1
60
|
## [0.0.17] - 2021-01-12
|
2
61
|
- The interpreter can evaluate all arithmetic and comparison operations.
|
3
62
|
- It implements `==`, `!=` and the unary operations `!`, `-`
|
4
63
|
|
5
64
|
## Added
|
6
|
-
- Class `
|
7
|
-
- Method `
|
65
|
+
- Class `Ast::LoxUnaryExpr`
|
66
|
+
- Method `Ast::ASTBuilder#reduce_unary_expr` to support the evaluation of `!` and ``-@`
|
8
67
|
- Method `Ast::ASTVisitor#visit_unnary_expr` for visiting unary expressions
|
9
68
|
- Method `Backend::Engine#after_unary_expr` evaluating an unary expression
|
10
69
|
- In class `Datatype::BuiltinDatatype` the methods `falsey?`, `truthy?`, `!`, `!=`
|
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
|
|
@@ -128,16 +128,22 @@ program
|
|
128
128
|
```
|
129
129
|
|
130
130
|
## Suppported Lox language features
|
131
|
-
|
132
|
-
|
131
|
+
On one hand, the parser covers the complete Lox grammar and should therefore, in principle,
|
132
|
+
parse any valid Lox program.
|
133
|
+
|
134
|
+
On the other hand, the interpreter is under development and currently it can evaluate only a tiny subset of __Lox__.
|
135
|
+
But the situation is changing almost daily, stay tuned...
|
133
136
|
|
134
137
|
Here are the language features currently supported by the interpreter:
|
135
138
|
|
136
139
|
- [Comments](#comments)
|
137
140
|
- [Keywords](#keywords)
|
138
|
-
- [Operators and Special Chars](#operators-and-special-chars)
|
139
141
|
- [Datatypes](#datatypes)
|
140
|
-
- [Statements](#statements)
|
142
|
+
- [Statements](#statements)
|
143
|
+
-[Expressions](#expressions)
|
144
|
+
- [Variable declarations](#var-statement)
|
145
|
+
- [If Statement](#if-statement)
|
146
|
+
- [Print Statement](#print-statement)
|
141
147
|
|
142
148
|
### Comments
|
143
149
|
|
@@ -148,36 +154,10 @@ Loxxy supports single line C-style comments.
|
|
148
154
|
```
|
149
155
|
|
150
156
|
### Keywords
|
151
|
-
|
152
|
-
The parser knows all the __Lox__ reserved keywords:
|
157
|
+
Loxxy implements the following __Lox__ reserved keywords:
|
153
158
|
```lang-none
|
154
|
-
and,
|
155
|
-
print, return, super, this, true, var, while
|
159
|
+
and, false, nil, or, print, true
|
156
160
|
```
|
157
|
-
Of these, the interpreter implements: `false`, `nil`, `print`, `true`
|
158
|
-
|
159
|
-
### Operators and Special Chars
|
160
|
-
#### Operators
|
161
|
-
The __loxxy__ interpreter supports all the __Lox__ unary and binary operators:
|
162
|
-
- Arithmetic operators: `+`, `-`, `*`, `/`
|
163
|
-
- Comparison operators: `>`, `>=`, `<`, `<=`
|
164
|
-
- Equality operators: `==`, `!=`
|
165
|
-
- Unary negate (change sign): `-`
|
166
|
-
- Unary not: `!`
|
167
|
-
|
168
|
-
#### Delimiters
|
169
|
-
The parser knows all the __Lox__ grouping delimiters:
|
170
|
-
(`, ), `{`, `}`
|
171
|
-
|
172
|
-
These aren't yet implemented in the interpreter.
|
173
|
-
|
174
|
-
The other characters that have a special meaning in __Lox__ are:
|
175
|
-
- `,` Used in parameter list
|
176
|
-
- `.` For the dot notation (i.e. calling a method)
|
177
|
-
- `;` The semicolon is used to terminates expressions
|
178
|
-
- `=` Assignment
|
179
|
-
|
180
|
-
The parser recognizes them all but the interpreter accepts the semicolons only.
|
181
161
|
|
182
162
|
### Datatypes
|
183
163
|
|
@@ -187,24 +167,158 @@ loxxy supports all the standard __Lox__ datatypes:
|
|
187
167
|
- `String`: Sequence of characters surrounded by `"`. For example: `"Hello!"`
|
188
168
|
- `Nil`: Used to define a null value, denoted by the `nil` keyword
|
189
169
|
|
190
|
-
|
191
|
-
|
192
|
-
Loxxy
|
193
|
-
-
|
194
|
-
- (
|
195
|
-
-
|
196
|
-
-
|
197
|
-
-
|
198
|
-
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
-
|
203
|
-
-
|
170
|
+
### Statements
|
171
|
+
|
172
|
+
Loxxy supports the following statements:
|
173
|
+
- [Expressions](#expressions)
|
174
|
+
-[Arithmetic expressions](#arithmetic-expressions)
|
175
|
+
-[String concatenation](#string-concatenation)
|
176
|
+
-[Comparison expressions](#comparison-expressions)
|
177
|
+
-[Logical expressions](#logical-expressions)
|
178
|
+
-[Grouping expressions](#grouping-expressions)
|
179
|
+
-[Variable expressions](#variable-expressions)
|
180
|
+
|
181
|
+
-[Variable declarations](#var-statement)
|
182
|
+
-[If Statement](#if-statement)
|
183
|
+
-[Print Statement](#print-statement)
|
184
|
+
|
185
|
+
#### Expressions
|
186
|
+
|
187
|
+
##### Arithmetic expressions
|
188
|
+
Loxxy supports the following operators for arithmetic expressions:
|
189
|
+
|
190
|
+
- `+`: Adds of two numbers. Both operands must be of the type Number
|
191
|
+
E.g. `37 + 5; // => 42`
|
192
|
+
`7 + -3; // => 4`
|
193
|
+
- `-`: (Binary) Subtracts right operand from left operand. Both operands must be numbers.
|
194
|
+
E.g. `47 - 5; // => 42`
|
195
|
+
- `-`: (Unary) Negates (= changes the sign) of the given number operand.
|
196
|
+
E.g. `- -3; // => 3`
|
197
|
+
- `*`: Multiplies two numbers
|
198
|
+
E.g. `2 * 3; // => 6`
|
199
|
+
- `/`: Divides two numbers
|
200
|
+
E.g. `8 / 2; // => 4`
|
201
|
+
`5 / 2; // => 2.5`
|
202
|
+
|
203
|
+
##### String concatenation
|
204
|
+
- `+`: Concatenates two strings. Both operands must be of the String type.
|
205
|
+
E.g. `"Hello" + ", " + "world! // => "Hello, world!"`
|
206
|
+
|
207
|
+
##### Comparison expressions
|
208
|
+
|
209
|
+
- `==`: Returns `true` if left operand is equal to right operand, otherwise `false`
|
210
|
+
E.g. `false == false; // => true`
|
211
|
+
`5 + 2 == 3 + 4; // => true`
|
212
|
+
`"" == ""; // => true`
|
213
|
+
- `!=`: Returns `true` if left operand is not equal to right operand, otherwise `false`
|
214
|
+
E.g. `false != "false"; // => true`
|
215
|
+
`5 + 2 != 4 + 3; // => false`
|
216
|
+
- `<`: Returns `true` if left operand is less than right operand, otherwise `false`. Both operands must be numbers
|
217
|
+
E.g. `1 < 3; // => true`
|
218
|
+
`1 < 0; // => false`
|
219
|
+
`2 < 2; // => false`
|
220
|
+
- `<=`: Returns `true` if left operand is equal to right operand, otherwise `false`. Both operands must be numbers
|
221
|
+
E.g. `1 <= 3; // => true`
|
222
|
+
`1 <= 0; // => false`
|
223
|
+
`2 <= 2; // => true`
|
224
|
+
- `>`: Returns `true` if left operand is equal to right operand, otherwise `false`. Both operands must be numbers
|
225
|
+
E.g. `1 > 3; // => false`
|
226
|
+
`1 > 0; // => true`
|
227
|
+
`2 > 2; // => false`
|
228
|
+
- `>=`: Returns `true` if left operand is equal to right operand, otherwise `false`. Both operands must be numbers
|
229
|
+
E.g. `1 > 3; // => false`
|
230
|
+
`1 > 0; // => true`
|
231
|
+
`2 > 2; // => false`
|
232
|
+
|
233
|
+
##### Logical expressions
|
234
|
+
|
235
|
+
REMINDER: In __Lox__, `false` and `nil` are considered falsey, everything else is truthy.
|
236
|
+
|
237
|
+
- `and`: When both operands are booleans, then returns `true` if both left and right operands are truthy, otherwise `false`.
|
238
|
+
If at least one operand isn't a boolean then returns first falsey operand else (both operands are truthy) returns the second operand.
|
239
|
+
truthy returns the second operand.
|
240
|
+
E.g. `false and true; // => false`
|
241
|
+
`true and nil; // => nil`
|
242
|
+
`0 and true and ""; // => ""`
|
243
|
+
- `or`: When both operands are booleans, then returns `true` if left or right operands are truthy, otherwise `false`.
|
244
|
+
If at least one operand isn't a boolean then returns first truthy operand else (both operands are truthy) returns the second operand.
|
245
|
+
E.g. `false or true; // => true`
|
246
|
+
`true or nil; // => nil`
|
247
|
+
`false or nil; // => nil`
|
248
|
+
`0 or true or ""; // => 0`
|
249
|
+
- `!`: Performs a logical negation on its operand
|
250
|
+
E.g. `!false; // => true`
|
251
|
+
`!!true; // => true`
|
252
|
+
`!0; // => false`
|
253
|
+
|
254
|
+
#### Grouping expressions
|
255
|
+
Use parentheses `(` `)` for a better control in expression/operator precedence.
|
256
|
+
|
257
|
+
``` javascript
|
258
|
+
print 3 + 4 * 5; // => 23
|
259
|
+
print (3 + 4) * 5; // => 35
|
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
|
+
|
269
|
+
#### Variable declarations
|
270
|
+
``` javascript
|
271
|
+
var iAmAVariable = "my-initial-value";
|
272
|
+
var iAmNil; // __Lox__ initializes variables to nil by default;
|
273
|
+
```
|
274
|
+
|
275
|
+
Warning: current version cannot assign a value to an existing variable.
|
276
|
+
Expect this capability to be implemented in the coming days.
|
277
|
+
|
278
|
+
|
279
|
+
#### If statement
|
280
|
+
|
281
|
+
Based on a given condition, an if statement executes one of two statements:
|
282
|
+
``` javascript
|
283
|
+
if (condition) {
|
284
|
+
print "then-branch";
|
285
|
+
} else {
|
286
|
+
print "else-branch";
|
287
|
+
}
|
288
|
+
```
|
289
|
+
|
290
|
+
As for other languages, the `else` part is optional.
|
291
|
+
##### Warning: nested `if`...`else`
|
292
|
+
Call it a bug ... Nested `if` `else` control flow structure aren't yet supported by __Loxxy__.
|
293
|
+
The culprit has a name: [the dangling else](https://en.wikipedia.org/wiki/Dangling_else).
|
294
|
+
|
295
|
+
The problem in a nutshell: in a nested if ... else ... statement like this:
|
296
|
+
``` javascript
|
297
|
+
'if (true) if (false) print "bad"; else print "good";
|
298
|
+
```
|
299
|
+
... there is an ambiguity. Indeed, according to the __Lox__ grammar, the `else` could be bound
|
300
|
+
either to the first `if` or to the second one.
|
301
|
+
This ambiguity is usually lifted by applying an ad-hoc rule: an `else` is aways bound to the most
|
302
|
+
recent (rightmost) `if`.
|
303
|
+
Being a generic parsing library, `Rley` doesn't apply any of these supplemental rules.
|
304
|
+
As a consequence,it complains about the found ambiguity and stops the parsing...
|
305
|
+
Although `Rley` can cope with ambiguities, this requires the use of an advanced data structure
|
306
|
+
called `Shared Packed Parse Forest (SPPF)`.
|
307
|
+
SPPF are much more complex to handle than the `common` parse trees present in most compiler or interpreter books.
|
308
|
+
Therefore, a future version of `Rley` will incorporate the capability to define disambuiguation rules.
|
309
|
+
|
310
|
+
In the meantime, the `Loxxy` will progress on other __Lox__ features like:
|
311
|
+
- Variables,
|
312
|
+
- Block structures...
|
313
|
+
|
314
|
+
|
315
|
+
#### Print Statement
|
316
|
+
|
317
|
+
The statement print + expression + ; prints the result of the expression to stdout.
|
318
|
+
|
319
|
+
``` javascript
|
320
|
+
print "Hello, world!"; // Output: Hello, world!
|
204
321
|
|
205
|
-
```javascript
|
206
|
-
// Print statement with nested string concatenation
|
207
|
-
print "Hello" + ", " + "world!";
|
208
322
|
```
|
209
323
|
|
210
324
|
## Installation
|
@@ -1,7 +1,13 @@
|
|
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
|
-
require_relative '
|
6
|
+
require_relative 'lox_grouping_expr'
|
6
7
|
require_relative 'lox_unary_expr'
|
8
|
+
require_relative 'lox_binary_expr'
|
9
|
+
require_relative 'lox_logical_expr'
|
7
10
|
require_relative 'lox_print_stmt'
|
11
|
+
require_relative 'lox_if_stmt'
|
12
|
+
require_relative 'lox_var_stmt'
|
13
|
+
require_relative 'lox_seq_decl'
|
@@ -96,6 +96,17 @@ module Loxxy
|
|
96
96
|
node
|
97
97
|
end
|
98
98
|
|
99
|
+
def reduce_logical_expr(_production, _range, tokens, theChildren)
|
100
|
+
operand1 = theChildren[0]
|
101
|
+
|
102
|
+
# Second child is array with couples [operator, operand2]
|
103
|
+
theChildren[1].each do |(operator, operand2)|
|
104
|
+
operand1 = LoxLogicalExpr.new(tokens[0].position, operator, operand1, operand2)
|
105
|
+
end
|
106
|
+
|
107
|
+
operand1
|
108
|
+
end
|
109
|
+
|
99
110
|
# rule('lhs' => 'nonterm_i nonterm_k_plus')
|
100
111
|
def reduce_binary_operator(_production, _range, tokens, theChildren)
|
101
112
|
operand1 = theChildren[0]
|
@@ -123,6 +134,11 @@ module Loxxy
|
|
123
134
|
[[operator, operand2]]
|
124
135
|
end
|
125
136
|
|
137
|
+
# Return the AST node corresponding to the second symbol in the rhs
|
138
|
+
def reduce_keep_symbol2(_production, _range, _tokens, theChildren)
|
139
|
+
theChildren[1]
|
140
|
+
end
|
141
|
+
|
126
142
|
#####################################
|
127
143
|
# SEMANTIC ACTIONS
|
128
144
|
#####################################
|
@@ -134,7 +150,17 @@ module Loxxy
|
|
134
150
|
|
135
151
|
# rule('program' => 'declaration_plus EOF').as ''
|
136
152
|
def reduce_lox_program(_production, range, tokens, theChildren)
|
137
|
-
|
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] ]
|
138
164
|
end
|
139
165
|
|
140
166
|
# rule('exprStmt' => 'expression SEMICOLON')
|
@@ -142,6 +168,27 @@ module Loxxy
|
|
142
168
|
return_first_child(range, tokens, theChildren) # Discard the semicolon
|
143
169
|
end
|
144
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
|
+
|
183
|
+
|
184
|
+
# rule('ifStmt' => 'IF ifCondition statement elsePart_opt')
|
185
|
+
def reduce_if_stmt(_production, _range, tokens, theChildren)
|
186
|
+
condition = theChildren[1]
|
187
|
+
then_stmt = theChildren[2]
|
188
|
+
else_stmt = theChildren[3]
|
189
|
+
LoxIfStmt.new(tokens[0].position, condition, then_stmt, else_stmt)
|
190
|
+
end
|
191
|
+
|
145
192
|
# rule('printStmt' => 'PRINT expression SEMICOLON')
|
146
193
|
def reduce_print_stmt(_production, _range, tokens, theChildren)
|
147
194
|
Ast::LoxPrintStmt.new(tokens[1].position, theChildren[1])
|
@@ -149,7 +196,7 @@ module Loxxy
|
|
149
196
|
|
150
197
|
# rule('logic_or' => 'logic_and disjunct_plus')
|
151
198
|
def reduce_logic_or_plus(production, range, tokens, theChildren)
|
152
|
-
|
199
|
+
reduce_logical_expr(production, range, tokens, theChildren)
|
153
200
|
end
|
154
201
|
|
155
202
|
# rule('disjunct_plus' => 'disjunct_plus OR logic_and')
|
@@ -164,7 +211,7 @@ module Loxxy
|
|
164
211
|
|
165
212
|
# rule('logic_and' => 'equality conjunct_plus')
|
166
213
|
def reduce_logic_and_plus(production, range, tokens, theChildren)
|
167
|
-
|
214
|
+
reduce_logical_expr(production, range, tokens, theChildren)
|
168
215
|
end
|
169
216
|
|
170
217
|
# rule('conjunct_plus' => 'conjunct_plus AND equality')
|
@@ -242,6 +289,12 @@ module Loxxy
|
|
242
289
|
LoxUnaryExpr.new(tokens[0].position, operator, operand)
|
243
290
|
end
|
244
291
|
|
292
|
+
# rule('primary' => 'LEFT_PAREN expression RIGHT_PAREN')
|
293
|
+
def reduce_grouping_expr(_production, _range, tokens, theChildren)
|
294
|
+
subexpr = theChildren[1]
|
295
|
+
LoxGroupingExpr.new(tokens[0].position, subexpr)
|
296
|
+
end
|
297
|
+
|
245
298
|
# rule('primary' => 'FALSE' | TRUE').as 'literal_expr'
|
246
299
|
def reduce_literal_expr(_production, _range, _tokens, theChildren)
|
247
300
|
first_child = theChildren.first
|
@@ -249,6 +302,13 @@ module Loxxy
|
|
249
302
|
literal = first_child.token.value
|
250
303
|
LoxLiteralExpr.new(pos, literal)
|
251
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
|
+
|
252
312
|
end # class
|
253
313
|
end # module
|
254
314
|
end # module
|