loxxy 0.4.00 → 0.4.01
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/.rubocop.yml +24 -0
- data/CHANGELOG.md +8 -0
- data/lib/loxxy/ast/ast_builder.rb +52 -89
- data/lib/loxxy/ast/lox_node.rb +1 -1
- data/lib/loxxy/front_end/grammar.rb +16 -39
- data/lib/loxxy/version.rb +1 -1
- data/loxxy.gemspec +2 -2
- data/spec/front_end/raw_parser_spec.rb +10 -3
- data/spec/spec_helper.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 03ef0a6b112537abbb890f56a5746a22be8aa9373451ce57a25d33ffd4cfe2be
|
4
|
+
data.tar.gz: 3abea4f9bfd799de85840c93a91aa37d0f9676b5e1d9af6a68bef7d189843470
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 74a279e2033090d6f4df08f30e4e71cf3c34c29dff2d2400a066528b68e73b2019345a84cabfad59f0342f8ba0a0d2ebf47ce87ac2195223a9c68886febb6a72
|
7
|
+
data.tar.gz: 9e1c5ba2b8e88af10c198bcefdc8a791be2900df2ee71127df560f1bcbfa18f03bc4cf86d149cc475cf5392938e4d74bb769d4a80630c9a5c82e0da90c936135
|
data/.rubocop.yml
CHANGED
@@ -50,6 +50,9 @@ Layout/IndentationConsistency:
|
|
50
50
|
Layout/HeredocIndentation:
|
51
51
|
Enabled: false
|
52
52
|
|
53
|
+
Layout/LineEndStringConcatenationIndentation:
|
54
|
+
Enabled: true
|
55
|
+
|
53
56
|
Layout/MultilineHashBraceLayout:
|
54
57
|
Enabled: true
|
55
58
|
|
@@ -81,6 +84,9 @@ Layout/TrailingWhitespace:
|
|
81
84
|
Lint/AmbiguousAssignment:
|
82
85
|
Enabled: true
|
83
86
|
|
87
|
+
Lint/AmbiguousRange:
|
88
|
+
Enabled: true
|
89
|
+
|
84
90
|
Lint/DeprecatedConstants:
|
85
91
|
Enabled: true
|
86
92
|
|
@@ -96,6 +102,9 @@ Lint/EmptyBlock:
|
|
96
102
|
Lint/EmptyClass:
|
97
103
|
Enabled: false
|
98
104
|
|
105
|
+
Lint/EmptyInPattern:
|
106
|
+
Enabled: true
|
107
|
+
|
99
108
|
Lint/LambdaWithoutLiteralBlock:
|
100
109
|
Enabled: true
|
101
110
|
|
@@ -192,6 +201,9 @@ Naming/ClassAndModuleCamelCase:
|
|
192
201
|
Naming/BlockParameterName:
|
193
202
|
Enabled: true
|
194
203
|
|
204
|
+
Naming/InclusiveLanguage:
|
205
|
+
Enabled: true
|
206
|
+
|
195
207
|
Naming/MethodParameterName:
|
196
208
|
Enabled: false
|
197
209
|
|
@@ -273,11 +285,17 @@ Style/HashTransformValues:
|
|
273
285
|
Style/IfUnlessModifier:
|
274
286
|
Enabled: false
|
275
287
|
|
288
|
+
Style/InPatternThen:
|
289
|
+
Enabled: true
|
290
|
+
|
276
291
|
Style/InverseMethods:
|
277
292
|
Enabled: false
|
278
293
|
|
279
294
|
Style/MissingRespondToMissing:
|
280
295
|
Enabled: false
|
296
|
+
|
297
|
+
Style/MultilineInPatternThen:
|
298
|
+
Enabled: true
|
281
299
|
|
282
300
|
Style/NegatedIfElseCondition:
|
283
301
|
Enabled: true
|
@@ -290,6 +308,9 @@ Style/NilLambda:
|
|
290
308
|
|
291
309
|
Style/NumericLiterals:
|
292
310
|
Enabled: false
|
311
|
+
|
312
|
+
Style/QuotedSymbols:
|
313
|
+
Enabled: true
|
293
314
|
|
294
315
|
Style/RaiseArgs:
|
295
316
|
Enabled: true
|
@@ -302,6 +323,9 @@ Style/RedundantReturn:
|
|
302
323
|
|
303
324
|
Style/RedundantSelf:
|
304
325
|
Enabled: true
|
326
|
+
|
327
|
+
Style/RedundantSelfAssignmentBranch:
|
328
|
+
Enabled: true
|
305
329
|
|
306
330
|
Style/RegexpLiteral:
|
307
331
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## [0.4.01] - 2021-08-22
|
2
|
+
- Grammar and AST::AstBuilder adapted to take profit of extended grammar notiation in Rley 0.8.01
|
3
|
+
|
4
|
+
### Changed
|
5
|
+
- Class `Ast::ASTBuilder` removal of methods made redundant with new Rley version
|
6
|
+
- File `.rubocop.yml` added config for new cops
|
7
|
+
- File `grammar.rb` changed rules to use new extended rule syntax in Rley
|
8
|
+
|
1
9
|
## [0.4.00] - 2021-05-24
|
2
10
|
- Version bump. `Loxxy` is capable to run the LoxLox interpreter, an interpreter written in `Lox`.
|
3
11
|
|
@@ -143,63 +143,36 @@ module Loxxy
|
|
143
143
|
# SEMANTIC ACTIONS
|
144
144
|
#####################################
|
145
145
|
|
146
|
-
# rule('program' => 'EOF').as '
|
147
|
-
def reduce_null_program(_production, _range, _tokens, _theChildren)
|
148
|
-
Ast::LoxNoopExpr.new(tokens[0].position)
|
149
|
-
end
|
150
|
-
|
151
|
-
# rule('program' => 'declaration_plus EOF').as ''
|
146
|
+
# rule('program' => 'declaration+ EOF').as ''
|
152
147
|
def reduce_lox_program(_production, _range, tokens, theChildren)
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
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]]
|
148
|
+
if theChildren[0].empty?
|
149
|
+
Ast::LoxNoopExpr.new(tokens[0].position)
|
150
|
+
else
|
151
|
+
LoxSeqDecl.new(tokens[0].position, theChildren[0])
|
152
|
+
end
|
164
153
|
end
|
165
154
|
|
166
155
|
# rule('classDecl' => 'CLASS classNaming class_body')
|
167
156
|
def reduce_class_decl(_production, _range, _tokens, theChildren)
|
168
|
-
|
169
|
-
|
170
|
-
parent = theChildren[1].last
|
171
|
-
else
|
172
|
-
name = theChildren[1]
|
173
|
-
parent = nil
|
174
|
-
end
|
157
|
+
name = theChildren[1].first
|
158
|
+
parent = theChildren[1].last
|
175
159
|
Ast::LoxClassStmt.new(tokens[1].position, name, parent, theChildren[2])
|
176
160
|
end
|
177
161
|
|
178
|
-
# rule('classNaming' => 'IDENTIFIER')
|
179
|
-
def
|
180
|
-
theChildren[
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
super_var = LoxVariableExpr.new(super_token.position, super_token.lexeme)
|
162
|
+
# rule('classNaming' => 'IDENTIFIER (LESS IDENTIFIER)?')
|
163
|
+
def reduce_class_naming(_production, _range, _tokens, theChildren)
|
164
|
+
if theChildren[1].nil?
|
165
|
+
super_var = nil
|
166
|
+
else
|
167
|
+
super_token = theChildren[1].subnodes[1].token
|
168
|
+
super_var = LoxVariableExpr.new(super_token.position, super_token.lexeme)
|
169
|
+
end
|
187
170
|
[theChildren[0].token.lexeme, super_var]
|
188
171
|
end
|
189
172
|
|
190
|
-
# rule('class_body' => 'LEFT_BRACE
|
173
|
+
# rule('class_body' => 'LEFT_BRACE function* RIGHT_BRACE')
|
191
174
|
def reduce_class_body(_production, _range, _tokens, theChildren)
|
192
|
-
theChildren[1]
|
193
|
-
end
|
194
|
-
|
195
|
-
# rule('method_plus' => 'method_plus function')
|
196
|
-
def reduce_method_plus_more(_production, _range, _tokens, theChildren)
|
197
|
-
theChildren[0] << theChildren[1]
|
198
|
-
end
|
199
|
-
|
200
|
-
# rule('method_plus' => 'function')
|
201
|
-
def reduce_method_plus_end(_production, _range, _tokens, theChildren)
|
202
|
-
theChildren
|
175
|
+
theChildren[1]
|
203
176
|
end
|
204
177
|
|
205
178
|
# rule('funDecl' => 'FUN function')
|
@@ -212,16 +185,11 @@ module Loxxy
|
|
212
185
|
return_first_child(range, tokens, theChildren) # Discard the semicolon
|
213
186
|
end
|
214
187
|
|
215
|
-
# rule('varDecl' => 'VAR IDENTIFIER SEMICOLON')
|
188
|
+
# rule('varDecl' => 'VAR IDENTIFIER (EQUAL expression)? SEMICOLON')
|
216
189
|
def reduce_var_declaration(_production, _range, tokens, theChildren)
|
217
190
|
var_name = theChildren[1].token.lexeme.dup
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
# rule('varDecl' => 'VAR IDENTIFIER EQUAL expression SEMICOLON')
|
222
|
-
def reduce_var_initialization(_production, _range, tokens, theChildren)
|
223
|
-
var_name = theChildren[1].token.lexeme.dup
|
224
|
-
Ast::LoxVarStmt.new(tokens[1].position, var_name, theChildren[3])
|
191
|
+
init_val = theChildren[2] ? theChildren[2].subnodes[1] : nil
|
192
|
+
Ast::LoxVarStmt.new(tokens[1].position, var_name, init_val)
|
225
193
|
end
|
226
194
|
|
227
195
|
# rule('forStmt' => 'FOR LEFT_PAREN forControl RIGHT_PAREN statement')
|
@@ -248,7 +216,7 @@ module Loxxy
|
|
248
216
|
for_stmt
|
249
217
|
end
|
250
218
|
|
251
|
-
# rule('forControl' => 'forInitialization forTest
|
219
|
+
# rule('forControl' => 'forInitialization forTest expression?')
|
252
220
|
def reduce_for_control(_production, _range, tokens, theChildren)
|
253
221
|
(init, test, update) = theChildren
|
254
222
|
if test.nil? && update
|
@@ -265,7 +233,7 @@ module Loxxy
|
|
265
233
|
nil
|
266
234
|
end
|
267
235
|
|
268
|
-
# rule('forTest' => '
|
236
|
+
# rule('forTest' => 'expression? SEMICOLON')
|
269
237
|
def reduce_for_test(_production, range, tokens, theChildren)
|
270
238
|
return_first_child(range, tokens, theChildren)
|
271
239
|
end
|
@@ -292,7 +260,7 @@ module Loxxy
|
|
292
260
|
Ast::LoxPrintStmt.new(tokens[1].position, theChildren[1])
|
293
261
|
end
|
294
262
|
|
295
|
-
# rule('returnStmt' => 'RETURN
|
263
|
+
# rule('returnStmt' => 'RETURN expression? SEMICOLON')
|
296
264
|
def reduce_return_stmt(_production, _range, tokens, theChildren)
|
297
265
|
Ast::LoxReturnStmt.new(tokens[1].position, theChildren[1])
|
298
266
|
end
|
@@ -302,34 +270,31 @@ module Loxxy
|
|
302
270
|
Ast::LoxWhileStmt.new(tokens[1].position, theChildren[2], theChildren[4])
|
303
271
|
end
|
304
272
|
|
305
|
-
# rule('block' => 'LEFT_BRACE
|
273
|
+
# rule('block' => 'LEFT_BRACE declaration* RIGHT_BRACE')
|
306
274
|
def reduce_block_stmt(_production, _range, tokens, theChildren)
|
307
|
-
decls =
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
275
|
+
decls = nil
|
276
|
+
if theChildren[1]
|
277
|
+
pos = tokens[1].position
|
278
|
+
decls = LoxSeqDecl.new(tokens[1].position, theChildren[1])
|
279
|
+
else
|
280
|
+
pos = tokens[0].position
|
281
|
+
end
|
282
|
+
Ast::LoxBlockStmt.new(pos, decls)
|
314
283
|
end
|
315
284
|
|
316
|
-
# rule('assignment' => '
|
285
|
+
# rule('assignment' => '(call DOT)? IDENTIFIER EQUAL assignment')
|
317
286
|
def reduce_assign_expr(_production, _range, tokens, theChildren)
|
318
287
|
name_assignee = theChildren[1].token.lexeme.dup
|
319
|
-
if theChildren[0]
|
320
|
-
theChildren[0].
|
321
|
-
|
322
|
-
theChildren[
|
288
|
+
if theChildren[0]
|
289
|
+
set_expr = Ast::LoxSetExpr.new(tokens[1].position, theChildren[0].subnodes[0])
|
290
|
+
set_expr.property = name_assignee
|
291
|
+
set_expr.value = theChildren[3]
|
292
|
+
set_expr
|
323
293
|
else
|
324
294
|
Ast::LoxAssignExpr.new(tokens[1].position, name_assignee, theChildren[3])
|
325
295
|
end
|
326
296
|
end
|
327
297
|
|
328
|
-
# rule('owner_opt' => 'call DOT')
|
329
|
-
def reduce_set_expr(_production, _range, tokens, theChildren)
|
330
|
-
Ast::LoxSetExpr.new(tokens[1].position, theChildren[0])
|
331
|
-
end
|
332
|
-
|
333
298
|
|
334
299
|
# rule('comparisonTest_plus' => 'comparisonTest_plus comparisonTest term').as 'comparison_t_plus_more'
|
335
300
|
# TODO: is it meaningful to implement this rule?
|
@@ -343,6 +308,7 @@ module Loxxy
|
|
343
308
|
|
344
309
|
# rule('call' => 'primary refinement_plus').as 'call_expr'
|
345
310
|
def reduce_call_expr(_production, _range, _tokens, theChildren)
|
311
|
+
# return theChildren[0] unless theChildren[1]
|
346
312
|
members = theChildren.flatten
|
347
313
|
call_expr = nil
|
348
314
|
loop do
|
@@ -365,7 +331,7 @@ module Loxxy
|
|
365
331
|
theChildren
|
366
332
|
end
|
367
333
|
|
368
|
-
# rule('refinement' => 'LEFT_PAREN
|
334
|
+
# rule('refinement' => 'LEFT_PAREN arguments? RIGHT_PAREN')
|
369
335
|
def reduce_call_arglist(_production, _range, tokens, theChildren)
|
370
336
|
args = theChildren[1] || []
|
371
337
|
if args.size > 255
|
@@ -422,24 +388,21 @@ module Loxxy
|
|
422
388
|
LoxFunStmt.new(pos, first_child.token.lexeme, theChildren[2], theChildren[4])
|
423
389
|
end
|
424
390
|
|
425
|
-
# rule('parameters' => '
|
426
|
-
def
|
427
|
-
|
428
|
-
|
391
|
+
# rule('parameters' => 'IDENTIFIER (COMMA IDENTIFIER)*').as 'parameters'
|
392
|
+
def reduce_parameters(_production, _range, _tokens, theChildren)
|
393
|
+
first_lexeme = theChildren[0].token.lexeme
|
394
|
+
return [first_lexeme] unless theChildren[1]
|
429
395
|
|
430
|
-
|
431
|
-
|
432
|
-
[theChildren[0].token.lexeme]
|
396
|
+
successors = theChildren[1].map { |seq_node| seq_node.subnodes[1].token.lexeme }
|
397
|
+
successors.unshift(first_lexeme)
|
433
398
|
end
|
434
399
|
|
435
|
-
# rule('arguments' => '
|
436
|
-
def
|
437
|
-
theChildren[0]
|
438
|
-
end
|
400
|
+
# rule('arguments' => 'expression (COMMA expression)*')
|
401
|
+
def reduce_arguments(_production, _range, _tokens, theChildren)
|
402
|
+
return [theChildren[0]] unless theChildren[1]
|
439
403
|
|
440
|
-
|
441
|
-
|
442
|
-
theChildren
|
404
|
+
successors = theChildren[1].map { |seq_node| seq_node.subnodes[1] }
|
405
|
+
successors.unshift(theChildren[0])
|
443
406
|
end
|
444
407
|
end # class
|
445
408
|
end # module
|
data/lib/loxxy/ast/lox_node.rb
CHANGED
@@ -11,7 +11,7 @@ module Loxxy
|
|
11
11
|
# Let nodes take `visitee` role as defined in the Visitor design pattern
|
12
12
|
extend ASTVisitee
|
13
13
|
|
14
|
-
# return [Rley::Lexical::Position] Position of the entry in the input stream.
|
14
|
+
# @return [Rley::Lexical::Position] Position of the entry in the input stream.
|
15
15
|
attr_reader :position
|
16
16
|
|
17
17
|
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
@@ -7,9 +7,9 @@ module Loxxy
|
|
7
7
|
module FrontEnd
|
8
8
|
########################################
|
9
9
|
# Grammar for Lox language
|
10
|
-
#
|
10
|
+
# Authoritative grammar at:
|
11
11
|
# https://craftinginterpreters.com/appendix-i.html
|
12
|
-
builder = Rley::
|
12
|
+
builder = Rley::grammar_builder do
|
13
13
|
# Punctuators, separators...
|
14
14
|
add_terminals('LEFT_PAREN', 'RIGHT_PAREN', 'LEFT_BRACE', 'RIGHT_BRACE')
|
15
15
|
add_terminals('COMMA', 'DOT', 'MINUS', 'PLUS')
|
@@ -26,30 +26,21 @@ module Loxxy
|
|
26
26
|
add_terminals('EOF')
|
27
27
|
|
28
28
|
# Top-level rule that matches an entire Lox program
|
29
|
-
rule('program' => 'EOF').as '
|
30
|
-
rule('program' => 'declaration_plus EOF').as 'lox_program'
|
29
|
+
rule('program' => 'declaration* EOF').as 'lox_program'
|
31
30
|
|
32
31
|
# Declarations: bind an identifier to something
|
33
|
-
rule('declaration_plus' => 'declaration_plus declaration').as 'declaration_plus_more'
|
34
|
-
rule('declaration_plus' => 'declaration').as 'declaration_plus_end'
|
35
32
|
rule('declaration' => 'classDecl')
|
36
33
|
rule('declaration' => 'funDecl')
|
37
34
|
rule('declaration' => 'varDecl')
|
38
35
|
rule('declaration' => 'stmt')
|
39
36
|
|
40
37
|
rule('classDecl' => 'CLASS classNaming class_body').as 'class_decl'
|
41
|
-
rule('classNaming' => 'IDENTIFIER LESS IDENTIFIER').as '
|
42
|
-
rule('
|
43
|
-
rule('class_body' => 'LEFT_BRACE methods_opt RIGHT_BRACE').as 'class_body'
|
44
|
-
rule('methods_opt' => 'method_plus')
|
45
|
-
rule('methods_opt' => [])
|
46
|
-
rule('method_plus' => 'method_plus function').as 'method_plus_more'
|
47
|
-
rule('method_plus' => 'function').as 'method_plus_end'
|
38
|
+
rule('classNaming' => 'IDENTIFIER (LESS IDENTIFIER)?').as 'class_naming'
|
39
|
+
rule('class_body' => 'LEFT_BRACE function* RIGHT_BRACE').as 'class_body'
|
48
40
|
|
49
41
|
rule('funDecl' => 'FUN function').as 'fun_decl'
|
50
42
|
|
51
|
-
rule('varDecl' => 'VAR IDENTIFIER SEMICOLON').as 'var_declaration'
|
52
|
-
rule('varDecl' => 'VAR IDENTIFIER EQUAL expression SEMICOLON').as 'var_initialization'
|
43
|
+
rule('varDecl' => 'VAR IDENTIFIER (EQUAL expression)? SEMICOLON').as 'var_declaration'
|
53
44
|
|
54
45
|
# Statements: produce side effects, but don't introduce bindings
|
55
46
|
rule('stmt' => 'statement')
|
@@ -65,12 +56,11 @@ module Loxxy
|
|
65
56
|
rule('exprStmt' => 'expression SEMICOLON').as 'exprStmt'
|
66
57
|
|
67
58
|
rule('forStmt' => 'FOR LEFT_PAREN forControl RIGHT_PAREN statement').as 'for_stmt'
|
68
|
-
rule('forControl' => 'forInitialization forTest
|
59
|
+
rule('forControl' => 'forInitialization forTest expression?').as 'for_control'
|
69
60
|
rule('forInitialization' => 'varDecl')
|
70
61
|
rule('forInitialization' => 'exprStmt')
|
71
62
|
rule('forInitialization' => 'SEMICOLON').as 'empty_for_initialization'
|
72
|
-
rule('forTest' => '
|
73
|
-
rule('forUpdate' => 'expression_opt')
|
63
|
+
rule('forTest' => 'expression? SEMICOLON').as 'for_test'
|
74
64
|
|
75
65
|
rule('ifStmt' => 'IF ifCondition statement ELSE statement').as 'if_else_stmt'
|
76
66
|
rule('unbalancedStmt' => 'IF ifCondition stmt').as 'if_stmt'
|
@@ -78,19 +68,14 @@ module Loxxy
|
|
78
68
|
rule('ifCondition' => 'LEFT_PAREN expression RIGHT_PAREN').as 'keep_symbol2'
|
79
69
|
|
80
70
|
rule('printStmt' => 'PRINT expression SEMICOLON').as 'print_stmt'
|
81
|
-
rule('returnStmt' => 'RETURN
|
71
|
+
rule('returnStmt' => 'RETURN expression? SEMICOLON').as 'return_stmt'
|
82
72
|
rule('whileStmt' => 'WHILE LEFT_PAREN expression RIGHT_PAREN statement').as 'while_stmt'
|
83
|
-
rule('block' => 'LEFT_BRACE
|
84
|
-
rule('block' => 'LEFT_BRACE RIGHT_BRACE').as 'block_empty'
|
73
|
+
rule('block' => 'LEFT_BRACE declaration* RIGHT_BRACE').as 'block_stmt'
|
85
74
|
|
86
75
|
# Expressions: produce values
|
87
|
-
rule('expression_opt' => 'expression')
|
88
|
-
rule('expression_opt' => [])
|
89
76
|
rule('expression' => 'assignment')
|
90
|
-
rule('assignment' => '
|
77
|
+
rule('assignment' => '(call DOT)? IDENTIFIER EQUAL assignment').as 'assign_expr'
|
91
78
|
rule('assignment' => 'logic_or')
|
92
|
-
rule('owner_opt' => 'call DOT').as 'set_expr'
|
93
|
-
rule('owner_opt' => [])
|
94
79
|
rule('logic_or' => 'logic_and')
|
95
80
|
rule('logic_or' => 'logic_and disjunct_plus').as 'logical_expr'
|
96
81
|
rule('disjunct_plus' => 'disjunct_plus OR logic_and').as 'binary_plus_more'
|
@@ -130,10 +115,8 @@ module Loxxy
|
|
130
115
|
rule('unaryOp' => 'BANG')
|
131
116
|
rule('unaryOp' => 'MINUS')
|
132
117
|
rule('call' => 'primary')
|
133
|
-
rule('call' => 'primary
|
134
|
-
rule('
|
135
|
-
rule('refinement_plus' => 'refinement').as 'refinement_plus_end'
|
136
|
-
rule('refinement' => 'LEFT_PAREN arguments_opt RIGHT_PAREN').as 'call_arglist'
|
118
|
+
rule('call' => 'primary refinement+').as 'call_expr'
|
119
|
+
rule('refinement' => 'LEFT_PAREN arguments? RIGHT_PAREN').as 'call_arglist'
|
137
120
|
rule('refinement' => 'DOT IDENTIFIER').as 'get_expr'
|
138
121
|
rule('primary' => 'TRUE').as 'literal_expr'
|
139
122
|
rule('primary' => 'FALSE').as 'literal_expr'
|
@@ -146,15 +129,9 @@ module Loxxy
|
|
146
129
|
rule('primary' => 'SUPER DOT IDENTIFIER').as 'super_expr'
|
147
130
|
|
148
131
|
# Utility rules
|
149
|
-
rule('function' => 'IDENTIFIER LEFT_PAREN
|
150
|
-
rule('
|
151
|
-
rule('
|
152
|
-
rule('parameters' => 'parameters COMMA IDENTIFIER').as 'parameters_plus_more'
|
153
|
-
rule('parameters' => 'IDENTIFIER').as 'parameters_plus_end'
|
154
|
-
rule('arguments_opt' => 'arguments')
|
155
|
-
rule('arguments_opt' => [])
|
156
|
-
rule('arguments' => 'arguments COMMA expression').as 'arguments_plus_more'
|
157
|
-
rule('arguments' => 'expression').as 'arguments_plus_end'
|
132
|
+
rule('function' => 'IDENTIFIER LEFT_PAREN parameters? RIGHT_PAREN block').as 'function'
|
133
|
+
rule('parameters' => 'IDENTIFIER (COMMA IDENTIFIER)*').as 'parameters'
|
134
|
+
rule('arguments' => 'expression (COMMA expression)*').as 'arguments'
|
158
135
|
end
|
159
136
|
|
160
137
|
unless defined?(Grammar)
|
data/lib/loxxy/version.rb
CHANGED
data/loxxy.gemspec
CHANGED
@@ -48,7 +48,7 @@ Gem::Specification.new do |spec|
|
|
48
48
|
DESCR_END
|
49
49
|
spec.homepage = 'https://github.com/famished-tiger/loxxy'
|
50
50
|
spec.license = 'MIT'
|
51
|
-
spec.required_ruby_version = '~> 2.
|
51
|
+
spec.required_ruby_version = '~> 2.5'
|
52
52
|
|
53
53
|
spec.bindir = 'bin'
|
54
54
|
spec.executables = ['loxxy']
|
@@ -58,7 +58,7 @@ Gem::Specification.new do |spec|
|
|
58
58
|
PkgExtending.pkg_documentation(spec)
|
59
59
|
|
60
60
|
# Runtime dependencies
|
61
|
-
spec.add_dependency 'rley', '~> 0.
|
61
|
+
spec.add_dependency 'rley', '~> 0.8.01'
|
62
62
|
|
63
63
|
# Development dependencies
|
64
64
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
@@ -26,7 +26,10 @@ module Loxxy
|
|
26
26
|
# program => declaration_star EOF
|
27
27
|
# where the declaration_star MUST be empty
|
28
28
|
expect(aParseTree.root.symbol.name).to eq('program')
|
29
|
-
eof = aParseTree.root.subnodes
|
29
|
+
(decls, eof) = aParseTree.root.subnodes
|
30
|
+
expect(decls).to be_kind_of(Rley::PTree::NonTerminalNode)
|
31
|
+
expect(decls.symbol.name).to eq('declaration_star')
|
32
|
+
expect(decls.subnodes).to be_empty
|
30
33
|
expect(eof).to be_kind_of(Rley::PTree::TerminalNode)
|
31
34
|
expect(eof.symbol.name).to eq('EOF')
|
32
35
|
end
|
@@ -73,8 +76,12 @@ LOX_END
|
|
73
76
|
expect(root.symbol.name).to eq('program')
|
74
77
|
(decls, eof) = root.subnodes
|
75
78
|
expect(decls).to be_kind_of(Rley::PTree::NonTerminalNode)
|
76
|
-
expect(decls.symbol.name).to eq('
|
77
|
-
|
79
|
+
expect(decls.symbol.name).to eq('declaration_star')
|
80
|
+
expect(decls.subnodes[0]).to be_kind_of(Rley::PTree::NonTerminalNode)
|
81
|
+
expect(decls.subnodes[0].symbol.name).to eq('declaration_star')
|
82
|
+
expect(decls.subnodes[1]).to be_kind_of(Rley::PTree::NonTerminalNode)
|
83
|
+
expect(decls.subnodes[1].symbol.name).to eq('declaration')
|
84
|
+
stmt = decls.subnodes[1].subnodes[0]
|
78
85
|
expect(stmt).to be_kind_of(Rley::PTree::NonTerminalNode)
|
79
86
|
expect(stmt.symbol.name).to eq('stmt')
|
80
87
|
statement = stmt.subnodes[0]
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: loxxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.01
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-08-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.8.01
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.8.01
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,7 +173,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
173
173
|
requirements:
|
174
174
|
- - "~>"
|
175
175
|
- !ruby/object:Gem::Version
|
176
|
-
version: '2.
|
176
|
+
version: '2.5'
|
177
177
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
178
178
|
requirements:
|
179
179
|
- - ">="
|