ruby_parser 3.13.1 → 3.15.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,9 +6,9 @@ class RubyLexer
6
6
 
7
7
  macro
8
8
 
9
- IDENT /^#{IDENT_CHAR}+/o
9
+ IDENT_CHAR /[a-zA-Z0-9_[:^ascii:]]/
10
10
 
11
- ESC /\\((?>[0-7]{1,3}|x[0-9a-fA-F]{1,2}|M-[^\\]|(C-|c)[^\\]|u[0-9a-fA-F]{1,4}|u\{[0-9a-fA-F]+\}|[^0-7xMCc]))/
11
+ ESC /\\((?>[0-7]{1,3}|x\h{1,2}|M-[^\\]|(C-|c)[^\\]|u\h{1,4}|u\{\h+(?:\s+\h+)*\}|[^0-7xMCc]))/
12
12
  SIMPLE_STRING /((#{ESC}|\#(#{ESC}|[^\{\#\@\$\"\\])|[^\"\\\#])*)/o
13
13
  SSTRING /((\\.|[^\'])*)/
14
14
 
@@ -62,7 +62,7 @@ rule
62
62
  | /\=(?=begin\b)/ { result arg_state, TOKENS[text], text }
63
63
 
64
64
  ruby22_label? /\"#{SIMPLE_STRING}\":/o process_label
65
- /\"(#{SIMPLE_STRING})\"/o { result EXPR_END, :tSTRING, text[1..-2].gsub(ESC) { unescape $1 } }
65
+ /\"(#{SIMPLE_STRING})\"/o process_simple_string
66
66
  /\"/ { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
67
67
 
68
68
  /\@\@?\d/ { rb_compile_error "`#{text}` is not allowed as a variable name" }
@@ -164,13 +164,12 @@ was_label? /\'#{SSTRING}\':?/o process_label_or_string
164
164
  | in_fname? /\$([1-9]\d*)/ process_gvar
165
165
  | /\$([1-9]\d*)/ process_nthref
166
166
  | /\$0/ process_gvar
167
- | /\$[^[:ascii:]]+/ process_gvar
167
+ | /\$#{IDENT_CHAR}+/ process_gvar
168
168
  | /\$\W|\$\z/ process_gvar_oddity
169
- | /\$\w+/ process_gvar
170
169
 
171
170
  /\_/ process_underscore
172
171
 
173
- /#{IDENT}/o process_token
172
+ /#{IDENT_CHAR}+/o process_token
174
173
 
175
174
  /\004|\032|\000|\Z/ { [RubyLexer::EOF, RubyLexer::EOF] }
176
175
 
@@ -1,7 +1,7 @@
1
1
  # encoding: UTF-8
2
2
  #--
3
3
  # This file is automatically generated. Do not modify it.
4
- # Generated by: oedipus_lex version 2.5.0.
4
+ # Generated by: oedipus_lex version 2.5.2.
5
5
  # Source: lib/ruby_lexer.rex
6
6
  #++
7
7
 
@@ -16,8 +16,8 @@ class RubyLexer
16
16
  require 'strscan'
17
17
 
18
18
  # :stopdoc:
19
- IDENT = /^#{IDENT_CHAR}+/o
20
- ESC = /\\((?>[0-7]{1,3}|x[0-9a-fA-F]{1,2}|M-[^\\]|(C-|c)[^\\]|u[0-9a-fA-F]{1,4}|u\{[0-9a-fA-F]+\}|[^0-7xMCc]))/
19
+ IDENT_CHAR = /[a-zA-Z0-9_[:^ascii:]]/
20
+ ESC = /\\((?>[0-7]{1,3}|x\h{1,2}|M-[^\\]|(C-|c)[^\\]|u\h{1,4}|u\{\h+(?:\s+\h+)*\}|[^0-7xMCc]))/
21
21
  SIMPLE_STRING = /((#{ESC}|\#(#{ESC}|[^\{\#\@\$\"\\])|[^\"\\\#])*)/o
22
22
  SSTRING = /((\\.|[^\'])*)/
23
23
  INT_DEC = /[+]?(?:(?:[1-9][\d_]*|0)(?!\.\d)(ri|r|i)?\b|0d[0-9_]+)(ri|r|i)?/i
@@ -160,7 +160,7 @@ class RubyLexer
160
160
  when ruby22_label? && (text = ss.scan(/\"#{SIMPLE_STRING}\":/o)) then
161
161
  process_label text
162
162
  when text = ss.scan(/\"(#{SIMPLE_STRING})\"/o) then
163
- action { result EXPR_END, :tSTRING, text[1..-2].gsub(ESC) { unescape $1 } }
163
+ process_simple_string text
164
164
  when text = ss.scan(/\"/) then
165
165
  action { string STR_DQUOTE; result nil, :tSTRING_BEG, text }
166
166
  when text = ss.scan(/\@\@?\d/) then
@@ -328,16 +328,14 @@ class RubyLexer
328
328
  process_nthref text
329
329
  when text = ss.scan(/\$0/) then
330
330
  process_gvar text
331
- when text = ss.scan(/\$[^[:ascii:]]+/) then
331
+ when text = ss.scan(/\$#{IDENT_CHAR}+/) then
332
332
  process_gvar text
333
333
  when text = ss.scan(/\$\W|\$\z/) then
334
334
  process_gvar_oddity text
335
- when text = ss.scan(/\$\w+/) then
336
- process_gvar text
337
335
  end # group /\$/
338
336
  when text = ss.scan(/\_/) then
339
337
  process_underscore text
340
- when text = ss.scan(/#{IDENT}/o) then
338
+ when text = ss.scan(/#{IDENT_CHAR}+/o) then
341
339
  process_token text
342
340
  when ss.skip(/\004|\032|\000|\Z/) then
343
341
  action { [RubyLexer::EOF, RubyLexer::EOF] }
@@ -11,23 +11,22 @@ class RubyParser
11
11
 
12
12
  attr_accessor :current
13
13
 
14
- class Parser < Racc::Parser
15
- include RubyParserStuff
16
-
17
- def self.inherited x
18
- RubyParser::VERSIONS << x
19
- end
20
-
21
- def self.version= v
22
- @version = v
23
- end
14
+ def self.for_current_ruby
15
+ name = "V#{RUBY_VERSION[/^\d+\.\d+/].delete "."}"
16
+ klass = if const_defined? name then
17
+ const_get name
18
+ else
19
+ latest = VERSIONS.first
20
+ warn "NOTE: RubyParser::#{name} undefined, using #{latest}."
21
+ latest
22
+ end
24
23
 
25
- def self.version
26
- @version ||= Parser > self && self.name[/(?:V|Ruby)(\d+)/, 1].to_i
27
- end
24
+ klass.new
28
25
  end
29
26
 
30
- class SyntaxError < RuntimeError; end
27
+ def self.latest
28
+ VERSIONS.first.new
29
+ end
31
30
 
32
31
  def process s, f = "(string)", t = 10
33
32
  e = nil
@@ -48,22 +47,23 @@ class RubyParser
48
47
  # do nothing
49
48
  end
50
49
 
51
- def self.latest
52
- VERSIONS.first.new
53
- end
50
+ class Parser < Racc::Parser
51
+ include RubyParserStuff
54
52
 
55
- def self.for_current_ruby
56
- name = "V#{RUBY_VERSION[/^\d+\.\d+/].delete "."}"
57
- klass = if const_defined? name then
58
- const_get name
59
- else
60
- latest = VERSIONS.first
61
- warn "NOTE: RubyParser::#{name} undefined, using #{latest}."
62
- latest
63
- end
53
+ def self.inherited x
54
+ RubyParser::VERSIONS << x
55
+ end
64
56
 
65
- klass.new
57
+ def self.version= v
58
+ @version = v
59
+ end
60
+
61
+ def self.version
62
+ @version ||= Parser > self && self.name[/(?:V|Ruby)(\d+)/, 1].to_i
63
+ end
66
64
  end
65
+
66
+ class SyntaxError < RuntimeError; end
67
67
  end
68
68
 
69
69
  ##
@@ -78,10 +78,12 @@ require "ruby23_parser"
78
78
  require "ruby24_parser"
79
79
  require "ruby25_parser"
80
80
  require "ruby26_parser"
81
+ require "ruby27_parser"
81
82
 
82
83
  class RubyParser # HACK
83
84
  VERSIONS.clear # also a HACK caused by racc namespace issues
84
85
 
86
+ class V27 < ::Ruby27Parser; end
85
87
  class V26 < ::Ruby26Parser; end
86
88
  class V25 < ::Ruby25Parser; end
87
89
  class V24 < ::Ruby24Parser; end
@@ -14,6 +14,8 @@ class Ruby24Parser
14
14
  class Ruby25Parser
15
15
  #elif V == 26
16
16
  class Ruby26Parser
17
+ #elif V == 27
18
+ class Ruby27Parser
17
19
  #else
18
20
  fail "version not specified or supported on code generation"
19
21
  #endif
@@ -45,30 +47,30 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
45
47
  tLONELY
46
48
  #endif
47
49
 
48
- prechigh
49
- right tBANG tTILDE tUPLUS
50
- right tPOW
51
- right tUMINUS_NUM tUMINUS
52
- left tSTAR2 tDIVIDE tPERCENT
53
- left tPLUS tMINUS
54
- left tLSHFT tRSHFT
55
- left tAMPER2
56
- left tPIPE tCARET
57
- left tGT tGEQ tLT tLEQ
58
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
59
- left tANDOP
60
- left tOROP
61
- nonassoc tDOT2 tDOT3
62
- right tEH tCOLON
63
- left kRESCUE_MOD
64
- right tEQL tOP_ASGN
65
- nonassoc kDEFINED
66
- right kNOT
67
- left kOR kAND
68
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
69
- nonassoc tLBRACE_ARG
70
- nonassoc tLOWEST
71
50
  preclow
51
+ nonassoc tLOWEST
52
+ nonassoc tLBRACE_ARG
53
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
54
+ left kOR kAND
55
+ right kNOT
56
+ nonassoc kDEFINED
57
+ right tEQL tOP_ASGN
58
+ left kRESCUE_MOD
59
+ right tEH tCOLON
60
+ nonassoc tDOT2 tDOT3
61
+ left tOROP
62
+ left tANDOP
63
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
64
+ left tGT tGEQ tLT tLEQ
65
+ left tPIPE tCARET
66
+ left tAMPER2
67
+ left tLSHFT tRSHFT
68
+ left tPLUS tMINUS
69
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
70
+ right tUMINUS_NUM tUMINUS
71
+ right tPOW
72
+ right tBANG tTILDE tUPLUS
73
+ prechigh
72
74
 
73
75
  rule
74
76
 
@@ -82,7 +84,8 @@ rule
82
84
 
83
85
  top_compstmt: top_stmts opt_terms
84
86
  {
85
- result = val[0]
87
+ stmt, _ = val
88
+ result = stmt
86
89
  }
87
90
 
88
91
  top_stmts: none
@@ -94,14 +97,6 @@ rule
94
97
  | error top_stmt
95
98
 
96
99
  top_stmt: stmt
97
- {
98
- result = val[0]
99
-
100
- # TODO: remove once I have more confidence this is fixed
101
- # result.each_of_type :call_args do |s|
102
- # debug20 666, s, result
103
- # end
104
- }
105
100
  | klBEGIN
106
101
  {
107
102
  if (self.in_def || self.in_single > 0) then
@@ -112,14 +107,19 @@ rule
112
107
  }
113
108
  begin_block
114
109
  {
115
- _, _, block = val
116
- result = block
110
+ (_, lineno), _, iter = val
111
+ iter.line lineno
112
+
113
+ (_, preexe,) = iter
114
+ preexe.line lineno
115
+
116
+ result = iter
117
117
  }
118
118
 
119
- begin_block: tLCURLY top_compstmt tRCURLY
119
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
120
120
  {
121
- _, stmt, _ = val
122
- result = new_iter s(:preexe), 0, stmt
121
+ _, line, stmt, _ = val
122
+ result = new_iter s(:preexe).line(line), 0, stmt
123
123
  }
124
124
 
125
125
  bodystmt: compstmt opt_rescue k_else
@@ -161,34 +161,27 @@ rule
161
161
  stmt_or_begin: stmt
162
162
  | klBEGIN
163
163
  {
164
- if (self.in_def || self.in_single > 0) then
165
- debug20 1
166
- yyerror "BEGIN in method"
167
- end
168
- self.env.extend
169
- }
170
- begin_block
171
- {
172
- _, _, stmt = val
173
- result = stmt
164
+ yyerror "BEGIN is permitted only at toplevel"
174
165
  }
175
166
 
176
167
  stmt: kALIAS fitem
177
168
  {
178
169
  lexer.lex_state = EXPR_FNAME
179
- result = self.lexer.lineno
180
170
  }
181
171
  fitem
182
172
  {
183
- result = s(:alias, val[1], val[3]).line(val[2])
173
+ (_, line), lhs, _, rhs = val
174
+ result = s(:alias, lhs, rhs).line(line).line line
184
175
  }
185
176
  | kALIAS tGVAR tGVAR
186
177
  {
187
- result = s(:valias, val[1].to_sym, val[2].to_sym)
178
+ (_, line), lhs, rhs = val
179
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
188
180
  }
189
181
  | kALIAS tGVAR tBACK_REF
190
182
  {
191
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
183
+ (_, line), lhs, rhs = val
184
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
192
185
  }
193
186
  | kALIAS tGVAR tNTH_REF
194
187
  {
@@ -200,32 +193,41 @@ rule
200
193
  }
201
194
  | stmt kIF_MOD expr_value
202
195
  {
203
- result = new_if val[2], val[0], nil
196
+ t, _, c = val
197
+ result = new_if c, t, nil
204
198
  }
205
199
  | stmt kUNLESS_MOD expr_value
206
200
  {
207
- result = new_if val[2], nil, val[0]
201
+ f, _, c = val
202
+ result = new_if c, nil, f
208
203
  }
209
204
  | stmt kWHILE_MOD expr_value
210
205
  {
211
- result = new_while val[0], val[2], true
206
+ e, _, c = val
207
+ result = new_while e, c, true
212
208
  }
213
209
  | stmt kUNTIL_MOD expr_value
214
210
  {
215
- result = new_until val[0], val[2], true
211
+ e, _, c = val
212
+ result = new_until e, c, true
216
213
  }
217
214
  | stmt kRESCUE_MOD stmt
218
215
  {
219
216
  body, _, resbody = val
220
- result = new_rescue body, new_resbody(s(:array), resbody)
217
+
218
+ resbody = new_resbody s(:array).line(resbody.line), resbody
219
+ result = new_rescue body, resbody
221
220
  }
222
221
  | klEND tLCURLY compstmt tRCURLY
223
222
  {
223
+ (_, line), _, stmt, _ = val
224
+
224
225
  if (self.in_def || self.in_single > 0) then
225
226
  debug20 3
226
227
  yyerror "END in method; use at_exit"
227
228
  end
228
- result = new_iter s(:postexe), 0, val[2]
229
+
230
+ result = new_iter s(:postexe).line(line), 0, stmt
229
231
  }
230
232
  | command_asgn
231
233
  | mlhs tEQL command_call
@@ -234,7 +236,8 @@ rule
234
236
  }
235
237
  | lhs tEQL mrhs
236
238
  {
237
- result = new_assign val[0], s(:svalue, val[2])
239
+ lhs, _, rhs = val
240
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
238
241
  }
239
242
  #if V == 20
240
243
  | mlhs tEQL arg_value
@@ -264,11 +267,12 @@ rule
264
267
  }
265
268
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
266
269
  {
267
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
270
+ result = new_op_asgn1 val
268
271
  }
269
272
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
270
273
  {
271
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
274
+ prim, _, id, opasgn, rhs = val
275
+ result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
272
276
  if val[1] == '&.'
273
277
  result.sexp_type = :safe_op_asgn
274
278
  end
@@ -284,13 +288,15 @@ rule
284
288
  }
285
289
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
286
290
  {
287
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
288
- debug20 4, val, result
291
+ lhs1, _, lhs2, op, rhs = val
292
+
293
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
289
294
  }
290
295
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
291
296
  {
292
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
293
- debug20 5, val, result
297
+ lhs1, _, lhs2, op, rhs = val
298
+
299
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
294
300
  }
295
301
  | backref tOP_ASGN command_rhs
296
302
  {
@@ -305,9 +311,11 @@ rule
305
311
  #if V >= 24
306
312
  | command_call kRESCUE_MOD stmt
307
313
  {
308
- expr, _, resbody = val
314
+ expr, (_, line), resbody = val
315
+
309
316
  expr = value_expr expr
310
- result = new_rescue(expr, new_resbody(s(:array), resbody))
317
+ ary = s(:array).line line
318
+ result = new_rescue(expr, new_resbody(ary, resbody))
311
319
  }
312
320
  #endif
313
321
  | command_asgn
@@ -315,19 +323,26 @@ rule
315
323
  expr: command_call
316
324
  | expr kAND expr
317
325
  {
318
- result = logical_op :and, val[0], val[2]
326
+ lhs, _, rhs = val
327
+ result = logical_op :and, lhs, rhs
319
328
  }
320
329
  | expr kOR expr
321
330
  {
322
- result = logical_op :or, val[0], val[2]
331
+ lhs, _, rhs = val
332
+ result = logical_op :or, lhs, rhs
323
333
  }
324
334
  | kNOT opt_nl expr
325
335
  {
326
- result = s(:call, val[2], :"!")
336
+ (_, line), _, expr = val
337
+ result = new_call(expr, :"!").line line
338
+ # REFACTOR: call_uni_op
327
339
  }
328
340
  | tBANG command_call
329
341
  {
330
- result = s(:call, val[1], :"!")
342
+ _, cmd = val
343
+ result = new_call(cmd, :"!").line cmd.line
344
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
345
+ # REFACTOR: call_uni_op -- see parse26.y
331
346
  }
332
347
  | arg
333
348
 
@@ -354,7 +369,8 @@ rule
354
369
  block_command: block_call
355
370
  | block_call call_op2 operation2 command_args
356
371
  {
357
- result = new_call val[0], val[2].to_sym, val[3]
372
+ blk, _, msg, args = val
373
+ result = new_call(blk, msg.to_sym, args).line blk.line
358
374
  }
359
375
 
360
376
  cmd_brace_block: tLBRACE_ARG
@@ -374,26 +390,32 @@ rule
374
390
 
375
391
  fcall: operation
376
392
  {
377
- result = new_call nil, val[0].to_sym
393
+ msg, = val
394
+ result = new_call(nil, msg.to_sym).line lexer.lineno
378
395
  }
379
396
 
380
397
  command: fcall command_args =tLOWEST
381
398
  {
382
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
399
+ call, args = val
400
+ result = call.concat args.sexp_body
383
401
  }
384
402
  | fcall command_args cmd_brace_block
385
403
  {
386
- result = val[0].concat val[1].sexp_body
387
- if val[2] then
388
- block_dup_check result, val[2]
404
+ call, args, block = val
389
405
 
390
- result, operation = val[2], result
406
+ result = call.concat args.sexp_body
407
+
408
+ if block then
409
+ block_dup_check result, block
410
+
411
+ result, operation = block, result
391
412
  result.insert 1, operation
392
413
  end
393
414
  }
394
415
  | primary_value call_op operation2 command_args =tLOWEST
395
416
  {
396
- result = new_call val[0], val[2].to_sym, val[3], val[1]
417
+ lhs, callop, op, args = val
418
+ result = new_call lhs, op.to_sym, args, callop
397
419
  }
398
420
  | primary_value call_op operation2 command_args cmd_brace_block
399
421
  {
@@ -425,7 +447,9 @@ rule
425
447
  }
426
448
  | kYIELD command_args
427
449
  {
428
- result = new_yield val[1]
450
+ (_, line), args = val
451
+ result = new_yield args
452
+ result.line line # TODO: push to new_yield
429
453
  }
430
454
  | k_return call_args
431
455
  {
@@ -434,8 +458,8 @@ rule
434
458
  }
435
459
  | kBREAK call_args
436
460
  {
437
- line = val[0].last
438
- result = s(:break, ret_args(val[1])).line(line)
461
+ (_, line), args = val
462
+ result = s(:break, ret_args(args)).line line
439
463
  }
440
464
  | kNEXT call_args
441
465
  {
@@ -452,56 +476,79 @@ rule
452
476
  mlhs_inner: mlhs_basic
453
477
  | tLPAREN mlhs_inner rparen
454
478
  {
455
- result = s(:masgn, s(:array, val[1]))
479
+ _, arg, _ = val
480
+ l = arg.line
481
+
482
+ result = s(:masgn, s(:array, arg).line(l)).line l
456
483
  }
457
484
 
458
485
  mlhs_basic: mlhs_head
459
486
  {
460
- result = s(:masgn, val[0])
487
+ head, = val
488
+ result = s(:masgn, head).line head.line
461
489
  }
462
490
  | mlhs_head mlhs_item
463
491
  {
464
- result = s(:masgn, val[0] << val[1].compact)
492
+ lhs, rhs = val
493
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
465
494
  }
466
495
  | mlhs_head tSTAR mlhs_node
467
496
  {
468
- result = s(:masgn, val[0] << s(:splat, val[2]))
497
+ head, _, tail = val
498
+ head << s(:splat, tail).line(tail.line)
499
+ result = s(:masgn, head).line head.line
469
500
  }
470
501
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
471
502
  {
472
503
  ary1, _, splat, _, ary2 = val
473
504
 
474
- result = list_append ary1, s(:splat, splat)
505
+ result = list_append ary1, s(:splat, splat).line(splat.line)
475
506
  result.concat ary2.sexp_body
476
- result = s(:masgn, result)
507
+ result = s(:masgn, result).line result.line
477
508
  }
478
509
  | mlhs_head tSTAR
479
510
  {
480
- result = s(:masgn, val[0] << s(:splat))
511
+ head, _ = val
512
+ l = head.line
513
+ result = s(:masgn, head << s(:splat).line(l)).line l
481
514
  }
482
515
  | mlhs_head tSTAR tCOMMA mlhs_post
483
516
  {
484
- ary = list_append val[0], s(:splat)
485
- ary.concat val[3].sexp_body
486
- result = s(:masgn, ary)
517
+ head, _, _, post = val
518
+ ary = list_append head, s(:splat).line(head.line)
519
+ ary.concat post.sexp_body
520
+ result = s(:masgn, ary).line ary.line
487
521
  }
488
522
  | tSTAR mlhs_node
489
523
  {
490
- result = s(:masgn, s(:array, s(:splat, val[1])))
524
+ _, node = val
525
+ l = node.line
526
+ splat = s(:splat, node).line l
527
+ ary = s(:array, splat).line l
528
+ result = s(:masgn, ary).line l
491
529
  }
492
530
  | tSTAR mlhs_node tCOMMA mlhs_post
493
531
  {
494
- ary = s(:array, s(:splat, val[1]))
495
- ary.concat val[3].sexp_body
496
- result = s(:masgn, ary)
532
+ _, node, _, post = val
533
+
534
+ splat = s(:splat, node).line node.line
535
+ ary = s(:array, splat).line splat.line
536
+ ary.concat post.sexp_body
537
+ result = s(:masgn, ary).line ary.line
497
538
  }
498
539
  | tSTAR
499
540
  {
500
- result = s(:masgn, s(:array, s(:splat)))
541
+ l = lexer.lineno
542
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
501
543
  }
502
544
  | tSTAR tCOMMA mlhs_post
503
545
  {
504
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
546
+ _, _, post = val
547
+ l = post.line
548
+
549
+ splat = s(:splat).line l
550
+ ary = s(:array, splat, *post.sexp_body).line l
551
+ result = s(:masgn, ary).line l
505
552
  }
506
553
 
507
554
  mlhs_item: mlhs_node
@@ -512,7 +559,8 @@ rule
512
559
 
513
560
  mlhs_head: mlhs_item tCOMMA
514
561
  {
515
- result = s(:array, val[0])
562
+ lhs, _ = val
563
+ result = s(:array, lhs).line lhs.line
516
564
  }
517
565
  | mlhs_head mlhs_item tCOMMA
518
566
  {
@@ -521,7 +569,8 @@ rule
521
569
 
522
570
  mlhs_post: mlhs_item
523
571
  {
524
- result = s(:array, val[0])
572
+ item, = val
573
+ result = s(:array, item).line item.line
525
574
  }
526
575
  | mlhs_post tCOMMA mlhs_item
527
576
  {
@@ -546,7 +595,8 @@ rule
546
595
  }
547
596
  | primary_value tCOLON2 tIDENTIFIER
548
597
  {
549
- result = s(:attrasgn, val[0], :"#{val[2]}=")
598
+ recv, _, id = val
599
+ result = new_attrasgn recv, id
550
600
  }
551
601
  | primary_value call_op tCONSTANT
552
602
  {
@@ -559,7 +609,10 @@ rule
559
609
  yyerror "dynamic constant assignment"
560
610
  end
561
611
 
562
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
612
+ expr, _, id = val
613
+ l = expr.line
614
+
615
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
563
616
  }
564
617
  | tCOLON3 tCONSTANT
565
618
  {
@@ -568,7 +621,10 @@ rule
568
621
  yyerror "dynamic constant assignment"
569
622
  end
570
623
 
571
- result = s(:const, nil, s(:colon3, val[1].to_sym))
624
+ _, id = val
625
+ l = lexer.lineno
626
+
627
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
572
628
  }
573
629
  | backref
574
630
  {
@@ -577,24 +633,31 @@ rule
577
633
 
578
634
  lhs: user_variable
579
635
  {
636
+ line = lexer.lineno
580
637
  result = self.assignable val[0]
638
+ result.line = line
581
639
  }
582
640
  | keyword_variable
583
641
  {
642
+ line = lexer.lineno
584
643
  result = self.assignable val[0]
644
+ result.line = line
585
645
  debug20 9, val, result
586
646
  }
587
647
  | primary_value tLBRACK2 opt_call_args rbracket
588
648
  {
589
- result = self.aryset val[0], val[2]
649
+ lhs, _, args, _ = val
650
+ result = self.aryset lhs, args
590
651
  }
591
652
  | primary_value call_op tIDENTIFIER # REFACTOR
592
653
  {
593
- result = new_attrasgn val[0], val[2], val[1]
654
+ lhs, op, id = val
655
+ result = new_attrasgn lhs, id, op
594
656
  }
595
657
  | primary_value tCOLON2 tIDENTIFIER
596
658
  {
597
- result = s(:attrasgn, val[0], :"#{val[2]}=")
659
+ lhs, _, id = val
660
+ result = new_attrasgn lhs, id
598
661
  }
599
662
  | primary_value call_op tCONSTANT # REFACTOR?
600
663
  {
@@ -602,21 +665,27 @@ rule
602
665
  }
603
666
  | primary_value tCOLON2 tCONSTANT
604
667
  {
668
+ expr, _, id = val
669
+
605
670
  if (self.in_def || self.in_single > 0) then
606
671
  debug20 10
607
672
  yyerror "dynamic constant assignment"
608
673
  end
609
674
 
610
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
675
+ l = expr.line
676
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
611
677
  }
612
678
  | tCOLON3 tCONSTANT
613
679
  {
680
+ _, id = val
681
+
614
682
  if (self.in_def || self.in_single > 0) then
615
683
  debug20 11
616
684
  yyerror "dynamic constant assignment"
617
685
  end
618
686
 
619
- result = s(:const, s(:colon3, val[1].to_sym))
687
+ l = lexer.lineno
688
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
620
689
  }
621
690
  | backref
622
691
  {
@@ -631,7 +700,8 @@ rule
631
700
 
632
701
  cpath: tCOLON3 cname
633
702
  {
634
- result = s(:colon3, val[1].to_sym)
703
+ _, name = val
704
+ result = s(:colon3, name.to_sym).line lexer.lineno
635
705
  }
636
706
  | cname
637
707
  {
@@ -639,7 +709,10 @@ rule
639
709
  }
640
710
  | primary_value tCOLON2 cname
641
711
  {
642
- result = s(:colon2, val[0], val[2].to_sym)
712
+ pval, _, name = val
713
+
714
+ result = s(:colon2, pval, name.to_sym)
715
+ result.line pval.line
643
716
  }
644
717
 
645
718
  fname: tIDENTIFIER | tCONSTANT | tFID
@@ -660,7 +733,8 @@ rule
660
733
 
661
734
  fitem: fsym
662
735
  {
663
- result = s(:lit, val[0].to_sym)
736
+ id, = val
737
+ result = s(:lit, id.to_sym).line lexer.lineno
664
738
  }
665
739
  | dsym
666
740
 
@@ -684,6 +758,7 @@ rule
684
758
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
685
759
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
686
760
  #if V >= 20
761
+ # TODO: tUBANG dead?
687
762
  | tUBANG
688
763
  #endif
689
764
 
@@ -707,8 +782,7 @@ rule
707
782
  }
708
783
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
709
784
  {
710
- val[2].sexp_type = :arglist if val[2]
711
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
785
+ result = new_op_asgn1 val
712
786
  }
713
787
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
714
788
  {
@@ -720,7 +794,9 @@ rule
720
794
  }
721
795
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
722
796
  {
723
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
797
+ lhs, _, id, op, rhs = val
798
+
799
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
724
800
  }
725
801
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
726
802
  {
@@ -750,32 +826,34 @@ rule
750
826
  {
751
827
  v1, v2 = val[0], val[2]
752
828
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
753
- result = s(:lit, (v1.last)..(v2.last))
829
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
754
830
  else
755
- result = s(:dot2, v1, v2)
831
+ result = s(:dot2, v1, v2).line v1.line
756
832
  end
757
833
  }
758
834
  | arg tDOT3 arg
759
835
  {
760
836
  v1, v2 = val[0], val[2]
761
837
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
762
- result = s(:lit, (v1.last)...(v2.last))
838
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
763
839
  else
764
- result = s(:dot3, v1, v2)
840
+ result = s(:dot3, v1, v2).line v1.line
765
841
  end
766
842
  }
767
843
  #if V >= 26
768
844
  | arg tDOT2
769
845
  {
770
- v1, v2 = val[0], nil
846
+ v1, _ = val
847
+ v2 = nil
771
848
 
772
- result = s(:dot2, v1, v2)
849
+ result = s(:dot2, v1, v2).line v1.line
773
850
  }
774
851
  | arg tDOT3
775
852
  {
776
- v1, v2 = val[0], nil
853
+ v1, _ = val
854
+ v2 = nil
777
855
 
778
- result = s(:dot3, v1, v2)
856
+ result = s(:dot3, v1, v2).line v1.line
779
857
  }
780
858
  #endif
781
859
  | arg tPLUS arg
@@ -805,14 +883,17 @@ rule
805
883
  #if V == 20
806
884
  | tUMINUS_NUM tINTEGER tPOW arg
807
885
  {
808
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
886
+ lit = s(:lit, val[1]).line lexer.lineno
887
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
809
888
  }
810
889
  | tUMINUS_NUM tFLOAT tPOW arg
811
890
  #else
812
891
  | tUMINUS_NUM simple_numeric tPOW arg
813
892
  #endif
814
893
  {
815
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
894
+ lit = s(:lit, val[1]).line lexer.lineno
895
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
896
+
816
897
  #if V == 20
817
898
  ## TODO: why is this 2.0 only?
818
899
  debug20 12, val, result
@@ -857,15 +938,19 @@ rule
857
938
  }
858
939
  | arg tMATCH arg
859
940
  {
860
- result = new_match val[0], val[2]
941
+ lhs, _, rhs = val
942
+ result = new_match lhs, rhs
861
943
  }
862
944
  | arg tNMATCH arg
863
945
  {
864
- result = s(:not, new_match(val[0], val[2]))
946
+ lhs, _, rhs = val
947
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
865
948
  }
866
949
  | tBANG arg
867
950
  {
868
- result = new_call val[1], :"!"
951
+ _, arg = val
952
+ result = new_call arg, :"!"
953
+ result.line arg.line
869
954
  }
870
955
  | tTILDE arg
871
956
  {
@@ -893,11 +978,13 @@ rule
893
978
  }
894
979
  | kDEFINED opt_nl arg
895
980
  {
896
- result = s(:defined, val[2])
981
+ (_, line), _, arg = val
982
+ result = s(:defined, arg).line line
897
983
  }
898
984
  | arg tEH arg opt_nl tCOLON arg
899
985
  {
900
- result = s(:if, val[0], val[2], val[5])
986
+ c, _, t, _, _, f = val
987
+ result = s(:if, c, t, f).line c.line
901
988
  }
902
989
  | primary
903
990
 
@@ -940,28 +1027,25 @@ rule
940
1027
  arg_rhs: arg =tOP_ASGN
941
1028
  | arg kRESCUE_MOD arg
942
1029
  {
943
- body, _, resbody = val
1030
+ body, (_, line), resbody = val
944
1031
  body = value_expr body
945
1032
  resbody = remove_begin resbody
946
- result = new_rescue(body, new_resbody(s(:array), resbody))
1033
+
1034
+ ary = s(:array).line line
1035
+ result = new_rescue(body, new_resbody(ary, resbody))
947
1036
  }
948
1037
 
949
1038
  paren_args: tLPAREN2 opt_call_args rparen
950
1039
  {
951
- result = val[1]
1040
+ _, args, _ = val
1041
+ result = args
952
1042
  }
953
1043
 
954
1044
  opt_paren_args: none
955
1045
  | paren_args
956
1046
 
957
1047
  opt_call_args: none
958
- {
959
- result = val[0]
960
- }
961
1048
  | call_args
962
- {
963
- result = val[0]
964
- }
965
1049
  | args tCOMMA
966
1050
  {
967
1051
  result = args val
@@ -983,17 +1067,14 @@ rule
983
1067
  | args opt_block_arg
984
1068
  {
985
1069
  result = call_args val
986
- result = self.arg_blk_pass val[0], val[1]
987
1070
  }
988
1071
  | assocs opt_block_arg
989
1072
  {
990
- result = call_args [array_to_hash(val[0])]
991
- result = self.arg_blk_pass result, val[1]
1073
+ result = call_args [array_to_hash(val[0]), val[1]]
992
1074
  }
993
1075
  | args tCOMMA assocs opt_block_arg
994
1076
  {
995
- result = call_args [val[0], array_to_hash(val[2])]
996
- result = self.arg_blk_pass result, val[3]
1077
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
997
1078
  }
998
1079
  | block_arg
999
1080
  {
@@ -1001,17 +1082,45 @@ rule
1001
1082
  }
1002
1083
 
1003
1084
  command_args: {
1004
- result = lexer.cmdarg.store true
1085
+ # parse26.y line 2200
1086
+
1087
+ # If call_args starts with a open paren '(' or
1088
+ # '[', look-ahead reading of the letters calls
1089
+ # CMDARG_PUSH(0), but the push must be done
1090
+ # after CMDARG_PUSH(1). So this code makes them
1091
+ # consistent by first cancelling the premature
1092
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1093
+ # finally redoing CMDARG_PUSH(0).
1094
+
1095
+ result = yychar = self.last_token_type.first
1096
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1097
+ lexer.cmdarg.pop if lookahead
1098
+ lexer.cmdarg.push true
1099
+ lexer.cmdarg.push false if lookahead
1005
1100
  }
1006
1101
  call_args
1007
1102
  {
1008
- lexer.cmdarg.restore val[0]
1009
- result = val[1]
1103
+ yychar, args = val
1104
+
1105
+ # call_args can be followed by tLBRACE_ARG (that
1106
+ # does CMDARG_PUSH(0) in the lexer) but the push
1107
+ # must be done after CMDARG_POP() in the parser.
1108
+ # So this code does CMDARG_POP() to pop 0 pushed
1109
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1110
+ # by command_args, and CMDARG_PUSH(0) to restore
1111
+ # back the flag set by tLBRACE_ARG.
1112
+
1113
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1114
+ lexer.cmdarg.pop if lookahead
1115
+ lexer.cmdarg.pop
1116
+ lexer.cmdarg.push false if lookahead
1117
+ result = args
1010
1118
  }
1011
1119
 
1012
1120
  block_arg: tAMPER arg_value
1013
1121
  {
1014
- result = s(:block_pass, val[1])
1122
+ _, arg = val
1123
+ result = s(:block_pass, arg).line arg.line
1015
1124
  }
1016
1125
 
1017
1126
  opt_block_arg: tCOMMA block_arg
@@ -1022,19 +1131,27 @@ rule
1022
1131
 
1023
1132
  args: arg_value
1024
1133
  {
1025
- result = s(:array, val[0])
1134
+ arg, = val
1135
+ lineno = arg.line || lexer.lineno # HACK
1136
+
1137
+ result = s(:array, arg).line lineno
1026
1138
  }
1027
1139
  | tSTAR arg_value
1028
1140
  {
1029
- result = s(:array, s(:splat, val[1]))
1141
+ _, arg = val
1142
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1030
1143
  }
1031
1144
  | args tCOMMA arg_value
1032
1145
  {
1033
- result = self.list_append val[0], val[2]
1146
+ args, _, id = val
1147
+ result = self.list_append args, id
1034
1148
  }
1035
1149
  | args tCOMMA tSTAR arg_value
1036
1150
  {
1037
- result = self.list_append val[0], s(:splat, val[3])
1151
+ # TODO: the line number from tSTAR has been dropped
1152
+ args, _, _, id = val
1153
+ line = lexer.lineno
1154
+ result = self.list_append args, s(:splat, id).line(line)
1038
1155
  }
1039
1156
 
1040
1157
  #if V >= 21
@@ -1054,11 +1171,14 @@ rule
1054
1171
  }
1055
1172
  | args tCOMMA tSTAR arg_value
1056
1173
  {
1057
- result = self.arg_concat val[0], val[3]
1174
+ # TODO: make all tXXXX terminals include lexer.lineno
1175
+ arg, _, _, splat = val
1176
+ result = self.arg_concat arg, splat
1058
1177
  }
1059
1178
  | tSTAR arg_value
1060
1179
  {
1061
- result = s(:splat, val[1])
1180
+ _, arg = val
1181
+ result = s(:splat, arg).line arg.line
1062
1182
  }
1063
1183
 
1064
1184
  primary: literal
@@ -1073,65 +1193,65 @@ rule
1073
1193
  | backref
1074
1194
  | tFID
1075
1195
  {
1076
- result = new_call nil, val[0].to_sym
1196
+ msg, = val
1197
+ result = new_call nil, msg.to_sym
1077
1198
  }
1078
1199
  | k_begin
1079
1200
  {
1201
+ lexer.cmdarg.push false
1080
1202
  result = self.lexer.lineno
1081
- # TODO:
1082
- # $<val>1 = cmdarg_stack;
1083
- # CMDARG_SET(0);
1084
1203
  }
1085
1204
  bodystmt k_end
1086
1205
  {
1087
- # TODO: CMDARG_SET($<val>1);
1088
- unless val[2] then
1089
- result = s(:nil)
1090
- else
1091
- result = s(:begin, val[2])
1092
- end
1093
-
1094
- result.line = val[1]
1206
+ lexer.cmdarg.pop
1207
+ result = new_begin val
1095
1208
  }
1096
- | tLPAREN_ARG rparen
1209
+ | tLPAREN_ARG
1097
1210
  {
1098
- # TODO: lex_state = EXPR_ENDARG in between
1099
- debug20 13, val, result
1211
+ lexer.lex_state = EXPR_ENDARG
1212
+ result = lexer.lineno
1100
1213
  }
1101
- | tLPAREN_ARG
1214
+ rparen
1102
1215
  {
1103
- result = lexer.cmdarg.store false
1104
- # result = self.lexer.cmdarg.stack.dup
1105
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1216
+ _, line, _ = val
1217
+ result = s(:begin).line line
1106
1218
  }
1219
+ | tLPAREN_ARG
1107
1220
  stmt
1108
1221
  {
1109
1222
  lexer.lex_state = EXPR_ENDARG
1110
1223
  }
1111
1224
  rparen
1112
1225
  {
1113
- _, cmdarg, stmt, _, _, = val
1114
- warning "(...) interpreted as grouped expression"
1115
- lexer.cmdarg.restore cmdarg
1226
+ _, stmt, _, _, = val
1227
+ # warning "(...) interpreted as grouped expression"
1116
1228
  result = stmt
1117
1229
  }
1118
1230
  | tLPAREN compstmt tRPAREN
1119
1231
  {
1120
- result = val[1] || s(:nil)
1232
+ _, stmt, _ = val
1233
+ result = stmt
1234
+ result ||= s(:nil).line lexer.lineno
1121
1235
  result.paren = true
1122
1236
  }
1123
1237
  | primary_value tCOLON2 tCONSTANT
1124
1238
  {
1125
- result = s(:colon2, val[0], val[2].to_sym)
1239
+ expr, _, id = val
1240
+
1241
+ result = s(:colon2, expr, id.to_sym).line expr.line
1126
1242
  }
1127
1243
  | tCOLON3 tCONSTANT
1128
1244
  {
1129
- result = s(:colon3, val[1].to_sym)
1245
+ _, id = val
1246
+
1247
+ result = s(:colon3, id.to_sym).line lexer.lineno
1130
1248
  }
1131
- | tLBRACK aref_args tRBRACK
1249
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1132
1250
  {
1133
- result = val[1] || s(:array)
1251
+ _, line, args, _ = val
1252
+ result = args || s(:array)
1134
1253
  result.sexp_type = :array # aref_args is :args
1254
+ result.line line
1135
1255
  }
1136
1256
  | tLBRACE
1137
1257
  {
@@ -1143,7 +1263,8 @@ rule
1143
1263
  }
1144
1264
  | k_return
1145
1265
  {
1146
- result = s(:return)
1266
+ (_, line), = val
1267
+ result = s(:return).line line
1147
1268
  }
1148
1269
  | kYIELD tLPAREN2 call_args rparen
1149
1270
  {
@@ -1159,11 +1280,14 @@ rule
1159
1280
  }
1160
1281
  | kDEFINED opt_nl tLPAREN2 expr rparen
1161
1282
  {
1162
- result = s(:defined, val[3])
1283
+ (_, line), _, _, arg, _ = val
1284
+
1285
+ result = s(:defined, arg).line line
1163
1286
  }
1164
1287
  | kNOT tLPAREN2 expr rparen
1165
1288
  {
1166
- result = s(:call, val[2], :"!")
1289
+ _, _, lhs, _ = val
1290
+ result = new_call lhs, :"!"
1167
1291
  }
1168
1292
  | kNOT tLPAREN2 rparen
1169
1293
  {
@@ -1171,11 +1295,11 @@ rule
1171
1295
  }
1172
1296
  | fcall brace_block
1173
1297
  {
1174
- oper, iter = val[0], val[1]
1175
- call = oper # FIX
1298
+ call, iter = val
1299
+
1176
1300
  iter.insert 1, call
1177
1301
  result = iter
1178
- call.line = iter.line
1302
+ # FIX: probably not: call.line = iter.line
1179
1303
  }
1180
1304
  | method_call
1181
1305
  | method_call brace_block
@@ -1283,66 +1407,82 @@ rule
1283
1407
  }
1284
1408
  | k_def fname
1285
1409
  {
1286
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1410
+ result = self.in_def
1287
1411
 
1288
- self.comments.push self.lexer.comments
1289
- self.in_def = true
1412
+ self.in_def = true # group = local_push
1290
1413
  self.env.extend
1291
- # TODO: local->cmdargs = cmdarg_stack;
1292
- # TODO: port local_push_gen and local_pop_gen
1293
- lexer.cmdarg.stack.replace [false]
1414
+ lexer.cmdarg.push false
1415
+ lexer.cond.push false
1416
+
1417
+ self.comments.push self.lexer.comments
1294
1418
  }
1295
- f_arglist bodystmt k_end
1419
+ f_arglist bodystmt { result = lexer.lineno } k_end
1296
1420
  {
1297
- in_def, cmdarg = val[2]
1421
+ in_def = val[2]
1298
1422
 
1299
1423
  result = new_defn val
1300
1424
 
1301
- lexer.cmdarg.stack.replace cmdarg
1425
+ lexer.cond.pop # group = local_pop
1426
+ lexer.cmdarg.pop
1302
1427
  self.env.unextend
1303
1428
  self.in_def = in_def
1429
+
1304
1430
  self.lexer.comments # we don't care about comments in the body
1305
1431
  }
1306
1432
  | k_def singleton dot_or_colon
1307
1433
  {
1308
- self.comments.push self.lexer.comments
1309
1434
  lexer.lex_state = EXPR_FNAME
1310
1435
  }
1311
1436
  fname
1312
1437
  {
1313
- self.in_single += 1
1438
+ result = [self.in_def, lexer.lineno]
1439
+
1440
+ self.in_single += 1 # TODO: remove?
1441
+
1442
+ self.in_def = true # local_push
1314
1443
  self.env.extend
1315
- lexer.lex_state = EXPR_ENDFN # force for args
1316
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1317
- lexer.cmdarg.stack.replace [false]
1444
+ lexer.cmdarg.push false
1445
+ lexer.cond.push false
1446
+
1447
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1448
+ self.comments.push self.lexer.comments
1318
1449
  }
1319
1450
  f_arglist bodystmt k_end
1320
1451
  {
1321
- line, cmdarg = val[5]
1322
- result = new_defs val
1323
- result[3].line line
1452
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1324
1453
 
1325
- lexer.cmdarg.stack.replace cmdarg
1454
+ result = new_defs val
1326
1455
 
1456
+ lexer.cond.pop # group = local_pop
1457
+ lexer.cmdarg.pop
1327
1458
  self.env.unextend
1459
+ self.in_def = in_def
1460
+
1328
1461
  self.in_single -= 1
1462
+
1463
+ # TODO: restore cur_arg ? what's cur_arg?
1464
+
1329
1465
  self.lexer.comments # we don't care about comments in the body
1330
1466
  }
1331
1467
  | kBREAK
1332
1468
  {
1333
- result = s(:break)
1469
+ (_, line), = val
1470
+ result = s(:break).line line
1334
1471
  }
1335
1472
  | kNEXT
1336
1473
  {
1337
- result = s(:next)
1474
+ (_, line), = val
1475
+ result = s(:next).line line
1338
1476
  }
1339
1477
  | kREDO
1340
1478
  {
1341
- result = s(:redo)
1479
+ (_, line), = val
1480
+ result = s(:redo).line line
1342
1481
  }
1343
1482
  | kRETRY
1344
1483
  {
1345
- result = s(:retry)
1484
+ (_, line), = val
1485
+ result = s(:retry).line line
1346
1486
  }
1347
1487
 
1348
1488
  primary_value: primary
@@ -1381,7 +1521,9 @@ rule
1381
1521
  if_tail: opt_else
1382
1522
  | k_elsif expr_value then compstmt if_tail
1383
1523
  {
1384
- result = s(:if, val[1], val[3], val[4])
1524
+ (_, line), c, _, t, rest = val
1525
+
1526
+ result = s(:if, c, t, rest).line line
1385
1527
  }
1386
1528
 
1387
1529
  opt_else: none
@@ -1404,7 +1546,9 @@ rule
1404
1546
 
1405
1547
  f_marg_list: f_marg
1406
1548
  {
1407
- result = s(:array, val[0])
1549
+ sym, = val
1550
+
1551
+ result = s(:array, sym).line lexer.lineno
1408
1552
  }
1409
1553
  | f_marg_list tCOMMA f_marg
1410
1554
  {
@@ -1478,7 +1622,9 @@ rule
1478
1622
  }
1479
1623
  | f_block_arg
1480
1624
  {
1481
- result = call_args val
1625
+ line = lexer.lineno
1626
+ result = call_args val # TODO: push line down
1627
+ result.line line
1482
1628
  }
1483
1629
 
1484
1630
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1509,7 +1655,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1509
1655
  }
1510
1656
  | f_arg tCOMMA
1511
1657
  {
1512
- result = args val
1658
+ result = args(val) << nil
1513
1659
  }
1514
1660
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1515
1661
  {
@@ -1561,7 +1707,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1561
1707
  }
1562
1708
  | tOROP
1563
1709
  {
1564
- result = s(:args)
1710
+ result = s(:args).line lexer.lineno
1565
1711
  }
1566
1712
  | tPIPE block_param opt_bv_decl tPIPE
1567
1713
  {
@@ -1586,34 +1732,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1586
1732
 
1587
1733
  bvar: tIDENTIFIER
1588
1734
  {
1589
- result = s(:shadow, val[0].to_sym)
1735
+ id, = val
1736
+ line = lexer.lineno
1737
+ result = s(:shadow, id.to_sym).line line
1590
1738
  }
1591
1739
  | f_bad_arg
1592
1740
 
1593
1741
  lambda: {
1594
1742
  self.env.extend :dynamic
1595
- result = self.lexer.lineno
1596
-
1597
- result = lexer.lpar_beg
1743
+ result = [lexer.lineno, lexer.lpar_beg]
1598
1744
  lexer.paren_nest += 1
1599
1745
  lexer.lpar_beg = lexer.paren_nest
1600
1746
  }
1601
1747
  f_larglist
1602
1748
  {
1603
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1749
+ lexer.cmdarg.push false
1604
1750
  }
1605
1751
  lambda_body
1606
1752
  {
1607
- lpar, args, (cmdarg, lineno), body = val
1753
+ (line, lpar), args, _cmdarg, body = val
1608
1754
  lexer.lpar_beg = lpar
1609
1755
 
1610
- lexer.cmdarg.restore cmdarg
1611
- lexer.cmdarg.lexpop
1756
+ lexer.cmdarg.pop
1612
1757
 
1613
- call = new_call nil, :lambda
1758
+ call = s(:lambda).line line
1614
1759
  result = new_iter call, args, body
1615
- result.line = lineno
1616
- self.env.unextend
1760
+ result.line = line
1761
+ self.env.unextend # TODO: dynapush & dynapop
1617
1762
  }
1618
1763
 
1619
1764
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1637,8 +1782,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1637
1782
 
1638
1783
  do_block: k_do_block do_body kEND
1639
1784
  {
1640
- # TODO: maybe fix lineno to kDO's lineno?
1641
- result = val[1]
1785
+ (_, line), iter, _ = val
1786
+ result = iter.line line
1642
1787
  }
1643
1788
 
1644
1789
  block_call: command do_block
@@ -1652,8 +1797,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1652
1797
 
1653
1798
  val = invert_block_call val if inverted? val
1654
1799
 
1655
- result = val[1]
1656
- result.insert 1, val[0]
1800
+ cmd, blk = val
1801
+
1802
+ result = blk
1803
+ result.insert 1, cmd
1657
1804
  }
1658
1805
  | block_call call_op2 operation2 opt_paren_args
1659
1806
  {
@@ -1684,8 +1831,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1684
1831
  }
1685
1832
  paren_args
1686
1833
  {
1687
- args = self.call_args val[2..-1]
1688
- result = val[0].concat args.sexp_body
1834
+ call, lineno, args = val
1835
+
1836
+ result = call.concat args.sexp_body if args
1837
+ result.line lineno
1689
1838
  }
1690
1839
  | primary_value call_op operation2 opt_paren_args
1691
1840
  {
@@ -1713,7 +1862,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1713
1862
  }
1714
1863
  | kSUPER
1715
1864
  {
1716
- result = s(:zsuper)
1865
+ result = s(:zsuper).line lexer.lineno
1717
1866
  }
1718
1867
  | primary_value tLBRACK2 opt_call_args rbracket
1719
1868
  {
@@ -1762,7 +1911,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1762
1911
  }
1763
1912
 
1764
1913
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1765
- { result = lexer.cmdarg.store(false) }
1914
+ { lexer.cmdarg.push false }
1766
1915
  opt_block_param
1767
1916
  #if V >= 25
1768
1917
  bodystmt
@@ -1770,11 +1919,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1770
1919
  compstmt
1771
1920
  #endif
1772
1921
  {
1773
- line, cmdarg, param, cmpstmt = val
1922
+ line, _cmdarg, param, cmpstmt = val
1774
1923
 
1775
1924
  result = new_do_body param, cmpstmt, line
1925
+ lexer.cmdarg.pop
1776
1926
  self.env.unextend
1777
- lexer.cmdarg.restore cmdarg
1778
1927
  }
1779
1928
 
1780
1929
  case_body: k_when
@@ -1795,7 +1944,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1795
1944
  (_, line), klasses, var, _, body, rest = val
1796
1945
 
1797
1946
  klasses ||= s(:array)
1798
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1947
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1799
1948
  klasses.line line
1800
1949
 
1801
1950
  result = new_resbody(klasses, body)
@@ -1808,7 +1957,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1808
1957
 
1809
1958
  exc_list: arg_value
1810
1959
  {
1811
- result = s(:array, val[0])
1960
+ arg, = val
1961
+ result = s(:array, arg).line arg.line
1812
1962
  }
1813
1963
  | mrhs
1814
1964
  | none
@@ -1821,26 +1971,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1821
1971
 
1822
1972
  opt_ensure: k_ensure compstmt
1823
1973
  {
1824
- _, body = val
1974
+ (_, line), body = val
1825
1975
 
1826
- result = body || s(:nil)
1976
+ result = body || s(:nil).line(line)
1827
1977
  }
1828
1978
  | none
1829
1979
 
1830
1980
  literal: numeric
1831
1981
  {
1982
+ line = lexer.lineno
1832
1983
  result = s(:lit, val[0])
1984
+ result.line = line
1833
1985
  }
1834
1986
  | symbol
1835
1987
  {
1988
+ line = lexer.lineno
1836
1989
  result = s(:lit, val[0])
1990
+ result.line = line
1837
1991
  }
1838
1992
  | dsym
1839
1993
 
1840
1994
  strings: string
1841
1995
  {
1842
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1843
- result = val[0]
1996
+ str, = val
1997
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1998
+ result = str
1844
1999
  }
1845
2000
 
1846
2001
  string: tCHAR
@@ -1855,7 +2010,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1855
2010
 
1856
2011
  string1: tSTRING_BEG string_contents tSTRING_END
1857
2012
  {
1858
- result = val[1]
2013
+ _, str, (_, func) = val
2014
+
2015
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2016
+
2017
+ result = str
1859
2018
  }
1860
2019
  | tSTRING
1861
2020
  {
@@ -1864,7 +2023,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1864
2023
 
1865
2024
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1866
2025
  {
1867
- result = new_xstring val[1]
2026
+ result = new_xstring val
2027
+ # TODO: dedent?!?! SERIOUSLY?!?
1868
2028
  }
1869
2029
 
1870
2030
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1874,7 +2034,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1874
2034
 
1875
2035
  words: tWORDS_BEG tSPACE tSTRING_END
1876
2036
  {
1877
- result = s(:array)
2037
+ result = s(:array).line lexer.lineno
1878
2038
  }
1879
2039
  | tWORDS_BEG word_list tSTRING_END
1880
2040
  {
@@ -1898,25 +2058,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1898
2058
 
1899
2059
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1900
2060
  {
1901
- result = s(:array)
2061
+ result = s(:array).line lexer.lineno
1902
2062
  }
1903
- | tSYMBOLS_BEG symbol_list tSTRING_END
2063
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1904
2064
  {
1905
- result = val[1]
2065
+ _, line, list, _, = val
2066
+ list.line = line
2067
+ result = list
1906
2068
  }
1907
2069
 
1908
2070
  symbol_list: none
1909
2071
  {
1910
- result = new_symbol_list
2072
+ result = new_symbol_list.line lexer.lineno
1911
2073
  }
1912
2074
  | symbol_list word tSPACE
1913
2075
  {
1914
- result = val[0].dup << new_symbol_list_entry(val)
2076
+ list, * = val
2077
+ result = list.dup << new_symbol_list_entry(val)
1915
2078
  }
1916
2079
 
1917
2080
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1918
2081
  {
1919
- result = s(:array)
2082
+ result = s(:array).line lexer.lineno
1920
2083
  }
1921
2084
  | tQWORDS_BEG qword_list tSTRING_END
1922
2085
  {
@@ -1925,7 +2088,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1925
2088
 
1926
2089
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1927
2090
  {
1928
- result = s(:array)
2091
+ result = s(:array).line lexer.lineno # FIX
1929
2092
  }
1930
2093
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1931
2094
  {
@@ -1952,11 +2115,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1952
2115
 
1953
2116
  string_contents: none
1954
2117
  {
1955
- result = s(:str, "")
2118
+ result = s(:str, "").line lexer.lineno
1956
2119
  }
1957
2120
  | string_contents string_content
1958
2121
  {
1959
- result = literal_concat(val[0], val[1])
2122
+ v1, v2 = val
2123
+ result = literal_concat v1, v2
1960
2124
  }
1961
2125
 
1962
2126
  xstring_contents: none
@@ -1965,7 +2129,8 @@ xstring_contents: none
1965
2129
  }
1966
2130
  | xstring_contents string_content
1967
2131
  {
1968
- result = literal_concat(val[0], val[1])
2132
+ v1, v2 = val
2133
+ result = literal_concat v1, v2
1969
2134
  }
1970
2135
 
1971
2136
  regexp_contents: none
@@ -1974,7 +2139,8 @@ regexp_contents: none
1974
2139
  }
1975
2140
  | regexp_contents string_content
1976
2141
  {
1977
- result = literal_concat(val[0], val[1])
2142
+ v1, v2 = val
2143
+ result = literal_concat v1, v2
1978
2144
  }
1979
2145
 
1980
2146
  string_content: tSTRING_CONTENT
@@ -1990,19 +2156,22 @@ regexp_contents: none
1990
2156
  }
1991
2157
  string_dvar
1992
2158
  {
1993
- lexer.lex_strterm = val[1]
1994
- result = s(:evstr, val[2])
2159
+ _, strterm, str = val
2160
+ lexer.lex_strterm = strterm
2161
+ result = s(:evstr, str).line str.line
1995
2162
  }
1996
2163
  | tSTRING_DBEG
1997
2164
  {
1998
2165
  result = [lexer.lex_strterm,
1999
2166
  lexer.brace_nest,
2000
2167
  lexer.string_nest, # TODO: remove
2001
- lexer.cond.store,
2002
- lexer.cmdarg.store,
2003
2168
  lexer.lex_state,
2169
+ lexer.lineno,
2004
2170
  ]
2005
2171
 
2172
+ lexer.cmdarg.push false
2173
+ lexer.cond.push false
2174
+
2006
2175
  lexer.lex_strterm = nil
2007
2176
  lexer.brace_nest = 0
2008
2177
  lexer.string_nest = 0
@@ -2014,14 +2183,15 @@ regexp_contents: none
2014
2183
  {
2015
2184
  _, memo, stmt, _ = val
2016
2185
 
2017
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2186
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2187
+ # TODO: heredoc_indent
2018
2188
 
2019
2189
  lexer.lex_strterm = lex_strterm
2020
2190
  lexer.brace_nest = brace_nest
2021
2191
  lexer.string_nest = string_nest
2022
2192
 
2023
- lexer.cond.restore oldcond
2024
- lexer.cmdarg.restore oldcmdarg
2193
+ lexer.cmdarg.pop
2194
+ lexer.cond.pop
2025
2195
 
2026
2196
  lexer.lex_state = oldlex_state
2027
2197
 
@@ -2031,19 +2201,19 @@ regexp_contents: none
2031
2201
  when :str, :dstr, :evstr then
2032
2202
  result = stmt
2033
2203
  else
2034
- result = s(:evstr, stmt)
2204
+ result = s(:evstr, stmt).line line
2035
2205
  end
2036
2206
  when nil then
2037
- result = s(:evstr)
2207
+ result = s(:evstr).line line
2038
2208
  else
2039
2209
  debug20 25
2040
2210
  raise "unknown string body: #{stmt.inspect}"
2041
2211
  end
2042
2212
  }
2043
2213
 
2044
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
2045
- | tIVAR { result = s(:ivar, val[0].to_sym) }
2046
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2214
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2215
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2216
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2047
2217
  | backref
2048
2218
 
2049
2219
  symbol: tSYMBEG sym
@@ -2060,18 +2230,19 @@ regexp_contents: none
2060
2230
 
2061
2231
  dsym: tSYMBEG xstring_contents tSTRING_END
2062
2232
  {
2233
+ _, result, _ = val
2234
+
2063
2235
  lexer.lex_state = EXPR_END
2064
- result = val[1]
2065
2236
 
2066
- result ||= s(:str, "")
2237
+ result ||= s(:str, "").line lexer.lineno
2067
2238
 
2068
2239
  case result.sexp_type
2069
2240
  when :dstr then
2070
2241
  result.sexp_type = :dsym
2071
2242
  when :str then
2072
- result = s(:lit, result.last.to_sym)
2243
+ result = s(:lit, result.last.to_sym).line result.line
2073
2244
  when :evstr then
2074
- result = s(:dsym, "", result)
2245
+ result = s(:dsym, "", result).line result.line
2075
2246
  else
2076
2247
  debug20 26, val, result
2077
2248
  end
@@ -2108,19 +2279,20 @@ regexp_contents: none
2108
2279
  | tCONSTANT
2109
2280
  | tCVAR
2110
2281
 
2111
- keyword_variable: kNIL { result = s(:nil) }
2112
- | kSELF { result = s(:self) }
2113
- | kTRUE { result = s(:true) }
2114
- | kFALSE { result = s(:false) }
2115
- | k__FILE__ { result = s(:str, self.file) }
2116
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2282
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2283
+ | kSELF { result = s(:self).line lexer.lineno }
2284
+ | kTRUE { result = s(:true).line lexer.lineno }
2285
+ | kFALSE { result = s(:false).line lexer.lineno }
2286
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2287
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2117
2288
  | k__ENCODING__
2118
2289
  {
2290
+ l = lexer.lineno
2119
2291
  result =
2120
2292
  if defined? Encoding then
2121
- s(:colon2, s(:const, :Encoding), :UTF_8)
2293
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2122
2294
  else
2123
- s(:str, "Unsupported!")
2295
+ s(:str, "Unsupported!").line l
2124
2296
  end
2125
2297
  }
2126
2298
 
@@ -2145,8 +2317,8 @@ keyword_variable: kNIL { result = s(:nil) }
2145
2317
  debug20 29, val, result
2146
2318
  }
2147
2319
 
2148
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2149
- | tBACK_REF { result = s(:back_ref, val[0]) }
2320
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2321
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2150
2322
 
2151
2323
  superclass: tLT
2152
2324
  {
@@ -2311,12 +2483,13 @@ keyword_variable: kNIL { result = s(:nil) }
2311
2483
 
2312
2484
  f_arg: f_arg_item
2313
2485
  {
2314
- case val[0]
2486
+ arg, = val
2487
+
2488
+ case arg
2315
2489
  when Symbol then
2316
- result = s(:args)
2317
- result << val[0]
2490
+ result = s(:args, arg).line lexer.lineno
2318
2491
  when Sexp then
2319
- result = val[0]
2492
+ result = arg
2320
2493
  else
2321
2494
  debug20 32
2322
2495
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2329,7 +2502,7 @@ keyword_variable: kNIL { result = s(:nil) }
2329
2502
  if list.sexp_type == :args then
2330
2503
  result = list
2331
2504
  else
2332
- result = s(:args, list)
2505
+ result = s(:args, list).line list.line
2333
2506
  end
2334
2507
 
2335
2508
  result << item
@@ -2343,21 +2516,24 @@ keyword_variable: kNIL { result = s(:nil) }
2343
2516
  f_kw: f_label arg_value
2344
2517
  #endif
2345
2518
  {
2346
- # TODO: call_args
2347
- label, _ = val[0] # TODO: fix lineno?
2519
+ # TODO: new_kw_arg
2520
+ (label, line), arg = val
2521
+
2348
2522
  identifier = label.to_sym
2349
2523
  self.env[identifier] = :lvar
2350
2524
 
2351
- result = s(:array, s(:kwarg, identifier, val[1]))
2525
+ kwarg = s(:kwarg, identifier, arg).line line
2526
+ result = s(:array, kwarg).line line
2352
2527
  }
2353
2528
  #if V >= 21
2354
2529
  | f_label
2355
2530
  {
2356
- label, _ = val[0] # TODO: fix lineno?
2357
- identifier = label.to_sym
2358
- self.env[identifier] = :lvar
2531
+ (label, line), = val
2359
2532
 
2360
- result = s(:array, s(:kwarg, identifier))
2533
+ id = label.to_sym
2534
+ self.env[id] = :lvar
2535
+
2536
+ result = s(:array, s(:kwarg, id).line(line)).line line
2361
2537
  }
2362
2538
  #endif
2363
2539
 
@@ -2367,21 +2543,22 @@ keyword_variable: kNIL { result = s(:nil) }
2367
2543
  f_block_kw: f_label primary_value
2368
2544
  #endif
2369
2545
  {
2370
- # TODO: call_args
2371
- label, _ = val[0] # TODO: fix lineno?
2372
- identifier = label.to_sym
2373
- self.env[identifier] = :lvar
2546
+ # TODO: new_kw_arg
2547
+ (label, line), expr = val
2548
+ id = label.to_sym
2549
+ self.env[id] = :lvar
2374
2550
 
2375
- result = s(:array, s(:kwarg, identifier, val[1]))
2551
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2376
2552
  }
2377
2553
  #if V >= 21
2378
2554
  | f_label
2379
2555
  {
2380
- label, _ = val[0] # TODO: fix lineno?
2381
- identifier = label.to_sym
2382
- self.env[identifier] = :lvar
2556
+ # TODO: new_kw_arg
2557
+ (label, line), = val
2558
+ id = label.to_sym
2559
+ self.env[id] = :lvar
2383
2560
 
2384
- result = s(:array, s(:kwarg, identifier))
2561
+ result = s(:array, s(:kwarg, id).line(line)).line line
2385
2562
  }
2386
2563
  #endif
2387
2564
 
@@ -2437,17 +2614,20 @@ keyword_variable: kNIL { result = s(:nil) }
2437
2614
 
2438
2615
  f_block_optarg: f_block_opt
2439
2616
  {
2440
- result = s(:block, val[0])
2617
+ optblk, = val
2618
+ result = s(:block, optblk).line optblk.line
2441
2619
  }
2442
2620
  | f_block_optarg tCOMMA f_block_opt
2443
2621
  {
2444
- result = val[0]
2445
- result << val[2]
2622
+ optarg, _, optblk = val
2623
+ result = optarg
2624
+ result << optblk
2446
2625
  }
2447
2626
 
2448
2627
  f_optarg: f_opt
2449
2628
  {
2450
- result = s(:block, val[0])
2629
+ opt, = val
2630
+ result = s(:block, opt).line opt.line
2451
2631
  }
2452
2632
  | f_optarg tCOMMA f_opt
2453
2633
  {
@@ -2501,14 +2681,11 @@ keyword_variable: kNIL { result = s(:nil) }
2501
2681
  result.sexp_type == :lit
2502
2682
  }
2503
2683
 
2504
- assoc_list: none # [!nil]
2684
+ assoc_list: none
2505
2685
  {
2506
- result = s(:array)
2507
- }
2508
- | assocs trailer # [!nil]
2509
- {
2510
- result = val[0]
2686
+ result = s(:array).line lexer.lineno
2511
2687
  }
2688
+ | assocs trailer
2512
2689
 
2513
2690
  assocs: assoc
2514
2691
  | assocs tCOMMA assoc
@@ -2522,24 +2699,29 @@ keyword_variable: kNIL { result = s(:nil) }
2522
2699
 
2523
2700
  assoc: arg_value tASSOC arg_value
2524
2701
  {
2525
- result = s(:array, val[0], val[2])
2702
+ v1, _, v2 = val
2703
+ result = s(:array, v1, v2).line v1.line
2526
2704
  }
2527
2705
  | tLABEL arg_value
2528
2706
  {
2529
- (label, _), arg = val
2530
- result = s(:array, s(:lit, label.to_sym), arg)
2707
+ (label, line), arg = val
2708
+
2709
+ lit = s(:lit, label.to_sym).line line
2710
+ result = s(:array, lit, arg).line line
2531
2711
  }
2532
2712
  #if V >= 22
2533
2713
  | tSTRING_BEG string_contents tLABEL_END arg_value
2534
2714
  {
2535
2715
  _, sym, _, value = val
2536
2716
  sym.sexp_type = :dsym
2537
- result = s(:array, sym, value)
2717
+ result = s(:array, sym, value).line sym.line
2538
2718
  }
2539
2719
  #endif
2540
2720
  | tDSTAR arg_value
2541
2721
  {
2542
- result = s(:array, s(:kwsplat, val[1]))
2722
+ _, arg = val
2723
+ line = arg.line
2724
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2543
2725
  }
2544
2726
 
2545
2727
  operation: tIDENTIFIER | tCONSTANT | tFID