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