loxxy 0.0.24 → 0.1.0
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 +74 -0
- data/README.md +52 -12
- data/lib/loxxy/ast/all_lox_nodes.rb +5 -0
- data/lib/loxxy/ast/ast_builder.rb +88 -81
- data/lib/loxxy/ast/ast_visitor.rb +51 -9
- data/lib/loxxy/ast/lox_block_stmt.rb +27 -0
- data/lib/loxxy/ast/lox_call_expr.rb +25 -0
- data/lib/loxxy/ast/lox_for_stmt.rb +41 -0
- data/lib/loxxy/ast/lox_fun_stmt.rb +32 -0
- data/lib/loxxy/ast/lox_if_stmt.rb +3 -1
- data/lib/loxxy/ast/lox_while_stmt.rb +32 -0
- data/lib/loxxy/back_end/engine.rb +102 -1
- data/lib/loxxy/back_end/environment.rb +3 -3
- data/lib/loxxy/back_end/function.rb +45 -0
- data/lib/loxxy/back_end/symbol_table.rb +3 -3
- data/lib/loxxy/front_end/grammar.rb +34 -34
- data/lib/loxxy/front_end/literal.rb +1 -1
- data/lib/loxxy/version.rb +1 -1
- data/spec/back_end/environment_spec.rb +1 -1
- data/spec/back_end/symbol_table_spec.rb +1 -1
- data/spec/datatype/lx_string_spec.rb +2 -0
- data/spec/datatype/number_spec.rb +3 -1
- data/spec/front_end/scanner_spec.rb +2 -0
- data/spec/interpreter_spec.rb +126 -2
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 42a88690625576399255ae7fadd3ac6aee022fc8d56a8e10c1206b55eca207ab
|
4
|
+
data.tar.gz: 4042d268f199763405a264480765bbd5fe7aeaa998eb5e0a4353ae702c3bef2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 21a6a82509ead9c0d9f38c6798147dda38c436d87b8800a33ca7027553631866ce4215f2eb90c482f3c5a9b0bb42e99b7868fca888b78fcf7eca67afcd7db756
|
7
|
+
data.tar.gz: 71b53af0df630894c0d45639a84f427f34c7b92a5092e07cea16bc3786af666be13b0035a13c07b2910c374c76caa009c3acdbd675f430c8f6e4b7951c2b68a7
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,77 @@
|
|
1
|
+
## [0.1.00] - 2021-02-20
|
2
|
+
- Version number bumped, `Loxxy` supports function definitions
|
3
|
+
|
4
|
+
### Added
|
5
|
+
- Class `Ast::LoxFunStmt` a node that represents a function declaration
|
6
|
+
- Method `Ast::ASTBuilder#reduce_fun_decl`
|
7
|
+
- Method `Ast::ASTBuilder#reduce_function` creates a `LoxFunStmt` instance
|
8
|
+
- Method `Ast::ASTBuilder#reduce_parameters_plus_more` for dealing with function parameters
|
9
|
+
- Method `Ast::ASTBuilder#reduce_parameters_plus_end`
|
10
|
+
- Method `Ast::ASTVisitor#visit_fun_stmt` for visiting an `Ast::LoxFunStmt` node
|
11
|
+
- Method `Ast::LoxBlockStmt#empty?` returns true if the code block is empty
|
12
|
+
- Method `BackEnd::Engine#after_fun_stmt`
|
13
|
+
- Method `Backend::NativeFunction#call`
|
14
|
+
- Method `Backend::NativeFunction#to_str`
|
15
|
+
- Method `Backend::Function` implementation of a function object.
|
16
|
+
|
17
|
+
### Changed
|
18
|
+
- Method `BackEnd::Engine#after_call_expr`
|
19
|
+
|
20
|
+
### Fixed
|
21
|
+
- Fixed inconsistencies in documentation comments.
|
22
|
+
|
23
|
+
## [0.0.28] - 2021-02-15
|
24
|
+
- The interpreter implements function calls (to a native function).
|
25
|
+
|
26
|
+
### Added
|
27
|
+
- Class `Ast::LoxCallExpr` a node that represents a function call expression
|
28
|
+
- Method `Ast::ASTBuilder#reduce_call_expr`
|
29
|
+
- Method `Ast::ASTBuilder#reduce_refinement_plus_end`
|
30
|
+
- Method `Ast::ASTBuilder#reduce_call_arglist` creates a `LoxCallExpr` node
|
31
|
+
- Method `Ast::ASTBuilder#reduce_arguments_plus_more` builds the function argument array
|
32
|
+
- Method `Ast::ASTVisitor#visit_call_expr` for visiting an `Ast::LoxCallExpr` node
|
33
|
+
- Method `BackEnd::Engine#after_call_expr`implements the evaluation of a function call.
|
34
|
+
- Method `BackEnd::Engine#after_for_stmt` implements most of the `for` control flow
|
35
|
+
|
36
|
+
## [0.0.27] - 2021-01-24
|
37
|
+
- The interpreter implements `while` loops.
|
38
|
+
|
39
|
+
### Added
|
40
|
+
- Class `Ast::LoxForStmt` a node that represents a `for` statement
|
41
|
+
- Method `Ast::ASTBuilder#reduce_for_stmt`
|
42
|
+
- Method `Ast::ASTBuilder#reduce_for_control` creates an `Ast::LoxForStmt` node
|
43
|
+
- Method `Ast::ASTVisitor#visit_for_stmt` for visiting an `Ast::LoxWhileStmt` node
|
44
|
+
- Method `BackEnd::Engine#before_for_stmt` builds a new environment for the loop variable
|
45
|
+
- Method `BackEnd::Engine#after_for_stmt` implements most of the `for` control flow
|
46
|
+
|
47
|
+
### Changed
|
48
|
+
- File `README.md` updated.
|
49
|
+
|
50
|
+
## [0.0.26] - 2021-01-22
|
51
|
+
- The interpreter implements `while` loops.
|
52
|
+
|
53
|
+
### Added
|
54
|
+
- Class `Ast::LoxWhileStmt` a node that represents a `while` statement
|
55
|
+
- Method `Ast::ASTBuilder#reduce_while_stmt` creates an `Ast::LoxWhileStmt` node
|
56
|
+
- Method `Ast::ASTVisitor#visit_while_stmt` for visiting an `Ast::LoxWhileStmt` node
|
57
|
+
- Method `BackEnd::Engine#after_while_stmt` implements the while looping structure
|
58
|
+
|
59
|
+
### Changed
|
60
|
+
- File `README.md` updated.
|
61
|
+
|
62
|
+
## [0.0.25] - 2021-01-21
|
63
|
+
- The interpreter implements blocks of code.
|
64
|
+
|
65
|
+
### Added
|
66
|
+
- Class `Ast::LoxBlockStmt` a node that represents a block of code
|
67
|
+
- Method `Ast::ASTBuilder#reduce_block_stmt` creates an `Ast::LoxBlockStmt` node
|
68
|
+
- Method `Ast::ASTVisitor#visit_block_stmt` for visiting an `Ast::LoxBlockStmt` node
|
69
|
+
- Method `BackEnd::Engine#before_block_stmt` creates an new enclosed Environment
|
70
|
+
- Method `BackEnd::Engine#after_block_stmt` close enclosed Environment and make parent Environment the current one
|
71
|
+
|
72
|
+
### Changed
|
73
|
+
- File `README.md` updated.
|
74
|
+
|
1
75
|
## [0.0.24] - 2021-01-20
|
2
76
|
- The interpreter implements the assignment of variables.
|
3
77
|
|
data/README.md
CHANGED
@@ -14,9 +14,13 @@ a simple language used in Bob Nystrom's online book [Crafting Interpreters](http
|
|
14
14
|
|
15
15
|
### Current status
|
16
16
|
The project is still in inception and the interpreter is being implemented...
|
17
|
-
Currently it can execute
|
17
|
+
Currently it can execute all allowed __Lox__ expressions and statement except:
|
18
|
+
- Functions and closures,
|
19
|
+
- Classes and objects.
|
20
|
+
|
21
|
+
These will be implemented soon.
|
22
|
+
|
18
23
|
|
19
|
-
But the __loxxy__ gem hosts also a parser class `RawPaser` that can parse, in principle, any valid Lox input.
|
20
24
|
|
21
25
|
## What's the fuss about Lox?
|
22
26
|
... Nothing...
|
@@ -131,7 +135,7 @@ program
|
|
131
135
|
On one hand, the parser covers the complete Lox grammar and should therefore, in principle,
|
132
136
|
parse any valid Lox program.
|
133
137
|
|
134
|
-
On the other hand, the interpreter is under development and currently it can evaluate only a
|
138
|
+
On the other hand, the interpreter is under development and currently it can evaluate only a subset of __Lox__.
|
135
139
|
But the situation is changing almost daily, stay tuned...
|
136
140
|
|
137
141
|
Here are the language features currently supported by the interpreter:
|
@@ -141,9 +145,12 @@ Here are the language features currently supported by the interpreter:
|
|
141
145
|
- [Datatypes](#datatypes)
|
142
146
|
- [Statements](#statements)
|
143
147
|
-[Expressions](#expressions)
|
144
|
-
- [Variable declarations](#var-statement)
|
148
|
+
- [Variable declarations](#var-statement)
|
149
|
+
- [For statement](#for-statement)
|
145
150
|
- [If Statement](#if-statement)
|
146
151
|
- [Print Statement](#print-statement)
|
152
|
+
- [While Statement](#while-statement)
|
153
|
+
- [Block Statement](#block-statement)
|
147
154
|
|
148
155
|
### Comments
|
149
156
|
|
@@ -180,7 +187,9 @@ Loxxy supports the following statements:
|
|
180
187
|
|
181
188
|
-[Variable declarations](#var-statement)
|
182
189
|
-[If Statement](#if-statement)
|
183
|
-
-[Print Statement](#print-statement)
|
190
|
+
-[Print Statement](#print-statement)
|
191
|
+
-[While Statement](#while-statement)
|
192
|
+
-[Block Statement](#block-statement)
|
184
193
|
|
185
194
|
#### Expressions
|
186
195
|
|
@@ -268,8 +277,6 @@ foo = "baz"; // Variable assignment
|
|
268
277
|
print foo; // Output: baz
|
269
278
|
```
|
270
279
|
|
271
|
-
|
272
|
-
|
273
280
|
#### Variable declarations
|
274
281
|
``` javascript
|
275
282
|
var iAmAVariable = "my-initial-value";
|
@@ -277,6 +284,15 @@ var iAmNil; // __Lox__ initializes variables to nil by default;
|
|
277
284
|
print iAmNil; // output: nil
|
278
285
|
```
|
279
286
|
|
287
|
+
#### For statement
|
288
|
+
|
289
|
+
Similar to the `for` statement in `C` language
|
290
|
+
``` javascript
|
291
|
+
for (var a = 1; a < 10; a = a + 1) {
|
292
|
+
print a; // Output: 123456789
|
293
|
+
}
|
294
|
+
```
|
295
|
+
|
280
296
|
#### If statement
|
281
297
|
|
282
298
|
Based on a given condition, an if statement executes one of two statements:
|
@@ -297,20 +313,21 @@ The problem in a nutshell: in a nested if ... else ... statement like this:
|
|
297
313
|
``` javascript
|
298
314
|
'if (true) if (false) print "bad"; else print "good";
|
299
315
|
```
|
300
|
-
... there is an ambiguity.
|
316
|
+
... there is an ambiguity.
|
317
|
+
Indeed, according to the __Lox__ grammar, the `else` could be bound
|
301
318
|
either to the first `if` or to the second one.
|
302
319
|
This ambiguity is usually lifted by applying an ad-hoc rule: an `else` is aways bound to the most
|
303
320
|
recent (rightmost) `if`.
|
304
|
-
Being a generic parsing library, `Rley` doesn't apply any of these supplemental rules.
|
321
|
+
Being a generic parsing library, `Rley` doesn't apply any of these supplemental rules.
|
305
322
|
As a consequence,it complains about the found ambiguity and stops the parsing...
|
306
323
|
Although `Rley` can cope with ambiguities, this requires the use of an advanced data structure
|
307
324
|
called `Shared Packed Parse Forest (SPPF)`.
|
308
|
-
SPPF are much more complex to handle than the
|
325
|
+
SPPF are much more complex to handle than the "common" parse trees present in most compiler or interpreter books.
|
309
326
|
Therefore, a future version of `Rley` will incorporate the capability to define disambuiguation rules.
|
310
327
|
|
311
328
|
In the meantime, the `Loxxy` will progress on other __Lox__ features like:
|
312
|
-
- Variables,
|
313
329
|
- Block structures...
|
330
|
+
- Iteration structures (`for` and `while` loops)
|
314
331
|
|
315
332
|
|
316
333
|
#### Print Statement
|
@@ -322,6 +339,29 @@ print "Hello, world!"; // Output: Hello, world!
|
|
322
339
|
|
323
340
|
```
|
324
341
|
|
342
|
+
#### While Statement
|
343
|
+
|
344
|
+
``` javascript
|
345
|
+
var a = 1;
|
346
|
+
while (a < 10) {
|
347
|
+
print a;
|
348
|
+
a = a + 1;
|
349
|
+
} // Output: 123456789
|
350
|
+
```
|
351
|
+
|
352
|
+
#### Block Statement
|
353
|
+
__Lox__ has code blocks.
|
354
|
+
``` javascript
|
355
|
+
var a = "outer";
|
356
|
+
|
357
|
+
{
|
358
|
+
var a = "inner";
|
359
|
+
print a; // output: inner
|
360
|
+
}
|
361
|
+
|
362
|
+
print a; // output: outer
|
363
|
+
```
|
364
|
+
|
325
365
|
## Installation
|
326
366
|
|
327
367
|
Add this line to your application's Gemfile:
|
@@ -344,7 +384,7 @@ TODO: Write usage instructions here
|
|
344
384
|
|
345
385
|
## Other Lox implementations in Ruby
|
346
386
|
|
347
|
-
For Ruby, there is the [lox](https://github.com/rdodson41/ruby-lox) gem.
|
387
|
+
For Ruby, there is the [lox](https://github.com/rdodson41/ruby-lox) gem.
|
348
388
|
There are other Ruby-based projects as well:
|
349
389
|
- [SlowLox](https://github.com/ArminKleinert/SlowLox), described as a "1-to-1 conversion of JLox to Ruby"
|
350
390
|
- [rulox](https://github.com/LevitatingBusinessMan/rulox)
|
@@ -1,14 +1,19 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative 'lox_fun_stmt'
|
3
4
|
require_relative 'lox_variable_expr'
|
4
5
|
require_relative 'lox_literal_expr'
|
5
6
|
require_relative 'lox_noop_expr'
|
7
|
+
require_relative 'lox_call_expr'
|
6
8
|
require_relative 'lox_grouping_expr'
|
7
9
|
require_relative 'lox_unary_expr'
|
8
10
|
require_relative 'lox_binary_expr'
|
9
11
|
require_relative 'lox_logical_expr'
|
10
12
|
require_relative 'lox_assign_expr'
|
13
|
+
require_relative 'lox_block_stmt'
|
14
|
+
require_relative 'lox_while_stmt'
|
11
15
|
require_relative 'lox_print_stmt'
|
12
16
|
require_relative 'lox_if_stmt'
|
17
|
+
require_relative 'lox_for_stmt'
|
13
18
|
require_relative 'lox_var_stmt'
|
14
19
|
require_relative 'lox_seq_decl'
|
@@ -163,6 +163,11 @@ module Loxxy
|
|
163
163
|
[theChildren[0]]
|
164
164
|
end
|
165
165
|
|
166
|
+
# rule('funDecl' => 'FUN function')
|
167
|
+
def reduce_fun_decl(_production, _range, _tokens, theChildren)
|
168
|
+
theChildren[1]
|
169
|
+
end
|
170
|
+
|
166
171
|
# rule('exprStmt' => 'expression SEMICOLON')
|
167
172
|
def reduce_exprStmt(_production, range, tokens, theChildren)
|
168
173
|
return_first_child(range, tokens, theChildren) # Discard the semicolon
|
@@ -180,6 +185,29 @@ module Loxxy
|
|
180
185
|
Ast::LoxVarStmt.new(tokens[1].position, var_name, theChildren[3])
|
181
186
|
end
|
182
187
|
|
188
|
+
# rule('forStmt' => 'FOR LEFT_PAREN forControl RIGHT_PAREN statement')
|
189
|
+
def reduce_for_stmt(_production, _range, _tokens, theChildren)
|
190
|
+
for_stmt = theChildren[2]
|
191
|
+
for_stmt.body_stmt = theChildren[4]
|
192
|
+
for_stmt
|
193
|
+
end
|
194
|
+
|
195
|
+
# rule('forControl' => 'forInitialization forTest forUpdate')
|
196
|
+
def reduce_for_control(_production, _range, tokens, theChildren)
|
197
|
+
(init, test, update) = theChildren
|
198
|
+
Ast::LoxForStmt.new(tokens[0].position, init, test, update)
|
199
|
+
end
|
200
|
+
|
201
|
+
# rule('forInitialization' => 'SEMICOLON')
|
202
|
+
def reduce_empty_for_initialization(_production, _range, _tokens, _theChildren)
|
203
|
+
nil
|
204
|
+
end
|
205
|
+
|
206
|
+
# rule('forTest' => 'expression_opt SEMICOLON')
|
207
|
+
def reduce_for_test(_production, range, tokens, theChildren)
|
208
|
+
return_first_child(range, tokens, theChildren)
|
209
|
+
end
|
210
|
+
|
183
211
|
# rule('ifStmt' => 'IF ifCondition statement elsePart_opt')
|
184
212
|
def reduce_if_stmt(_production, _range, tokens, theChildren)
|
185
213
|
condition = theChildren[1]
|
@@ -193,105 +221,57 @@ module Loxxy
|
|
193
221
|
Ast::LoxPrintStmt.new(tokens[1].position, theChildren[1])
|
194
222
|
end
|
195
223
|
|
196
|
-
# rule('
|
197
|
-
def
|
198
|
-
|
199
|
-
Ast::LoxAssignExpr.new(tokens[1].position, var_name, theChildren[3])
|
200
|
-
end
|
201
|
-
|
202
|
-
# rule('logic_or' => 'logic_and disjunct_plus')
|
203
|
-
def reduce_logic_or_plus(production, range, tokens, theChildren)
|
204
|
-
reduce_logical_expr(production, range, tokens, theChildren)
|
205
|
-
end
|
206
|
-
|
207
|
-
# rule('disjunct_plus' => 'disjunct_plus OR logic_and')
|
208
|
-
def reduce_logic_or_plus_more(production, range, tokens, theChildren)
|
209
|
-
reduce_binary_plus_more(production, range, tokens, theChildren)
|
210
|
-
end
|
211
|
-
|
212
|
-
# rule('disjunct_plus' => 'OR logic_and')
|
213
|
-
def reduce_logic_or_plus_end(production, range, tokens, theChildren)
|
214
|
-
reduce_binary_plus_end(production, range, tokens, theChildren)
|
215
|
-
end
|
216
|
-
|
217
|
-
# rule('logic_and' => 'equality conjunct_plus')
|
218
|
-
def reduce_logic_and_plus(production, range, tokens, theChildren)
|
219
|
-
reduce_logical_expr(production, range, tokens, theChildren)
|
220
|
-
end
|
221
|
-
|
222
|
-
# rule('conjunct_plus' => 'conjunct_plus AND equality')
|
223
|
-
def reduce_logic_and_plus_more(production, range, tokens, theChildren)
|
224
|
-
reduce_binary_plus_more(production, range, tokens, theChildren)
|
225
|
-
end
|
226
|
-
|
227
|
-
# rule('conjunct_plus' => 'AND equality')
|
228
|
-
def reduce_logic_and_plus_end(production, range, tokens, theChildren)
|
229
|
-
reduce_binary_plus_end(production, range, tokens, theChildren)
|
230
|
-
end
|
231
|
-
|
232
|
-
# rule('equality' => 'comparison equalityTest_plus')
|
233
|
-
def reduce_equality_plus(production, range, tokens, theChildren)
|
234
|
-
reduce_binary_operator(production, range, tokens, theChildren)
|
224
|
+
# rule('whileStmt' => 'WHILE LEFT_PAREN expression RIGHT_PAREN statement').as ''
|
225
|
+
def reduce_while_stmt(_production, _range, tokens, theChildren)
|
226
|
+
Ast::LoxWhileStmt.new(tokens[1].position, theChildren[2], theChildren[4])
|
235
227
|
end
|
236
228
|
|
237
|
-
# rule('
|
238
|
-
def
|
239
|
-
|
229
|
+
# rule('block' => 'LEFT_BRACE declaration_plus RIGHT_BRACE')
|
230
|
+
def reduce_block_stmt(_production, _range, tokens, theChildren)
|
231
|
+
decls = LoxSeqDecl.new(tokens[1].position, theChildren[1])
|
232
|
+
Ast::LoxBlockStmt.new(tokens[1].position, decls)
|
240
233
|
end
|
241
234
|
|
242
|
-
# rule('
|
243
|
-
def
|
244
|
-
|
235
|
+
# rule('block' => 'LEFT_BRACE RIGHT_BRACE').as 'block_empty'
|
236
|
+
def reduce_block_empty(_production, _range, tokens, theChildren)
|
237
|
+
Ast::LoxBlockStmt.new(tokens[0].position, nil)
|
245
238
|
end
|
246
239
|
|
247
|
-
# rule('
|
248
|
-
def
|
249
|
-
|
240
|
+
# rule('assignment' => 'owner_opt IDENTIFIER EQUAL assignment')
|
241
|
+
def reduce_assign_expr(_production, _range, tokens, theChildren)
|
242
|
+
var_name = theChildren[1].token.lexeme.dup
|
243
|
+
Ast::LoxAssignExpr.new(tokens[1].position, var_name, theChildren[3])
|
250
244
|
end
|
251
245
|
|
252
246
|
# rule('comparisonTest_plus' => 'comparisonTest_plus comparisonTest term').as 'comparison_t_plus_more'
|
253
247
|
# TODO: is it meaningful to implement this rule?
|
254
248
|
|
255
|
-
# rule('
|
256
|
-
def
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
# rule('term' => 'factor additive_plus')
|
261
|
-
def reduce_term_additive(production, range, tokens, theChildren)
|
262
|
-
reduce_binary_operator(production, range, tokens, theChildren)
|
263
|
-
end
|
264
|
-
|
265
|
-
# rule('additive_star' => 'additive_star additionOp factor').as 'additionOp_expr'
|
266
|
-
def reduce_additive_plus_more(production, range, tokens, theChildren)
|
267
|
-
reduce_binary_plus_more(production, range, tokens, theChildren)
|
268
|
-
end
|
269
|
-
|
270
|
-
# rule('additive_plus' => 'additionOp factor')
|
271
|
-
def reduce_additive_plus_end(production, range, tokens, theChildren)
|
272
|
-
reduce_binary_plus_end(production, range, tokens, theChildren)
|
249
|
+
# rule('unary' => 'unaryOp unary')
|
250
|
+
def reduce_unary_expr(_production, _range, tokens, theChildren)
|
251
|
+
operator = Name2unary[theChildren[0].symbol.name].to_sym
|
252
|
+
operand = theChildren[1]
|
253
|
+
LoxUnaryExpr.new(tokens[0].position, operator, operand)
|
273
254
|
end
|
274
255
|
|
275
|
-
# rule('
|
276
|
-
def
|
277
|
-
|
256
|
+
# rule('call' => 'primary refinement_plus').as 'call_expr'
|
257
|
+
def reduce_call_expr(_production, _range, _tokens, theChildren)
|
258
|
+
theChildren[1].callee = theChildren[0]
|
259
|
+
theChildren[1]
|
278
260
|
end
|
279
261
|
|
280
|
-
# rule('
|
281
|
-
def
|
282
|
-
|
262
|
+
# rule('refinement_plus' => 'refinement').
|
263
|
+
def reduce_refinement_plus_end(_production, _range, _tokens, theChildren)
|
264
|
+
theChildren[0]
|
283
265
|
end
|
284
266
|
|
285
|
-
# rule('
|
286
|
-
def
|
287
|
-
|
288
|
-
|
267
|
+
# rule('refinement' => 'LEFT_PAREN arguments_opt RIGHT_PAREN')
|
268
|
+
def reduce_call_arglist(_production, _range, tokens, theChildren)
|
269
|
+
args = theChildren[1] || []
|
270
|
+
if args.size > 255
|
271
|
+
raise StandardError, "Can't have more than 255 arguments."
|
272
|
+
end
|
289
273
|
|
290
|
-
|
291
|
-
def reduce_unary_expr(_production, _range, tokens, theChildren)
|
292
|
-
operator = Name2unary[theChildren[0].symbol.name].to_sym
|
293
|
-
operand = theChildren[1]
|
294
|
-
LoxUnaryExpr.new(tokens[0].position, operator, operand)
|
274
|
+
LoxCallExpr.new(tokens[0].position, args)
|
295
275
|
end
|
296
276
|
|
297
277
|
# rule('primary' => 'LEFT_PAREN expression RIGHT_PAREN')
|
@@ -313,6 +293,33 @@ module Loxxy
|
|
313
293
|
var_name = theChildren[0].token.lexeme
|
314
294
|
LoxVariableExpr.new(tokens[0].position, var_name)
|
315
295
|
end
|
296
|
+
|
297
|
+
# rule('function' => 'IDENTIFIER LEFT_PAREN params_opt RIGHT_PAREN block').as 'function'
|
298
|
+
def reduce_function(_production, _range, _tokens, theChildren)
|
299
|
+
first_child = theChildren.first
|
300
|
+
pos = first_child.token.position
|
301
|
+
fun_stmt = LoxFunStmt.new(pos, first_child.token.lexeme, theChildren[2], theChildren[4])
|
302
|
+
end
|
303
|
+
|
304
|
+
# rule('parameters' => 'parameters COMMA IDENTIFIER')
|
305
|
+
def reduce_parameters_plus_more(_production, _range, _tokens, theChildren)
|
306
|
+
theChildren[0] << theChildren[2].token.lexeme
|
307
|
+
end
|
308
|
+
|
309
|
+
# rule('parameters' => 'IDENTIFIER')
|
310
|
+
def reduce_parameters_plus_end(_production, _range, _tokens, theChildren)
|
311
|
+
[theChildren[0].token.lexeme]
|
312
|
+
end
|
313
|
+
|
314
|
+
# rule('arguments' => 'arguments COMMA expression')
|
315
|
+
def reduce_arguments_plus_more(_production, _range, _tokens, theChildren)
|
316
|
+
theChildren[0] << theChildren[2]
|
317
|
+
end
|
318
|
+
|
319
|
+
# rule('arguments' => 'expression')
|
320
|
+
def reduce_arguments_plus_end(_production, _range, _tokens, theChildren)
|
321
|
+
theChildren
|
322
|
+
end
|
316
323
|
end # class
|
317
324
|
end # module
|
318
325
|
end # module
|