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
  {
@@ -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