ruby_parser 3.13.1 → 3.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
  {
@@ -274,28 +278,37 @@ rule
274
278
  }
275
279
  | command_call kRESCUE_MOD stmt
276
280
  {
277
- expr, _, resbody = val
281
+ expr, (_, line), resbody = val
282
+
278
283
  expr = value_expr expr
279
- result = new_rescue(expr, new_resbody(s(:array), resbody))
284
+ ary = s(:array).line line
285
+ result = new_rescue(expr, new_resbody(ary, resbody))
280
286
  }
281
287
  | command_asgn
282
288
 
283
289
  expr: command_call
284
290
  | expr kAND expr
285
291
  {
286
- result = logical_op :and, val[0], val[2]
292
+ lhs, _, rhs = val
293
+ result = logical_op :and, lhs, rhs
287
294
  }
288
295
  | expr kOR expr
289
296
  {
290
- result = logical_op :or, val[0], val[2]
297
+ lhs, _, rhs = val
298
+ result = logical_op :or, lhs, rhs
291
299
  }
292
300
  | kNOT opt_nl expr
293
301
  {
294
- result = s(:call, val[2], :"!")
302
+ (_, line), _, expr = val
303
+ result = new_call(expr, :"!").line line
304
+ # REFACTOR: call_uni_op
295
305
  }
296
306
  | tBANG command_call
297
307
  {
298
- result = s(:call, val[1], :"!")
308
+ _, cmd = val
309
+ result = new_call(cmd, :"!").line cmd.line
310
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
+ # REFACTOR: call_uni_op -- see parse26.y
299
312
  }
300
313
  | arg
301
314
 
@@ -322,7 +335,8 @@ rule
322
335
  block_command: block_call
323
336
  | block_call call_op2 operation2 command_args
324
337
  {
325
- result = new_call val[0], val[2].to_sym, val[3]
338
+ blk, _, msg, args = val
339
+ result = new_call(blk, msg.to_sym, args).line blk.line
326
340
  }
327
341
 
328
342
  cmd_brace_block: tLBRACE_ARG
@@ -342,26 +356,32 @@ rule
342
356
 
343
357
  fcall: operation
344
358
  {
345
- result = new_call nil, val[0].to_sym
359
+ msg, = val
360
+ result = new_call(nil, msg.to_sym).line lexer.lineno
346
361
  }
347
362
 
348
363
  command: fcall command_args =tLOWEST
349
364
  {
350
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
365
+ call, args = val
366
+ result = call.concat args.sexp_body
351
367
  }
352
368
  | fcall command_args cmd_brace_block
353
369
  {
354
- result = val[0].concat val[1].sexp_body
355
- if val[2] then
356
- block_dup_check result, val[2]
370
+ call, args, block = val
357
371
 
358
- result, operation = val[2], result
372
+ result = call.concat args.sexp_body
373
+
374
+ if block then
375
+ block_dup_check result, block
376
+
377
+ result, operation = block, result
359
378
  result.insert 1, operation
360
379
  end
361
380
  }
362
381
  | primary_value call_op operation2 command_args =tLOWEST
363
382
  {
364
- result = new_call val[0], val[2].to_sym, val[3], val[1]
383
+ lhs, callop, op, args = val
384
+ result = new_call lhs, op.to_sym, args, callop
365
385
  }
366
386
  | primary_value call_op operation2 command_args cmd_brace_block
367
387
  {
@@ -393,7 +413,9 @@ rule
393
413
  }
394
414
  | kYIELD command_args
395
415
  {
396
- result = new_yield val[1]
416
+ (_, line), args = val
417
+ result = new_yield args
418
+ result.line line # TODO: push to new_yield
397
419
  }
398
420
  | k_return call_args
399
421
  {
@@ -402,8 +424,8 @@ rule
402
424
  }
403
425
  | kBREAK call_args
404
426
  {
405
- line = val[0].last
406
- result = s(:break, ret_args(val[1])).line(line)
427
+ (_, line), args = val
428
+ result = s(:break, ret_args(args)).line line
407
429
  }
408
430
  | kNEXT call_args
409
431
  {
@@ -420,56 +442,79 @@ rule
420
442
  mlhs_inner: mlhs_basic
421
443
  | tLPAREN mlhs_inner rparen
422
444
  {
423
- result = s(:masgn, s(:array, val[1]))
445
+ _, arg, _ = val
446
+ l = arg.line
447
+
448
+ result = s(:masgn, s(:array, arg).line(l)).line l
424
449
  }
425
450
 
426
451
  mlhs_basic: mlhs_head
427
452
  {
428
- result = s(:masgn, val[0])
453
+ head, = val
454
+ result = s(:masgn, head).line head.line
429
455
  }
430
456
  | mlhs_head mlhs_item
431
457
  {
432
- result = s(:masgn, val[0] << val[1].compact)
458
+ lhs, rhs = val
459
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
433
460
  }
434
461
  | mlhs_head tSTAR mlhs_node
435
462
  {
436
- result = s(:masgn, val[0] << s(:splat, val[2]))
463
+ head, _, tail = val
464
+ head << s(:splat, tail).line(tail.line)
465
+ result = s(:masgn, head).line head.line
437
466
  }
438
467
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
439
468
  {
440
469
  ary1, _, splat, _, ary2 = val
441
470
 
442
- result = list_append ary1, s(:splat, splat)
471
+ result = list_append ary1, s(:splat, splat).line(splat.line)
443
472
  result.concat ary2.sexp_body
444
- result = s(:masgn, result)
473
+ result = s(:masgn, result).line result.line
445
474
  }
446
475
  | mlhs_head tSTAR
447
476
  {
448
- result = s(:masgn, val[0] << s(:splat))
477
+ head, _ = val
478
+ l = head.line
479
+ result = s(:masgn, head << s(:splat).line(l)).line l
449
480
  }
450
481
  | mlhs_head tSTAR tCOMMA mlhs_post
451
482
  {
452
- ary = list_append val[0], s(:splat)
453
- ary.concat val[3].sexp_body
454
- result = s(:masgn, ary)
483
+ head, _, _, post = val
484
+ ary = list_append head, s(:splat).line(head.line)
485
+ ary.concat post.sexp_body
486
+ result = s(:masgn, ary).line ary.line
455
487
  }
456
488
  | tSTAR mlhs_node
457
489
  {
458
- result = s(:masgn, s(:array, s(:splat, val[1])))
490
+ _, node = val
491
+ l = node.line
492
+ splat = s(:splat, node).line l
493
+ ary = s(:array, splat).line l
494
+ result = s(:masgn, ary).line l
459
495
  }
460
496
  | tSTAR mlhs_node tCOMMA mlhs_post
461
497
  {
462
- ary = s(:array, s(:splat, val[1]))
463
- ary.concat val[3].sexp_body
464
- result = s(:masgn, ary)
498
+ _, node, _, post = val
499
+
500
+ splat = s(:splat, node).line node.line
501
+ ary = s(:array, splat).line splat.line
502
+ ary.concat post.sexp_body
503
+ result = s(:masgn, ary).line ary.line
465
504
  }
466
505
  | tSTAR
467
506
  {
468
- result = s(:masgn, s(:array, s(:splat)))
507
+ l = lexer.lineno
508
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
469
509
  }
470
510
  | tSTAR tCOMMA mlhs_post
471
511
  {
472
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
512
+ _, _, post = val
513
+ l = post.line
514
+
515
+ splat = s(:splat).line l
516
+ ary = s(:array, splat, *post.sexp_body).line l
517
+ result = s(:masgn, ary).line l
473
518
  }
474
519
 
475
520
  mlhs_item: mlhs_node
@@ -480,7 +525,8 @@ rule
480
525
 
481
526
  mlhs_head: mlhs_item tCOMMA
482
527
  {
483
- result = s(:array, val[0])
528
+ lhs, _ = val
529
+ result = s(:array, lhs).line lhs.line
484
530
  }
485
531
  | mlhs_head mlhs_item tCOMMA
486
532
  {
@@ -489,7 +535,8 @@ rule
489
535
 
490
536
  mlhs_post: mlhs_item
491
537
  {
492
- result = s(:array, val[0])
538
+ item, = val
539
+ result = s(:array, item).line item.line
493
540
  }
494
541
  | mlhs_post tCOMMA mlhs_item
495
542
  {
@@ -514,7 +561,8 @@ rule
514
561
  }
515
562
  | primary_value tCOLON2 tIDENTIFIER
516
563
  {
517
- result = s(:attrasgn, val[0], :"#{val[2]}=")
564
+ recv, _, id = val
565
+ result = new_attrasgn recv, id
518
566
  }
519
567
  | primary_value call_op tCONSTANT
520
568
  {
@@ -527,7 +575,10 @@ rule
527
575
  yyerror "dynamic constant assignment"
528
576
  end
529
577
 
530
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
578
+ expr, _, id = val
579
+ l = expr.line
580
+
581
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
531
582
  }
532
583
  | tCOLON3 tCONSTANT
533
584
  {
@@ -536,7 +587,10 @@ rule
536
587
  yyerror "dynamic constant assignment"
537
588
  end
538
589
 
539
- result = s(:const, nil, s(:colon3, val[1].to_sym))
590
+ _, id = val
591
+ l = lexer.lineno
592
+
593
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
540
594
  }
541
595
  | backref
542
596
  {
@@ -545,24 +599,31 @@ rule
545
599
 
546
600
  lhs: user_variable
547
601
  {
602
+ line = lexer.lineno
548
603
  result = self.assignable val[0]
604
+ result.line = line
549
605
  }
550
606
  | keyword_variable
551
607
  {
608
+ line = lexer.lineno
552
609
  result = self.assignable val[0]
610
+ result.line = line
553
611
  debug20 9, val, result
554
612
  }
555
613
  | primary_value tLBRACK2 opt_call_args rbracket
556
614
  {
557
- result = self.aryset val[0], val[2]
615
+ lhs, _, args, _ = val
616
+ result = self.aryset lhs, args
558
617
  }
559
618
  | primary_value call_op tIDENTIFIER # REFACTOR
560
619
  {
561
- result = new_attrasgn val[0], val[2], val[1]
620
+ lhs, op, id = val
621
+ result = new_attrasgn lhs, id, op
562
622
  }
563
623
  | primary_value tCOLON2 tIDENTIFIER
564
624
  {
565
- result = s(:attrasgn, val[0], :"#{val[2]}=")
625
+ lhs, _, id = val
626
+ result = new_attrasgn lhs, id
566
627
  }
567
628
  | primary_value call_op tCONSTANT # REFACTOR?
568
629
  {
@@ -570,21 +631,27 @@ rule
570
631
  }
571
632
  | primary_value tCOLON2 tCONSTANT
572
633
  {
634
+ expr, _, id = val
635
+
573
636
  if (self.in_def || self.in_single > 0) then
574
637
  debug20 10
575
638
  yyerror "dynamic constant assignment"
576
639
  end
577
640
 
578
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
641
+ l = expr.line
642
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
579
643
  }
580
644
  | tCOLON3 tCONSTANT
581
645
  {
646
+ _, id = val
647
+
582
648
  if (self.in_def || self.in_single > 0) then
583
649
  debug20 11
584
650
  yyerror "dynamic constant assignment"
585
651
  end
586
652
 
587
- result = s(:const, s(:colon3, val[1].to_sym))
653
+ l = lexer.lineno
654
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
588
655
  }
589
656
  | backref
590
657
  {
@@ -599,7 +666,8 @@ rule
599
666
 
600
667
  cpath: tCOLON3 cname
601
668
  {
602
- result = s(:colon3, val[1].to_sym)
669
+ _, name = val
670
+ result = s(:colon3, name.to_sym).line lexer.lineno
603
671
  }
604
672
  | cname
605
673
  {
@@ -607,7 +675,10 @@ rule
607
675
  }
608
676
  | primary_value tCOLON2 cname
609
677
  {
610
- result = s(:colon2, val[0], val[2].to_sym)
678
+ pval, _, name = val
679
+
680
+ result = s(:colon2, pval, name.to_sym)
681
+ result.line pval.line
611
682
  }
612
683
 
613
684
  fname: tIDENTIFIER | tCONSTANT | tFID
@@ -628,7 +699,8 @@ rule
628
699
 
629
700
  fitem: fsym
630
701
  {
631
- result = s(:lit, val[0].to_sym)
702
+ id, = val
703
+ result = s(:lit, id.to_sym).line lexer.lineno
632
704
  }
633
705
  | dsym
634
706
 
@@ -651,6 +723,7 @@ rule
651
723
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
652
724
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
653
725
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
+ # TODO: tUBANG dead?
654
727
  | tUBANG
655
728
 
656
729
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
@@ -673,8 +746,7 @@ rule
673
746
  }
674
747
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
675
748
  {
676
- val[2].sexp_type = :arglist if val[2]
677
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
749
+ result = new_op_asgn1 val
678
750
  }
679
751
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
680
752
  {
@@ -686,7 +758,9 @@ rule
686
758
  }
687
759
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
688
760
  {
689
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
761
+ lhs, _, id, op, rhs = val
762
+
763
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
690
764
  }
691
765
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
692
766
  {
@@ -716,31 +790,33 @@ rule
716
790
  {
717
791
  v1, v2 = val[0], val[2]
718
792
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
719
- result = s(:lit, (v1.last)..(v2.last))
793
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
720
794
  else
721
- result = s(:dot2, v1, v2)
795
+ result = s(:dot2, v1, v2).line v1.line
722
796
  end
723
797
  }
724
798
  | arg tDOT3 arg
725
799
  {
726
800
  v1, v2 = val[0], val[2]
727
801
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
728
- result = s(:lit, (v1.last)...(v2.last))
802
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
729
803
  else
730
- result = s(:dot3, v1, v2)
804
+ result = s(:dot3, v1, v2).line v1.line
731
805
  end
732
806
  }
733
807
  | arg tDOT2
734
808
  {
735
- v1, v2 = val[0], nil
809
+ v1, _ = val
810
+ v2 = nil
736
811
 
737
- result = s(:dot2, v1, v2)
812
+ result = s(:dot2, v1, v2).line v1.line
738
813
  }
739
814
  | arg tDOT3
740
815
  {
741
- v1, v2 = val[0], nil
816
+ v1, _ = val
817
+ v2 = nil
742
818
 
743
- result = s(:dot3, v1, v2)
819
+ result = s(:dot3, v1, v2).line v1.line
744
820
  }
745
821
  | arg tPLUS arg
746
822
  {
@@ -768,7 +844,9 @@ rule
768
844
  }
769
845
  | tUMINUS_NUM simple_numeric tPOW arg
770
846
  {
771
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
847
+ lit = s(:lit, val[1]).line lexer.lineno
848
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
849
+
772
850
  }
773
851
  | tUPLUS arg
774
852
  {
@@ -809,15 +887,19 @@ rule
809
887
  }
810
888
  | arg tMATCH arg
811
889
  {
812
- result = new_match val[0], val[2]
890
+ lhs, _, rhs = val
891
+ result = new_match lhs, rhs
813
892
  }
814
893
  | arg tNMATCH arg
815
894
  {
816
- result = s(:not, new_match(val[0], val[2]))
895
+ lhs, _, rhs = val
896
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
817
897
  }
818
898
  | tBANG arg
819
899
  {
820
- result = new_call val[1], :"!"
900
+ _, arg = val
901
+ result = new_call arg, :"!"
902
+ result.line arg.line
821
903
  }
822
904
  | tTILDE arg
823
905
  {
@@ -845,11 +927,13 @@ rule
845
927
  }
846
928
  | kDEFINED opt_nl arg
847
929
  {
848
- result = s(:defined, val[2])
930
+ (_, line), _, arg = val
931
+ result = s(:defined, arg).line line
849
932
  }
850
933
  | arg tEH arg opt_nl tCOLON arg
851
934
  {
852
- result = s(:if, val[0], val[2], val[5])
935
+ c, _, t, _, _, f = val
936
+ result = s(:if, c, t, f).line c.line
853
937
  }
854
938
  | primary
855
939
 
@@ -892,28 +976,25 @@ rule
892
976
  arg_rhs: arg =tOP_ASGN
893
977
  | arg kRESCUE_MOD arg
894
978
  {
895
- body, _, resbody = val
979
+ body, (_, line), resbody = val
896
980
  body = value_expr body
897
981
  resbody = remove_begin resbody
898
- result = new_rescue(body, new_resbody(s(:array), resbody))
982
+
983
+ ary = s(:array).line line
984
+ result = new_rescue(body, new_resbody(ary, resbody))
899
985
  }
900
986
 
901
987
  paren_args: tLPAREN2 opt_call_args rparen
902
988
  {
903
- result = val[1]
989
+ _, args, _ = val
990
+ result = args
904
991
  }
905
992
 
906
993
  opt_paren_args: none
907
994
  | paren_args
908
995
 
909
996
  opt_call_args: none
910
- {
911
- result = val[0]
912
- }
913
997
  | call_args
914
- {
915
- result = val[0]
916
- }
917
998
  | args tCOMMA
918
999
  {
919
1000
  result = args val
@@ -935,17 +1016,14 @@ rule
935
1016
  | args opt_block_arg
936
1017
  {
937
1018
  result = call_args val
938
- result = self.arg_blk_pass val[0], val[1]
939
1019
  }
940
1020
  | assocs opt_block_arg
941
1021
  {
942
- result = call_args [array_to_hash(val[0])]
943
- result = self.arg_blk_pass result, val[1]
1022
+ result = call_args [array_to_hash(val[0]), val[1]]
944
1023
  }
945
1024
  | args tCOMMA assocs opt_block_arg
946
1025
  {
947
- result = call_args [val[0], array_to_hash(val[2])]
948
- result = self.arg_blk_pass result, val[3]
1026
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
949
1027
  }
950
1028
  | block_arg
951
1029
  {
@@ -953,17 +1031,45 @@ rule
953
1031
  }
954
1032
 
955
1033
  command_args: {
956
- result = lexer.cmdarg.store true
1034
+ # parse26.y line 2200
1035
+
1036
+ # If call_args starts with a open paren '(' or
1037
+ # '[', look-ahead reading of the letters calls
1038
+ # CMDARG_PUSH(0), but the push must be done
1039
+ # after CMDARG_PUSH(1). So this code makes them
1040
+ # consistent by first cancelling the premature
1041
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1042
+ # finally redoing CMDARG_PUSH(0).
1043
+
1044
+ result = yychar = self.last_token_type.first
1045
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1046
+ lexer.cmdarg.pop if lookahead
1047
+ lexer.cmdarg.push true
1048
+ lexer.cmdarg.push false if lookahead
957
1049
  }
958
1050
  call_args
959
1051
  {
960
- lexer.cmdarg.restore val[0]
961
- result = val[1]
1052
+ yychar, args = val
1053
+
1054
+ # call_args can be followed by tLBRACE_ARG (that
1055
+ # does CMDARG_PUSH(0) in the lexer) but the push
1056
+ # must be done after CMDARG_POP() in the parser.
1057
+ # So this code does CMDARG_POP() to pop 0 pushed
1058
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1059
+ # by command_args, and CMDARG_PUSH(0) to restore
1060
+ # back the flag set by tLBRACE_ARG.
1061
+
1062
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1063
+ lexer.cmdarg.pop if lookahead
1064
+ lexer.cmdarg.pop
1065
+ lexer.cmdarg.push false if lookahead
1066
+ result = args
962
1067
  }
963
1068
 
964
1069
  block_arg: tAMPER arg_value
965
1070
  {
966
- result = s(:block_pass, val[1])
1071
+ _, arg = val
1072
+ result = s(:block_pass, arg).line arg.line
967
1073
  }
968
1074
 
969
1075
  opt_block_arg: tCOMMA block_arg
@@ -974,19 +1080,27 @@ rule
974
1080
 
975
1081
  args: arg_value
976
1082
  {
977
- result = s(:array, val[0])
1083
+ arg, = val
1084
+ lineno = arg.line || lexer.lineno # HACK
1085
+
1086
+ result = s(:array, arg).line lineno
978
1087
  }
979
1088
  | tSTAR arg_value
980
1089
  {
981
- result = s(:array, s(:splat, val[1]))
1090
+ _, arg = val
1091
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
982
1092
  }
983
1093
  | args tCOMMA arg_value
984
1094
  {
985
- result = self.list_append val[0], val[2]
1095
+ args, _, id = val
1096
+ result = self.list_append args, id
986
1097
  }
987
1098
  | args tCOMMA tSTAR arg_value
988
1099
  {
989
- result = self.list_append val[0], s(:splat, val[3])
1100
+ # TODO: the line number from tSTAR has been dropped
1101
+ args, _, _, id = val
1102
+ line = lexer.lineno
1103
+ result = self.list_append args, s(:splat, id).line(line)
990
1104
  }
991
1105
 
992
1106
  mrhs_arg: mrhs
@@ -1004,11 +1118,14 @@ rule
1004
1118
  }
1005
1119
  | args tCOMMA tSTAR arg_value
1006
1120
  {
1007
- result = self.arg_concat val[0], val[3]
1121
+ # TODO: make all tXXXX terminals include lexer.lineno
1122
+ arg, _, _, splat = val
1123
+ result = self.arg_concat arg, splat
1008
1124
  }
1009
1125
  | tSTAR arg_value
1010
1126
  {
1011
- result = s(:splat, val[1])
1127
+ _, arg = val
1128
+ result = s(:splat, arg).line arg.line
1012
1129
  }
1013
1130
 
1014
1131
  primary: literal
@@ -1023,65 +1140,65 @@ rule
1023
1140
  | backref
1024
1141
  | tFID
1025
1142
  {
1026
- result = new_call nil, val[0].to_sym
1143
+ msg, = val
1144
+ result = new_call nil, msg.to_sym
1027
1145
  }
1028
1146
  | k_begin
1029
1147
  {
1148
+ lexer.cmdarg.push false
1030
1149
  result = self.lexer.lineno
1031
- # TODO:
1032
- # $<val>1 = cmdarg_stack;
1033
- # CMDARG_SET(0);
1034
1150
  }
1035
1151
  bodystmt k_end
1036
1152
  {
1037
- # TODO: CMDARG_SET($<val>1);
1038
- unless val[2] then
1039
- result = s(:nil)
1040
- else
1041
- result = s(:begin, val[2])
1042
- end
1043
-
1044
- result.line = val[1]
1153
+ lexer.cmdarg.pop
1154
+ result = new_begin val
1045
1155
  }
1046
- | tLPAREN_ARG rparen
1156
+ | tLPAREN_ARG
1047
1157
  {
1048
- # TODO: lex_state = EXPR_ENDARG in between
1049
- debug20 13, val, result
1158
+ lexer.lex_state = EXPR_ENDARG
1159
+ result = lexer.lineno
1050
1160
  }
1051
- | tLPAREN_ARG
1161
+ rparen
1052
1162
  {
1053
- result = lexer.cmdarg.store false
1054
- # result = self.lexer.cmdarg.stack.dup
1055
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1163
+ _, line, _ = val
1164
+ result = s(:begin).line line
1056
1165
  }
1166
+ | tLPAREN_ARG
1057
1167
  stmt
1058
1168
  {
1059
1169
  lexer.lex_state = EXPR_ENDARG
1060
1170
  }
1061
1171
  rparen
1062
1172
  {
1063
- _, cmdarg, stmt, _, _, = val
1064
- warning "(...) interpreted as grouped expression"
1065
- lexer.cmdarg.restore cmdarg
1173
+ _, stmt, _, _, = val
1174
+ # warning "(...) interpreted as grouped expression"
1066
1175
  result = stmt
1067
1176
  }
1068
1177
  | tLPAREN compstmt tRPAREN
1069
1178
  {
1070
- result = val[1] || s(:nil)
1179
+ _, stmt, _ = val
1180
+ result = stmt
1181
+ result ||= s(:nil).line lexer.lineno
1071
1182
  result.paren = true
1072
1183
  }
1073
1184
  | primary_value tCOLON2 tCONSTANT
1074
1185
  {
1075
- result = s(:colon2, val[0], val[2].to_sym)
1186
+ expr, _, id = val
1187
+
1188
+ result = s(:colon2, expr, id.to_sym).line expr.line
1076
1189
  }
1077
1190
  | tCOLON3 tCONSTANT
1078
1191
  {
1079
- result = s(:colon3, val[1].to_sym)
1192
+ _, id = val
1193
+
1194
+ result = s(:colon3, id.to_sym).line lexer.lineno
1080
1195
  }
1081
- | tLBRACK aref_args tRBRACK
1196
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1082
1197
  {
1083
- result = val[1] || s(:array)
1198
+ _, line, args, _ = val
1199
+ result = args || s(:array)
1084
1200
  result.sexp_type = :array # aref_args is :args
1201
+ result.line line
1085
1202
  }
1086
1203
  | tLBRACE
1087
1204
  {
@@ -1093,7 +1210,8 @@ rule
1093
1210
  }
1094
1211
  | k_return
1095
1212
  {
1096
- result = s(:return)
1213
+ (_, line), = val
1214
+ result = s(:return).line line
1097
1215
  }
1098
1216
  | kYIELD tLPAREN2 call_args rparen
1099
1217
  {
@@ -1109,11 +1227,14 @@ rule
1109
1227
  }
1110
1228
  | kDEFINED opt_nl tLPAREN2 expr rparen
1111
1229
  {
1112
- result = s(:defined, val[3])
1230
+ (_, line), _, _, arg, _ = val
1231
+
1232
+ result = s(:defined, arg).line line
1113
1233
  }
1114
1234
  | kNOT tLPAREN2 expr rparen
1115
1235
  {
1116
- result = s(:call, val[2], :"!")
1236
+ _, _, lhs, _ = val
1237
+ result = new_call lhs, :"!"
1117
1238
  }
1118
1239
  | kNOT tLPAREN2 rparen
1119
1240
  {
@@ -1121,11 +1242,11 @@ rule
1121
1242
  }
1122
1243
  | fcall brace_block
1123
1244
  {
1124
- oper, iter = val[0], val[1]
1125
- call = oper # FIX
1245
+ call, iter = val
1246
+
1126
1247
  iter.insert 1, call
1127
1248
  result = iter
1128
- call.line = iter.line
1249
+ # FIX: probably not: call.line = iter.line
1129
1250
  }
1130
1251
  | method_call
1131
1252
  | method_call brace_block
@@ -1233,66 +1354,82 @@ rule
1233
1354
  }
1234
1355
  | k_def fname
1235
1356
  {
1236
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1357
+ result = self.in_def
1237
1358
 
1238
- self.comments.push self.lexer.comments
1239
- self.in_def = true
1359
+ self.in_def = true # group = local_push
1240
1360
  self.env.extend
1241
- # TODO: local->cmdargs = cmdarg_stack;
1242
- # TODO: port local_push_gen and local_pop_gen
1243
- lexer.cmdarg.stack.replace [false]
1361
+ lexer.cmdarg.push false
1362
+ lexer.cond.push false
1363
+
1364
+ self.comments.push self.lexer.comments
1244
1365
  }
1245
- f_arglist bodystmt k_end
1366
+ f_arglist bodystmt { result = lexer.lineno } k_end
1246
1367
  {
1247
- in_def, cmdarg = val[2]
1368
+ in_def = val[2]
1248
1369
 
1249
1370
  result = new_defn val
1250
1371
 
1251
- lexer.cmdarg.stack.replace cmdarg
1372
+ lexer.cond.pop # group = local_pop
1373
+ lexer.cmdarg.pop
1252
1374
  self.env.unextend
1253
1375
  self.in_def = in_def
1376
+
1254
1377
  self.lexer.comments # we don't care about comments in the body
1255
1378
  }
1256
1379
  | k_def singleton dot_or_colon
1257
1380
  {
1258
- self.comments.push self.lexer.comments
1259
1381
  lexer.lex_state = EXPR_FNAME
1260
1382
  }
1261
1383
  fname
1262
1384
  {
1263
- self.in_single += 1
1385
+ result = [self.in_def, lexer.lineno]
1386
+
1387
+ self.in_single += 1 # TODO: remove?
1388
+
1389
+ self.in_def = true # local_push
1264
1390
  self.env.extend
1265
- lexer.lex_state = EXPR_ENDFN # force for args
1266
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1267
- lexer.cmdarg.stack.replace [false]
1391
+ lexer.cmdarg.push false
1392
+ lexer.cond.push false
1393
+
1394
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1395
+ self.comments.push self.lexer.comments
1268
1396
  }
1269
1397
  f_arglist bodystmt k_end
1270
1398
  {
1271
- line, cmdarg = val[5]
1272
- result = new_defs val
1273
- result[3].line line
1399
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1274
1400
 
1275
- lexer.cmdarg.stack.replace cmdarg
1401
+ result = new_defs val
1276
1402
 
1403
+ lexer.cond.pop # group = local_pop
1404
+ lexer.cmdarg.pop
1277
1405
  self.env.unextend
1406
+ self.in_def = in_def
1407
+
1278
1408
  self.in_single -= 1
1409
+
1410
+ # TODO: restore cur_arg ? what's cur_arg?
1411
+
1279
1412
  self.lexer.comments # we don't care about comments in the body
1280
1413
  }
1281
1414
  | kBREAK
1282
1415
  {
1283
- result = s(:break)
1416
+ (_, line), = val
1417
+ result = s(:break).line line
1284
1418
  }
1285
1419
  | kNEXT
1286
1420
  {
1287
- result = s(:next)
1421
+ (_, line), = val
1422
+ result = s(:next).line line
1288
1423
  }
1289
1424
  | kREDO
1290
1425
  {
1291
- result = s(:redo)
1426
+ (_, line), = val
1427
+ result = s(:redo).line line
1292
1428
  }
1293
1429
  | kRETRY
1294
1430
  {
1295
- result = s(:retry)
1431
+ (_, line), = val
1432
+ result = s(:retry).line line
1296
1433
  }
1297
1434
 
1298
1435
  primary_value: primary
@@ -1331,7 +1468,9 @@ rule
1331
1468
  if_tail: opt_else
1332
1469
  | k_elsif expr_value then compstmt if_tail
1333
1470
  {
1334
- result = s(:if, val[1], val[3], val[4])
1471
+ (_, line), c, _, t, rest = val
1472
+
1473
+ result = s(:if, c, t, rest).line line
1335
1474
  }
1336
1475
 
1337
1476
  opt_else: none
@@ -1354,7 +1493,9 @@ rule
1354
1493
 
1355
1494
  f_marg_list: f_marg
1356
1495
  {
1357
- result = s(:array, val[0])
1496
+ sym, = val
1497
+
1498
+ result = s(:array, sym).line lexer.lineno
1358
1499
  }
1359
1500
  | f_marg_list tCOMMA f_marg
1360
1501
  {
@@ -1428,7 +1569,9 @@ rule
1428
1569
  }
1429
1570
  | f_block_arg
1430
1571
  {
1431
- result = call_args val
1572
+ line = lexer.lineno
1573
+ result = call_args val # TODO: push line down
1574
+ result.line line
1432
1575
  }
1433
1576
 
1434
1577
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1459,7 +1602,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1459
1602
  }
1460
1603
  | f_arg tCOMMA
1461
1604
  {
1462
- result = args val
1605
+ result = args(val) << nil
1463
1606
  }
1464
1607
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1465
1608
  {
@@ -1511,7 +1654,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1511
1654
  }
1512
1655
  | tOROP
1513
1656
  {
1514
- result = s(:args)
1657
+ result = s(:args).line lexer.lineno
1515
1658
  }
1516
1659
  | tPIPE block_param opt_bv_decl tPIPE
1517
1660
  {
@@ -1536,34 +1679,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1536
1679
 
1537
1680
  bvar: tIDENTIFIER
1538
1681
  {
1539
- result = s(:shadow, val[0].to_sym)
1682
+ id, = val
1683
+ line = lexer.lineno
1684
+ result = s(:shadow, id.to_sym).line line
1540
1685
  }
1541
1686
  | f_bad_arg
1542
1687
 
1543
1688
  lambda: {
1544
1689
  self.env.extend :dynamic
1545
- result = self.lexer.lineno
1546
-
1547
- result = lexer.lpar_beg
1690
+ result = [lexer.lineno, lexer.lpar_beg]
1548
1691
  lexer.paren_nest += 1
1549
1692
  lexer.lpar_beg = lexer.paren_nest
1550
1693
  }
1551
1694
  f_larglist
1552
1695
  {
1553
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1696
+ lexer.cmdarg.push false
1554
1697
  }
1555
1698
  lambda_body
1556
1699
  {
1557
- lpar, args, (cmdarg, lineno), body = val
1700
+ (line, lpar), args, _cmdarg, body = val
1558
1701
  lexer.lpar_beg = lpar
1559
1702
 
1560
- lexer.cmdarg.restore cmdarg
1561
- lexer.cmdarg.lexpop
1703
+ lexer.cmdarg.pop
1562
1704
 
1563
- call = new_call nil, :lambda
1705
+ call = s(:lambda).line line
1564
1706
  result = new_iter call, args, body
1565
- result.line = lineno
1566
- self.env.unextend
1707
+ result.line = line
1708
+ self.env.unextend # TODO: dynapush & dynapop
1567
1709
  }
1568
1710
 
1569
1711
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1587,8 +1729,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1587
1729
 
1588
1730
  do_block: k_do_block do_body kEND
1589
1731
  {
1590
- # TODO: maybe fix lineno to kDO's lineno?
1591
- result = val[1]
1732
+ (_, line), iter, _ = val
1733
+ result = iter.line line
1592
1734
  }
1593
1735
 
1594
1736
  block_call: command do_block
@@ -1602,8 +1744,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1602
1744
 
1603
1745
  val = invert_block_call val if inverted? val
1604
1746
 
1605
- result = val[1]
1606
- result.insert 1, val[0]
1747
+ cmd, blk = val
1748
+
1749
+ result = blk
1750
+ result.insert 1, cmd
1607
1751
  }
1608
1752
  | block_call call_op2 operation2 opt_paren_args
1609
1753
  {
@@ -1634,8 +1778,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1634
1778
  }
1635
1779
  paren_args
1636
1780
  {
1637
- args = self.call_args val[2..-1]
1638
- result = val[0].concat args.sexp_body
1781
+ call, lineno, args = val
1782
+
1783
+ result = call.concat args.sexp_body if args
1784
+ result.line lineno
1639
1785
  }
1640
1786
  | primary_value call_op operation2 opt_paren_args
1641
1787
  {
@@ -1663,7 +1809,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1663
1809
  }
1664
1810
  | kSUPER
1665
1811
  {
1666
- result = s(:zsuper)
1812
+ result = s(:zsuper).line lexer.lineno
1667
1813
  }
1668
1814
  | primary_value tLBRACK2 opt_call_args rbracket
1669
1815
  {
@@ -1712,15 +1858,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1712
1858
  }
1713
1859
 
1714
1860
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1715
- { result = lexer.cmdarg.store(false) }
1861
+ { lexer.cmdarg.push false }
1716
1862
  opt_block_param
1717
1863
  bodystmt
1718
1864
  {
1719
- line, cmdarg, param, cmpstmt = val
1865
+ line, _cmdarg, param, cmpstmt = val
1720
1866
 
1721
1867
  result = new_do_body param, cmpstmt, line
1868
+ lexer.cmdarg.pop
1722
1869
  self.env.unextend
1723
- lexer.cmdarg.restore cmdarg
1724
1870
  }
1725
1871
 
1726
1872
  case_body: k_when
@@ -1741,7 +1887,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1741
1887
  (_, line), klasses, var, _, body, rest = val
1742
1888
 
1743
1889
  klasses ||= s(:array)
1744
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1890
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1745
1891
  klasses.line line
1746
1892
 
1747
1893
  result = new_resbody(klasses, body)
@@ -1754,7 +1900,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1754
1900
 
1755
1901
  exc_list: arg_value
1756
1902
  {
1757
- result = s(:array, val[0])
1903
+ arg, = val
1904
+ result = s(:array, arg).line arg.line
1758
1905
  }
1759
1906
  | mrhs
1760
1907
  | none
@@ -1767,26 +1914,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1767
1914
 
1768
1915
  opt_ensure: k_ensure compstmt
1769
1916
  {
1770
- _, body = val
1917
+ (_, line), body = val
1771
1918
 
1772
- result = body || s(:nil)
1919
+ result = body || s(:nil).line(line)
1773
1920
  }
1774
1921
  | none
1775
1922
 
1776
1923
  literal: numeric
1777
1924
  {
1925
+ line = lexer.lineno
1778
1926
  result = s(:lit, val[0])
1927
+ result.line = line
1779
1928
  }
1780
1929
  | symbol
1781
1930
  {
1931
+ line = lexer.lineno
1782
1932
  result = s(:lit, val[0])
1933
+ result.line = line
1783
1934
  }
1784
1935
  | dsym
1785
1936
 
1786
1937
  strings: string
1787
1938
  {
1788
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1789
- result = val[0]
1939
+ str, = val
1940
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1941
+ result = str
1790
1942
  }
1791
1943
 
1792
1944
  string: tCHAR
@@ -1801,7 +1953,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1801
1953
 
1802
1954
  string1: tSTRING_BEG string_contents tSTRING_END
1803
1955
  {
1804
- result = val[1]
1956
+ _, str, (_, func) = val
1957
+
1958
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1959
+
1960
+ result = str
1805
1961
  }
1806
1962
  | tSTRING
1807
1963
  {
@@ -1810,7 +1966,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1810
1966
 
1811
1967
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1812
1968
  {
1813
- result = new_xstring val[1]
1969
+ result = new_xstring val
1970
+ # TODO: dedent?!?! SERIOUSLY?!?
1814
1971
  }
1815
1972
 
1816
1973
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1820,7 +1977,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1820
1977
 
1821
1978
  words: tWORDS_BEG tSPACE tSTRING_END
1822
1979
  {
1823
- result = s(:array)
1980
+ result = s(:array).line lexer.lineno
1824
1981
  }
1825
1982
  | tWORDS_BEG word_list tSTRING_END
1826
1983
  {
@@ -1844,25 +2001,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1844
2001
 
1845
2002
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1846
2003
  {
1847
- result = s(:array)
2004
+ result = s(:array).line lexer.lineno
1848
2005
  }
1849
- | tSYMBOLS_BEG symbol_list tSTRING_END
2006
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1850
2007
  {
1851
- result = val[1]
2008
+ _, line, list, _, = val
2009
+ list.line = line
2010
+ result = list
1852
2011
  }
1853
2012
 
1854
2013
  symbol_list: none
1855
2014
  {
1856
- result = new_symbol_list
2015
+ result = new_symbol_list.line lexer.lineno
1857
2016
  }
1858
2017
  | symbol_list word tSPACE
1859
2018
  {
1860
- result = val[0].dup << new_symbol_list_entry(val)
2019
+ list, * = val
2020
+ result = list.dup << new_symbol_list_entry(val)
1861
2021
  }
1862
2022
 
1863
2023
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1864
2024
  {
1865
- result = s(:array)
2025
+ result = s(:array).line lexer.lineno
1866
2026
  }
1867
2027
  | tQWORDS_BEG qword_list tSTRING_END
1868
2028
  {
@@ -1871,7 +2031,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1871
2031
 
1872
2032
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1873
2033
  {
1874
- result = s(:array)
2034
+ result = s(:array).line lexer.lineno # FIX
1875
2035
  }
1876
2036
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1877
2037
  {
@@ -1898,11 +2058,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1898
2058
 
1899
2059
  string_contents: none
1900
2060
  {
1901
- result = s(:str, "")
2061
+ result = s(:str, "").line lexer.lineno
1902
2062
  }
1903
2063
  | string_contents string_content
1904
2064
  {
1905
- result = literal_concat(val[0], val[1])
2065
+ v1, v2 = val
2066
+ result = literal_concat v1, v2
1906
2067
  }
1907
2068
 
1908
2069
  xstring_contents: none
@@ -1911,7 +2072,8 @@ xstring_contents: none
1911
2072
  }
1912
2073
  | xstring_contents string_content
1913
2074
  {
1914
- result = literal_concat(val[0], val[1])
2075
+ v1, v2 = val
2076
+ result = literal_concat v1, v2
1915
2077
  }
1916
2078
 
1917
2079
  regexp_contents: none
@@ -1920,7 +2082,8 @@ regexp_contents: none
1920
2082
  }
1921
2083
  | regexp_contents string_content
1922
2084
  {
1923
- result = literal_concat(val[0], val[1])
2085
+ v1, v2 = val
2086
+ result = literal_concat v1, v2
1924
2087
  }
1925
2088
 
1926
2089
  string_content: tSTRING_CONTENT
@@ -1936,19 +2099,22 @@ regexp_contents: none
1936
2099
  }
1937
2100
  string_dvar
1938
2101
  {
1939
- lexer.lex_strterm = val[1]
1940
- result = s(:evstr, val[2])
2102
+ _, strterm, str = val
2103
+ lexer.lex_strterm = strterm
2104
+ result = s(:evstr, str).line str.line
1941
2105
  }
1942
2106
  | tSTRING_DBEG
1943
2107
  {
1944
2108
  result = [lexer.lex_strterm,
1945
2109
  lexer.brace_nest,
1946
2110
  lexer.string_nest, # TODO: remove
1947
- lexer.cond.store,
1948
- lexer.cmdarg.store,
1949
2111
  lexer.lex_state,
2112
+ lexer.lineno,
1950
2113
  ]
1951
2114
 
2115
+ lexer.cmdarg.push false
2116
+ lexer.cond.push false
2117
+
1952
2118
  lexer.lex_strterm = nil
1953
2119
  lexer.brace_nest = 0
1954
2120
  lexer.string_nest = 0
@@ -1960,14 +2126,15 @@ regexp_contents: none
1960
2126
  {
1961
2127
  _, memo, stmt, _ = val
1962
2128
 
1963
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2129
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2130
+ # TODO: heredoc_indent
1964
2131
 
1965
2132
  lexer.lex_strterm = lex_strterm
1966
2133
  lexer.brace_nest = brace_nest
1967
2134
  lexer.string_nest = string_nest
1968
2135
 
1969
- lexer.cond.restore oldcond
1970
- lexer.cmdarg.restore oldcmdarg
2136
+ lexer.cmdarg.pop
2137
+ lexer.cond.pop
1971
2138
 
1972
2139
  lexer.lex_state = oldlex_state
1973
2140
 
@@ -1977,19 +2144,19 @@ regexp_contents: none
1977
2144
  when :str, :dstr, :evstr then
1978
2145
  result = stmt
1979
2146
  else
1980
- result = s(:evstr, stmt)
2147
+ result = s(:evstr, stmt).line line
1981
2148
  end
1982
2149
  when nil then
1983
- result = s(:evstr)
2150
+ result = s(:evstr).line line
1984
2151
  else
1985
2152
  debug20 25
1986
2153
  raise "unknown string body: #{stmt.inspect}"
1987
2154
  end
1988
2155
  }
1989
2156
 
1990
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1991
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1992
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2157
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2158
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2159
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
1993
2160
  | backref
1994
2161
 
1995
2162
  symbol: tSYMBEG sym
@@ -2006,18 +2173,19 @@ regexp_contents: none
2006
2173
 
2007
2174
  dsym: tSYMBEG xstring_contents tSTRING_END
2008
2175
  {
2176
+ _, result, _ = val
2177
+
2009
2178
  lexer.lex_state = EXPR_END
2010
- result = val[1]
2011
2179
 
2012
- result ||= s(:str, "")
2180
+ result ||= s(:str, "").line lexer.lineno
2013
2181
 
2014
2182
  case result.sexp_type
2015
2183
  when :dstr then
2016
2184
  result.sexp_type = :dsym
2017
2185
  when :str then
2018
- result = s(:lit, result.last.to_sym)
2186
+ result = s(:lit, result.last.to_sym).line result.line
2019
2187
  when :evstr then
2020
- result = s(:dsym, "", result)
2188
+ result = s(:dsym, "", result).line result.line
2021
2189
  else
2022
2190
  debug20 26, val, result
2023
2191
  end
@@ -2040,19 +2208,20 @@ regexp_contents: none
2040
2208
  | tCONSTANT
2041
2209
  | tCVAR
2042
2210
 
2043
- keyword_variable: kNIL { result = s(:nil) }
2044
- | kSELF { result = s(:self) }
2045
- | kTRUE { result = s(:true) }
2046
- | kFALSE { result = s(:false) }
2047
- | k__FILE__ { result = s(:str, self.file) }
2048
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2211
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2212
+ | kSELF { result = s(:self).line lexer.lineno }
2213
+ | kTRUE { result = s(:true).line lexer.lineno }
2214
+ | kFALSE { result = s(:false).line lexer.lineno }
2215
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2216
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2049
2217
  | k__ENCODING__
2050
2218
  {
2219
+ l = lexer.lineno
2051
2220
  result =
2052
2221
  if defined? Encoding then
2053
- s(:colon2, s(:const, :Encoding), :UTF_8)
2222
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2054
2223
  else
2055
- s(:str, "Unsupported!")
2224
+ s(:str, "Unsupported!").line l
2056
2225
  end
2057
2226
  }
2058
2227
 
@@ -2077,8 +2246,8 @@ keyword_variable: kNIL { result = s(:nil) }
2077
2246
  debug20 29, val, result
2078
2247
  }
2079
2248
 
2080
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2081
- | tBACK_REF { result = s(:back_ref, val[0]) }
2249
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2250
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2082
2251
 
2083
2252
  superclass: tLT
2084
2253
  {
@@ -2235,12 +2404,13 @@ keyword_variable: kNIL { result = s(:nil) }
2235
2404
 
2236
2405
  f_arg: f_arg_item
2237
2406
  {
2238
- case val[0]
2407
+ arg, = val
2408
+
2409
+ case arg
2239
2410
  when Symbol then
2240
- result = s(:args)
2241
- result << val[0]
2411
+ result = s(:args, arg).line lexer.lineno
2242
2412
  when Sexp then
2243
- result = val[0]
2413
+ result = arg
2244
2414
  else
2245
2415
  debug20 32
2246
2416
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2253,7 +2423,7 @@ keyword_variable: kNIL { result = s(:nil) }
2253
2423
  if list.sexp_type == :args then
2254
2424
  result = list
2255
2425
  else
2256
- result = s(:args, list)
2426
+ result = s(:args, list).line list.line
2257
2427
  end
2258
2428
 
2259
2429
  result << item
@@ -2263,38 +2433,42 @@ keyword_variable: kNIL { result = s(:nil) }
2263
2433
 
2264
2434
  f_kw: f_label arg_value
2265
2435
  {
2266
- # TODO: call_args
2267
- label, _ = val[0] # TODO: fix lineno?
2436
+ # TODO: new_kw_arg
2437
+ (label, line), arg = val
2438
+
2268
2439
  identifier = label.to_sym
2269
2440
  self.env[identifier] = :lvar
2270
2441
 
2271
- result = s(:array, s(:kwarg, identifier, val[1]))
2442
+ kwarg = s(:kwarg, identifier, arg).line line
2443
+ result = s(:array, kwarg).line line
2272
2444
  }
2273
2445
  | f_label
2274
2446
  {
2275
- label, _ = val[0] # TODO: fix lineno?
2276
- identifier = label.to_sym
2277
- self.env[identifier] = :lvar
2447
+ (label, line), = val
2278
2448
 
2279
- result = s(:array, s(:kwarg, identifier))
2449
+ id = label.to_sym
2450
+ self.env[id] = :lvar
2451
+
2452
+ result = s(:array, s(:kwarg, id).line(line)).line line
2280
2453
  }
2281
2454
 
2282
2455
  f_block_kw: f_label primary_value
2283
2456
  {
2284
- # TODO: call_args
2285
- label, _ = val[0] # TODO: fix lineno?
2286
- identifier = label.to_sym
2287
- self.env[identifier] = :lvar
2457
+ # TODO: new_kw_arg
2458
+ (label, line), expr = val
2459
+ id = label.to_sym
2460
+ self.env[id] = :lvar
2288
2461
 
2289
- result = s(:array, s(:kwarg, identifier, val[1]))
2462
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2290
2463
  }
2291
2464
  | f_label
2292
2465
  {
2293
- label, _ = val[0] # TODO: fix lineno?
2294
- identifier = label.to_sym
2295
- self.env[identifier] = :lvar
2466
+ # TODO: new_kw_arg
2467
+ (label, line), = val
2468
+ id = label.to_sym
2469
+ self.env[id] = :lvar
2296
2470
 
2297
- result = s(:array, s(:kwarg, identifier))
2471
+ result = s(:array, s(:kwarg, id).line(line)).line line
2298
2472
  }
2299
2473
 
2300
2474
  f_block_kwarg: f_block_kw
@@ -2337,17 +2511,20 @@ keyword_variable: kNIL { result = s(:nil) }
2337
2511
 
2338
2512
  f_block_optarg: f_block_opt
2339
2513
  {
2340
- result = s(:block, val[0])
2514
+ optblk, = val
2515
+ result = s(:block, optblk).line optblk.line
2341
2516
  }
2342
2517
  | f_block_optarg tCOMMA f_block_opt
2343
2518
  {
2344
- result = val[0]
2345
- result << val[2]
2519
+ optarg, _, optblk = val
2520
+ result = optarg
2521
+ result << optblk
2346
2522
  }
2347
2523
 
2348
2524
  f_optarg: f_opt
2349
2525
  {
2350
- result = s(:block, val[0])
2526
+ opt, = val
2527
+ result = s(:block, opt).line opt.line
2351
2528
  }
2352
2529
  | f_optarg tCOMMA f_opt
2353
2530
  {
@@ -2401,14 +2578,11 @@ keyword_variable: kNIL { result = s(:nil) }
2401
2578
  result.sexp_type == :lit
2402
2579
  }
2403
2580
 
2404
- assoc_list: none # [!nil]
2581
+ assoc_list: none
2405
2582
  {
2406
- result = s(:array)
2407
- }
2408
- | assocs trailer # [!nil]
2409
- {
2410
- result = val[0]
2583
+ result = s(:array).line lexer.lineno
2411
2584
  }
2585
+ | assocs trailer
2412
2586
 
2413
2587
  assocs: assoc
2414
2588
  | assocs tCOMMA assoc
@@ -2422,22 +2596,27 @@ keyword_variable: kNIL { result = s(:nil) }
2422
2596
 
2423
2597
  assoc: arg_value tASSOC arg_value
2424
2598
  {
2425
- result = s(:array, val[0], val[2])
2599
+ v1, _, v2 = val
2600
+ result = s(:array, v1, v2).line v1.line
2426
2601
  }
2427
2602
  | tLABEL arg_value
2428
2603
  {
2429
- (label, _), arg = val
2430
- result = s(:array, s(:lit, label.to_sym), arg)
2604
+ (label, line), arg = val
2605
+
2606
+ lit = s(:lit, label.to_sym).line line
2607
+ result = s(:array, lit, arg).line line
2431
2608
  }
2432
2609
  | tSTRING_BEG string_contents tLABEL_END arg_value
2433
2610
  {
2434
2611
  _, sym, _, value = val
2435
2612
  sym.sexp_type = :dsym
2436
- result = s(:array, sym, value)
2613
+ result = s(:array, sym, value).line sym.line
2437
2614
  }
2438
2615
  | tDSTAR arg_value
2439
2616
  {
2440
- result = s(:array, s(:kwsplat, val[1]))
2617
+ _, arg = val
2618
+ line = arg.line
2619
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2441
2620
  }
2442
2621
 
2443
2622
  operation: tIDENTIFIER | tCONSTANT | tFID