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.
@@ -23,30 +23,30 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
23
23
  tLABEL_END
24
24
  tLONELY
25
25
 
26
- prechigh
27
- right tBANG tTILDE tUPLUS
28
- right tPOW
29
- right tUMINUS_NUM tUMINUS
30
- left tSTAR2 tDIVIDE tPERCENT
31
- left tPLUS tMINUS
32
- left tLSHFT tRSHFT
33
- left tAMPER2
34
- left tPIPE tCARET
35
- left tGT tGEQ tLT tLEQ
36
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
37
- left tANDOP
38
- left tOROP
39
- nonassoc tDOT2 tDOT3
40
- right tEH tCOLON
41
- left kRESCUE_MOD
42
- right tEQL tOP_ASGN
43
- nonassoc kDEFINED
44
- right kNOT
45
- left kOR kAND
46
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
47
- nonassoc tLBRACE_ARG
48
- nonassoc tLOWEST
49
26
  preclow
27
+ nonassoc tLOWEST
28
+ nonassoc tLBRACE_ARG
29
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
30
+ left kOR kAND
31
+ right kNOT
32
+ nonassoc kDEFINED
33
+ right tEQL tOP_ASGN
34
+ left kRESCUE_MOD
35
+ right tEH tCOLON
36
+ nonassoc tDOT2 tDOT3
37
+ left tOROP
38
+ left tANDOP
39
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
40
+ left tGT tGEQ tLT tLEQ
41
+ left tPIPE tCARET
42
+ left tAMPER2
43
+ left tLSHFT tRSHFT
44
+ left tPLUS tMINUS
45
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
46
+ right tUMINUS_NUM tUMINUS
47
+ right tPOW
48
+ right tBANG tTILDE tUPLUS
49
+ prechigh
50
50
 
51
51
  rule
52
52
 
@@ -60,7 +60,8 @@ rule
60
60
 
61
61
  top_compstmt: top_stmts opt_terms
62
62
  {
63
- result = val[0]
63
+ stmt, _ = val
64
+ result = stmt
64
65
  }
65
66
 
66
67
  top_stmts: none
@@ -72,14 +73,6 @@ rule
72
73
  | error top_stmt
73
74
 
74
75
  top_stmt: stmt
75
- {
76
- result = val[0]
77
-
78
- # TODO: remove once I have more confidence this is fixed
79
- # result.each_of_type :call_args do |s|
80
- # debug20 666, s, result
81
- # end
82
- }
83
76
  | klBEGIN
84
77
  {
85
78
  if (self.in_def || self.in_single > 0) then
@@ -90,14 +83,19 @@ rule
90
83
  }
91
84
  begin_block
92
85
  {
93
- _, _, block = val
94
- result = block
86
+ (_, lineno), _, iter = val
87
+ iter.line lineno
88
+
89
+ (_, preexe,) = iter
90
+ preexe.line lineno
91
+
92
+ result = iter
95
93
  }
96
94
 
97
- begin_block: tLCURLY top_compstmt tRCURLY
95
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
98
96
  {
99
- _, stmt, _ = val
100
- result = new_iter s(:preexe), 0, stmt
97
+ _, line, stmt, _ = val
98
+ result = new_iter s(:preexe).line(line), 0, stmt
101
99
  }
102
100
 
103
101
  bodystmt: compstmt opt_rescue k_else
@@ -139,34 +137,27 @@ rule
139
137
  stmt_or_begin: stmt
140
138
  | klBEGIN
141
139
  {
142
- if (self.in_def || self.in_single > 0) then
143
- debug20 1
144
- yyerror "BEGIN in method"
145
- end
146
- self.env.extend
147
- }
148
- begin_block
149
- {
150
- _, _, stmt = val
151
- result = stmt
140
+ yyerror "BEGIN is permitted only at toplevel"
152
141
  }
153
142
 
154
143
  stmt: kALIAS fitem
155
144
  {
156
145
  lexer.lex_state = EXPR_FNAME
157
- result = self.lexer.lineno
158
146
  }
159
147
  fitem
160
148
  {
161
- result = s(:alias, val[1], val[3]).line(val[2])
149
+ (_, line), lhs, _, rhs = val
150
+ result = s(:alias, lhs, rhs).line(line).line line
162
151
  }
163
152
  | kALIAS tGVAR tGVAR
164
153
  {
165
- result = s(:valias, val[1].to_sym, val[2].to_sym)
154
+ (_, line), lhs, rhs = val
155
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
166
156
  }
167
157
  | kALIAS tGVAR tBACK_REF
168
158
  {
169
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
159
+ (_, line), lhs, rhs = val
160
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
170
161
  }
171
162
  | kALIAS tGVAR tNTH_REF
172
163
  {
@@ -178,32 +169,41 @@ rule
178
169
  }
179
170
  | stmt kIF_MOD expr_value
180
171
  {
181
- result = new_if val[2], val[0], nil
172
+ t, _, c = val
173
+ result = new_if c, t, nil
182
174
  }
183
175
  | stmt kUNLESS_MOD expr_value
184
176
  {
185
- result = new_if val[2], nil, val[0]
177
+ f, _, c = val
178
+ result = new_if c, nil, f
186
179
  }
187
180
  | stmt kWHILE_MOD expr_value
188
181
  {
189
- result = new_while val[0], val[2], true
182
+ e, _, c = val
183
+ result = new_while e, c, true
190
184
  }
191
185
  | stmt kUNTIL_MOD expr_value
192
186
  {
193
- result = new_until val[0], val[2], true
187
+ e, _, c = val
188
+ result = new_until e, c, true
194
189
  }
195
190
  | stmt kRESCUE_MOD stmt
196
191
  {
197
192
  body, _, resbody = val
198
- result = new_rescue body, new_resbody(s(:array), resbody)
193
+
194
+ resbody = new_resbody s(:array).line(resbody.line), resbody
195
+ result = new_rescue body, resbody
199
196
  }
200
197
  | klEND tLCURLY compstmt tRCURLY
201
198
  {
199
+ (_, line), _, stmt, _ = val
200
+
202
201
  if (self.in_def || self.in_single > 0) then
203
202
  debug20 3
204
203
  yyerror "END in method; use at_exit"
205
204
  end
206
- result = new_iter s(:postexe), 0, val[2]
205
+
206
+ result = new_iter s(:postexe).line(line), 0, stmt
207
207
  }
208
208
  | command_asgn
209
209
  | mlhs tEQL command_call
@@ -212,7 +212,8 @@ rule
212
212
  }
213
213
  | lhs tEQL mrhs
214
214
  {
215
- result = new_assign val[0], s(:svalue, val[2])
215
+ lhs, _, rhs = val
216
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
216
217
  }
217
218
  | mlhs tEQL mrhs_arg
218
219
  {
@@ -234,11 +235,12 @@ rule
234
235
  }
235
236
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
236
237
  {
237
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
238
+ result = new_op_asgn1 val
238
239
  }
239
240
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
240
241
  {
241
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
242
+ prim, _, id, opasgn, rhs = val
243
+ result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
242
244
  if val[1] == '&.'
243
245
  result.sexp_type = :safe_op_asgn
244
246
  end
@@ -254,13 +256,15 @@ rule
254
256
  }
255
257
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
256
258
  {
257
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
258
- debug20 4, val, result
259
+ lhs1, _, lhs2, op, rhs = val
260
+
261
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
259
262
  }
260
263
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
261
264
  {
262
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
263
- debug20 5, val, result
265
+ lhs1, _, lhs2, op, rhs = val
266
+
267
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
264
268
  }
265
269
  | backref tOP_ASGN command_rhs
266
270
  {
@@ -277,19 +281,26 @@ rule
277
281
  expr: command_call
278
282
  | expr kAND expr
279
283
  {
280
- result = logical_op :and, val[0], val[2]
284
+ lhs, _, rhs = val
285
+ result = logical_op :and, lhs, rhs
281
286
  }
282
287
  | expr kOR expr
283
288
  {
284
- result = logical_op :or, val[0], val[2]
289
+ lhs, _, rhs = val
290
+ result = logical_op :or, lhs, rhs
285
291
  }
286
292
  | kNOT opt_nl expr
287
293
  {
288
- result = s(:call, val[2], :"!")
294
+ (_, line), _, expr = val
295
+ result = new_call(expr, :"!").line line
296
+ # REFACTOR: call_uni_op
289
297
  }
290
298
  | tBANG command_call
291
299
  {
292
- result = s(:call, val[1], :"!")
300
+ _, cmd = val
301
+ result = new_call(cmd, :"!").line cmd.line
302
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
303
+ # REFACTOR: call_uni_op -- see parse26.y
293
304
  }
294
305
  | arg
295
306
 
@@ -316,7 +327,8 @@ rule
316
327
  block_command: block_call
317
328
  | block_call call_op2 operation2 command_args
318
329
  {
319
- result = new_call val[0], val[2].to_sym, val[3]
330
+ blk, _, msg, args = val
331
+ result = new_call(blk, msg.to_sym, args).line blk.line
320
332
  }
321
333
 
322
334
  cmd_brace_block: tLBRACE_ARG
@@ -336,26 +348,32 @@ rule
336
348
 
337
349
  fcall: operation
338
350
  {
339
- result = new_call nil, val[0].to_sym
351
+ msg, = val
352
+ result = new_call(nil, msg.to_sym).line lexer.lineno
340
353
  }
341
354
 
342
355
  command: fcall command_args =tLOWEST
343
356
  {
344
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
357
+ call, args = val
358
+ result = call.concat args.sexp_body
345
359
  }
346
360
  | fcall command_args cmd_brace_block
347
361
  {
348
- result = val[0].concat val[1].sexp_body
349
- if val[2] then
350
- block_dup_check result, val[2]
362
+ call, args, block = val
363
+
364
+ result = call.concat args.sexp_body
351
365
 
352
- result, operation = val[2], result
366
+ if block then
367
+ block_dup_check result, block
368
+
369
+ result, operation = block, result
353
370
  result.insert 1, operation
354
371
  end
355
372
  }
356
373
  | primary_value call_op operation2 command_args =tLOWEST
357
374
  {
358
- result = new_call val[0], val[2].to_sym, val[3], val[1]
375
+ lhs, callop, op, args = val
376
+ result = new_call lhs, op.to_sym, args, callop
359
377
  }
360
378
  | primary_value call_op operation2 command_args cmd_brace_block
361
379
  {
@@ -387,7 +405,9 @@ rule
387
405
  }
388
406
  | kYIELD command_args
389
407
  {
390
- result = new_yield val[1]
408
+ (_, line), args = val
409
+ result = new_yield args
410
+ result.line line # TODO: push to new_yield
391
411
  }
392
412
  | k_return call_args
393
413
  {
@@ -396,8 +416,8 @@ rule
396
416
  }
397
417
  | kBREAK call_args
398
418
  {
399
- line = val[0].last
400
- result = s(:break, ret_args(val[1])).line(line)
419
+ (_, line), args = val
420
+ result = s(:break, ret_args(args)).line line
401
421
  }
402
422
  | kNEXT call_args
403
423
  {
@@ -414,56 +434,79 @@ rule
414
434
  mlhs_inner: mlhs_basic
415
435
  | tLPAREN mlhs_inner rparen
416
436
  {
417
- result = s(:masgn, s(:array, val[1]))
437
+ _, arg, _ = val
438
+ l = arg.line
439
+
440
+ result = s(:masgn, s(:array, arg).line(l)).line l
418
441
  }
419
442
 
420
443
  mlhs_basic: mlhs_head
421
444
  {
422
- result = s(:masgn, val[0])
445
+ head, = val
446
+ result = s(:masgn, head).line head.line
423
447
  }
424
448
  | mlhs_head mlhs_item
425
449
  {
426
- result = s(:masgn, val[0] << val[1].compact)
450
+ lhs, rhs = val
451
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
427
452
  }
428
453
  | mlhs_head tSTAR mlhs_node
429
454
  {
430
- result = s(:masgn, val[0] << s(:splat, val[2]))
455
+ head, _, tail = val
456
+ head << s(:splat, tail).line(tail.line)
457
+ result = s(:masgn, head).line head.line
431
458
  }
432
459
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
433
460
  {
434
461
  ary1, _, splat, _, ary2 = val
435
462
 
436
- result = list_append ary1, s(:splat, splat)
463
+ result = list_append ary1, s(:splat, splat).line(splat.line)
437
464
  result.concat ary2.sexp_body
438
- result = s(:masgn, result)
465
+ result = s(:masgn, result).line result.line
439
466
  }
440
467
  | mlhs_head tSTAR
441
468
  {
442
- result = s(:masgn, val[0] << s(:splat))
469
+ head, _ = val
470
+ l = head.line
471
+ result = s(:masgn, head << s(:splat).line(l)).line l
443
472
  }
444
473
  | mlhs_head tSTAR tCOMMA mlhs_post
445
474
  {
446
- ary = list_append val[0], s(:splat)
447
- ary.concat val[3].sexp_body
448
- result = s(:masgn, ary)
475
+ head, _, _, post = val
476
+ ary = list_append head, s(:splat).line(head.line)
477
+ ary.concat post.sexp_body
478
+ result = s(:masgn, ary).line ary.line
449
479
  }
450
480
  | tSTAR mlhs_node
451
481
  {
452
- result = s(:masgn, s(:array, s(:splat, val[1])))
482
+ _, node = val
483
+ l = node.line
484
+ splat = s(:splat, node).line l
485
+ ary = s(:array, splat).line l
486
+ result = s(:masgn, ary).line l
453
487
  }
454
488
  | tSTAR mlhs_node tCOMMA mlhs_post
455
489
  {
456
- ary = s(:array, s(:splat, val[1]))
457
- ary.concat val[3].sexp_body
458
- result = s(:masgn, ary)
490
+ _, node, _, post = val
491
+
492
+ splat = s(:splat, node).line node.line
493
+ ary = s(:array, splat).line splat.line
494
+ ary.concat post.sexp_body
495
+ result = s(:masgn, ary).line ary.line
459
496
  }
460
497
  | tSTAR
461
498
  {
462
- result = s(:masgn, s(:array, s(:splat)))
499
+ l = lexer.lineno
500
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
463
501
  }
464
502
  | tSTAR tCOMMA mlhs_post
465
503
  {
466
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
504
+ _, _, post = val
505
+ l = post.line
506
+
507
+ splat = s(:splat).line l
508
+ ary = s(:array, splat, *post.sexp_body).line l
509
+ result = s(:masgn, ary).line l
467
510
  }
468
511
 
469
512
  mlhs_item: mlhs_node
@@ -474,7 +517,8 @@ rule
474
517
 
475
518
  mlhs_head: mlhs_item tCOMMA
476
519
  {
477
- result = s(:array, val[0])
520
+ lhs, _ = val
521
+ result = s(:array, lhs).line lhs.line
478
522
  }
479
523
  | mlhs_head mlhs_item tCOMMA
480
524
  {
@@ -483,7 +527,8 @@ rule
483
527
 
484
528
  mlhs_post: mlhs_item
485
529
  {
486
- result = s(:array, val[0])
530
+ item, = val
531
+ result = s(:array, item).line item.line
487
532
  }
488
533
  | mlhs_post tCOMMA mlhs_item
489
534
  {
@@ -508,7 +553,8 @@ rule
508
553
  }
509
554
  | primary_value tCOLON2 tIDENTIFIER
510
555
  {
511
- result = s(:attrasgn, val[0], :"#{val[2]}=")
556
+ recv, _, id = val
557
+ result = new_attrasgn recv, id
512
558
  }
513
559
  | primary_value call_op tCONSTANT
514
560
  {
@@ -521,7 +567,10 @@ rule
521
567
  yyerror "dynamic constant assignment"
522
568
  end
523
569
 
524
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
570
+ expr, _, id = val
571
+ l = expr.line
572
+
573
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
525
574
  }
526
575
  | tCOLON3 tCONSTANT
527
576
  {
@@ -530,7 +579,10 @@ rule
530
579
  yyerror "dynamic constant assignment"
531
580
  end
532
581
 
533
- result = s(:const, nil, s(:colon3, val[1].to_sym))
582
+ _, id = val
583
+ l = lexer.lineno
584
+
585
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
534
586
  }
535
587
  | backref
536
588
  {
@@ -539,24 +591,31 @@ rule
539
591
 
540
592
  lhs: user_variable
541
593
  {
594
+ line = lexer.lineno
542
595
  result = self.assignable val[0]
596
+ result.line = line
543
597
  }
544
598
  | keyword_variable
545
599
  {
600
+ line = lexer.lineno
546
601
  result = self.assignable val[0]
602
+ result.line = line
547
603
  debug20 9, val, result
548
604
  }
549
605
  | primary_value tLBRACK2 opt_call_args rbracket
550
606
  {
551
- result = self.aryset val[0], val[2]
607
+ lhs, _, args, _ = val
608
+ result = self.aryset lhs, args
552
609
  }
553
610
  | primary_value call_op tIDENTIFIER # REFACTOR
554
611
  {
555
- result = new_attrasgn val[0], val[2], val[1]
612
+ lhs, op, id = val
613
+ result = new_attrasgn lhs, id, op
556
614
  }
557
615
  | primary_value tCOLON2 tIDENTIFIER
558
616
  {
559
- result = s(:attrasgn, val[0], :"#{val[2]}=")
617
+ lhs, _, id = val
618
+ result = new_attrasgn lhs, id
560
619
  }
561
620
  | primary_value call_op tCONSTANT # REFACTOR?
562
621
  {
@@ -564,21 +623,27 @@ rule
564
623
  }
565
624
  | primary_value tCOLON2 tCONSTANT
566
625
  {
626
+ expr, _, id = val
627
+
567
628
  if (self.in_def || self.in_single > 0) then
568
629
  debug20 10
569
630
  yyerror "dynamic constant assignment"
570
631
  end
571
632
 
572
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
633
+ l = expr.line
634
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
573
635
  }
574
636
  | tCOLON3 tCONSTANT
575
637
  {
638
+ _, id = val
639
+
576
640
  if (self.in_def || self.in_single > 0) then
577
641
  debug20 11
578
642
  yyerror "dynamic constant assignment"
579
643
  end
580
644
 
581
- result = s(:const, s(:colon3, val[1].to_sym))
645
+ l = lexer.lineno
646
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
582
647
  }
583
648
  | backref
584
649
  {
@@ -593,7 +658,8 @@ rule
593
658
 
594
659
  cpath: tCOLON3 cname
595
660
  {
596
- result = s(:colon3, val[1].to_sym)
661
+ _, name = val
662
+ result = s(:colon3, name.to_sym).line lexer.lineno
597
663
  }
598
664
  | cname
599
665
  {
@@ -601,7 +667,10 @@ rule
601
667
  }
602
668
  | primary_value tCOLON2 cname
603
669
  {
604
- result = s(:colon2, val[0], val[2].to_sym)
670
+ pval, _, name = val
671
+
672
+ result = s(:colon2, pval, name.to_sym)
673
+ result.line pval.line
605
674
  }
606
675
 
607
676
  fname: tIDENTIFIER | tCONSTANT | tFID
@@ -622,7 +691,8 @@ rule
622
691
 
623
692
  fitem: fsym
624
693
  {
625
- result = s(:lit, val[0].to_sym)
694
+ id, = val
695
+ result = s(:lit, id.to_sym).line lexer.lineno
626
696
  }
627
697
  | dsym
628
698
 
@@ -645,6 +715,7 @@ rule
645
715
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
646
716
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
647
717
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
718
+ # TODO: tUBANG dead?
648
719
  | tUBANG
649
720
 
650
721
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
@@ -667,8 +738,7 @@ rule
667
738
  }
668
739
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
669
740
  {
670
- val[2].sexp_type = :arglist if val[2]
671
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
741
+ result = new_op_asgn1 val
672
742
  }
673
743
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
674
744
  {
@@ -680,7 +750,9 @@ rule
680
750
  }
681
751
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
682
752
  {
683
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
753
+ lhs, _, id, op, rhs = val
754
+
755
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
684
756
  }
685
757
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
686
758
  {
@@ -710,18 +782,18 @@ rule
710
782
  {
711
783
  v1, v2 = val[0], val[2]
712
784
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
713
- result = s(:lit, (v1.last)..(v2.last))
785
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
714
786
  else
715
- result = s(:dot2, v1, v2)
787
+ result = s(:dot2, v1, v2).line v1.line
716
788
  end
717
789
  }
718
790
  | arg tDOT3 arg
719
791
  {
720
792
  v1, v2 = val[0], val[2]
721
793
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
722
- result = s(:lit, (v1.last)...(v2.last))
794
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
723
795
  else
724
- result = s(:dot3, v1, v2)
796
+ result = s(:dot3, v1, v2).line v1.line
725
797
  end
726
798
  }
727
799
  | arg tPLUS arg
@@ -750,7 +822,9 @@ rule
750
822
  }
751
823
  | tUMINUS_NUM simple_numeric tPOW arg
752
824
  {
753
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
825
+ lit = s(:lit, val[1]).line lexer.lineno
826
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
827
+
754
828
  }
755
829
  | tUPLUS arg
756
830
  {
@@ -791,15 +865,19 @@ rule
791
865
  }
792
866
  | arg tMATCH arg
793
867
  {
794
- result = new_match val[0], val[2]
868
+ lhs, _, rhs = val
869
+ result = new_match lhs, rhs
795
870
  }
796
871
  | arg tNMATCH arg
797
872
  {
798
- result = s(:not, new_match(val[0], val[2]))
873
+ lhs, _, rhs = val
874
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
799
875
  }
800
876
  | tBANG arg
801
877
  {
802
- result = new_call val[1], :"!"
878
+ _, arg = val
879
+ result = new_call arg, :"!"
880
+ result.line arg.line
803
881
  }
804
882
  | tTILDE arg
805
883
  {
@@ -827,11 +905,13 @@ rule
827
905
  }
828
906
  | kDEFINED opt_nl arg
829
907
  {
830
- result = s(:defined, val[2])
908
+ (_, line), _, arg = val
909
+ result = s(:defined, arg).line line
831
910
  }
832
911
  | arg tEH arg opt_nl tCOLON arg
833
912
  {
834
- result = s(:if, val[0], val[2], val[5])
913
+ c, _, t, _, _, f = val
914
+ result = s(:if, c, t, f).line c.line
835
915
  }
836
916
  | primary
837
917
 
@@ -874,28 +954,25 @@ rule
874
954
  arg_rhs: arg =tOP_ASGN
875
955
  | arg kRESCUE_MOD arg
876
956
  {
877
- body, _, resbody = val
957
+ body, (_, line), resbody = val
878
958
  body = value_expr body
879
959
  resbody = remove_begin resbody
880
- result = new_rescue(body, new_resbody(s(:array), resbody))
960
+
961
+ ary = s(:array).line line
962
+ result = new_rescue(body, new_resbody(ary, resbody))
881
963
  }
882
964
 
883
965
  paren_args: tLPAREN2 opt_call_args rparen
884
966
  {
885
- result = val[1]
967
+ _, args, _ = val
968
+ result = args
886
969
  }
887
970
 
888
971
  opt_paren_args: none
889
972
  | paren_args
890
973
 
891
974
  opt_call_args: none
892
- {
893
- result = val[0]
894
- }
895
975
  | call_args
896
- {
897
- result = val[0]
898
- }
899
976
  | args tCOMMA
900
977
  {
901
978
  result = args val
@@ -917,17 +994,14 @@ rule
917
994
  | args opt_block_arg
918
995
  {
919
996
  result = call_args val
920
- result = self.arg_blk_pass val[0], val[1]
921
997
  }
922
998
  | assocs opt_block_arg
923
999
  {
924
- result = call_args [array_to_hash(val[0])]
925
- result = self.arg_blk_pass result, val[1]
1000
+ result = call_args [array_to_hash(val[0]), val[1]]
926
1001
  }
927
1002
  | args tCOMMA assocs opt_block_arg
928
1003
  {
929
- result = call_args [val[0], array_to_hash(val[2])]
930
- result = self.arg_blk_pass result, val[3]
1004
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
931
1005
  }
932
1006
  | block_arg
933
1007
  {
@@ -935,17 +1009,45 @@ rule
935
1009
  }
936
1010
 
937
1011
  command_args: {
938
- result = lexer.cmdarg.store true
1012
+ # parse26.y line 2200
1013
+
1014
+ # If call_args starts with a open paren '(' or
1015
+ # '[', look-ahead reading of the letters calls
1016
+ # CMDARG_PUSH(0), but the push must be done
1017
+ # after CMDARG_PUSH(1). So this code makes them
1018
+ # consistent by first cancelling the premature
1019
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1020
+ # finally redoing CMDARG_PUSH(0).
1021
+
1022
+ result = yychar = self.last_token_type.first
1023
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1024
+ lexer.cmdarg.pop if lookahead
1025
+ lexer.cmdarg.push true
1026
+ lexer.cmdarg.push false if lookahead
939
1027
  }
940
1028
  call_args
941
1029
  {
942
- lexer.cmdarg.restore val[0]
943
- result = val[1]
1030
+ yychar, args = val
1031
+
1032
+ # call_args can be followed by tLBRACE_ARG (that
1033
+ # does CMDARG_PUSH(0) in the lexer) but the push
1034
+ # must be done after CMDARG_POP() in the parser.
1035
+ # So this code does CMDARG_POP() to pop 0 pushed
1036
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1037
+ # by command_args, and CMDARG_PUSH(0) to restore
1038
+ # back the flag set by tLBRACE_ARG.
1039
+
1040
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1041
+ lexer.cmdarg.pop if lookahead
1042
+ lexer.cmdarg.pop
1043
+ lexer.cmdarg.push false if lookahead
1044
+ result = args
944
1045
  }
945
1046
 
946
1047
  block_arg: tAMPER arg_value
947
1048
  {
948
- result = s(:block_pass, val[1])
1049
+ _, arg = val
1050
+ result = s(:block_pass, arg).line arg.line
949
1051
  }
950
1052
 
951
1053
  opt_block_arg: tCOMMA block_arg
@@ -956,19 +1058,27 @@ rule
956
1058
 
957
1059
  args: arg_value
958
1060
  {
959
- result = s(:array, val[0])
1061
+ arg, = val
1062
+ lineno = arg.line || lexer.lineno # HACK
1063
+
1064
+ result = s(:array, arg).line lineno
960
1065
  }
961
1066
  | tSTAR arg_value
962
1067
  {
963
- result = s(:array, s(:splat, val[1]))
1068
+ _, arg = val
1069
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
964
1070
  }
965
1071
  | args tCOMMA arg_value
966
1072
  {
967
- result = self.list_append val[0], val[2]
1073
+ args, _, id = val
1074
+ result = self.list_append args, id
968
1075
  }
969
1076
  | args tCOMMA tSTAR arg_value
970
1077
  {
971
- result = self.list_append val[0], s(:splat, val[3])
1078
+ # TODO: the line number from tSTAR has been dropped
1079
+ args, _, _, id = val
1080
+ line = lexer.lineno
1081
+ result = self.list_append args, s(:splat, id).line(line)
972
1082
  }
973
1083
 
974
1084
  mrhs_arg: mrhs
@@ -986,11 +1096,14 @@ rule
986
1096
  }
987
1097
  | args tCOMMA tSTAR arg_value
988
1098
  {
989
- result = self.arg_concat val[0], val[3]
1099
+ # TODO: make all tXXXX terminals include lexer.lineno
1100
+ arg, _, _, splat = val
1101
+ result = self.arg_concat arg, splat
990
1102
  }
991
1103
  | tSTAR arg_value
992
1104
  {
993
- result = s(:splat, val[1])
1105
+ _, arg = val
1106
+ result = s(:splat, arg).line arg.line
994
1107
  }
995
1108
 
996
1109
  primary: literal
@@ -1005,65 +1118,65 @@ rule
1005
1118
  | backref
1006
1119
  | tFID
1007
1120
  {
1008
- result = new_call nil, val[0].to_sym
1121
+ msg, = val
1122
+ result = new_call nil, msg.to_sym
1009
1123
  }
1010
1124
  | k_begin
1011
1125
  {
1126
+ lexer.cmdarg.push false
1012
1127
  result = self.lexer.lineno
1013
- # TODO:
1014
- # $<val>1 = cmdarg_stack;
1015
- # CMDARG_SET(0);
1016
1128
  }
1017
1129
  bodystmt k_end
1018
1130
  {
1019
- # TODO: CMDARG_SET($<val>1);
1020
- unless val[2] then
1021
- result = s(:nil)
1022
- else
1023
- result = s(:begin, val[2])
1024
- end
1025
-
1026
- result.line = val[1]
1131
+ lexer.cmdarg.pop
1132
+ result = new_begin val
1027
1133
  }
1028
- | tLPAREN_ARG rparen
1134
+ | tLPAREN_ARG
1029
1135
  {
1030
- # TODO: lex_state = EXPR_ENDARG in between
1031
- debug20 13, val, result
1136
+ lexer.lex_state = EXPR_ENDARG
1137
+ result = lexer.lineno
1032
1138
  }
1033
- | tLPAREN_ARG
1139
+ rparen
1034
1140
  {
1035
- result = lexer.cmdarg.store false
1036
- # result = self.lexer.cmdarg.stack.dup
1037
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1141
+ _, line, _ = val
1142
+ result = s(:begin).line line
1038
1143
  }
1144
+ | tLPAREN_ARG
1039
1145
  stmt
1040
1146
  {
1041
1147
  lexer.lex_state = EXPR_ENDARG
1042
1148
  }
1043
1149
  rparen
1044
1150
  {
1045
- _, cmdarg, stmt, _, _, = val
1046
- warning "(...) interpreted as grouped expression"
1047
- lexer.cmdarg.restore cmdarg
1151
+ _, stmt, _, _, = val
1152
+ # warning "(...) interpreted as grouped expression"
1048
1153
  result = stmt
1049
1154
  }
1050
1155
  | tLPAREN compstmt tRPAREN
1051
1156
  {
1052
- result = val[1] || s(:nil)
1157
+ _, stmt, _ = val
1158
+ result = stmt
1159
+ result ||= s(:nil).line lexer.lineno
1053
1160
  result.paren = true
1054
1161
  }
1055
1162
  | primary_value tCOLON2 tCONSTANT
1056
1163
  {
1057
- result = s(:colon2, val[0], val[2].to_sym)
1164
+ expr, _, id = val
1165
+
1166
+ result = s(:colon2, expr, id.to_sym).line expr.line
1058
1167
  }
1059
1168
  | tCOLON3 tCONSTANT
1060
1169
  {
1061
- result = s(:colon3, val[1].to_sym)
1170
+ _, id = val
1171
+
1172
+ result = s(:colon3, id.to_sym).line lexer.lineno
1062
1173
  }
1063
- | tLBRACK aref_args tRBRACK
1174
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1064
1175
  {
1065
- result = val[1] || s(:array)
1176
+ _, line, args, _ = val
1177
+ result = args || s(:array)
1066
1178
  result.sexp_type = :array # aref_args is :args
1179
+ result.line line
1067
1180
  }
1068
1181
  | tLBRACE
1069
1182
  {
@@ -1075,7 +1188,8 @@ rule
1075
1188
  }
1076
1189
  | k_return
1077
1190
  {
1078
- result = s(:return)
1191
+ (_, line), = val
1192
+ result = s(:return).line line
1079
1193
  }
1080
1194
  | kYIELD tLPAREN2 call_args rparen
1081
1195
  {
@@ -1091,11 +1205,14 @@ rule
1091
1205
  }
1092
1206
  | kDEFINED opt_nl tLPAREN2 expr rparen
1093
1207
  {
1094
- result = s(:defined, val[3])
1208
+ (_, line), _, _, arg, _ = val
1209
+
1210
+ result = s(:defined, arg).line line
1095
1211
  }
1096
1212
  | kNOT tLPAREN2 expr rparen
1097
1213
  {
1098
- result = s(:call, val[2], :"!")
1214
+ _, _, lhs, _ = val
1215
+ result = new_call lhs, :"!"
1099
1216
  }
1100
1217
  | kNOT tLPAREN2 rparen
1101
1218
  {
@@ -1103,11 +1220,11 @@ rule
1103
1220
  }
1104
1221
  | fcall brace_block
1105
1222
  {
1106
- oper, iter = val[0], val[1]
1107
- call = oper # FIX
1223
+ call, iter = val
1224
+
1108
1225
  iter.insert 1, call
1109
1226
  result = iter
1110
- call.line = iter.line
1227
+ # FIX: probably not: call.line = iter.line
1111
1228
  }
1112
1229
  | method_call
1113
1230
  | method_call brace_block
@@ -1215,66 +1332,82 @@ rule
1215
1332
  }
1216
1333
  | k_def fname
1217
1334
  {
1218
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1335
+ result = self.in_def
1219
1336
 
1220
- self.comments.push self.lexer.comments
1221
- self.in_def = true
1337
+ self.in_def = true # group = local_push
1222
1338
  self.env.extend
1223
- # TODO: local->cmdargs = cmdarg_stack;
1224
- # TODO: port local_push_gen and local_pop_gen
1225
- lexer.cmdarg.stack.replace [false]
1339
+ lexer.cmdarg.push false
1340
+ lexer.cond.push false
1341
+
1342
+ self.comments.push self.lexer.comments
1226
1343
  }
1227
- f_arglist bodystmt k_end
1344
+ f_arglist bodystmt { result = lexer.lineno } k_end
1228
1345
  {
1229
- in_def, cmdarg = val[2]
1346
+ in_def = val[2]
1230
1347
 
1231
1348
  result = new_defn val
1232
1349
 
1233
- lexer.cmdarg.stack.replace cmdarg
1350
+ lexer.cond.pop # group = local_pop
1351
+ lexer.cmdarg.pop
1234
1352
  self.env.unextend
1235
1353
  self.in_def = in_def
1354
+
1236
1355
  self.lexer.comments # we don't care about comments in the body
1237
1356
  }
1238
1357
  | k_def singleton dot_or_colon
1239
1358
  {
1240
- self.comments.push self.lexer.comments
1241
1359
  lexer.lex_state = EXPR_FNAME
1242
1360
  }
1243
1361
  fname
1244
1362
  {
1245
- self.in_single += 1
1363
+ result = [self.in_def, lexer.lineno]
1364
+
1365
+ self.in_single += 1 # TODO: remove?
1366
+
1367
+ self.in_def = true # local_push
1246
1368
  self.env.extend
1247
- lexer.lex_state = EXPR_ENDFN # force for args
1248
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1249
- lexer.cmdarg.stack.replace [false]
1369
+ lexer.cmdarg.push false
1370
+ lexer.cond.push false
1371
+
1372
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1373
+ self.comments.push self.lexer.comments
1250
1374
  }
1251
1375
  f_arglist bodystmt k_end
1252
1376
  {
1253
- line, cmdarg = val[5]
1254
- result = new_defs val
1255
- result[3].line line
1377
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1256
1378
 
1257
- lexer.cmdarg.stack.replace cmdarg
1379
+ result = new_defs val
1258
1380
 
1381
+ lexer.cond.pop # group = local_pop
1382
+ lexer.cmdarg.pop
1259
1383
  self.env.unextend
1384
+ self.in_def = in_def
1385
+
1260
1386
  self.in_single -= 1
1387
+
1388
+ # TODO: restore cur_arg ? what's cur_arg?
1389
+
1261
1390
  self.lexer.comments # we don't care about comments in the body
1262
1391
  }
1263
1392
  | kBREAK
1264
1393
  {
1265
- result = s(:break)
1394
+ (_, line), = val
1395
+ result = s(:break).line line
1266
1396
  }
1267
1397
  | kNEXT
1268
1398
  {
1269
- result = s(:next)
1399
+ (_, line), = val
1400
+ result = s(:next).line line
1270
1401
  }
1271
1402
  | kREDO
1272
1403
  {
1273
- result = s(:redo)
1404
+ (_, line), = val
1405
+ result = s(:redo).line line
1274
1406
  }
1275
1407
  | kRETRY
1276
1408
  {
1277
- result = s(:retry)
1409
+ (_, line), = val
1410
+ result = s(:retry).line line
1278
1411
  }
1279
1412
 
1280
1413
  primary_value: primary
@@ -1313,7 +1446,9 @@ rule
1313
1446
  if_tail: opt_else
1314
1447
  | k_elsif expr_value then compstmt if_tail
1315
1448
  {
1316
- result = s(:if, val[1], val[3], val[4])
1449
+ (_, line), c, _, t, rest = val
1450
+
1451
+ result = s(:if, c, t, rest).line line
1317
1452
  }
1318
1453
 
1319
1454
  opt_else: none
@@ -1336,7 +1471,9 @@ rule
1336
1471
 
1337
1472
  f_marg_list: f_marg
1338
1473
  {
1339
- result = s(:array, val[0])
1474
+ sym, = val
1475
+
1476
+ result = s(:array, sym).line lexer.lineno
1340
1477
  }
1341
1478
  | f_marg_list tCOMMA f_marg
1342
1479
  {
@@ -1410,7 +1547,9 @@ rule
1410
1547
  }
1411
1548
  | f_block_arg
1412
1549
  {
1413
- result = call_args val
1550
+ line = lexer.lineno
1551
+ result = call_args val # TODO: push line down
1552
+ result.line line
1414
1553
  }
1415
1554
 
1416
1555
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1441,7 +1580,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1441
1580
  }
1442
1581
  | f_arg tCOMMA
1443
1582
  {
1444
- result = args val
1583
+ result = args(val) << nil
1445
1584
  }
1446
1585
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1447
1586
  {
@@ -1493,7 +1632,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1493
1632
  }
1494
1633
  | tOROP
1495
1634
  {
1496
- result = s(:args)
1635
+ result = s(:args).line lexer.lineno
1497
1636
  }
1498
1637
  | tPIPE block_param opt_bv_decl tPIPE
1499
1638
  {
@@ -1518,34 +1657,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1518
1657
 
1519
1658
  bvar: tIDENTIFIER
1520
1659
  {
1521
- result = s(:shadow, val[0].to_sym)
1660
+ id, = val
1661
+ line = lexer.lineno
1662
+ result = s(:shadow, id.to_sym).line line
1522
1663
  }
1523
1664
  | f_bad_arg
1524
1665
 
1525
1666
  lambda: {
1526
1667
  self.env.extend :dynamic
1527
- result = self.lexer.lineno
1528
-
1529
- result = lexer.lpar_beg
1668
+ result = [lexer.lineno, lexer.lpar_beg]
1530
1669
  lexer.paren_nest += 1
1531
1670
  lexer.lpar_beg = lexer.paren_nest
1532
1671
  }
1533
1672
  f_larglist
1534
1673
  {
1535
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1674
+ lexer.cmdarg.push false
1536
1675
  }
1537
1676
  lambda_body
1538
1677
  {
1539
- lpar, args, (cmdarg, lineno), body = val
1678
+ (line, lpar), args, _cmdarg, body = val
1540
1679
  lexer.lpar_beg = lpar
1541
1680
 
1542
- lexer.cmdarg.restore cmdarg
1543
- lexer.cmdarg.lexpop
1681
+ lexer.cmdarg.pop
1544
1682
 
1545
- call = new_call nil, :lambda
1683
+ call = s(:lambda).line line
1546
1684
  result = new_iter call, args, body
1547
- result.line = lineno
1548
- self.env.unextend
1685
+ result.line = line
1686
+ self.env.unextend # TODO: dynapush & dynapop
1549
1687
  }
1550
1688
 
1551
1689
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1569,8 +1707,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1569
1707
 
1570
1708
  do_block: k_do_block do_body kEND
1571
1709
  {
1572
- # TODO: maybe fix lineno to kDO's lineno?
1573
- result = val[1]
1710
+ (_, line), iter, _ = val
1711
+ result = iter.line line
1574
1712
  }
1575
1713
 
1576
1714
  block_call: command do_block
@@ -1584,8 +1722,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1584
1722
 
1585
1723
  val = invert_block_call val if inverted? val
1586
1724
 
1587
- result = val[1]
1588
- result.insert 1, val[0]
1725
+ cmd, blk = val
1726
+
1727
+ result = blk
1728
+ result.insert 1, cmd
1589
1729
  }
1590
1730
  | block_call call_op2 operation2 opt_paren_args
1591
1731
  {
@@ -1616,8 +1756,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1616
1756
  }
1617
1757
  paren_args
1618
1758
  {
1619
- args = self.call_args val[2..-1]
1620
- result = val[0].concat args.sexp_body
1759
+ call, lineno, args = val
1760
+
1761
+ result = call.concat args.sexp_body if args
1762
+ result.line lineno
1621
1763
  }
1622
1764
  | primary_value call_op operation2 opt_paren_args
1623
1765
  {
@@ -1645,7 +1787,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1645
1787
  }
1646
1788
  | kSUPER
1647
1789
  {
1648
- result = s(:zsuper)
1790
+ result = s(:zsuper).line lexer.lineno
1649
1791
  }
1650
1792
  | primary_value tLBRACK2 opt_call_args rbracket
1651
1793
  {
@@ -1694,15 +1836,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1694
1836
  }
1695
1837
 
1696
1838
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1697
- { result = lexer.cmdarg.store(false) }
1839
+ { lexer.cmdarg.push false }
1698
1840
  opt_block_param
1699
1841
  compstmt
1700
1842
  {
1701
- line, cmdarg, param, cmpstmt = val
1843
+ line, _cmdarg, param, cmpstmt = val
1702
1844
 
1703
1845
  result = new_do_body param, cmpstmt, line
1846
+ lexer.cmdarg.pop
1704
1847
  self.env.unextend
1705
- lexer.cmdarg.restore cmdarg
1706
1848
  }
1707
1849
 
1708
1850
  case_body: k_when
@@ -1723,7 +1865,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1723
1865
  (_, line), klasses, var, _, body, rest = val
1724
1866
 
1725
1867
  klasses ||= s(:array)
1726
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1868
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1727
1869
  klasses.line line
1728
1870
 
1729
1871
  result = new_resbody(klasses, body)
@@ -1736,7 +1878,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1736
1878
 
1737
1879
  exc_list: arg_value
1738
1880
  {
1739
- result = s(:array, val[0])
1881
+ arg, = val
1882
+ result = s(:array, arg).line arg.line
1740
1883
  }
1741
1884
  | mrhs
1742
1885
  | none
@@ -1749,26 +1892,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1749
1892
 
1750
1893
  opt_ensure: k_ensure compstmt
1751
1894
  {
1752
- _, body = val
1895
+ (_, line), body = val
1753
1896
 
1754
- result = body || s(:nil)
1897
+ result = body || s(:nil).line(line)
1755
1898
  }
1756
1899
  | none
1757
1900
 
1758
1901
  literal: numeric
1759
1902
  {
1903
+ line = lexer.lineno
1760
1904
  result = s(:lit, val[0])
1905
+ result.line = line
1761
1906
  }
1762
1907
  | symbol
1763
1908
  {
1909
+ line = lexer.lineno
1764
1910
  result = s(:lit, val[0])
1911
+ result.line = line
1765
1912
  }
1766
1913
  | dsym
1767
1914
 
1768
1915
  strings: string
1769
1916
  {
1770
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1771
- result = val[0]
1917
+ str, = val
1918
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1919
+ result = str
1772
1920
  }
1773
1921
 
1774
1922
  string: tCHAR
@@ -1783,7 +1931,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1783
1931
 
1784
1932
  string1: tSTRING_BEG string_contents tSTRING_END
1785
1933
  {
1786
- result = val[1]
1934
+ _, str, (_, func) = val
1935
+
1936
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1937
+
1938
+ result = str
1787
1939
  }
1788
1940
  | tSTRING
1789
1941
  {
@@ -1792,7 +1944,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1792
1944
 
1793
1945
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1794
1946
  {
1795
- result = new_xstring val[1]
1947
+ result = new_xstring val
1948
+ # TODO: dedent?!?! SERIOUSLY?!?
1796
1949
  }
1797
1950
 
1798
1951
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1802,7 +1955,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1955
 
1803
1956
  words: tWORDS_BEG tSPACE tSTRING_END
1804
1957
  {
1805
- result = s(:array)
1958
+ result = s(:array).line lexer.lineno
1806
1959
  }
1807
1960
  | tWORDS_BEG word_list tSTRING_END
1808
1961
  {
@@ -1826,25 +1979,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1979
 
1827
1980
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1828
1981
  {
1829
- result = s(:array)
1982
+ result = s(:array).line lexer.lineno
1830
1983
  }
1831
- | tSYMBOLS_BEG symbol_list tSTRING_END
1984
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1832
1985
  {
1833
- result = val[1]
1986
+ _, line, list, _, = val
1987
+ list.line = line
1988
+ result = list
1834
1989
  }
1835
1990
 
1836
1991
  symbol_list: none
1837
1992
  {
1838
- result = new_symbol_list
1993
+ result = new_symbol_list.line lexer.lineno
1839
1994
  }
1840
1995
  | symbol_list word tSPACE
1841
1996
  {
1842
- result = val[0].dup << new_symbol_list_entry(val)
1997
+ list, * = val
1998
+ result = list.dup << new_symbol_list_entry(val)
1843
1999
  }
1844
2000
 
1845
2001
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1846
2002
  {
1847
- result = s(:array)
2003
+ result = s(:array).line lexer.lineno
1848
2004
  }
1849
2005
  | tQWORDS_BEG qword_list tSTRING_END
1850
2006
  {
@@ -1853,7 +2009,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1853
2009
 
1854
2010
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1855
2011
  {
1856
- result = s(:array)
2012
+ result = s(:array).line lexer.lineno # FIX
1857
2013
  }
1858
2014
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1859
2015
  {
@@ -1880,11 +2036,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1880
2036
 
1881
2037
  string_contents: none
1882
2038
  {
1883
- result = s(:str, "")
2039
+ result = s(:str, "").line lexer.lineno
1884
2040
  }
1885
2041
  | string_contents string_content
1886
2042
  {
1887
- result = literal_concat(val[0], val[1])
2043
+ v1, v2 = val
2044
+ result = literal_concat v1, v2
1888
2045
  }
1889
2046
 
1890
2047
  xstring_contents: none
@@ -1893,7 +2050,8 @@ xstring_contents: none
1893
2050
  }
1894
2051
  | xstring_contents string_content
1895
2052
  {
1896
- result = literal_concat(val[0], val[1])
2053
+ v1, v2 = val
2054
+ result = literal_concat v1, v2
1897
2055
  }
1898
2056
 
1899
2057
  regexp_contents: none
@@ -1902,7 +2060,8 @@ regexp_contents: none
1902
2060
  }
1903
2061
  | regexp_contents string_content
1904
2062
  {
1905
- result = literal_concat(val[0], val[1])
2063
+ v1, v2 = val
2064
+ result = literal_concat v1, v2
1906
2065
  }
1907
2066
 
1908
2067
  string_content: tSTRING_CONTENT
@@ -1918,19 +2077,22 @@ regexp_contents: none
1918
2077
  }
1919
2078
  string_dvar
1920
2079
  {
1921
- lexer.lex_strterm = val[1]
1922
- result = s(:evstr, val[2])
2080
+ _, strterm, str = val
2081
+ lexer.lex_strterm = strterm
2082
+ result = s(:evstr, str).line str.line
1923
2083
  }
1924
2084
  | tSTRING_DBEG
1925
2085
  {
1926
2086
  result = [lexer.lex_strterm,
1927
2087
  lexer.brace_nest,
1928
2088
  lexer.string_nest, # TODO: remove
1929
- lexer.cond.store,
1930
- lexer.cmdarg.store,
1931
2089
  lexer.lex_state,
2090
+ lexer.lineno,
1932
2091
  ]
1933
2092
 
2093
+ lexer.cmdarg.push false
2094
+ lexer.cond.push false
2095
+
1934
2096
  lexer.lex_strterm = nil
1935
2097
  lexer.brace_nest = 0
1936
2098
  lexer.string_nest = 0
@@ -1942,14 +2104,15 @@ regexp_contents: none
1942
2104
  {
1943
2105
  _, memo, stmt, _ = val
1944
2106
 
1945
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2107
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2108
+ # TODO: heredoc_indent
1946
2109
 
1947
2110
  lexer.lex_strterm = lex_strterm
1948
2111
  lexer.brace_nest = brace_nest
1949
2112
  lexer.string_nest = string_nest
1950
2113
 
1951
- lexer.cond.restore oldcond
1952
- lexer.cmdarg.restore oldcmdarg
2114
+ lexer.cmdarg.pop
2115
+ lexer.cond.pop
1953
2116
 
1954
2117
  lexer.lex_state = oldlex_state
1955
2118
 
@@ -1959,19 +2122,19 @@ regexp_contents: none
1959
2122
  when :str, :dstr, :evstr then
1960
2123
  result = stmt
1961
2124
  else
1962
- result = s(:evstr, stmt)
2125
+ result = s(:evstr, stmt).line line
1963
2126
  end
1964
2127
  when nil then
1965
- result = s(:evstr)
2128
+ result = s(:evstr).line line
1966
2129
  else
1967
2130
  debug20 25
1968
2131
  raise "unknown string body: #{stmt.inspect}"
1969
2132
  end
1970
2133
  }
1971
2134
 
1972
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1973
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1974
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2135
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2136
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2137
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
1975
2138
  | backref
1976
2139
 
1977
2140
  symbol: tSYMBEG sym
@@ -1988,18 +2151,19 @@ regexp_contents: none
1988
2151
 
1989
2152
  dsym: tSYMBEG xstring_contents tSTRING_END
1990
2153
  {
2154
+ _, result, _ = val
2155
+
1991
2156
  lexer.lex_state = EXPR_END
1992
- result = val[1]
1993
2157
 
1994
- result ||= s(:str, "")
2158
+ result ||= s(:str, "").line lexer.lineno
1995
2159
 
1996
2160
  case result.sexp_type
1997
2161
  when :dstr then
1998
2162
  result.sexp_type = :dsym
1999
2163
  when :str then
2000
- result = s(:lit, result.last.to_sym)
2164
+ result = s(:lit, result.last.to_sym).line result.line
2001
2165
  when :evstr then
2002
- result = s(:dsym, "", result)
2166
+ result = s(:dsym, "", result).line result.line
2003
2167
  else
2004
2168
  debug20 26, val, result
2005
2169
  end
@@ -2022,19 +2186,20 @@ regexp_contents: none
2022
2186
  | tCONSTANT
2023
2187
  | tCVAR
2024
2188
 
2025
- keyword_variable: kNIL { result = s(:nil) }
2026
- | kSELF { result = s(:self) }
2027
- | kTRUE { result = s(:true) }
2028
- | kFALSE { result = s(:false) }
2029
- | k__FILE__ { result = s(:str, self.file) }
2030
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2189
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2190
+ | kSELF { result = s(:self).line lexer.lineno }
2191
+ | kTRUE { result = s(:true).line lexer.lineno }
2192
+ | kFALSE { result = s(:false).line lexer.lineno }
2193
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2194
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2031
2195
  | k__ENCODING__
2032
2196
  {
2197
+ l = lexer.lineno
2033
2198
  result =
2034
2199
  if defined? Encoding then
2035
- s(:colon2, s(:const, :Encoding), :UTF_8)
2200
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2036
2201
  else
2037
- s(:str, "Unsupported!")
2202
+ s(:str, "Unsupported!").line l
2038
2203
  end
2039
2204
  }
2040
2205
 
@@ -2059,8 +2224,8 @@ keyword_variable: kNIL { result = s(:nil) }
2059
2224
  debug20 29, val, result
2060
2225
  }
2061
2226
 
2062
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2063
- | tBACK_REF { result = s(:back_ref, val[0]) }
2227
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2228
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2064
2229
 
2065
2230
  superclass: tLT
2066
2231
  {
@@ -2217,12 +2382,13 @@ keyword_variable: kNIL { result = s(:nil) }
2217
2382
 
2218
2383
  f_arg: f_arg_item
2219
2384
  {
2220
- case val[0]
2385
+ arg, = val
2386
+
2387
+ case arg
2221
2388
  when Symbol then
2222
- result = s(:args)
2223
- result << val[0]
2389
+ result = s(:args, arg).line lexer.lineno
2224
2390
  when Sexp then
2225
- result = val[0]
2391
+ result = arg
2226
2392
  else
2227
2393
  debug20 32
2228
2394
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2235,7 +2401,7 @@ keyword_variable: kNIL { result = s(:nil) }
2235
2401
  if list.sexp_type == :args then
2236
2402
  result = list
2237
2403
  else
2238
- result = s(:args, list)
2404
+ result = s(:args, list).line list.line
2239
2405
  end
2240
2406
 
2241
2407
  result << item
@@ -2245,38 +2411,42 @@ keyword_variable: kNIL { result = s(:nil) }
2245
2411
 
2246
2412
  f_kw: f_label arg_value
2247
2413
  {
2248
- # TODO: call_args
2249
- label, _ = val[0] # TODO: fix lineno?
2414
+ # TODO: new_kw_arg
2415
+ (label, line), arg = val
2416
+
2250
2417
  identifier = label.to_sym
2251
2418
  self.env[identifier] = :lvar
2252
2419
 
2253
- result = s(:array, s(:kwarg, identifier, val[1]))
2420
+ kwarg = s(:kwarg, identifier, arg).line line
2421
+ result = s(:array, kwarg).line line
2254
2422
  }
2255
2423
  | f_label
2256
2424
  {
2257
- label, _ = val[0] # TODO: fix lineno?
2258
- identifier = label.to_sym
2259
- self.env[identifier] = :lvar
2425
+ (label, line), = val
2260
2426
 
2261
- result = s(:array, s(:kwarg, identifier))
2427
+ id = label.to_sym
2428
+ self.env[id] = :lvar
2429
+
2430
+ result = s(:array, s(:kwarg, id).line(line)).line line
2262
2431
  }
2263
2432
 
2264
2433
  f_block_kw: f_label primary_value
2265
2434
  {
2266
- # TODO: call_args
2267
- label, _ = val[0] # TODO: fix lineno?
2268
- identifier = label.to_sym
2269
- self.env[identifier] = :lvar
2435
+ # TODO: new_kw_arg
2436
+ (label, line), expr = val
2437
+ id = label.to_sym
2438
+ self.env[id] = :lvar
2270
2439
 
2271
- result = s(:array, s(:kwarg, identifier, val[1]))
2440
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2272
2441
  }
2273
2442
  | f_label
2274
2443
  {
2275
- label, _ = val[0] # TODO: fix lineno?
2276
- identifier = label.to_sym
2277
- self.env[identifier] = :lvar
2444
+ # TODO: new_kw_arg
2445
+ (label, line), = val
2446
+ id = label.to_sym
2447
+ self.env[id] = :lvar
2278
2448
 
2279
- result = s(:array, s(:kwarg, identifier))
2449
+ result = s(:array, s(:kwarg, id).line(line)).line line
2280
2450
  }
2281
2451
 
2282
2452
  f_block_kwarg: f_block_kw
@@ -2319,17 +2489,20 @@ keyword_variable: kNIL { result = s(:nil) }
2319
2489
 
2320
2490
  f_block_optarg: f_block_opt
2321
2491
  {
2322
- result = s(:block, val[0])
2492
+ optblk, = val
2493
+ result = s(:block, optblk).line optblk.line
2323
2494
  }
2324
2495
  | f_block_optarg tCOMMA f_block_opt
2325
2496
  {
2326
- result = val[0]
2327
- result << val[2]
2497
+ optarg, _, optblk = val
2498
+ result = optarg
2499
+ result << optblk
2328
2500
  }
2329
2501
 
2330
2502
  f_optarg: f_opt
2331
2503
  {
2332
- result = s(:block, val[0])
2504
+ opt, = val
2505
+ result = s(:block, opt).line opt.line
2333
2506
  }
2334
2507
  | f_optarg tCOMMA f_opt
2335
2508
  {
@@ -2383,14 +2556,11 @@ keyword_variable: kNIL { result = s(:nil) }
2383
2556
  result.sexp_type == :lit
2384
2557
  }
2385
2558
 
2386
- assoc_list: none # [!nil]
2559
+ assoc_list: none
2387
2560
  {
2388
- result = s(:array)
2389
- }
2390
- | assocs trailer # [!nil]
2391
- {
2392
- result = val[0]
2561
+ result = s(:array).line lexer.lineno
2393
2562
  }
2563
+ | assocs trailer
2394
2564
 
2395
2565
  assocs: assoc
2396
2566
  | assocs tCOMMA assoc
@@ -2404,22 +2574,27 @@ keyword_variable: kNIL { result = s(:nil) }
2404
2574
 
2405
2575
  assoc: arg_value tASSOC arg_value
2406
2576
  {
2407
- result = s(:array, val[0], val[2])
2577
+ v1, _, v2 = val
2578
+ result = s(:array, v1, v2).line v1.line
2408
2579
  }
2409
2580
  | tLABEL arg_value
2410
2581
  {
2411
- (label, _), arg = val
2412
- result = s(:array, s(:lit, label.to_sym), arg)
2582
+ (label, line), arg = val
2583
+
2584
+ lit = s(:lit, label.to_sym).line line
2585
+ result = s(:array, lit, arg).line line
2413
2586
  }
2414
2587
  | tSTRING_BEG string_contents tLABEL_END arg_value
2415
2588
  {
2416
2589
  _, sym, _, value = val
2417
2590
  sym.sexp_type = :dsym
2418
- result = s(:array, sym, value)
2591
+ result = s(:array, sym, value).line sym.line
2419
2592
  }
2420
2593
  | tDSTAR arg_value
2421
2594
  {
2422
- result = s(:array, s(:kwsplat, val[1]))
2595
+ _, arg = val
2596
+ line = arg.line
2597
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2423
2598
  }
2424
2599
 
2425
2600
  operation: tIDENTIFIER | tCONSTANT | tFID