loxxy 0.4.05 → 0.4.08
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +20 -1
- data/CHANGELOG.md +31 -1
- data/LICENSE.txt +1 -1
- data/lib/loxxy/ast/ast_builder.rb +11 -11
- 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 +1 -1
- data/lib/loxxy/front_end/scanner.rb +83 -78
- data/lib/loxxy/version.rb +1 -1
- data/loxxy.gemspec +2 -2
- data/spec/front_end/raw_parser_spec.rb +3 -3
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e7e447625d999f4b95129d7feff1586c6759cb929a8faaa82e3ecc94105d0268
|
4
|
+
data.tar.gz: 00a4801454ffd09b2d4e810fd15d0f9b40fea13f46e6d4eed7eba4cab8d35ebe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4a59f746cb7b8086ff3e1252c3fc0846229cb6927dcc4d62ad261c5e0c2fec4b1a75176cab6788cedb5c57a2fe9e7bec94d92d7dc63a2c455609a18761f78043
|
7
|
+
data.tar.gz: 66f72710a3f422e4431c88c44b56419f727711c1fbf339491f1fcb2f8f18edb0f4a21ce49a66ee4325ccf3b2576b0b94490d74f96c922a9d340d476e43660881
|
data/.rubocop.yml
CHANGED
@@ -162,6 +162,9 @@ Lint/UnusedMethodArgument:
|
|
162
162
|
Lint/UselessAccessModifier:
|
163
163
|
Enabled: true
|
164
164
|
|
165
|
+
Lint/UselessRuby2Keywords: # new in 1.23
|
166
|
+
Enabled: true
|
167
|
+
|
165
168
|
Lint/Void:
|
166
169
|
Enabled: false
|
167
170
|
|
@@ -201,6 +204,9 @@ Metrics/ModuleLength:
|
|
201
204
|
Metrics/PerceivedComplexity:
|
202
205
|
Enabled: false
|
203
206
|
|
207
|
+
Naming/BlockForwarding: # new in 1.24
|
208
|
+
Enabled: true
|
209
|
+
|
204
210
|
Naming/ConstantName:
|
205
211
|
Enabled: false
|
206
212
|
|
@@ -427,6 +433,12 @@ Style/EndlessMethod:
|
|
427
433
|
Style/ExplicitBlockArgument:
|
428
434
|
Enabled: true
|
429
435
|
|
436
|
+
Style/FileRead: # new in 1.24
|
437
|
+
Enabled: true
|
438
|
+
|
439
|
+
Style/FileWrite: # new in 1.24
|
440
|
+
Enabled: true
|
441
|
+
|
430
442
|
Style/GlobalStdStream:
|
431
443
|
Enabled: true
|
432
444
|
|
@@ -438,12 +450,19 @@ Style/HashConversion:
|
|
438
450
|
|
439
451
|
Style/HashLikeCase:
|
440
452
|
Enabled: true
|
441
|
-
|
453
|
+
|
442
454
|
Style/IfWithBooleanLiteralBranches:
|
443
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
|
444
462
|
|
445
463
|
Style/OptionalBooleanParameter:
|
446
464
|
Enabled: true
|
465
|
+
|
447
466
|
|
448
467
|
Style/RedundantAssignment:
|
449
468
|
Enabled: true
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,33 @@
|
|
1
|
+
## [0.4.08] - 2022-04-09
|
2
|
+
- Refactoring of the `Scanner` class.
|
3
|
+
|
4
|
+
### Changed
|
5
|
+
- `Frontend::Scanner` class: major code refactoring.
|
6
|
+
|
7
|
+
## [0.4.07] - 2021-11-21
|
8
|
+
- Minor fixes; dependency towards Rubies 3+ allowed...
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
- File `loxxy.gemspec` dependency on Ruby version relaxed to support Ruby 3+
|
12
|
+
- File `resolver.rb` Fixed a typo in standard Lox error message.
|
13
|
+
- File `collide_with_paramaeter.lox` Fixed typo in error message.
|
14
|
+
- File `duplicate_local.lox` Fixed typo in error message.
|
15
|
+
- File `duplicate_parameter.lox` Fixed typo in error message.
|
16
|
+
|
17
|
+
|
18
|
+
## [0.4.06] - 2021-11-01
|
19
|
+
- Code update to cope with `Rley` v.0.8.08 changes
|
20
|
+
|
21
|
+
### Changed
|
22
|
+
- File `AST::AstBuilder` some `reduce_` to cope implementation change of ? quantifier
|
23
|
+
- Method `AST::LoxCallExpr#initialize` call to `Array#flatten` with argList argument
|
24
|
+
- File `loxxy.gemspec` dependency towards `rely` minimal version number is now `0.8.08`
|
25
|
+
- Some spec files updated after `rley` changes of ?, *, + quantifiers
|
26
|
+
|
27
|
+
### Removed
|
28
|
+
- File `front_end/literal.rb`: obsolete
|
29
|
+
|
30
|
+
|
1
31
|
## [0.4.05] - 2021-10-10
|
2
32
|
- Removal of `Literal` class, code restyling to please Rubocop 1.22
|
3
33
|
|
@@ -16,7 +46,7 @@
|
|
16
46
|
- File `grammar.rb` use `match_closest` constraint from Rley to cope with dangling else statement
|
17
47
|
|
18
48
|
## [0.4.02] - 2021-09-10
|
19
|
-
- Fixes in`AST::AstBuilder` class to
|
49
|
+
- Fixes in`AST::AstBuilder` class to cope with changes in Rley 0.8.03
|
20
50
|
|
21
51
|
### Changed
|
22
52
|
- File `loxxy.gemspec` forced dependency to Rley 0.8.03
|
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,7 +399,7 @@ 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
404
|
successors = theChildren[1].map(&:last)
|
405
405
|
successors.unshift(theChildren[0])
|
@@ -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."
|
@@ -5,7 +5,7 @@ require 'rley' # Load the gem
|
|
5
5
|
module Loxxy
|
6
6
|
module FrontEnd
|
7
7
|
########################################
|
8
|
-
# Grammar for Lox language
|
8
|
+
# Grammar for the Lox language
|
9
9
|
# Authoritative grammar at:
|
10
10
|
# https://craftinginterpreters.com/appendix-i.html
|
11
11
|
builder = Rley::grammar_builder do
|
@@ -20,6 +20,15 @@ module Loxxy
|
|
20
20
|
# Delimiters: e.g. parentheses '(', ')'
|
21
21
|
# Separators: e.g. comma
|
22
22
|
class Scanner
|
23
|
+
PATT_BLOCK_COMMENT_BEGIN = /\/\*/.freeze
|
24
|
+
PATT_BLOCK_COMMENT_END = /\*\//.freeze
|
25
|
+
PATT_COMPARISON = /[!=><]=?/.freeze
|
26
|
+
PATT_IDENTIFIER = /[a-zA-Z_][a-zA-Z_0-9]*/.freeze
|
27
|
+
PATT_LINE_COMMENT = /\/\/[^\r\n]*/.freeze
|
28
|
+
PATT_NEWLINE = /(?:\r\n)|\r|\n/.freeze
|
29
|
+
PATT_NUMBER = /\d+(?:\.\d+)?/.freeze
|
30
|
+
PATT_WHITESPACE = /[ \t\f]+/.freeze
|
31
|
+
|
23
32
|
# @return [StringScanner] Low-level input scanner
|
24
33
|
attr_reader(:scanner)
|
25
34
|
|
@@ -31,7 +40,7 @@ module Loxxy
|
|
31
40
|
|
32
41
|
# One or two special character tokens.
|
33
42
|
# These are enumerated in section 4.2.1 Token type
|
34
|
-
|
43
|
+
Lexeme2name = {
|
35
44
|
'(' => 'LEFT_PAREN',
|
36
45
|
')' => 'RIGHT_PAREN',
|
37
46
|
'{' => 'LEFT_BRACE',
|
@@ -77,16 +86,16 @@ module Loxxy
|
|
77
86
|
# Constructor. Initialize a tokenizer for Lox input.
|
78
87
|
# @param source [String] Lox text to tokenize.
|
79
88
|
def initialize(source = nil)
|
80
|
-
|
81
|
-
|
89
|
+
reset
|
90
|
+
input = source || ''
|
91
|
+
@scanner = StringScanner.new(input)
|
82
92
|
end
|
83
93
|
|
84
94
|
# Reset the tokenizer and make the given text, the current input.
|
85
95
|
# @param source [String] Lox text to tokenize.
|
86
96
|
def start_with(source)
|
97
|
+
reset
|
87
98
|
@scanner.string = source
|
88
|
-
@lineno = 1
|
89
|
-
@line_start = 0
|
90
99
|
end
|
91
100
|
|
92
101
|
# Scan the source and return an array of tokens.
|
@@ -99,39 +108,79 @@ module Loxxy
|
|
99
108
|
end
|
100
109
|
tok_sequence << build_token('EOF', nil)
|
101
110
|
|
102
|
-
|
111
|
+
tok_sequence
|
103
112
|
end
|
104
113
|
|
105
114
|
private
|
106
115
|
|
107
|
-
def
|
108
|
-
|
109
|
-
|
110
|
-
|
116
|
+
def reset
|
117
|
+
@state = :default
|
118
|
+
@lineno = 1
|
119
|
+
@line_start = 0
|
120
|
+
end
|
111
121
|
|
122
|
+
def _next_token
|
123
|
+
nesting_level = 0
|
112
124
|
token = nil
|
113
125
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
elsif scanner.scan(/"/) # Start of string detected...
|
121
|
-
token = build_string_token
|
122
|
-
elsif (lexeme = scanner.scan(/\d+(?:\.\d+)?/))
|
123
|
-
token = build_token('NUMBER', lexeme)
|
124
|
-
elsif (lexeme = scanner.scan(/[a-zA-Z_][a-zA-Z_0-9]*/))
|
125
|
-
keyw = @@keywords[lexeme]
|
126
|
-
tok_type = keyw ? keyw.upcase : 'IDENTIFIER'
|
127
|
-
token = build_token(tok_type, lexeme)
|
128
|
-
else # Unknown token
|
129
|
-
col = scanner.pos - @line_start + 1
|
130
|
-
_erroneous = curr_ch.nil? ? '' : scanner.scan(/./)
|
131
|
-
raise ScanError, "Error: [line #{lineno}:#{col}]: Unexpected character."
|
132
|
-
end
|
126
|
+
# Loop until end of input reached or token found
|
127
|
+
until token || scanner.eos?
|
128
|
+
if scanner.skip(PATT_NEWLINE)
|
129
|
+
next_line_scanned
|
130
|
+
next
|
131
|
+
end
|
133
132
|
|
134
|
-
|
133
|
+
case @state
|
134
|
+
when :default
|
135
|
+
next if scanner.skip(PATT_WHITESPACE) # Skip whitespaces
|
136
|
+
|
137
|
+
curr_ch = scanner.peek(1)
|
138
|
+
|
139
|
+
token = if scanner.skip(PATT_LINE_COMMENT)
|
140
|
+
next
|
141
|
+
elsif scanner.skip(PATT_BLOCK_COMMENT_BEGIN)
|
142
|
+
@state = :in_block_comment
|
143
|
+
nesting_level = 1
|
144
|
+
next
|
145
|
+
elsif '(){},.;+-/*'.include? curr_ch
|
146
|
+
# Single delimiter or separator character
|
147
|
+
build_token(Lexeme2name[curr_ch], scanner.getch)
|
148
|
+
elsif (lexeme = scanner.scan(PATT_COMPARISON))
|
149
|
+
# One or two special character tokens
|
150
|
+
build_token(Lexeme2name[lexeme], lexeme)
|
151
|
+
elsif scanner.scan(/"/) # Start of string detected...
|
152
|
+
build_string_token
|
153
|
+
elsif (lexeme = scanner.scan(PATT_NUMBER))
|
154
|
+
build_token('NUMBER', lexeme)
|
155
|
+
elsif (lexeme = scanner.scan(PATT_IDENTIFIER))
|
156
|
+
keyw = @@keywords[lexeme]
|
157
|
+
tok_type = keyw ? keyw.upcase : 'IDENTIFIER'
|
158
|
+
build_token(tok_type, lexeme)
|
159
|
+
else # Unknown token
|
160
|
+
col = scanner.pos - @line_start + 1
|
161
|
+
_erroneous = curr_ch.nil? ? '' : scanner.scan(/./)
|
162
|
+
raise ScanError, "Error: [line #{lineno}:#{col}]: Unexpected character."
|
163
|
+
end
|
164
|
+
|
165
|
+
when :in_block_comment
|
166
|
+
comment_part = scanner.scan_until(/(?:\/\*)|(?:\*\/)|(?:(?:\r\n)|\r|\n)/)
|
167
|
+
unterminated_comment unless comment_part
|
168
|
+
|
169
|
+
case scanner.matched
|
170
|
+
when PATT_NEWLINE
|
171
|
+
next_line_scanned
|
172
|
+
when PATT_BLOCK_COMMENT_END
|
173
|
+
nesting_level -= 1
|
174
|
+
@state = :default if nesting_level.zero?
|
175
|
+
when PATT_BLOCK_COMMENT_BEGIN
|
176
|
+
nesting_level += 1
|
177
|
+
end
|
178
|
+
next
|
179
|
+
end # case
|
180
|
+
end # until
|
181
|
+
|
182
|
+
unterminated_comment unless nesting_level.zero?
|
183
|
+
token
|
135
184
|
end
|
136
185
|
|
137
186
|
def build_token(aSymbolName, aLexeme)
|
@@ -214,56 +263,12 @@ module Loxxy
|
|
214
263
|
Rley::Lexical::Literal.new(lox_string, lexeme, 'STRING', pos)
|
215
264
|
end
|
216
265
|
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
loop do
|
221
|
-
ws_found = scanner.skip(/[ \t\f]+/) ? true : false
|
222
|
-
nl_found = scanner.skip(/(?:\r\n)|\r|\n/)
|
223
|
-
if nl_found
|
224
|
-
ws_found = true
|
225
|
-
next_line
|
226
|
-
end
|
227
|
-
cmt_found = false
|
228
|
-
if scanner.scan(/\/(\/|\*)/)
|
229
|
-
cmt_found = true
|
230
|
-
case scanner.matched
|
231
|
-
when '//'
|
232
|
-
scanner.skip(/[^\r\n]*(?:(?:\r\n)|\r|\n)?/)
|
233
|
-
next_line
|
234
|
-
when '/*'
|
235
|
-
skip_block_comment
|
236
|
-
next
|
237
|
-
end
|
238
|
-
end
|
239
|
-
break unless ws_found || cmt_found
|
240
|
-
end
|
241
|
-
|
242
|
-
scanner.pos
|
243
|
-
end
|
244
|
-
|
245
|
-
def skip_block_comment
|
246
|
-
nesting_level = 1
|
247
|
-
loop do
|
248
|
-
comment_part = scanner.scan_until(/(?:\/\*)|(?:\*\/)|(?:(?:\r\n)|\r|\n)/)
|
249
|
-
unless comment_part
|
250
|
-
msg = "Unterminated '/* ... */' block comment on line #{lineno}"
|
251
|
-
raise ScanError, msg
|
252
|
-
end
|
253
|
-
|
254
|
-
case scanner.matched
|
255
|
-
when /(?:(?:\r\n)|\r|\n)/
|
256
|
-
next_line
|
257
|
-
when '*/'
|
258
|
-
nesting_level -= 1
|
259
|
-
break if nesting_level.zero?
|
260
|
-
when '/*'
|
261
|
-
nesting_level += 1
|
262
|
-
end
|
263
|
-
end
|
266
|
+
def unterminated_comment
|
267
|
+
msg = "Unterminated '/* ... */' block comment on line #{lineno}"
|
268
|
+
raise ScanError, msg
|
264
269
|
end
|
265
270
|
|
266
|
-
def
|
271
|
+
def next_line_scanned
|
267
272
|
@lineno += 1
|
268
273
|
@line_start = scanner.pos
|
269
274
|
end
|
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')
|
@@ -76,9 +76,9 @@ 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
84
|
statement = decls.subnodes[1].subnodes[0]
|
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.08
|
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-04-09 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
|
@@ -170,7 +170,7 @@ require_paths:
|
|
170
170
|
- lib
|
171
171
|
required_ruby_version: !ruby/object:Gem::Requirement
|
172
172
|
requirements:
|
173
|
-
- - "
|
173
|
+
- - ">="
|
174
174
|
- !ruby/object:Gem::Version
|
175
175
|
version: '2.5'
|
176
176
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -179,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
179
179
|
- !ruby/object:Gem::Version
|
180
180
|
version: '0'
|
181
181
|
requirements: []
|
182
|
-
rubygems_version: 3.
|
182
|
+
rubygems_version: 3.3.3
|
183
183
|
signing_key:
|
184
184
|
specification_version: 4
|
185
185
|
summary: An implementation of the Lox programming language.
|