loxxy 0.4.03 → 0.4.07
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 +47 -7
- data/CHANGELOG.md +58 -17
- data/LICENSE.txt +1 -1
- data/lib/loxxy/ast/ast_builder.rb +12 -12
- data/lib/loxxy/ast/ast_visitor.rb +0 -1
- data/lib/loxxy/ast/lox_call_expr.rb +1 -1
- data/lib/loxxy/ast/lox_return_stmt.rb +1 -1
- data/lib/loxxy/back_end/resolver.rb +1 -1
- data/lib/loxxy/front_end/grammar.rb +3 -10
- data/lib/loxxy/front_end/scanner.rb +2 -3
- data/lib/loxxy/version.rb +1 -1
- data/loxxy.gemspec +2 -2
- data/spec/front_end/parser_spec.rb +1 -1
- data/spec/front_end/raw_parser_spec.rb +5 -8
- data/spec/front_end/scanner_spec.rb +7 -7
- metadata +6 -7
- data/lib/loxxy/front_end/literal.rb +0 -25
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7cd3e438270c62a4863cddfd1b737182993ea205d84985e8862a25c74bb2e8c4
|
|
4
|
+
data.tar.gz: f6bd428ebc505e238392cbb04e5fb1207eb34752f974ae8f81a23798e4ef51b5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 77ac1d09cb77b8afab98c21bb2f8544fd2961473efd1acaae3134a2aba0ed7138270aa86f384fe2ce1f76d865c8cd049dc3b8379b954c70992cc53b068244593
|
|
7
|
+
data.tar.gz: 9fa0e0c3c3d96600bc4e8cd0447383a287be6ff483fb2a843056c87175239bc5fd319e0f11cfe8ab496652a773c91d91f8c05176275b07873f08ffad0de7a1f4
|
data/.rubocop.yml
CHANGED
|
@@ -84,6 +84,9 @@ Layout/TrailingWhitespace:
|
|
|
84
84
|
Lint/AmbiguousAssignment:
|
|
85
85
|
Enabled: true
|
|
86
86
|
|
|
87
|
+
Lint/AmbiguousOperatorPrecedence: # new in 1.21
|
|
88
|
+
Enabled: true
|
|
89
|
+
|
|
87
90
|
Lint/AmbiguousRange:
|
|
88
91
|
Enabled: true
|
|
89
92
|
|
|
@@ -105,6 +108,9 @@ Lint/EmptyClass:
|
|
|
105
108
|
Lint/EmptyInPattern:
|
|
106
109
|
Enabled: true
|
|
107
110
|
|
|
111
|
+
Lint/IncompatibleIoSelectWithFiberScheduler: # new in 1.21
|
|
112
|
+
Enabled: true
|
|
113
|
+
|
|
108
114
|
Lint/LambdaWithoutLiteralBlock:
|
|
109
115
|
Enabled: true
|
|
110
116
|
|
|
@@ -126,6 +132,9 @@ Lint/RaiseException:
|
|
|
126
132
|
Lint/RedundantDirGlobSort:
|
|
127
133
|
Enabled: true
|
|
128
134
|
|
|
135
|
+
Lint/RequireRelativeSelfPath: # new in 1.22
|
|
136
|
+
Enabled: true
|
|
137
|
+
|
|
129
138
|
Lint/RescueException:
|
|
130
139
|
Enabled: true
|
|
131
140
|
|
|
@@ -153,6 +162,9 @@ Lint/UnusedMethodArgument:
|
|
|
153
162
|
Lint/UselessAccessModifier:
|
|
154
163
|
Enabled: true
|
|
155
164
|
|
|
165
|
+
Lint/UselessRuby2Keywords: # new in 1.23
|
|
166
|
+
Enabled: true
|
|
167
|
+
|
|
156
168
|
Lint/Void:
|
|
157
169
|
Enabled: false
|
|
158
170
|
|
|
@@ -192,6 +204,9 @@ Metrics/ModuleLength:
|
|
|
192
204
|
Metrics/PerceivedComplexity:
|
|
193
205
|
Enabled: false
|
|
194
206
|
|
|
207
|
+
Naming/BlockForwarding: # new in 1.24
|
|
208
|
+
Enabled: true
|
|
209
|
+
|
|
195
210
|
Naming/ConstantName:
|
|
196
211
|
Enabled: false
|
|
197
212
|
|
|
@@ -213,6 +228,9 @@ Naming/MethodName:
|
|
|
213
228
|
Naming/VariableName:
|
|
214
229
|
Enabled: false
|
|
215
230
|
|
|
231
|
+
Security/IoMethods: # new in 1.22
|
|
232
|
+
Enabled: true
|
|
233
|
+
|
|
216
234
|
Style/Alias:
|
|
217
235
|
Enabled: true
|
|
218
236
|
|
|
@@ -293,9 +311,9 @@ Style/InverseMethods:
|
|
|
293
311
|
|
|
294
312
|
Style/MissingRespondToMissing:
|
|
295
313
|
Enabled: false
|
|
296
|
-
|
|
314
|
+
|
|
297
315
|
Style/MultilineInPatternThen:
|
|
298
|
-
Enabled: true
|
|
316
|
+
Enabled: true
|
|
299
317
|
|
|
300
318
|
Style/NegatedIfElseCondition:
|
|
301
319
|
Enabled: true
|
|
@@ -306,11 +324,17 @@ Style/Next:
|
|
|
306
324
|
Style/NilLambda:
|
|
307
325
|
Enabled: true
|
|
308
326
|
|
|
327
|
+
Style/NumberedParameters: # new in 1.22
|
|
328
|
+
Enabled: true
|
|
329
|
+
|
|
330
|
+
Style/NumberedParametersLimit: # new in 1.22
|
|
331
|
+
Enabled: true
|
|
332
|
+
|
|
309
333
|
Style/NumericLiterals:
|
|
310
334
|
Enabled: false
|
|
311
|
-
|
|
335
|
+
|
|
312
336
|
Style/QuotedSymbols:
|
|
313
|
-
Enabled: true
|
|
337
|
+
Enabled: true
|
|
314
338
|
|
|
315
339
|
Style/RaiseArgs:
|
|
316
340
|
Enabled: true
|
|
@@ -323,9 +347,9 @@ Style/RedundantReturn:
|
|
|
323
347
|
|
|
324
348
|
Style/RedundantSelf:
|
|
325
349
|
Enabled: true
|
|
326
|
-
|
|
350
|
+
|
|
327
351
|
Style/RedundantSelfAssignmentBranch:
|
|
328
|
-
Enabled: true
|
|
352
|
+
Enabled: true
|
|
329
353
|
|
|
330
354
|
Style/RegexpLiteral:
|
|
331
355
|
Enabled: false
|
|
@@ -333,6 +357,9 @@ Style/RegexpLiteral:
|
|
|
333
357
|
Style/PercentLiteralDelimiters:
|
|
334
358
|
Enabled: false
|
|
335
359
|
|
|
360
|
+
Style/SelectByRegexp: # new in 1.22
|
|
361
|
+
Enabled: true
|
|
362
|
+
|
|
336
363
|
Style/StderrPuts:
|
|
337
364
|
Enabled: false
|
|
338
365
|
|
|
@@ -406,6 +433,12 @@ Style/EndlessMethod:
|
|
|
406
433
|
Style/ExplicitBlockArgument:
|
|
407
434
|
Enabled: true
|
|
408
435
|
|
|
436
|
+
Style/FileRead: # new in 1.24
|
|
437
|
+
Enabled: true
|
|
438
|
+
|
|
439
|
+
Style/FileWrite: # new in 1.24
|
|
440
|
+
Enabled: true
|
|
441
|
+
|
|
409
442
|
Style/GlobalStdStream:
|
|
410
443
|
Enabled: true
|
|
411
444
|
|
|
@@ -417,12 +450,19 @@ Style/HashConversion:
|
|
|
417
450
|
|
|
418
451
|
Style/HashLikeCase:
|
|
419
452
|
Enabled: true
|
|
420
|
-
|
|
453
|
+
|
|
421
454
|
Style/IfWithBooleanLiteralBranches:
|
|
422
455
|
Enabled: true
|
|
456
|
+
|
|
457
|
+
Style/MapToHash: # new in 1.24
|
|
458
|
+
Enabled: true
|
|
459
|
+
|
|
460
|
+
Style/OpenStructUse: # new in 1.23
|
|
461
|
+
Enabled: true
|
|
423
462
|
|
|
424
463
|
Style/OptionalBooleanParameter:
|
|
425
464
|
Enabled: true
|
|
465
|
+
|
|
426
466
|
|
|
427
467
|
Style/RedundantAssignment:
|
|
428
468
|
Enabled: true
|
data/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,56 @@
|
|
|
1
|
+
## [0.4.07] - 2022-11-21
|
|
2
|
+
- Minor fixes; dependency towards Rubies 3+ allowed...
|
|
3
|
+
|
|
4
|
+
### Fixed
|
|
5
|
+
- File `loxxy.gemspec` dependency on Ruby version relaxed to support Ruby 3+
|
|
6
|
+
- File `resolver.rb` Fixed a typo in standard Lox error message.
|
|
7
|
+
- File `collide_with_paramaeter.lox` Fixed typo in error message.
|
|
8
|
+
- File `duplicate_local.lox` Fixed typo in error message.
|
|
9
|
+
- File `duplicate_parameter.lox` Fixed typo in error message.
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
## [0.4.06] - 2021-11-01
|
|
13
|
+
- Code update to cope with `Rley` v.0.8.08 changes
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- File `AST::AstBuilder` some `reduce_` to cope implementation change of ? quantifier
|
|
17
|
+
- Method `AST::LoxCallExpr#initialize` call to `Array#flatten` with argList argument
|
|
18
|
+
- File `loxxy.gemspec` dependency towards `rely` minimal version number is now `0.8.08`
|
|
19
|
+
- Some spec files updated after `rley` changes of ?, *, + quantifiers
|
|
20
|
+
|
|
21
|
+
### Removed
|
|
22
|
+
- File `front_end/literal.rb`: obsolete
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
## [0.4.05] - 2021-10-10
|
|
26
|
+
- Removal of `Literal` class, code restyling to please Rubocop 1.22
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
- Class `Scanner` remove all dependencies to `Frontend::Literal` class
|
|
30
|
+
- File `.rubocop.yml` added new cops from Rubocop 1.21 and 1.22
|
|
31
|
+
- File `parser_spec.rb` use of parentheses in ambiguous expressions
|
|
32
|
+
- File `raw_parser_spec.rb` use of parentheses in ambiguous expressions
|
|
33
|
+
- File `loxxy.gemspec` forced dependency to Rley 0.8.06
|
|
34
|
+
|
|
35
|
+
## [0.4.04] - 2021-09-11
|
|
36
|
+
- Grammar optimization (3 rules less, use of match_closest feature from `Rley`)
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
- Method `Ast::AstBuilder#reduce_arguments` code re-styling: use shorthand &:
|
|
40
|
+
- File `grammar.rb` use `match_closest` constraint from Rley to cope with dangling else statement
|
|
41
|
+
|
|
1
42
|
## [0.4.02] - 2021-09-10
|
|
2
|
-
- Fixes in`AST::AstBuilder` class to
|
|
43
|
+
- Fixes in`AST::AstBuilder` class to cope with changes in Rley 0.8.03
|
|
3
44
|
|
|
4
45
|
### Changed
|
|
5
46
|
- File `loxxy.gemspec` forced dependency to Rley 0.8.03
|
|
6
47
|
|
|
7
48
|
### Fixed
|
|
8
49
|
- Method `Ast::AstBuilder#reduce_class_naming` fixed access to `IDENTIFER` in (LESS IDENTIFER)?
|
|
9
|
-
- Method `Ast::AstBuilder#reduce_var_declaration` fixed access to `expression` in (EQUAL expression)?
|
|
10
|
-
- Method `Ast::AstBuilder#reduce_assign_expr`fixed access to `call` in (call DOT)?
|
|
11
|
-
- Method `Ast::AstBuilder#reduce_parameters`fixed access to `IDENTIFIER` in (COMMA IDENTIFIER)*
|
|
12
|
-
- Method `Ast::AstBuilder#reduce_arguments`fixed access to `expression` in (COMMA expression)*
|
|
50
|
+
- Method `Ast::AstBuilder#reduce_var_declaration` fixed access to `expression` in (EQUAL expression)?
|
|
51
|
+
- Method `Ast::AstBuilder#reduce_assign_expr`fixed access to `call` in (call DOT)?
|
|
52
|
+
- Method `Ast::AstBuilder#reduce_parameters`fixed access to `IDENTIFIER` in (COMMA IDENTIFIER)*
|
|
53
|
+
- Method `Ast::AstBuilder#reduce_arguments`fixed access to `expression` in (COMMA expression)*
|
|
13
54
|
|
|
14
55
|
|
|
15
56
|
|
|
@@ -68,14 +109,14 @@
|
|
|
68
109
|
- Milestone: `Loxxy` passes all reference test suite.
|
|
69
110
|
|
|
70
111
|
### Fixed
|
|
71
|
-
- Method `BackEnd::Resolver#before_variable_expr`: Standard `Lox` allows re-declaration of a variable at top-level scope
|
|
112
|
+
- Method `BackEnd::Resolver#before_variable_expr`: Standard `Lox` allows re-declaration of a variable at top-level scope
|
|
113
|
+
|
|
72
114
|
|
|
73
|
-
|
|
74
115
|
## [0.2.06] - 2021-05-04
|
|
75
116
|
- Nearly passing the 'official' test suite, fixing non-compliant behavior, specialized exceptions for errors
|
|
76
117
|
|
|
77
118
|
### New
|
|
78
|
-
- Module `LoxFileTester` module that hosts methods that simplify the tests of `Lox` source file.
|
|
119
|
+
- Module `LoxFileTester` module that hosts methods that simplify the tests of `Lox` source file.
|
|
79
120
|
|
|
80
121
|
### Changed
|
|
81
122
|
- Folder `test_suite` vastly reorganized. Sub-folder `baseline` contains spec files testing the `Lox` files from official implementation
|
|
@@ -85,7 +126,7 @@
|
|
|
85
126
|
|
|
86
127
|
### Fixed
|
|
87
128
|
- `0/0` expression results in a ZeroDivisionError exception, in Lox this result to a NaN (Not a Number). Now, `Loxxy` is aligned to standard `Lox`
|
|
88
|
-
- `FrontEnd::Scanner` now always treats expression like `-123` as the unary or binary minus operator applied to a positive number.
|
|
129
|
+
- `FrontEnd::Scanner` now always treats expression like `-123` as the unary or binary minus operator applied to a positive number.
|
|
89
130
|
|
|
90
131
|
## [0.2.05] - 2021-04-26
|
|
91
132
|
- `Loxxy` now transforms for loops into while loops (desugaring), fix in Scanner class
|
|
@@ -112,7 +153,7 @@
|
|
|
112
153
|
- Method `BackEnd::Resolver#after_for_stmt now accepts nil test expression
|
|
113
154
|
|
|
114
155
|
## [0.2.03] - 2021-04-24
|
|
115
|
-
- Fixes for the set (field) expressions, `accept` methods for AST nodes are meta-programmed
|
|
156
|
+
- Fixes for the set (field) expressions, `accept` methods for AST nodes are meta-programmed
|
|
116
157
|
|
|
117
158
|
### New
|
|
118
159
|
- Module `Ast::Visitee` provides the `define_accept` method that generate `accept` method with meta-programming
|
|
@@ -287,7 +328,7 @@
|
|
|
287
328
|
- Fix and test suite for return statements
|
|
288
329
|
|
|
289
330
|
### CHANGED
|
|
290
|
-
- `Loxxy` reports an error when a return statement occurs in top-level scope
|
|
331
|
+
- `Loxxy` reports an error when a return statement occurs in top-level scope
|
|
291
332
|
|
|
292
333
|
### Fixed
|
|
293
334
|
- A return without explicit value genrated an exception in some cases.
|
|
@@ -311,7 +352,7 @@
|
|
|
311
352
|
- Class `BackEnd::Environment`: added the attributes `predecessor` and `embedding` to support closures.
|
|
312
353
|
- Class `BackeEnd::LoxFunction`: added the attribute `closure` that is equal to the environment where the function is declared.
|
|
313
354
|
- Constructor `BackEnd::LoxFunction#new` now takes a `BackEnd::Engine`as its fourth parameter
|
|
314
|
-
- Methods `BackEnd::SymbolTable#enter_environment`, `BackEnd::SymbolTable#leave_environment` take into account closures.
|
|
355
|
+
- Methods `BackEnd::SymbolTable#enter_environment`, `BackEnd::SymbolTable#leave_environment` take into account closures.
|
|
315
356
|
|
|
316
357
|
### Fixed
|
|
317
358
|
- Method `Ast::AstBuilder#after_var_stmt` now takes into account the value from the top of stack
|
|
@@ -357,7 +398,7 @@
|
|
|
357
398
|
|
|
358
399
|
### Changed
|
|
359
400
|
- File `console` renamed to `loxxy`. Very basic command-line interface.
|
|
360
|
-
- Custom exception classes
|
|
401
|
+
- Custom exception classes
|
|
361
402
|
- File `README.md` updated list of supported `Lox` keywords.
|
|
362
403
|
|
|
363
404
|
|
|
@@ -388,8 +429,8 @@
|
|
|
388
429
|
- Method `Ast::ASTVisitor#visit_fun_stmt` for visiting an `Ast::LoxFunStmt` node
|
|
389
430
|
- Method `Ast::LoxBlockStmt#empty?` returns true if the code block is empty
|
|
390
431
|
- Method `BackEnd::Engine#after_fun_stmt`
|
|
391
|
-
- Method `BackEnd::NativeFunction#call`
|
|
392
|
-
- Method `BackEnd::NativeFunction#to_str`
|
|
432
|
+
- Method `BackEnd::NativeFunction#call`
|
|
433
|
+
- Method `BackEnd::NativeFunction#to_str`
|
|
393
434
|
- Method `BackEnd::LoxFunction` runtime representation of a Lox function.
|
|
394
435
|
|
|
395
436
|
### Changed
|
|
@@ -458,7 +499,7 @@
|
|
|
458
499
|
- Method `Ast::ASTBuilder#reduce_assign_expr` creates an `Ast::LoxAssignExpr` node
|
|
459
500
|
- Method `Ast::ASTVisitor#visit_assign_expr` for visiting an `Ast::LoxAssignExpr` node
|
|
460
501
|
- Method `BackEnd::Engine#after_assign_expr` implementation of the assignment
|
|
461
|
-
- Method `BackEnd::Variable#assign` to assign a value to a variable
|
|
502
|
+
- Method `BackEnd::Variable#assign` to assign a value to a variable
|
|
462
503
|
|
|
463
504
|
## [0.0.23] - 2021-01-20
|
|
464
505
|
- Fix for variables without explicit initialization.
|
|
@@ -728,4 +769,4 @@
|
|
|
728
769
|
|
|
729
770
|
## [0.0.1] - 2020-12-27
|
|
730
771
|
### Added
|
|
731
|
-
- Initial Github commit
|
|
772
|
+
- Initial Github commit
|
data/LICENSE.txt
CHANGED
|
@@ -222,10 +222,8 @@ module Loxxy
|
|
|
222
222
|
if test.nil? && update
|
|
223
223
|
# when test expr is nil but update expr is not, then force test to be true
|
|
224
224
|
test = LoxLiteralExpr.new(tokens[0].position, Datatype::True.instance)
|
|
225
|
-
[init, test, update]
|
|
226
|
-
else
|
|
227
|
-
theChildren
|
|
228
225
|
end
|
|
226
|
+
[init, test, update&.first]
|
|
229
227
|
end
|
|
230
228
|
|
|
231
229
|
# rule('forInitialization' => 'SEMICOLON')
|
|
@@ -234,8 +232,8 @@ module Loxxy
|
|
|
234
232
|
end
|
|
235
233
|
|
|
236
234
|
# rule('forTest' => 'expression? SEMICOLON')
|
|
237
|
-
def reduce_for_test(_production,
|
|
238
|
-
|
|
235
|
+
def reduce_for_test(_production, _range, _tokens, theChildren)
|
|
236
|
+
theChildren[0]&.first
|
|
239
237
|
end
|
|
240
238
|
|
|
241
239
|
# rule('ifStmt' => 'IF ifCondition statement ELSE statement')
|
|
@@ -262,7 +260,8 @@ module Loxxy
|
|
|
262
260
|
|
|
263
261
|
# rule('returnStmt' => 'RETURN expression? SEMICOLON')
|
|
264
262
|
def reduce_return_stmt(_production, _range, tokens, theChildren)
|
|
265
|
-
|
|
263
|
+
ret_expr = theChildren[1].nil? ? nil : theChildren[1].first
|
|
264
|
+
Ast::LoxReturnStmt.new(tokens[1].position, ret_expr)
|
|
266
265
|
end
|
|
267
266
|
|
|
268
267
|
# rule('whileStmt' => 'WHILE LEFT_PAREN expression RIGHT_PAREN statement').as ''
|
|
@@ -275,7 +274,7 @@ module Loxxy
|
|
|
275
274
|
decls = nil
|
|
276
275
|
if theChildren[1]
|
|
277
276
|
pos = tokens[1].position
|
|
278
|
-
decls = LoxSeqDecl.new(
|
|
277
|
+
decls = LoxSeqDecl.new(pos, theChildren[1].flatten)
|
|
279
278
|
else
|
|
280
279
|
pos = tokens[0].position
|
|
281
280
|
end
|
|
@@ -377,15 +376,16 @@ module Loxxy
|
|
|
377
376
|
LoxSuperExpr.new(theChildren[0].token.position, theChildren[2].token.lexeme)
|
|
378
377
|
end
|
|
379
378
|
|
|
380
|
-
# rule('function' => 'IDENTIFIER LEFT_PAREN
|
|
379
|
+
# rule('function' => 'IDENTIFIER LEFT_PAREN parameters? RIGHT_PAREN block').as 'function'
|
|
381
380
|
def reduce_function(_production, _range, _tokens, theChildren)
|
|
382
381
|
first_child = theChildren.first
|
|
383
382
|
pos = first_child.token.position
|
|
384
|
-
|
|
383
|
+
params = theChildren[2] ? theChildren[2].flatten : []
|
|
384
|
+
if params.size > 255
|
|
385
385
|
msg = "Can't have more than 255 parameters."
|
|
386
386
|
raise Loxxy::SyntaxError, msg
|
|
387
387
|
end
|
|
388
|
-
LoxFunStmt.new(pos, first_child.token.lexeme,
|
|
388
|
+
LoxFunStmt.new(pos, first_child.token.lexeme, params, theChildren[4])
|
|
389
389
|
end
|
|
390
390
|
|
|
391
391
|
# rule('parameters' => 'IDENTIFIER (COMMA IDENTIFIER)*').as 'parameters'
|
|
@@ -399,9 +399,9 @@ module Loxxy
|
|
|
399
399
|
|
|
400
400
|
# rule('arguments' => 'expression (COMMA expression)*')
|
|
401
401
|
def reduce_arguments(_production, _range, _tokens, theChildren)
|
|
402
|
-
return [theChildren[0]]
|
|
402
|
+
return [theChildren[0]] if theChildren[1].empty?
|
|
403
403
|
|
|
404
|
-
successors = theChildren[1].map
|
|
404
|
+
successors = theChildren[1].map(&:last)
|
|
405
405
|
successors.unshift(theChildren[0])
|
|
406
406
|
end
|
|
407
407
|
end # class
|
|
@@ -12,7 +12,7 @@ module Loxxy
|
|
|
12
12
|
# @param argList [Array<Loxxy::Ast::LoxNode>]
|
|
13
13
|
def initialize(aPosition, argList)
|
|
14
14
|
super(aPosition, [])
|
|
15
|
-
@arguments = argList
|
|
15
|
+
@arguments = argList.flatten
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
define_accept # Add `accept` method as found in Visitor design pattern
|
|
@@ -6,7 +6,7 @@ module Loxxy
|
|
|
6
6
|
module Ast
|
|
7
7
|
class LoxReturnStmt < LoxCompoundExpr
|
|
8
8
|
# @param aPosition [Rley::Lexical::Position] Position of the entry in the input stream.
|
|
9
|
-
# @param anExpression [Ast::LoxNode] expression to return
|
|
9
|
+
# @param anExpression [Ast::LoxNode, NilClass] expression to return
|
|
10
10
|
def initialize(aPosition, anExpression)
|
|
11
11
|
expr = anExpression || Datatype::Nil.instance
|
|
12
12
|
super(aPosition, [expr])
|
|
@@ -220,7 +220,7 @@ module Loxxy
|
|
|
220
220
|
curr_scope = scopes.last
|
|
221
221
|
# Oddly enough, Lox allows variable re-declaration at top-level
|
|
222
222
|
if curr_scope.include?(aVarName)
|
|
223
|
-
msg = "Error at '#{aVarName}': Already variable with this name in this scope."
|
|
223
|
+
msg = "Error at '#{aVarName}': Already a variable with this name in this scope."
|
|
224
224
|
raise Loxxy::RuntimeError, msg
|
|
225
225
|
elsif curr_scope.size == 255 && current_function != :none
|
|
226
226
|
msg = "Error at '#{aVarName}': Too many local variables in function."
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
|
|
4
3
|
require 'rley' # Load the gem
|
|
5
4
|
|
|
6
5
|
module Loxxy
|
|
7
6
|
module FrontEnd
|
|
8
7
|
########################################
|
|
9
|
-
# Grammar for Lox language
|
|
8
|
+
# Grammar for the Lox language
|
|
10
9
|
# Authoritative grammar at:
|
|
11
10
|
# https://craftinginterpreters.com/appendix-i.html
|
|
12
11
|
builder = Rley::grammar_builder do
|
|
@@ -32,7 +31,7 @@ module Loxxy
|
|
|
32
31
|
rule('declaration' => 'classDecl')
|
|
33
32
|
rule('declaration' => 'funDecl')
|
|
34
33
|
rule('declaration' => 'varDecl')
|
|
35
|
-
rule('declaration' => '
|
|
34
|
+
rule('declaration' => 'statement')
|
|
36
35
|
|
|
37
36
|
rule('classDecl' => 'CLASS classNaming class_body').as 'class_decl'
|
|
38
37
|
rule('classNaming' => 'IDENTIFIER (LESS IDENTIFIER)?').as 'class_naming'
|
|
@@ -43,8 +42,6 @@ module Loxxy
|
|
|
43
42
|
rule('varDecl' => 'VAR IDENTIFIER (EQUAL expression)? SEMICOLON').as 'var_declaration'
|
|
44
43
|
|
|
45
44
|
# Statements: produce side effects, but don't introduce bindings
|
|
46
|
-
rule('stmt' => 'statement')
|
|
47
|
-
# rule('stmt' => 'unbalancedStmt') # Tweak to cope with "dangling else" problem
|
|
48
45
|
rule('statement' => 'exprStmt')
|
|
49
46
|
rule('statement' => 'forStmt')
|
|
50
47
|
rule('statement' => 'ifStmt')
|
|
@@ -63,11 +60,7 @@ module Loxxy
|
|
|
63
60
|
rule('forTest' => 'expression? SEMICOLON').as 'for_test'
|
|
64
61
|
|
|
65
62
|
rule('ifStmt' => 'IF ifCondition statement ELSE {match_closest: "IF"} statement').as 'if_else_stmt'
|
|
66
|
-
rule('ifStmt' => 'IF ifCondition
|
|
67
|
-
# rule('unbalancedStmt' => 'IF ifCondition statement ELSE unbalancedStmt').as 'if_else_stmt'
|
|
68
|
-
# rule('ifStmt' => 'IF ifCondition statement ELSE statement').as 'if_else_stmt'
|
|
69
|
-
# rule('unbalancedStmt' => 'IF ifCondition stmt').as 'if_stmt'
|
|
70
|
-
# rule('unbalancedStmt' => 'IF ifCondition statement ELSE unbalancedStmt').as 'if_else_stmt'
|
|
63
|
+
rule('ifStmt' => 'IF ifCondition statement').as 'if_stmt'
|
|
71
64
|
rule('ifCondition' => 'LEFT_PAREN expression RIGHT_PAREN').as 'keep_symbol2'
|
|
72
65
|
|
|
73
66
|
rule('printStmt' => 'PRINT expression SEMICOLON').as 'print_stmt'
|
|
@@ -4,7 +4,6 @@ require 'strscan'
|
|
|
4
4
|
require 'rley'
|
|
5
5
|
require_relative '../error'
|
|
6
6
|
require_relative '../datatype/all_datatypes'
|
|
7
|
-
require_relative 'literal'
|
|
8
7
|
|
|
9
8
|
module Loxxy
|
|
10
9
|
module FrontEnd
|
|
@@ -142,7 +141,7 @@ module Loxxy
|
|
|
142
141
|
col = scanner.pos - lex_length - @line_start + 1
|
|
143
142
|
pos = Rley::Lexical::Position.new(@lineno, col)
|
|
144
143
|
if value
|
|
145
|
-
token = Literal.new(value, aLexeme.dup, symb, pos)
|
|
144
|
+
token = Rley::Lexical::Literal.new(value, aLexeme.dup, symb, pos)
|
|
146
145
|
else
|
|
147
146
|
token = Rley::Lexical::Token.new(aLexeme.dup, symb, pos)
|
|
148
147
|
end
|
|
@@ -212,7 +211,7 @@ module Loxxy
|
|
|
212
211
|
pos = Rley::Lexical::Position.new(line, column_start)
|
|
213
212
|
lox_string = Datatype::LXString.new(literal)
|
|
214
213
|
lexeme = scanner.string[scan_pos - 1..scanner.pos - 1]
|
|
215
|
-
Literal.new(lox_string, lexeme, 'STRING', pos)
|
|
214
|
+
Rley::Lexical::Literal.new(lox_string, lexeme, 'STRING', pos)
|
|
216
215
|
end
|
|
217
216
|
|
|
218
217
|
# Skip non-significant whitespaces and comments.
|
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 = '
|
|
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.8.
|
|
61
|
+
spec.add_dependency 'rley', '~> 0.8.08'
|
|
62
62
|
|
|
63
63
|
# Development dependencies
|
|
64
64
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
|
@@ -28,7 +28,7 @@ module Loxxy
|
|
|
28
28
|
expect(aParseTree.root.symbol.name).to eq('program')
|
|
29
29
|
(decls, eof) = aParseTree.root.subnodes
|
|
30
30
|
expect(decls).to be_kind_of(Rley::PTree::NonTerminalNode)
|
|
31
|
-
expect(decls.symbol.name).to eq('
|
|
31
|
+
expect(decls.symbol.name).to eq('rep_declaration_star')
|
|
32
32
|
expect(decls.subnodes).to be_empty
|
|
33
33
|
expect(eof).to be_kind_of(Rley::PTree::TerminalNode)
|
|
34
34
|
expect(eof.symbol.name).to eq('EOF')
|
|
@@ -40,7 +40,7 @@ module Loxxy
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
it 'should cope with whitespaces only input' do
|
|
43
|
-
ptree = subject.parse(' ' * 80 + "\n" * 20)
|
|
43
|
+
ptree = subject.parse((' ' * 80) + ("\n" * 20))
|
|
44
44
|
check_empty_input_result(ptree)
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -76,15 +76,12 @@ LOX_END
|
|
|
76
76
|
expect(root.symbol.name).to eq('program')
|
|
77
77
|
(decls, eof) = root.subnodes
|
|
78
78
|
expect(decls).to be_kind_of(Rley::PTree::NonTerminalNode)
|
|
79
|
-
expect(decls.symbol.name).to eq('
|
|
79
|
+
expect(decls.symbol.name).to eq('rep_declaration_star')
|
|
80
80
|
expect(decls.subnodes[0]).to be_kind_of(Rley::PTree::NonTerminalNode)
|
|
81
|
-
expect(decls.subnodes[0].symbol.name).to eq('
|
|
81
|
+
expect(decls.subnodes[0].symbol.name).to eq('rep_declaration_star')
|
|
82
82
|
expect(decls.subnodes[1]).to be_kind_of(Rley::PTree::NonTerminalNode)
|
|
83
83
|
expect(decls.subnodes[1].symbol.name).to eq('declaration')
|
|
84
|
-
|
|
85
|
-
expect(stmt).to be_kind_of(Rley::PTree::NonTerminalNode)
|
|
86
|
-
expect(stmt.symbol.name).to eq('stmt')
|
|
87
|
-
statement = stmt.subnodes[0]
|
|
84
|
+
statement = decls.subnodes[1].subnodes[0]
|
|
88
85
|
expect(statement).to be_kind_of(Rley::PTree::NonTerminalNode)
|
|
89
86
|
expect(statement.symbol.name).to eq('statement')
|
|
90
87
|
prnt_stmt = statement.subnodes[0]
|
|
@@ -105,7 +105,7 @@ LOX_END
|
|
|
105
105
|
it 'should recognize a false boolean token' do
|
|
106
106
|
subject.start_with('false')
|
|
107
107
|
token_false = subject.tokens[0]
|
|
108
|
-
expect(token_false).to be_kind_of(Literal)
|
|
108
|
+
expect(token_false).to be_kind_of(Rley::Lexical::Literal)
|
|
109
109
|
expect(token_false.terminal).to eq('FALSE')
|
|
110
110
|
expect(token_false.lexeme).to eq('false')
|
|
111
111
|
expect(token_false.value).to be_kind_of(Datatype::False)
|
|
@@ -115,7 +115,7 @@ LOX_END
|
|
|
115
115
|
it 'should recognize a true boolean token' do
|
|
116
116
|
subject.start_with('true')
|
|
117
117
|
token_true = subject.tokens[0]
|
|
118
|
-
expect(token_true).to be_kind_of(Literal)
|
|
118
|
+
expect(token_true).to be_kind_of(Rley::Lexical::Literal)
|
|
119
119
|
expect(token_true.terminal).to eq('TRUE')
|
|
120
120
|
expect(token_true.lexeme).to eq('true')
|
|
121
121
|
expect(token_true.value).to be_kind_of(Datatype::True)
|
|
@@ -137,7 +137,7 @@ LOX_END
|
|
|
137
137
|
|
|
138
138
|
subject.start_with(input)
|
|
139
139
|
subject.tokens[0..-2].each_with_index do |tok, i|
|
|
140
|
-
expect(tok).to be_kind_of(Literal)
|
|
140
|
+
expect(tok).to be_kind_of(Rley::Lexical::Literal)
|
|
141
141
|
expect(tok.terminal).to eq('NUMBER')
|
|
142
142
|
(lexeme, val) = expectations[i]
|
|
143
143
|
expect(tok.lexeme).to eq(lexeme)
|
|
@@ -177,10 +177,10 @@ LOX_END
|
|
|
177
177
|
tokens = subject.tokens[0..-2]
|
|
178
178
|
expect(tokens[0]).to be_kind_of(Rley::Lexical::Token)
|
|
179
179
|
expect(tokens[0].terminal).to eq('DOT')
|
|
180
|
-
expect(tokens[1]).to be_kind_of(Literal)
|
|
180
|
+
expect(tokens[1]).to be_kind_of(Rley::Lexical::Literal)
|
|
181
181
|
expect(tokens[1].terminal).to eq('NUMBER')
|
|
182
182
|
expect(tokens[1].value.value).to eq(456)
|
|
183
|
-
expect(tokens[2]).to be_kind_of(Literal)
|
|
183
|
+
expect(tokens[2]).to be_kind_of(Rley::Lexical::Literal)
|
|
184
184
|
expect(tokens[2].terminal).to eq('NUMBER')
|
|
185
185
|
expect(tokens[2].value.value).to eq(123)
|
|
186
186
|
expect(tokens[3]).to be_kind_of(Rley::Lexical::Token)
|
|
@@ -202,7 +202,7 @@ LOX_END
|
|
|
202
202
|
|
|
203
203
|
subject.start_with(input)
|
|
204
204
|
subject.tokens[0..-2].each_with_index do |str, i|
|
|
205
|
-
expect(str).to be_kind_of(Literal)
|
|
205
|
+
expect(str).to be_kind_of(Rley::Lexical::Literal)
|
|
206
206
|
expect(str.terminal).to eq('STRING')
|
|
207
207
|
val = expectations[i]
|
|
208
208
|
expect(str.value).to be_kind_of(Datatype::LXString)
|
|
@@ -236,7 +236,7 @@ LOX_END
|
|
|
236
236
|
it 'should recognize a nil token' do
|
|
237
237
|
subject.start_with('nil')
|
|
238
238
|
token_nil = subject.tokens[0]
|
|
239
|
-
expect(token_nil).to be_kind_of(Literal)
|
|
239
|
+
expect(token_nil).to be_kind_of(Rley::Lexical::Literal)
|
|
240
240
|
expect(token_nil.terminal).to eq('NIL')
|
|
241
241
|
expect(token_nil.lexeme).to eq('nil')
|
|
242
242
|
expect(token_nil.value).to be_kind_of(Datatype::Nil)
|
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.07
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dimitri Geshef
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-01-21 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.8.
|
|
19
|
+
version: 0.8.08
|
|
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.8.
|
|
26
|
+
version: 0.8.08
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: bundler
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -139,7 +139,6 @@ files:
|
|
|
139
139
|
- lib/loxxy/datatype/true.rb
|
|
140
140
|
- lib/loxxy/error.rb
|
|
141
141
|
- lib/loxxy/front_end/grammar.rb
|
|
142
|
-
- lib/loxxy/front_end/literal.rb
|
|
143
142
|
- lib/loxxy/front_end/parser.rb
|
|
144
143
|
- lib/loxxy/front_end/raw_parser.rb
|
|
145
144
|
- lib/loxxy/front_end/scanner.rb
|
|
@@ -171,7 +170,7 @@ require_paths:
|
|
|
171
170
|
- lib
|
|
172
171
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
173
172
|
requirements:
|
|
174
|
-
- - "
|
|
173
|
+
- - ">="
|
|
175
174
|
- !ruby/object:Gem::Version
|
|
176
175
|
version: '2.5'
|
|
177
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
@@ -180,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
180
179
|
- !ruby/object:Gem::Version
|
|
181
180
|
version: '0'
|
|
182
181
|
requirements: []
|
|
183
|
-
rubygems_version: 3.
|
|
182
|
+
rubygems_version: 3.3.3
|
|
184
183
|
signing_key:
|
|
185
184
|
specification_version: 4
|
|
186
185
|
summary: An implementation of the Lox programming language.
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require 'rley'
|
|
4
|
-
|
|
5
|
-
module Loxxy
|
|
6
|
-
module FrontEnd
|
|
7
|
-
# The superclass for all tokens that have a data value.
|
|
8
|
-
class Literal < Rley::Lexical::Token
|
|
9
|
-
# @return [Datatype] The value expressed in one of the Lox datatype.
|
|
10
|
-
attr_reader :value
|
|
11
|
-
|
|
12
|
-
# Constructor.
|
|
13
|
-
# @param aValue [Datatype::BuiltinDatatype] the Lox data value
|
|
14
|
-
# @param aLexeme [String] the lexeme (= piece of text from input)
|
|
15
|
-
# @param aTerminal [Rley::Syntax::Terminal, String]
|
|
16
|
-
# The terminal symbol corresponding to the lexeme.
|
|
17
|
-
# @param aPosition [Rley::Lexical::Position] The position of lexeme
|
|
18
|
-
# in input text.
|
|
19
|
-
def initialize(aValue, aLexeme, aTerminal, aPosition)
|
|
20
|
-
super(aLexeme, aTerminal, aPosition)
|
|
21
|
-
@value = aValue
|
|
22
|
-
end
|
|
23
|
-
end # class
|
|
24
|
-
end # module
|
|
25
|
-
end # module
|