ruby_parser 3.15.0 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/ruby26_parser.y CHANGED
@@ -18,10 +18,11 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
24
  tLONELY
25
+ tBDOT2 tBDOT3
25
26
 
26
27
  preclow
27
28
  nonassoc tLOWEST
@@ -33,7 +34,7 @@ preclow
33
34
  right tEQL tOP_ASGN
34
35
  left kRESCUE_MOD
35
36
  right tEH tCOLON
36
- nonassoc tDOT2 tDOT3
37
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
38
  left tOROP
38
39
  left tANDOP
39
40
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -56,6 +57,9 @@ rule
56
57
  top_compstmt
57
58
  {
58
59
  result = new_compstmt val
60
+
61
+ lexer.cond.pop # local_pop
62
+ lexer.cmdarg.pop
59
63
  }
60
64
 
61
65
  top_compstmt: top_stmts opt_terms
@@ -76,7 +80,7 @@ rule
76
80
  | klBEGIN
77
81
  {
78
82
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
83
+ debug 11
80
84
  yyerror "BEGIN in method"
81
85
  end
82
86
  self.env.extend
@@ -101,6 +105,8 @@ rule
101
105
  bodystmt: compstmt opt_rescue k_else
102
106
  {
103
107
  res = _values[-2]
108
+ # TODO: move down to main match so I can just use val
109
+
104
110
  yyerror "else without rescue is useless" unless res
105
111
  }
106
112
  compstmt
@@ -131,7 +137,7 @@ rule
131
137
  | error stmt
132
138
  {
133
139
  result = val[1]
134
- debug20 2, val, result
140
+ debug 12
135
141
  }
136
142
 
137
143
  stmt_or_begin: stmt
@@ -139,6 +145,10 @@ rule
139
145
  {
140
146
  yyerror "BEGIN is permitted only at toplevel"
141
147
  }
148
+ begin_block
149
+ {
150
+ result = val[2] # wtf?
151
+ }
142
152
 
143
153
  stmt: kALIAS fitem
144
154
  {
@@ -151,12 +161,12 @@ rule
151
161
  }
152
162
  | kALIAS tGVAR tGVAR
153
163
  {
154
- (_, line), lhs, rhs = val
164
+ (_, line), (lhs, _), (rhs, _) = val
155
165
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
166
  }
157
167
  | kALIAS tGVAR tBACK_REF
158
168
  {
159
- (_, line), lhs, rhs = val
169
+ (_, line), (lhs, _), (rhs, _) = val
160
170
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
171
  }
162
172
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +209,7 @@ rule
199
209
  (_, line), _, stmt, _ = val
200
210
 
201
211
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
212
+ debug 13
203
213
  yyerror "END in method; use at_exit"
204
214
  end
205
215
 
@@ -239,32 +249,31 @@ rule
239
249
  }
240
250
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
241
251
  {
242
- prim, _, id, opasgn, rhs = val
243
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
244
- if val[1] == '&.'
245
- result.sexp_type = :safe_op_asgn
246
- end
247
- result.line = val[0].line
252
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
253
+
254
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
255
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
256
+ result.line prim.line
248
257
  }
249
258
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
250
259
  {
251
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
252
- if val[1] == '&.'
253
- result.sexp_type = :safe_op_asgn
254
- end
255
- result.line = val[0].line
260
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
261
+
262
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
263
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
264
+ result.line prim.line
256
265
  }
257
266
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
258
267
  {
259
- lhs1, _, lhs2, op, rhs = val
268
+ lhs1, _, (lhs2, line), (id, _), rhs = val
260
269
 
261
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
270
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
262
271
  }
263
272
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
264
273
  {
265
- lhs1, _, lhs2, op, rhs = val
274
+ lhs1, _, (lhs2, line), (id, _), rhs = val
266
275
 
267
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
276
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
268
277
  }
269
278
  | backref tOP_ASGN command_rhs
270
279
  {
@@ -310,7 +319,7 @@ rule
310
319
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
320
  # REFACTOR: call_uni_op -- see parse26.y
312
321
  }
313
- | arg
322
+ | arg =tLBRACE_ARG
314
323
 
315
324
  expr_value: expr
316
325
  {
@@ -335,7 +344,7 @@ rule
335
344
  block_command: block_call
336
345
  | block_call call_op2 operation2 command_args
337
346
  {
338
- blk, _, msg, args = val
347
+ blk, _, (msg, _line), args = val
339
348
  result = new_call(blk, msg.to_sym, args).line blk.line
340
349
  }
341
350
 
@@ -349,15 +358,15 @@ rule
349
358
  _, line, body, _ = val
350
359
 
351
360
  result = body
352
- result.line = line
361
+ result.line line
353
362
 
354
363
  # self.env.unextend
355
364
  }
356
365
 
357
366
  fcall: operation
358
367
  {
359
- msg, = val
360
- result = new_call(nil, msg.to_sym).line lexer.lineno
368
+ (msg, line), = val
369
+ result = new_call(nil, msg.to_sym).line line
361
370
  }
362
371
 
363
372
  command: fcall command_args =tLOWEST
@@ -380,12 +389,14 @@ rule
380
389
  }
381
390
  | primary_value call_op operation2 command_args =tLOWEST
382
391
  {
383
- lhs, callop, op, args = val
392
+ lhs, callop, (op, _), args = val
393
+
384
394
  result = new_call lhs, op.to_sym, args, callop
395
+ result.line lhs.line
385
396
  }
386
397
  | primary_value call_op operation2 command_args cmd_brace_block
387
398
  {
388
- recv, _, msg, args, block = val
399
+ recv, _, (msg, _line), args, block = val
389
400
  call = new_call recv, msg.to_sym, args, val[1]
390
401
 
391
402
  block_dup_check call, block
@@ -395,11 +406,14 @@ rule
395
406
  }
396
407
  | primary_value tCOLON2 operation2 command_args =tLOWEST
397
408
  {
398
- result = new_call val[0], val[2].to_sym, val[3]
409
+ lhs, _, (id, line), args = val
410
+
411
+ result = new_call lhs, id.to_sym, args
412
+ result.line line
399
413
  }
400
414
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
401
415
  {
402
- recv, _, msg, args, block = val
416
+ recv, _, (msg, _line), args, block = val
403
417
  call = new_call recv, msg.to_sym, args
404
418
 
405
419
  block_dup_check call, block
@@ -557,25 +571,29 @@ rule
557
571
  }
558
572
  | primary_value call_op tIDENTIFIER
559
573
  {
560
- result = new_attrasgn val[0], val[2], val[1]
574
+ lhs, call_op, (id, _line) = val
575
+
576
+ result = new_attrasgn lhs, id, call_op
561
577
  }
562
578
  | primary_value tCOLON2 tIDENTIFIER
563
579
  {
564
- recv, _, id = val
580
+ recv, _, (id, _line) = val
565
581
  result = new_attrasgn recv, id
566
582
  }
567
583
  | primary_value call_op tCONSTANT
568
584
  {
569
- result = new_attrasgn val[0], val[2], val[1]
585
+ lhs, call_op, (id, _line) = val
586
+
587
+ result = new_attrasgn lhs, id, call_op
570
588
  }
571
589
  | primary_value tCOLON2 tCONSTANT
572
590
  {
573
591
  if (self.in_def || self.in_single > 0) then
574
- debug20 7
592
+ debug 14
575
593
  yyerror "dynamic constant assignment"
576
594
  end
577
595
 
578
- expr, _, id = val
596
+ expr, _, (id, _line) = val
579
597
  l = expr.line
580
598
 
581
599
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -583,58 +601,65 @@ rule
583
601
  | tCOLON3 tCONSTANT
584
602
  {
585
603
  if (self.in_def || self.in_single > 0) then
586
- debug20 8
604
+ debug 15
587
605
  yyerror "dynamic constant assignment"
588
606
  end
589
607
 
590
- _, id = val
591
- l = lexer.lineno
608
+ _, (id, l) = val
592
609
 
593
610
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
594
611
  }
595
612
  | backref
596
613
  {
597
- self.backref_assign_error val[0]
614
+ ref, = val
615
+
616
+ self.backref_assign_error ref
598
617
  }
599
618
 
600
619
  lhs: user_variable
601
620
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
621
+ var, = val
622
+
623
+ result = self.assignable var
605
624
  }
606
625
  | keyword_variable
607
626
  {
608
- line = lexer.lineno
609
- result = self.assignable val[0]
610
- result.line = line
611
- debug20 9, val, result
627
+ var, = val
628
+
629
+ result = self.assignable var
630
+
631
+ debug 16
612
632
  }
613
633
  | primary_value tLBRACK2 opt_call_args rbracket
614
634
  {
615
635
  lhs, _, args, _ = val
636
+
616
637
  result = self.aryset lhs, args
617
638
  }
618
639
  | primary_value call_op tIDENTIFIER # REFACTOR
619
640
  {
620
- lhs, op, id = val
641
+ lhs, op, (id, _line) = val
642
+
621
643
  result = new_attrasgn lhs, id, op
622
644
  }
623
645
  | primary_value tCOLON2 tIDENTIFIER
624
646
  {
625
- lhs, _, id = val
647
+ lhs, _, (id, _line) = val
648
+
626
649
  result = new_attrasgn lhs, id
627
650
  }
628
651
  | primary_value call_op tCONSTANT # REFACTOR?
629
652
  {
630
- result = new_attrasgn val[0], val[2], val[1]
653
+ lhs, call_op, (id, _line) = val
654
+
655
+ result = new_attrasgn lhs, id, call_op
631
656
  }
632
657
  | primary_value tCOLON2 tCONSTANT
633
658
  {
634
- expr, _, id = val
659
+ expr, _, (id, _line) = val
635
660
 
636
661
  if (self.in_def || self.in_single > 0) then
637
- debug20 10
662
+ debug 17
638
663
  yyerror "dynamic constant assignment"
639
664
  end
640
665
 
@@ -643,14 +668,13 @@ rule
643
668
  }
644
669
  | tCOLON3 tCONSTANT
645
670
  {
646
- _, id = val
671
+ _, (id, l) = val
647
672
 
648
673
  if (self.in_def || self.in_single > 0) then
649
- debug20 11
674
+ debug 18
650
675
  yyerror "dynamic constant assignment"
651
676
  end
652
677
 
653
- l = lexer.lineno
654
678
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
655
679
  }
656
680
  | backref
@@ -666,16 +690,17 @@ rule
666
690
 
667
691
  cpath: tCOLON3 cname
668
692
  {
669
- _, name = val
670
- result = s(:colon3, name.to_sym).line lexer.lineno
693
+ _, (name, line) = val
694
+ result = s(:colon3, name.to_sym).line line
671
695
  }
672
696
  | cname
673
697
  {
674
- result = val[0].to_sym
698
+ (id, line), = val
699
+ result = [id.to_sym, line] # TODO: sexp?
675
700
  }
676
701
  | primary_value tCOLON2 cname
677
702
  {
678
- pval, _, name = val
703
+ pval, _, (name, _line) = val
679
704
 
680
705
  result = s(:colon2, pval, name.to_sym)
681
706
  result.line pval.line
@@ -685,24 +710,17 @@ rule
685
710
  | op
686
711
  {
687
712
  lexer.lex_state = EXPR_END
688
- result = val[0]
689
713
  }
690
714
 
691
715
  | reswords
692
- {
693
- (sym, _line), = val
694
- lexer.lex_state = EXPR_END
695
- result = sym
696
- }
697
-
698
- fsym: fname | symbol
699
716
 
700
- fitem: fsym
717
+ fitem: fname
701
718
  {
702
- id, = val
703
- result = s(:lit, id.to_sym).line lexer.lineno
719
+ (id, line), = val
720
+
721
+ result = s(:lit, id.to_sym).line line
704
722
  }
705
- | dsym
723
+ | symbol
706
724
 
707
725
  undef_list: fitem
708
726
  {
@@ -723,8 +741,6 @@ rule
723
741
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
724
742
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
725
743
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
- # TODO: tUBANG dead?
727
- | tUBANG
728
744
 
729
745
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
730
746
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -758,24 +774,20 @@ rule
758
774
  }
759
775
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
760
776
  {
761
- lhs, _, id, op, rhs = val
777
+ lhs, _, (id, _line), (op, _), rhs = val
762
778
 
763
779
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
764
780
  }
765
781
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
766
782
  {
767
- lhs1, _, lhs2, op, rhs = val
783
+ lhs1, _, (lhs2, _line), op, rhs = val
768
784
 
769
785
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
786
  result = new_const_op_asgn [lhs, op, rhs]
771
787
  }
772
- | tCOLON3 tCONSTANT
788
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
773
789
  {
774
- result = self.lexer.lineno
775
- }
776
- tOP_ASGN arg_rhs
777
- {
778
- _, lhs, line, op, rhs = val
790
+ _, (lhs, line), op, rhs = val
779
791
 
780
792
  lhs = s(:colon3, lhs.to_sym).line line
781
793
  result = new_const_op_asgn [lhs, op, rhs]
@@ -789,7 +801,7 @@ rule
789
801
  | arg tDOT2 arg
790
802
  {
791
803
  v1, v2 = val[0], val[2]
792
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
804
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
805
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
794
806
  else
795
807
  result = s(:dot2, v1, v2).line v1.line
@@ -798,7 +810,7 @@ rule
798
810
  | arg tDOT3 arg
799
811
  {
800
812
  v1, v2 = val[0], val[2]
801
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
813
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
814
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
803
815
  else
804
816
  result = s(:dot3, v1, v2).line v1.line
@@ -818,6 +830,8 @@ rule
818
830
 
819
831
  result = s(:dot3, v1, v2).line v1.line
820
832
  }
833
+
834
+
821
835
  | arg tPLUS arg
822
836
  {
823
837
  result = new_call val[0], :+, argl(val[2])
@@ -844,8 +858,9 @@ rule
844
858
  }
845
859
  | tUMINUS_NUM simple_numeric tPOW arg
846
860
  {
847
- lit = s(:lit, val[1]).line lexer.lineno
848
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
861
+ _, (num, line), _, arg = val
862
+ lit = s(:lit, num).line line
863
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
849
864
 
850
865
  }
851
866
  | tUPLUS arg
@@ -944,12 +959,12 @@ rule
944
959
 
945
960
  rel_expr: arg relop arg =tGT
946
961
  {
947
- lhs, op, rhs = val
962
+ lhs, (op, _), rhs = val
948
963
  result = new_call lhs, op.to_sym, argl(rhs)
949
964
  }
950
965
  | rel_expr relop arg =tGT
951
966
  {
952
- lhs, op, rhs = val
967
+ lhs, (op, _), rhs = val
953
968
  warn "comparison '%s' after comparison", op
954
969
  result = new_call lhs, op.to_sym, argl(rhs)
955
970
  }
@@ -1140,8 +1155,9 @@ rule
1140
1155
  | backref
1141
1156
  | tFID
1142
1157
  {
1143
- msg, = val
1158
+ (msg, line), = val
1144
1159
  result = new_call nil, msg.to_sym
1160
+ result.line line
1145
1161
  }
1146
1162
  | k_begin
1147
1163
  {
@@ -1183,15 +1199,15 @@ rule
1183
1199
  }
1184
1200
  | primary_value tCOLON2 tCONSTANT
1185
1201
  {
1186
- expr, _, id = val
1202
+ expr, _, (id, _line) = val
1187
1203
 
1188
1204
  result = s(:colon2, expr, id.to_sym).line expr.line
1189
1205
  }
1190
1206
  | tCOLON3 tCONSTANT
1191
1207
  {
1192
- _, id = val
1208
+ _, (id, line) = val
1193
1209
 
1194
- result = s(:colon3, id.to_sym).line lexer.lineno
1210
+ result = s(:colon3, id.to_sym).line line
1195
1211
  }
1196
1212
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1197
1213
  {
@@ -1238,7 +1254,7 @@ rule
1238
1254
  }
1239
1255
  | kNOT tLPAREN2 rparen
1240
1256
  {
1241
- debug20 14, val, result
1257
+ debug 20
1242
1258
  }
1243
1259
  | fcall brace_block
1244
1260
  {
@@ -1256,9 +1272,10 @@ rule
1256
1272
  iter.insert 1, call # FIX
1257
1273
  result = iter
1258
1274
  }
1259
- | tLAMBDA lambda
1275
+ | lambda
1260
1276
  {
1261
- result = val[1] # TODO: fix lineno
1277
+ expr, = val
1278
+ result = expr
1262
1279
  }
1263
1280
  | k_if expr_value then compstmt if_tail k_end
1264
1281
  {
@@ -1301,7 +1318,6 @@ rule
1301
1318
  }
1302
1319
  cpath superclass
1303
1320
  {
1304
- self.comments.push self.lexer.comments
1305
1321
  if (self.in_def || self.in_single > 0) then
1306
1322
  yyerror "class definition in method body"
1307
1323
  end
@@ -1311,7 +1327,7 @@ rule
1311
1327
  {
1312
1328
  result = new_class val
1313
1329
  self.env.unextend
1314
- self.lexer.comments # we don't care about comments in the body
1330
+ self.lexer.ignore_body_comments
1315
1331
  }
1316
1332
  | k_class tLSHFT
1317
1333
  {
@@ -1332,7 +1348,7 @@ rule
1332
1348
  {
1333
1349
  result = new_sclass val
1334
1350
  self.env.unextend
1335
- self.lexer.comments # we don't care about comments in the body
1351
+ self.lexer.ignore_body_comments
1336
1352
  }
1337
1353
  | k_module
1338
1354
  {
@@ -1340,7 +1356,6 @@ rule
1340
1356
  }
1341
1357
  cpath
1342
1358
  {
1343
- self.comments.push self.lexer.comments
1344
1359
  yyerror "module definition in method body" if
1345
1360
  self.in_def or self.in_single > 0
1346
1361
 
@@ -1350,7 +1365,7 @@ rule
1350
1365
  {
1351
1366
  result = new_module val
1352
1367
  self.env.unextend
1353
- self.lexer.comments # we don't care about comments in the body
1368
+ self.lexer.ignore_body_comments
1354
1369
  }
1355
1370
  | k_def fname
1356
1371
  {
@@ -1360,21 +1375,17 @@ rule
1360
1375
  self.env.extend
1361
1376
  lexer.cmdarg.push false
1362
1377
  lexer.cond.push false
1363
-
1364
- self.comments.push self.lexer.comments
1365
1378
  }
1366
- f_arglist bodystmt { result = lexer.lineno } k_end
1379
+ f_arglist bodystmt k_end
1367
1380
  {
1368
- in_def = val[2]
1369
-
1370
- result = new_defn val
1381
+ result, in_def = new_defn val
1371
1382
 
1372
1383
  lexer.cond.pop # group = local_pop
1373
1384
  lexer.cmdarg.pop
1374
1385
  self.env.unextend
1375
1386
  self.in_def = in_def
1376
1387
 
1377
- self.lexer.comments # we don't care about comments in the body
1388
+ self.lexer.ignore_body_comments
1378
1389
  }
1379
1390
  | k_def singleton dot_or_colon
1380
1391
  {
@@ -1382,7 +1393,7 @@ rule
1382
1393
  }
1383
1394
  fname
1384
1395
  {
1385
- result = [self.in_def, lexer.lineno]
1396
+ result = self.in_def
1386
1397
 
1387
1398
  self.in_single += 1 # TODO: remove?
1388
1399
 
@@ -1392,13 +1403,18 @@ rule
1392
1403
  lexer.cond.push false
1393
1404
 
1394
1405
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1395
- self.comments.push self.lexer.comments
1396
1406
  }
1397
1407
  f_arglist bodystmt k_end
1398
1408
  {
1399
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1400
1409
 
1401
- result = new_defs val
1410
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1411
+ # =>
1412
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1413
+
1414
+ val.delete_at 3
1415
+ val.delete_at 2
1416
+
1417
+ result, in_def = new_defs val
1402
1418
 
1403
1419
  lexer.cond.pop # group = local_pop
1404
1420
  lexer.cmdarg.pop
@@ -1409,7 +1425,7 @@ rule
1409
1425
 
1410
1426
  # TODO: restore cur_arg ? what's cur_arg?
1411
1427
 
1412
- self.lexer.comments # we don't care about comments in the body
1428
+ self.lexer.ignore_body_comments
1413
1429
  }
1414
1430
  | kBREAK
1415
1431
  {
@@ -1446,8 +1462,17 @@ rule
1446
1462
  k_case: kCASE
1447
1463
  k_for: kFOR
1448
1464
  k_class: kCLASS
1465
+ {
1466
+ self.comments.push self.lexer.comments
1467
+ }
1449
1468
  k_module: kMODULE
1469
+ {
1470
+ self.comments.push self.lexer.comments
1471
+ }
1450
1472
  k_def: kDEF
1473
+ {
1474
+ self.comments.push self.lexer.comments
1475
+ }
1451
1476
  k_do: kDO
1452
1477
  k_do_block: kDO_BLOCK
1453
1478
  k_rescue: kRESCUE
@@ -1508,51 +1533,42 @@ rule
1508
1533
 
1509
1534
  result = block_var args
1510
1535
  }
1511
- | f_marg_list tCOMMA tSTAR f_norm_arg
1536
+ | f_marg_list tCOMMA f_rest_marg
1512
1537
  {
1513
- args, _, _, splat = val
1538
+ args, _, rest = val
1514
1539
 
1515
- result = block_var args, "*#{splat}".to_sym
1540
+ result = block_var args, rest
1516
1541
  }
1517
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1542
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1518
1543
  {
1519
- args, _, _, splat, _, args2 = val
1544
+ lhs, _, splat, _, rhs = val
1520
1545
 
1521
- result = block_var args, "*#{splat}".to_sym, args2
1546
+ result = block_var lhs, splat, rhs
1522
1547
  }
1523
- | f_marg_list tCOMMA tSTAR
1548
+ | f_rest_marg
1524
1549
  {
1525
- args, _, _ = val
1550
+ rest, = val
1526
1551
 
1527
- result = block_var args, :*
1552
+ result = block_var rest
1528
1553
  }
1529
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1554
+ | f_rest_marg tCOMMA f_marg_list
1530
1555
  {
1531
- args, _, _, _, args2 = val
1556
+ splat, _, rest = val
1532
1557
 
1533
- result = block_var args, :*, args2
1558
+ result = block_var splat, rest
1534
1559
  }
1535
- | tSTAR f_norm_arg
1536
- {
1537
- _, splat = val
1538
1560
 
1539
- result = block_var :"*#{splat}"
1540
- }
1541
- | tSTAR f_norm_arg tCOMMA f_marg_list
1561
+ f_rest_marg: tSTAR f_norm_arg
1542
1562
  {
1543
- _, splat, _, args = val
1563
+ _, (id, line) = val
1544
1564
 
1545
- result = block_var :"*#{splat}", args
1565
+ result = args ["*#{id}".to_sym]
1566
+ result.line line
1546
1567
  }
1547
1568
  | tSTAR
1548
1569
  {
1549
- result = block_var :*
1550
- }
1551
- | tSTAR tCOMMA f_marg_list
1552
- {
1553
- _, _, args = val
1554
-
1555
- result = block_var :*, args
1570
+ result = args [:*]
1571
+ result.line lexer.lineno # FIX: tSTAR -> line
1556
1572
  }
1557
1573
 
1558
1574
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1569,8 +1585,8 @@ rule
1569
1585
  }
1570
1586
  | f_block_arg
1571
1587
  {
1572
- line = lexer.lineno
1573
- result = call_args val # TODO: push line down
1588
+ (id, line), = val
1589
+ result = call_args [id]
1574
1590
  result.line line
1575
1591
  }
1576
1592
 
@@ -1679,13 +1695,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1679
1695
 
1680
1696
  bvar: tIDENTIFIER
1681
1697
  {
1682
- id, = val
1683
- line = lexer.lineno
1698
+ (id, line), = val
1684
1699
  result = s(:shadow, id.to_sym).line line
1685
1700
  }
1686
1701
  | f_bad_arg
1687
1702
 
1688
- lambda: {
1703
+ lambda: tLAMBDA
1704
+ {
1689
1705
  self.env.extend :dynamic
1690
1706
  result = [lexer.lineno, lexer.lpar_beg]
1691
1707
  lexer.paren_nest += 1
@@ -1697,14 +1713,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1697
1713
  }
1698
1714
  lambda_body
1699
1715
  {
1700
- (line, lpar), args, _cmdarg, body = val
1716
+ _, (line, lpar), args, _cmdarg, body = val
1701
1717
  lexer.lpar_beg = lpar
1702
1718
 
1703
1719
  lexer.cmdarg.pop
1704
1720
 
1705
1721
  call = s(:lambda).line line
1706
1722
  result = new_iter call, args, body
1707
- result.line = line
1723
+ result.line line
1708
1724
  self.env.unextend # TODO: dynapush & dynapop
1709
1725
  }
1710
1726
 
@@ -1739,23 +1755,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1739
1755
  ## if (nd_type($1) == NODE_YIELD) {
1740
1756
  ## compile_error(PARSER_ARG "block given to yield");
1741
1757
 
1742
- syntax_error "Both block arg and actual block given." if
1743
- val[0].block_pass?
1758
+ cmd, blk = val
1744
1759
 
1745
- val = invert_block_call val if inverted? val
1760
+ syntax_error "Both block arg and actual block given." if
1761
+ cmd.block_pass?
1746
1762
 
1747
- cmd, blk = val
1763
+ if inverted? val then
1764
+ val = invert_block_call val
1765
+ cmd, blk = val
1766
+ end
1748
1767
 
1749
1768
  result = blk
1750
1769
  result.insert 1, cmd
1751
1770
  }
1752
1771
  | block_call call_op2 operation2 opt_paren_args
1753
1772
  {
1754
- result = new_call val[0], val[2].to_sym, val[3]
1773
+ lhs, _, (id, _line), args = val
1774
+
1775
+ result = new_call lhs, id.to_sym, args
1755
1776
  }
1756
1777
  | block_call call_op2 operation2 opt_paren_args brace_block
1757
1778
  {
1758
- iter1, _, name, args, iter2 = val
1779
+ iter1, _, (name, _line), args, iter2 = val
1759
1780
 
1760
1781
  call = new_call iter1, name.to_sym, args
1761
1782
  iter2.insert 1, call
@@ -1764,7 +1785,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1764
1785
  }
1765
1786
  | block_call call_op2 operation2 command_args do_block
1766
1787
  {
1767
- iter1, _, name, args, iter2 = val
1788
+ iter1, _, (name, _line), args, iter2 = val
1768
1789
 
1769
1790
  call = new_call iter1, name.to_sym, args
1770
1791
  iter2.insert 1, call
@@ -1772,28 +1793,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1772
1793
  result = iter2
1773
1794
  }
1774
1795
 
1775
- method_call: fcall
1796
+ method_call: fcall paren_args
1776
1797
  {
1777
- result = self.lexer.lineno
1778
- }
1779
- paren_args
1780
- {
1781
- call, lineno, args = val
1798
+ call, args = val
1782
1799
 
1783
1800
  result = call.concat args.sexp_body if args
1784
- result.line lineno
1785
1801
  }
1786
1802
  | primary_value call_op operation2 opt_paren_args
1787
1803
  {
1788
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1804
+ recv, call_op, (op, _line), args = val
1805
+
1806
+ result = new_call recv, op.to_sym, args, call_op
1789
1807
  }
1790
1808
  | primary_value tCOLON2 operation2 paren_args
1791
1809
  {
1792
- result = new_call val[0], val[2].to_sym, val[3]
1810
+ recv, _, (op, _line), args = val
1811
+
1812
+ result = new_call recv, op.to_sym, args
1793
1813
  }
1794
1814
  | primary_value tCOLON2 operation3
1795
1815
  {
1796
- result = new_call val[0], val[2].to_sym
1816
+ lhs, _, (id, _line) = val
1817
+
1818
+ result = new_call lhs, id.to_sym
1797
1819
  }
1798
1820
  | primary_value call_op paren_args
1799
1821
  {
@@ -1826,7 +1848,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1848
  _, line, body, _ = val
1827
1849
 
1828
1850
  result = body
1829
- result.line = line
1851
+ result.line line
1830
1852
 
1831
1853
  self.env.unextend
1832
1854
  }
@@ -1840,7 +1862,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1840
1862
  _, line, body, _ = val
1841
1863
 
1842
1864
  result = body
1843
- result.line = line
1865
+ result.line line
1844
1866
 
1845
1867
  self.env.unextend
1846
1868
  }
@@ -1869,14 +1891,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1869
1891
  self.env.unextend
1870
1892
  }
1871
1893
 
1894
+ case_args: arg_value
1895
+ {
1896
+ arg, = val
1897
+
1898
+ result = s(:array, arg).line arg.line
1899
+ }
1900
+ | tSTAR arg_value
1901
+ {
1902
+ _, arg = val
1903
+
1904
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1905
+ }
1906
+ | case_args tCOMMA arg_value
1907
+ {
1908
+ args, _, id = val
1909
+
1910
+ result = self.list_append args, id
1911
+ }
1912
+ | case_args tCOMMA tSTAR arg_value
1913
+ {
1914
+ args, _, _, id = val
1915
+
1916
+ result = self.list_append args, s(:splat, id).line(id.line)
1917
+ }
1918
+
1872
1919
  case_body: k_when
1873
1920
  {
1874
1921
  result = self.lexer.lineno
1875
1922
  }
1876
- args then compstmt cases
1923
+ case_args then compstmt cases
1877
1924
  {
1878
1925
  result = new_when(val[2], val[4])
1879
- result.line = val[1]
1926
+ result.line val[1]
1880
1927
  result << val[5] if val[5]
1881
1928
  }
1882
1929
 
@@ -1922,17 +1969,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1922
1969
 
1923
1970
  literal: numeric
1924
1971
  {
1925
- line = lexer.lineno
1926
- result = s(:lit, val[0])
1927
- result.line = line
1972
+ (lit, line), = val
1973
+ result = s(:lit, lit).line line
1928
1974
  }
1929
1975
  | symbol
1930
- {
1931
- line = lexer.lineno
1932
- result = s(:lit, val[0])
1933
- result.line = line
1934
- }
1935
- | dsym
1936
1976
 
1937
1977
  strings: string
1938
1978
  {
@@ -1943,7 +1983,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1943
1983
 
1944
1984
  string: tCHAR
1945
1985
  {
1946
- debug20 23, val, result
1986
+ debug 37
1947
1987
  }
1948
1988
  | string1
1949
1989
  | string string1
@@ -1953,11 +1993,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1953
1993
 
1954
1994
  string1: tSTRING_BEG string_contents tSTRING_END
1955
1995
  {
1956
- _, str, (_, func) = val
1996
+ (_, line), str, (_, func) = val
1957
1997
 
1958
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1998
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1959
1999
 
1960
- result = str
2000
+ result = str.line line
1961
2001
  }
1962
2002
  | tSTRING
1963
2003
  {
@@ -1977,11 +2017,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1977
2017
 
1978
2018
  words: tWORDS_BEG tSPACE tSTRING_END
1979
2019
  {
1980
- result = s(:array).line lexer.lineno
2020
+ (_, line), _, _ = val
2021
+
2022
+ result = s(:array).line line
1981
2023
  }
1982
2024
  | tWORDS_BEG word_list tSTRING_END
1983
2025
  {
1984
- result = val[1]
2026
+ (_, line), list, _ = val
2027
+
2028
+ result = list.line line
1985
2029
  }
1986
2030
 
1987
2031
  word_list: none
@@ -2001,18 +2045,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2001
2045
 
2002
2046
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2003
2047
  {
2004
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2005
2051
  }
2006
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2052
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2007
2053
  {
2008
- _, line, list, _, = val
2009
- list.line = line
2054
+ (_, line), list, _, = val
2055
+ list.line line
2010
2056
  result = list
2011
2057
  }
2012
2058
 
2013
2059
  symbol_list: none
2014
2060
  {
2015
- result = new_symbol_list.line lexer.lineno
2061
+ result = new_symbol_list
2016
2062
  }
2017
2063
  | symbol_list word tSPACE
2018
2064
  {
@@ -2022,20 +2068,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2022
2068
 
2023
2069
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2024
2070
  {
2025
- result = s(:array).line lexer.lineno
2071
+ (_, line), _, _ = val
2072
+
2073
+ result = s(:array).line line
2026
2074
  }
2027
2075
  | tQWORDS_BEG qword_list tSTRING_END
2028
2076
  {
2029
- result = val[1]
2077
+ (_, line), list, _ = val
2078
+
2079
+ result = list.line line
2030
2080
  }
2031
2081
 
2032
2082
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2033
2083
  {
2034
- result = s(:array).line lexer.lineno # FIX
2084
+ (_, line), _, _ = val
2085
+
2086
+ result = s(:array).line line
2035
2087
  }
2036
2088
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2037
2089
  {
2038
- result = val[1]
2090
+ (_, line), list, _ = val
2091
+
2092
+ result = list.line line
2039
2093
  }
2040
2094
 
2041
2095
  qword_list: none
@@ -2058,7 +2112,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2058
2112
 
2059
2113
  string_contents: none
2060
2114
  {
2061
- result = s(:str, "").line lexer.lineno
2115
+ line = prev_value_to_lineno _values.last
2116
+ result = s(:str, +"").line line
2062
2117
  }
2063
2118
  | string_contents string_content
2064
2119
  {
@@ -2133,8 +2188,8 @@ regexp_contents: none
2133
2188
  lexer.brace_nest = brace_nest
2134
2189
  lexer.string_nest = string_nest
2135
2190
 
2136
- lexer.cmdarg.pop
2137
2191
  lexer.cond.pop
2192
+ lexer.cmdarg.pop
2138
2193
 
2139
2194
  lexer.lex_state = oldlex_state
2140
2195
 
@@ -2149,29 +2204,49 @@ regexp_contents: none
2149
2204
  when nil then
2150
2205
  result = s(:evstr).line line
2151
2206
  else
2152
- debug20 25
2207
+ debug 38
2153
2208
  raise "unknown string body: #{stmt.inspect}"
2154
2209
  end
2155
2210
  }
2156
2211
 
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 }
2212
+ string_dvar: tGVAR
2213
+ {
2214
+ (id, line), = val
2215
+ result = s(:gvar, id.to_sym).line line
2216
+ }
2217
+ | tIVAR
2218
+ {
2219
+ (id, line), = val
2220
+ result = s(:ivar, id.to_sym).line line
2221
+ }
2222
+ | tCVAR
2223
+ {
2224
+ (id, line), = val
2225
+ result = s(:cvar, id.to_sym).line line
2226
+ }
2160
2227
  | backref
2161
2228
 
2162
- symbol: tSYMBEG sym
2229
+ symbol: ssym
2230
+ | dsym
2231
+
2232
+ ssym: tSYMBEG sym
2163
2233
  {
2234
+ _, (id, line) = val
2235
+
2164
2236
  lexer.lex_state = EXPR_END
2165
- result = val[1].to_sym
2237
+ result = s(:lit, id.to_sym).line line
2166
2238
  }
2167
2239
  | tSYMBOL
2168
2240
  {
2169
- result = val[0].to_sym
2241
+ (id, line), = val
2242
+
2243
+ lexer.lex_state = EXPR_END
2244
+ result = s(:lit, id.to_sym).line line
2170
2245
  }
2171
2246
 
2172
2247
  sym: fname | tIVAR | tGVAR | tCVAR
2173
2248
 
2174
- dsym: tSYMBEG xstring_contents tSTRING_END
2249
+ dsym: tSYMBEG string_contents tSTRING_END
2175
2250
  {
2176
2251
  _, result, _ = val
2177
2252
 
@@ -2187,14 +2262,15 @@ regexp_contents: none
2187
2262
  when :evstr then
2188
2263
  result = s(:dsym, "", result).line result.line
2189
2264
  else
2190
- debug20 26, val, result
2265
+ debug 39
2191
2266
  end
2192
2267
  }
2193
2268
 
2194
2269
  numeric: simple_numeric
2195
- | tUMINUS_NUM simple_numeric
2270
+ | tUMINUS_NUM simple_numeric =tLOWEST
2196
2271
  {
2197
- result = -val[1] # TODO: pt_testcase
2272
+ _, (num, line) = val
2273
+ result = [-num, line]
2198
2274
  }
2199
2275
 
2200
2276
  simple_numeric: tINTEGER
@@ -2227,8 +2303,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2227
2303
 
2228
2304
  var_ref: user_variable
2229
2305
  {
2230
- var = val[0]
2306
+ raise "NO: #{val.inspect}" if Sexp === val.first
2307
+ (var, line), = val
2231
2308
  result = Sexp === var ? var : self.gettable(var)
2309
+ result.line line
2232
2310
  }
2233
2311
  | keyword_variable
2234
2312
  {
@@ -2243,11 +2321,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2243
2321
  | keyword_variable
2244
2322
  {
2245
2323
  result = self.assignable val[0]
2246
- debug20 29, val, result
2324
+ debug 40
2247
2325
  }
2248
2326
 
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 }
2327
+ backref: tNTH_REF
2328
+ {
2329
+ (ref, line), = val
2330
+ result = s(:nth_ref, ref).line line
2331
+ }
2332
+ | tBACK_REF
2333
+ {
2334
+ (ref, line), = val
2335
+ result = s(:back_ref, ref).line line
2336
+ }
2251
2337
 
2252
2338
  superclass: tLT
2253
2339
  {
@@ -2265,9 +2351,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2351
 
2266
2352
  f_arglist: tLPAREN2 f_args rparen
2267
2353
  {
2268
- result = val[1]
2269
- self.lexer.lex_state = EXPR_BEG
2270
- self.lexer.command_start = true
2354
+ result = end_args val
2271
2355
  }
2272
2356
  | {
2273
2357
  result = self.in_kwarg
@@ -2276,12 +2360,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2276
2360
  }
2277
2361
  f_args term
2278
2362
  {
2279
- kwarg, args, _ = val
2280
-
2281
- self.in_kwarg = kwarg
2282
- result = args
2283
- lexer.lex_state = EXPR_BEG
2284
- lexer.command_start = true
2363
+ result = end_args val
2285
2364
  }
2286
2365
 
2287
2366
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2366,8 +2445,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2366
2445
  |
2367
2446
  {
2368
2447
  result = args val
2448
+ # result.line lexer.lineno
2369
2449
  }
2370
2450
 
2451
+
2371
2452
  f_bad_arg: tCONSTANT
2372
2453
  {
2373
2454
  yyerror "formal argument cannot be a constant"
@@ -2388,10 +2469,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2388
2469
  f_norm_arg: f_bad_arg
2389
2470
  | tIDENTIFIER
2390
2471
  {
2391
- identifier = val[0].to_sym
2472
+ (id, line), = val
2473
+ identifier = id.to_sym
2392
2474
  self.env[identifier] = :lvar
2393
2475
 
2394
- result = identifier
2476
+ result = [identifier, line]
2395
2477
  }
2396
2478
 
2397
2479
  f_arg_asgn: f_norm_arg
@@ -2399,22 +2481,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2399
2481
  f_arg_item: f_arg_asgn
2400
2482
  | tLPAREN f_margs rparen
2401
2483
  {
2402
- result = val[1]
2484
+ _, margs, _ = val
2485
+
2486
+ result = margs
2403
2487
  }
2404
2488
 
2405
2489
  f_arg: f_arg_item
2406
2490
  {
2407
- arg, = val
2408
-
2409
- case arg
2410
- when Symbol then
2411
- result = s(:args, arg).line lexer.lineno
2412
- when Sexp then
2413
- result = arg
2414
- else
2415
- debug20 32
2416
- raise "Unknown f_arg type: #{val.inspect}"
2417
- end
2491
+ result = new_arg val
2418
2492
  }
2419
2493
  | f_arg tCOMMA f_arg_item
2420
2494
  {
@@ -2426,7 +2500,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2426
2500
  result = s(:args, list).line list.line
2427
2501
  end
2428
2502
 
2429
- result << item
2503
+ result << (Sexp === item ? item : item.first)
2430
2504
  }
2431
2505
 
2432
2506
  f_label: tLABEL
@@ -2487,26 +2561,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2487
2561
  kwrest_mark: tPOW
2488
2562
  | tDSTAR
2489
2563
 
2564
+
2490
2565
  f_kwrest: kwrest_mark tIDENTIFIER
2491
2566
  {
2492
- name = val[1].to_sym
2493
- self.assignable name
2494
- result = :"**#{name}"
2567
+ _, (id, line) = val
2568
+
2569
+ name = id.to_sym
2570
+ self.assignable [name, line]
2571
+ result = [:"**#{name}", line]
2495
2572
  }
2496
2573
  | kwrest_mark
2497
2574
  {
2498
- result = :"**"
2575
+ id = :"**"
2576
+ self.env[id] = :lvar # TODO: needed?!?
2577
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2499
2578
  }
2500
2579
 
2501
2580
  f_opt: f_arg_asgn tEQL arg_value
2502
2581
  {
2503
- result = self.assignable val[0], val[2]
2582
+ lhs, _, rhs = val
2583
+ result = self.assignable lhs, rhs
2504
2584
  # TODO: detect duplicate names
2505
2585
  }
2506
2586
 
2507
2587
  f_block_opt: f_arg_asgn tEQL primary_value
2508
2588
  {
2509
- result = self.assignable val[0], val[2]
2589
+ lhs, _, rhs = val
2590
+ result = self.assignable lhs, rhs
2510
2591
  }
2511
2592
 
2512
2593
  f_block_optarg: f_block_opt
@@ -2536,30 +2617,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2536
2617
  f_rest_arg: restarg_mark tIDENTIFIER
2537
2618
  {
2538
2619
  # TODO: differs from parse.y - needs tests
2539
- name = val[1].to_sym
2540
- self.assignable name
2541
- result = :"*#{name}"
2620
+ _, (id, line) = val
2621
+ name = id.to_sym
2622
+ self.assignable [name, line]
2623
+ result = [:"*#{name}", line]
2542
2624
  }
2543
2625
  | restarg_mark
2544
2626
  {
2545
2627
  name = :"*"
2546
2628
  self.env[name] = :lvar
2547
- result = name
2629
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2548
2630
  }
2549
2631
 
2550
2632
  blkarg_mark: tAMPER2 | tAMPER
2551
2633
 
2552
2634
  f_block_arg: blkarg_mark tIDENTIFIER
2553
2635
  {
2554
- identifier = val[1].to_sym
2636
+ _, (id, line) = val
2637
+ identifier = id.to_sym
2555
2638
 
2556
2639
  self.env[identifier] = :lvar
2557
- result = "&#{identifier}".to_sym
2640
+ result = ["&#{identifier}".to_sym, line]
2558
2641
  }
2559
2642
 
2560
2643
  opt_f_block_arg: tCOMMA f_block_arg
2561
2644
  {
2562
- result = val[1]
2645
+ _, arg = val
2646
+ result = arg
2563
2647
  }
2564
2648
  |
2565
2649
  {
@@ -2608,9 +2692,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2608
2692
  }
2609
2693
  | tSTRING_BEG string_contents tLABEL_END arg_value
2610
2694
  {
2611
- _, sym, _, value = val
2695
+ (_, line), sym, _, value = val
2696
+
2612
2697
  sym.sexp_type = :dsym
2613
- result = s(:array, sym, value).line sym.line
2698
+
2699
+ result = s(:array, sym, value).line line
2614
2700
  }
2615
2701
  | tDSTAR arg_value
2616
2702
  {