loxxy 0.4.05 → 0.4.08

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 36f3b49ca1158cd6922cb5ece2340f53efec793e5877a96f94aebc0eee34235d
4
- data.tar.gz: ade953da452fbf9ad6552e8dbfb035161c79c2bffcd0d531c4e79cf6d785c51c
3
+ metadata.gz: e7e447625d999f4b95129d7feff1586c6759cb929a8faaa82e3ecc94105d0268
4
+ data.tar.gz: 00a4801454ffd09b2d4e810fd15d0f9b40fea13f46e6d4eed7eba4cab8d35ebe
5
5
  SHA512:
6
- metadata.gz: bc0ff7ac6da9846a5a70ead053ceeee2eb390f778a70932392fcbe10ce70c7e147f11983baee96dc5aed924de492d744c3b6b61c8d03f389a74432a56b3916a5
7
- data.tar.gz: 40e36a53abc6ce121299952ff98f71175198271659f3a7dabf1cbd0f8e79bdc4c76242f47a4707c513f9ca63459bd4495d56de2287136cedb5cadac14ed4fca3
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 cope with changes in Rley 0.8.03
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
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2020-2021 Dimitri Geshef
3
+ Copyright (c) 2020-2022 Dimitri Geshef
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -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, range, tokens, theChildren)
238
- return_first_child(range, tokens, theChildren)
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
- Ast::LoxReturnStmt.new(tokens[1].position, theChildren[1])
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(tokens[1].position, theChildren[1])
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 params_opt RIGHT_PAREN block').as 'function'
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
- if theChildren[2] && theChildren[2].size > 255
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, theChildren[2], theChildren[4])
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]] unless theChildren[1]
402
+ return [theChildren[0]] if theChildren[1].empty?
403
403
 
404
404
  successors = theChildren[1].map(&:last)
405
405
  successors.unshift(theChildren[0])
@@ -244,7 +244,6 @@ module Loxxy
244
244
 
245
245
  # Let's proceed with the visit of subnodes
246
246
  subnodes.each { |a_node| a_node.accept(self) }
247
-
248
247
  broadcast(:after_subnodes, aParentNode, subnodes)
249
248
  end
250
249
 
@@ -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
- @@lexeme2name = {
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
- @scanner = StringScanner.new('')
81
- start_with(source) if source
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
- return tok_sequence
111
+ tok_sequence
103
112
  end
104
113
 
105
114
  private
106
115
 
107
- def _next_token
108
- skip_intertoken_spaces
109
- curr_ch = scanner.peek(1)
110
- return nil if curr_ch.nil? || curr_ch.empty?
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
- if '(){},.;+-/*'.include? curr_ch
115
- # Single delimiter or separator character
116
- token = build_token(@@lexeme2name[curr_ch], scanner.getch)
117
- elsif (lexeme = scanner.scan(/[!=><]=?/))
118
- # One or two special character tokens
119
- token = build_token(@@lexeme2name[lexeme], lexeme)
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
- return token
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
- # Skip non-significant whitespaces and comments.
218
- # Advance the scanner until something significant is found.
219
- def skip_intertoken_spaces
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 next_line
271
+ def next_line_scanned
267
272
  @lineno += 1
268
273
  @line_start = scanner.pos
269
274
  end
data/lib/loxxy/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Loxxy
4
- VERSION = '0.4.05'
4
+ VERSION = '0.4.08'
5
5
  end
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.5'
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.06'
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('declaration_star')
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('declaration_star')
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('declaration_star')
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.05
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: 2021-10-10 00:00:00.000000000 Z
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.06
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.06
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.1.4
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.