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/ruby21_parser.y CHANGED
@@ -18,7 +18,7 @@ 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
 
24
24
  preclow
@@ -31,7 +31,7 @@ preclow
31
31
  right tEQL tOP_ASGN
32
32
  left kRESCUE_MOD
33
33
  right tEH tCOLON
34
- nonassoc tDOT2 tDOT3
34
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
35
35
  left tOROP
36
36
  left tANDOP
37
37
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -54,6 +54,9 @@ rule
54
54
  top_compstmt
55
55
  {
56
56
  result = new_compstmt val
57
+
58
+ lexer.cond.pop # local_pop
59
+ lexer.cmdarg.pop
57
60
  }
58
61
 
59
62
  top_compstmt: top_stmts opt_terms
@@ -74,7 +77,7 @@ rule
74
77
  | klBEGIN
75
78
  {
76
79
  if (self.in_def || self.in_single > 0) then
77
- debug20 1
80
+ debug 11
78
81
  yyerror "BEGIN in method"
79
82
  end
80
83
  self.env.extend
@@ -99,7 +102,9 @@ rule
99
102
  bodystmt: compstmt opt_rescue k_else
100
103
  {
101
104
  res = _values[-2]
102
- yyerror "else without rescue is useless" unless res
105
+ # TODO: move down to main match so I can just use val
106
+
107
+ warn "else without rescue is useless" unless res
103
108
  }
104
109
  compstmt
105
110
  opt_ensure
@@ -129,7 +134,7 @@ rule
129
134
  | error stmt
130
135
  {
131
136
  result = val[1]
132
- debug20 2, val, result
137
+ debug 12
133
138
  }
134
139
 
135
140
  stmt_or_begin: stmt
@@ -137,6 +142,10 @@ rule
137
142
  {
138
143
  yyerror "BEGIN is permitted only at toplevel"
139
144
  }
145
+ begin_block
146
+ {
147
+ result = val[2] # wtf?
148
+ }
140
149
 
141
150
  stmt: kALIAS fitem
142
151
  {
@@ -149,12 +158,12 @@ rule
149
158
  }
150
159
  | kALIAS tGVAR tGVAR
151
160
  {
152
- (_, line), lhs, rhs = val
161
+ (_, line), (lhs, _), (rhs, _) = val
153
162
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
154
163
  }
155
164
  | kALIAS tGVAR tBACK_REF
156
165
  {
157
- (_, line), lhs, rhs = val
166
+ (_, line), (lhs, _), (rhs, _) = val
158
167
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
159
168
  }
160
169
  | kALIAS tGVAR tNTH_REF
@@ -197,7 +206,7 @@ rule
197
206
  (_, line), _, stmt, _ = val
198
207
 
199
208
  if (self.in_def || self.in_single > 0) then
200
- debug20 3
209
+ debug 13
201
210
  yyerror "END in method; use at_exit"
202
211
  end
203
212
 
@@ -237,32 +246,31 @@ rule
237
246
  }
238
247
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
239
248
  {
240
- prim, _, id, opasgn, rhs = val
241
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
242
- if val[1] == '&.'
243
- result.sexp_type = :safe_op_asgn
244
- end
245
- result.line = val[0].line
249
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
250
+
251
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
252
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
253
+ result.line prim.line
246
254
  }
247
255
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
248
256
  {
249
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
250
- if val[1] == '&.'
251
- result.sexp_type = :safe_op_asgn
252
- end
253
- result.line = val[0].line
257
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
258
+
259
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
260
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
261
+ result.line prim.line
254
262
  }
255
263
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
256
264
  {
257
- lhs1, _, lhs2, op, rhs = val
265
+ lhs1, _, (lhs2, line), (id, _), rhs = val
258
266
 
259
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
267
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
260
268
  }
261
269
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
262
270
  {
263
- lhs1, _, lhs2, op, rhs = val
271
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
272
 
265
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
273
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
266
274
  }
267
275
  | backref tOP_ASGN command_rhs
268
276
  {
@@ -300,7 +308,7 @@ rule
300
308
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
301
309
  # REFACTOR: call_uni_op -- see parse26.y
302
310
  }
303
- | arg
311
+ | arg =tLBRACE_ARG
304
312
 
305
313
  expr_value: expr
306
314
  {
@@ -325,7 +333,7 @@ rule
325
333
  block_command: block_call
326
334
  | block_call call_op2 operation2 command_args
327
335
  {
328
- blk, _, msg, args = val
336
+ blk, _, (msg, _line), args = val
329
337
  result = new_call(blk, msg.to_sym, args).line blk.line
330
338
  }
331
339
 
@@ -339,15 +347,15 @@ rule
339
347
  _, line, body, _ = val
340
348
 
341
349
  result = body
342
- result.line = line
350
+ result.line line
343
351
 
344
352
  # self.env.unextend
345
353
  }
346
354
 
347
355
  fcall: operation
348
356
  {
349
- msg, = val
350
- result = new_call(nil, msg.to_sym).line lexer.lineno
357
+ (msg, line), = val
358
+ result = new_call(nil, msg.to_sym).line line
351
359
  }
352
360
 
353
361
  command: fcall command_args =tLOWEST
@@ -370,12 +378,14 @@ rule
370
378
  }
371
379
  | primary_value call_op operation2 command_args =tLOWEST
372
380
  {
373
- lhs, callop, op, args = val
381
+ lhs, callop, (op, _), args = val
382
+
374
383
  result = new_call lhs, op.to_sym, args, callop
384
+ result.line lhs.line
375
385
  }
376
386
  | primary_value call_op operation2 command_args cmd_brace_block
377
387
  {
378
- recv, _, msg, args, block = val
388
+ recv, _, (msg, _line), args, block = val
379
389
  call = new_call recv, msg.to_sym, args, val[1]
380
390
 
381
391
  block_dup_check call, block
@@ -385,11 +395,14 @@ rule
385
395
  }
386
396
  | primary_value tCOLON2 operation2 command_args =tLOWEST
387
397
  {
388
- result = new_call val[0], val[2].to_sym, val[3]
398
+ lhs, _, (id, line), args = val
399
+
400
+ result = new_call lhs, id.to_sym, args
401
+ result.line line
389
402
  }
390
403
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
391
404
  {
392
- recv, _, msg, args, block = val
405
+ recv, _, (msg, _line), args, block = val
393
406
  call = new_call recv, msg.to_sym, args
394
407
 
395
408
  block_dup_check call, block
@@ -547,25 +560,29 @@ rule
547
560
  }
548
561
  | primary_value call_op tIDENTIFIER
549
562
  {
550
- result = new_attrasgn val[0], val[2], val[1]
563
+ lhs, call_op, (id, _line) = val
564
+
565
+ result = new_attrasgn lhs, id, call_op
551
566
  }
552
567
  | primary_value tCOLON2 tIDENTIFIER
553
568
  {
554
- recv, _, id = val
569
+ recv, _, (id, _line) = val
555
570
  result = new_attrasgn recv, id
556
571
  }
557
572
  | primary_value call_op tCONSTANT
558
573
  {
559
- 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
560
577
  }
561
578
  | primary_value tCOLON2 tCONSTANT
562
579
  {
563
580
  if (self.in_def || self.in_single > 0) then
564
- debug20 7
581
+ debug 14
565
582
  yyerror "dynamic constant assignment"
566
583
  end
567
584
 
568
- expr, _, id = val
585
+ expr, _, (id, _line) = val
569
586
  l = expr.line
570
587
 
571
588
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -573,58 +590,65 @@ rule
573
590
  | tCOLON3 tCONSTANT
574
591
  {
575
592
  if (self.in_def || self.in_single > 0) then
576
- debug20 8
593
+ debug 15
577
594
  yyerror "dynamic constant assignment"
578
595
  end
579
596
 
580
- _, id = val
581
- l = lexer.lineno
597
+ _, (id, l) = val
582
598
 
583
599
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
584
600
  }
585
601
  | backref
586
602
  {
587
- self.backref_assign_error val[0]
603
+ ref, = val
604
+
605
+ self.backref_assign_error ref
588
606
  }
589
607
 
590
608
  lhs: user_variable
591
609
  {
592
- line = lexer.lineno
593
- result = self.assignable val[0]
594
- result.line = line
610
+ var, = val
611
+
612
+ result = self.assignable var
595
613
  }
596
614
  | keyword_variable
597
615
  {
598
- line = lexer.lineno
599
- result = self.assignable val[0]
600
- result.line = line
601
- debug20 9, val, result
616
+ var, = val
617
+
618
+ result = self.assignable var
619
+
620
+ debug 16
602
621
  }
603
622
  | primary_value tLBRACK2 opt_call_args rbracket
604
623
  {
605
624
  lhs, _, args, _ = val
625
+
606
626
  result = self.aryset lhs, args
607
627
  }
608
628
  | primary_value call_op tIDENTIFIER # REFACTOR
609
629
  {
610
- lhs, op, id = val
630
+ lhs, op, (id, _line) = val
631
+
611
632
  result = new_attrasgn lhs, id, op
612
633
  }
613
634
  | primary_value tCOLON2 tIDENTIFIER
614
635
  {
615
- lhs, _, id = val
636
+ lhs, _, (id, _line) = val
637
+
616
638
  result = new_attrasgn lhs, id
617
639
  }
618
640
  | primary_value call_op tCONSTANT # REFACTOR?
619
641
  {
620
- result = new_attrasgn val[0], val[2], val[1]
642
+ lhs, call_op, (id, _line) = val
643
+
644
+ result = new_attrasgn lhs, id, call_op
621
645
  }
622
646
  | primary_value tCOLON2 tCONSTANT
623
647
  {
624
- expr, _, id = val
648
+ expr, _, (id, _line) = val
625
649
 
626
650
  if (self.in_def || self.in_single > 0) then
627
- debug20 10
651
+ debug 17
628
652
  yyerror "dynamic constant assignment"
629
653
  end
630
654
 
@@ -633,14 +657,13 @@ rule
633
657
  }
634
658
  | tCOLON3 tCONSTANT
635
659
  {
636
- _, id = val
660
+ _, (id, l) = val
637
661
 
638
662
  if (self.in_def || self.in_single > 0) then
639
- debug20 11
663
+ debug 18
640
664
  yyerror "dynamic constant assignment"
641
665
  end
642
666
 
643
- l = lexer.lineno
644
667
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
645
668
  }
646
669
  | backref
@@ -656,16 +679,17 @@ rule
656
679
 
657
680
  cpath: tCOLON3 cname
658
681
  {
659
- _, name = val
660
- result = s(:colon3, name.to_sym).line lexer.lineno
682
+ _, (name, line) = val
683
+ result = s(:colon3, name.to_sym).line line
661
684
  }
662
685
  | cname
663
686
  {
664
- result = val[0].to_sym
687
+ (id, line), = val
688
+ result = [id.to_sym, line] # TODO: sexp?
665
689
  }
666
690
  | primary_value tCOLON2 cname
667
691
  {
668
- pval, _, name = val
692
+ pval, _, (name, _line) = val
669
693
 
670
694
  result = s(:colon2, pval, name.to_sym)
671
695
  result.line pval.line
@@ -675,24 +699,17 @@ rule
675
699
  | op
676
700
  {
677
701
  lexer.lex_state = EXPR_END
678
- result = val[0]
679
702
  }
680
703
 
681
704
  | reswords
682
- {
683
- (sym, _line), = val
684
- lexer.lex_state = EXPR_END
685
- result = sym
686
- }
687
-
688
- fsym: fname | symbol
689
705
 
690
- fitem: fsym
706
+ fitem: fname
691
707
  {
692
- id, = val
693
- result = s(:lit, id.to_sym).line lexer.lineno
708
+ (id, line), = val
709
+
710
+ result = s(:lit, id.to_sym).line line
694
711
  }
695
- | dsym
712
+ | symbol
696
713
 
697
714
  undef_list: fitem
698
715
  {
@@ -713,8 +730,6 @@ rule
713
730
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
714
731
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
715
732
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
716
- # TODO: tUBANG dead?
717
- | tUBANG
718
733
 
719
734
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
720
735
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -748,24 +763,20 @@ rule
748
763
  }
749
764
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
750
765
  {
751
- lhs, _, id, op, rhs = val
766
+ lhs, _, (id, _line), (op, _), rhs = val
752
767
 
753
768
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
754
769
  }
755
770
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
756
771
  {
757
- lhs1, _, lhs2, op, rhs = val
772
+ lhs1, _, (lhs2, _line), op, rhs = val
758
773
 
759
774
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
760
775
  result = new_const_op_asgn [lhs, op, rhs]
761
776
  }
762
- | tCOLON3 tCONSTANT
777
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
763
778
  {
764
- result = self.lexer.lineno
765
- }
766
- tOP_ASGN arg_rhs
767
- {
768
- _, lhs, line, op, rhs = val
779
+ _, (lhs, line), op, rhs = val
769
780
 
770
781
  lhs = s(:colon3, lhs.to_sym).line line
771
782
  result = new_const_op_asgn [lhs, op, rhs]
@@ -779,7 +790,7 @@ rule
779
790
  | arg tDOT2 arg
780
791
  {
781
792
  v1, v2 = val[0], val[2]
782
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
793
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
783
794
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
784
795
  else
785
796
  result = s(:dot2, v1, v2).line v1.line
@@ -788,12 +799,14 @@ rule
788
799
  | arg tDOT3 arg
789
800
  {
790
801
  v1, v2 = val[0], val[2]
791
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
802
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
792
803
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
793
804
  else
794
805
  result = s(:dot3, v1, v2).line v1.line
795
806
  end
796
807
  }
808
+
809
+
797
810
  | arg tPLUS arg
798
811
  {
799
812
  result = new_call val[0], :+, argl(val[2])
@@ -820,8 +833,9 @@ rule
820
833
  }
821
834
  | tUMINUS_NUM simple_numeric tPOW arg
822
835
  {
823
- lit = s(:lit, val[1]).line lexer.lineno
824
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
836
+ _, (num, line), _, arg = val
837
+ lit = s(:lit, num).line line
838
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
825
839
 
826
840
  }
827
841
  | tUPLUS arg
@@ -920,12 +934,12 @@ rule
920
934
 
921
935
  rel_expr: arg relop arg =tGT
922
936
  {
923
- lhs, op, rhs = val
937
+ lhs, (op, _), rhs = val
924
938
  result = new_call lhs, op.to_sym, argl(rhs)
925
939
  }
926
940
  | rel_expr relop arg =tGT
927
941
  {
928
- lhs, op, rhs = val
942
+ lhs, (op, _), rhs = val
929
943
  warn "comparison '%s' after comparison", op
930
944
  result = new_call lhs, op.to_sym, argl(rhs)
931
945
  }
@@ -1116,8 +1130,9 @@ rule
1116
1130
  | backref
1117
1131
  | tFID
1118
1132
  {
1119
- msg, = val
1133
+ (msg, line), = val
1120
1134
  result = new_call nil, msg.to_sym
1135
+ result.line line
1121
1136
  }
1122
1137
  | k_begin
1123
1138
  {
@@ -1159,15 +1174,15 @@ rule
1159
1174
  }
1160
1175
  | primary_value tCOLON2 tCONSTANT
1161
1176
  {
1162
- expr, _, id = val
1177
+ expr, _, (id, _line) = val
1163
1178
 
1164
1179
  result = s(:colon2, expr, id.to_sym).line expr.line
1165
1180
  }
1166
1181
  | tCOLON3 tCONSTANT
1167
1182
  {
1168
- _, id = val
1183
+ _, (id, line) = val
1169
1184
 
1170
- result = s(:colon3, id.to_sym).line lexer.lineno
1185
+ result = s(:colon3, id.to_sym).line line
1171
1186
  }
1172
1187
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1173
1188
  {
@@ -1214,7 +1229,7 @@ rule
1214
1229
  }
1215
1230
  | kNOT tLPAREN2 rparen
1216
1231
  {
1217
- debug20 14, val, result
1232
+ debug 20
1218
1233
  }
1219
1234
  | fcall brace_block
1220
1235
  {
@@ -1232,9 +1247,10 @@ rule
1232
1247
  iter.insert 1, call # FIX
1233
1248
  result = iter
1234
1249
  }
1235
- | tLAMBDA lambda
1250
+ | lambda
1236
1251
  {
1237
- result = val[1] # TODO: fix lineno
1252
+ expr, = val
1253
+ result = expr
1238
1254
  }
1239
1255
  | k_if expr_value then compstmt if_tail k_end
1240
1256
  {
@@ -1277,7 +1293,6 @@ rule
1277
1293
  }
1278
1294
  cpath superclass
1279
1295
  {
1280
- self.comments.push self.lexer.comments
1281
1296
  if (self.in_def || self.in_single > 0) then
1282
1297
  yyerror "class definition in method body"
1283
1298
  end
@@ -1287,7 +1302,7 @@ rule
1287
1302
  {
1288
1303
  result = new_class val
1289
1304
  self.env.unextend
1290
- self.lexer.comments # we don't care about comments in the body
1305
+ self.lexer.ignore_body_comments
1291
1306
  }
1292
1307
  | k_class tLSHFT
1293
1308
  {
@@ -1308,7 +1323,7 @@ rule
1308
1323
  {
1309
1324
  result = new_sclass val
1310
1325
  self.env.unextend
1311
- self.lexer.comments # we don't care about comments in the body
1326
+ self.lexer.ignore_body_comments
1312
1327
  }
1313
1328
  | k_module
1314
1329
  {
@@ -1316,7 +1331,6 @@ rule
1316
1331
  }
1317
1332
  cpath
1318
1333
  {
1319
- self.comments.push self.lexer.comments
1320
1334
  yyerror "module definition in method body" if
1321
1335
  self.in_def or self.in_single > 0
1322
1336
 
@@ -1326,7 +1340,7 @@ rule
1326
1340
  {
1327
1341
  result = new_module val
1328
1342
  self.env.unextend
1329
- self.lexer.comments # we don't care about comments in the body
1343
+ self.lexer.ignore_body_comments
1330
1344
  }
1331
1345
  | k_def fname
1332
1346
  {
@@ -1336,21 +1350,17 @@ rule
1336
1350
  self.env.extend
1337
1351
  lexer.cmdarg.push false
1338
1352
  lexer.cond.push false
1339
-
1340
- self.comments.push self.lexer.comments
1341
1353
  }
1342
- f_arglist bodystmt { result = lexer.lineno } k_end
1354
+ f_arglist bodystmt k_end
1343
1355
  {
1344
- in_def = val[2]
1345
-
1346
- result = new_defn val
1356
+ result, in_def = new_defn val
1347
1357
 
1348
1358
  lexer.cond.pop # group = local_pop
1349
1359
  lexer.cmdarg.pop
1350
1360
  self.env.unextend
1351
1361
  self.in_def = in_def
1352
1362
 
1353
- self.lexer.comments # we don't care about comments in the body
1363
+ self.lexer.ignore_body_comments
1354
1364
  }
1355
1365
  | k_def singleton dot_or_colon
1356
1366
  {
@@ -1358,7 +1368,7 @@ rule
1358
1368
  }
1359
1369
  fname
1360
1370
  {
1361
- result = [self.in_def, lexer.lineno]
1371
+ result = self.in_def
1362
1372
 
1363
1373
  self.in_single += 1 # TODO: remove?
1364
1374
 
@@ -1368,13 +1378,18 @@ rule
1368
1378
  lexer.cond.push false
1369
1379
 
1370
1380
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1371
- self.comments.push self.lexer.comments
1372
1381
  }
1373
1382
  f_arglist bodystmt k_end
1374
1383
  {
1375
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1376
1384
 
1377
- result = new_defs val
1385
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1386
+ # =>
1387
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1388
+
1389
+ val.delete_at 3
1390
+ val.delete_at 2
1391
+
1392
+ result, in_def = new_defs val
1378
1393
 
1379
1394
  lexer.cond.pop # group = local_pop
1380
1395
  lexer.cmdarg.pop
@@ -1385,7 +1400,7 @@ rule
1385
1400
 
1386
1401
  # TODO: restore cur_arg ? what's cur_arg?
1387
1402
 
1388
- self.lexer.comments # we don't care about comments in the body
1403
+ self.lexer.ignore_body_comments
1389
1404
  }
1390
1405
  | kBREAK
1391
1406
  {
@@ -1422,8 +1437,17 @@ rule
1422
1437
  k_case: kCASE
1423
1438
  k_for: kFOR
1424
1439
  k_class: kCLASS
1440
+ {
1441
+ self.comments.push self.lexer.comments
1442
+ }
1425
1443
  k_module: kMODULE
1444
+ {
1445
+ self.comments.push self.lexer.comments
1446
+ }
1426
1447
  k_def: kDEF
1448
+ {
1449
+ self.comments.push self.lexer.comments
1450
+ }
1427
1451
  k_do: kDO
1428
1452
  k_do_block: kDO_BLOCK
1429
1453
  k_rescue: kRESCUE
@@ -1484,51 +1508,42 @@ rule
1484
1508
 
1485
1509
  result = block_var args
1486
1510
  }
1487
- | f_marg_list tCOMMA tSTAR f_norm_arg
1511
+ | f_marg_list tCOMMA f_rest_marg
1488
1512
  {
1489
- args, _, _, splat = val
1513
+ args, _, rest = val
1490
1514
 
1491
- result = block_var args, "*#{splat}".to_sym
1515
+ result = block_var args, rest
1492
1516
  }
1493
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1517
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1494
1518
  {
1495
- args, _, _, splat, _, args2 = val
1519
+ lhs, _, splat, _, rhs = val
1496
1520
 
1497
- result = block_var args, "*#{splat}".to_sym, args2
1521
+ result = block_var lhs, splat, rhs
1498
1522
  }
1499
- | f_marg_list tCOMMA tSTAR
1523
+ | f_rest_marg
1500
1524
  {
1501
- args, _, _ = val
1525
+ rest, = val
1502
1526
 
1503
- result = block_var args, :*
1527
+ result = block_var rest
1504
1528
  }
1505
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1529
+ | f_rest_marg tCOMMA f_marg_list
1506
1530
  {
1507
- args, _, _, _, args2 = val
1531
+ splat, _, rest = val
1508
1532
 
1509
- result = block_var args, :*, args2
1533
+ result = block_var splat, rest
1510
1534
  }
1511
- | tSTAR f_norm_arg
1512
- {
1513
- _, splat = val
1514
1535
 
1515
- result = block_var :"*#{splat}"
1516
- }
1517
- | tSTAR f_norm_arg tCOMMA f_marg_list
1536
+ f_rest_marg: tSTAR f_norm_arg
1518
1537
  {
1519
- _, splat, _, args = val
1538
+ _, (id, line) = val
1520
1539
 
1521
- result = block_var :"*#{splat}", args
1540
+ result = args ["*#{id}".to_sym]
1541
+ result.line line
1522
1542
  }
1523
1543
  | tSTAR
1524
1544
  {
1525
- result = block_var :*
1526
- }
1527
- | tSTAR tCOMMA f_marg_list
1528
- {
1529
- _, _, args = val
1530
-
1531
- result = block_var :*, args
1545
+ result = args [:*]
1546
+ result.line lexer.lineno # FIX: tSTAR -> line
1532
1547
  }
1533
1548
 
1534
1549
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1545,8 +1560,8 @@ rule
1545
1560
  }
1546
1561
  | f_block_arg
1547
1562
  {
1548
- line = lexer.lineno
1549
- result = call_args val # TODO: push line down
1563
+ (id, line), = val
1564
+ result = call_args [id]
1550
1565
  result.line line
1551
1566
  }
1552
1567
 
@@ -1655,13 +1670,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1655
1670
 
1656
1671
  bvar: tIDENTIFIER
1657
1672
  {
1658
- id, = val
1659
- line = lexer.lineno
1673
+ (id, line), = val
1660
1674
  result = s(:shadow, id.to_sym).line line
1661
1675
  }
1662
1676
  | f_bad_arg
1663
1677
 
1664
- lambda: {
1678
+ lambda: tLAMBDA
1679
+ {
1665
1680
  self.env.extend :dynamic
1666
1681
  result = [lexer.lineno, lexer.lpar_beg]
1667
1682
  lexer.paren_nest += 1
@@ -1673,14 +1688,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1673
1688
  }
1674
1689
  lambda_body
1675
1690
  {
1676
- (line, lpar), args, _cmdarg, body = val
1691
+ _, (line, lpar), args, _cmdarg, body = val
1677
1692
  lexer.lpar_beg = lpar
1678
1693
 
1679
1694
  lexer.cmdarg.pop
1680
1695
 
1681
1696
  call = s(:lambda).line line
1682
1697
  result = new_iter call, args, body
1683
- result.line = line
1698
+ result.line line
1684
1699
  self.env.unextend # TODO: dynapush & dynapop
1685
1700
  }
1686
1701
 
@@ -1715,23 +1730,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1715
1730
  ## if (nd_type($1) == NODE_YIELD) {
1716
1731
  ## compile_error(PARSER_ARG "block given to yield");
1717
1732
 
1718
- syntax_error "Both block arg and actual block given." if
1719
- val[0].block_pass?
1733
+ cmd, blk = val
1720
1734
 
1721
- val = invert_block_call val if inverted? val
1735
+ syntax_error "Both block arg and actual block given." if
1736
+ cmd.block_pass?
1722
1737
 
1723
- cmd, blk = val
1738
+ if inverted? val then
1739
+ val = invert_block_call val
1740
+ cmd, blk = val
1741
+ end
1724
1742
 
1725
1743
  result = blk
1726
1744
  result.insert 1, cmd
1727
1745
  }
1728
1746
  | block_call call_op2 operation2 opt_paren_args
1729
1747
  {
1730
- result = new_call val[0], val[2].to_sym, val[3]
1748
+ lhs, _, (id, _line), args = val
1749
+
1750
+ result = new_call lhs, id.to_sym, args
1731
1751
  }
1732
1752
  | block_call call_op2 operation2 opt_paren_args brace_block
1733
1753
  {
1734
- iter1, _, name, args, iter2 = val
1754
+ iter1, _, (name, _line), args, iter2 = val
1735
1755
 
1736
1756
  call = new_call iter1, name.to_sym, args
1737
1757
  iter2.insert 1, call
@@ -1740,7 +1760,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1740
1760
  }
1741
1761
  | block_call call_op2 operation2 command_args do_block
1742
1762
  {
1743
- iter1, _, name, args, iter2 = val
1763
+ iter1, _, (name, _line), args, iter2 = val
1744
1764
 
1745
1765
  call = new_call iter1, name.to_sym, args
1746
1766
  iter2.insert 1, call
@@ -1748,28 +1768,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1748
1768
  result = iter2
1749
1769
  }
1750
1770
 
1751
- method_call: fcall
1771
+ method_call: fcall paren_args
1752
1772
  {
1753
- result = self.lexer.lineno
1754
- }
1755
- paren_args
1756
- {
1757
- call, lineno, args = val
1773
+ call, args = val
1758
1774
 
1759
1775
  result = call.concat args.sexp_body if args
1760
- result.line lineno
1761
1776
  }
1762
1777
  | primary_value call_op operation2 opt_paren_args
1763
1778
  {
1764
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1779
+ recv, call_op, (op, _line), args = val
1780
+
1781
+ result = new_call recv, op.to_sym, args, call_op
1765
1782
  }
1766
1783
  | primary_value tCOLON2 operation2 paren_args
1767
1784
  {
1768
- result = new_call val[0], val[2].to_sym, val[3]
1785
+ recv, _, (op, _line), args = val
1786
+
1787
+ result = new_call recv, op.to_sym, args
1769
1788
  }
1770
1789
  | primary_value tCOLON2 operation3
1771
1790
  {
1772
- result = new_call val[0], val[2].to_sym
1791
+ lhs, _, (id, _line) = val
1792
+
1793
+ result = new_call lhs, id.to_sym
1773
1794
  }
1774
1795
  | primary_value call_op paren_args
1775
1796
  {
@@ -1802,7 +1823,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1823
  _, line, body, _ = val
1803
1824
 
1804
1825
  result = body
1805
- result.line = line
1826
+ result.line line
1806
1827
 
1807
1828
  self.env.unextend
1808
1829
  }
@@ -1816,7 +1837,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1816
1837
  _, line, body, _ = val
1817
1838
 
1818
1839
  result = body
1819
- result.line = line
1840
+ result.line line
1820
1841
 
1821
1842
  self.env.unextend
1822
1843
  }
@@ -1845,14 +1866,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1845
1866
  self.env.unextend
1846
1867
  }
1847
1868
 
1869
+ case_args: arg_value
1870
+ {
1871
+ arg, = val
1872
+
1873
+ result = s(:array, arg).line arg.line
1874
+ }
1875
+ | tSTAR arg_value
1876
+ {
1877
+ _, arg = val
1878
+
1879
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1880
+ }
1881
+ | case_args tCOMMA arg_value
1882
+ {
1883
+ args, _, id = val
1884
+
1885
+ result = self.list_append args, id
1886
+ }
1887
+ | case_args tCOMMA tSTAR arg_value
1888
+ {
1889
+ args, _, _, id = val
1890
+
1891
+ result = self.list_append args, s(:splat, id).line(id.line)
1892
+ }
1893
+
1848
1894
  case_body: k_when
1849
1895
  {
1850
1896
  result = self.lexer.lineno
1851
1897
  }
1852
- args then compstmt cases
1898
+ case_args then compstmt cases
1853
1899
  {
1854
1900
  result = new_when(val[2], val[4])
1855
- result.line = val[1]
1901
+ result.line val[1]
1856
1902
  result << val[5] if val[5]
1857
1903
  }
1858
1904
 
@@ -1898,17 +1944,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1898
1944
 
1899
1945
  literal: numeric
1900
1946
  {
1901
- line = lexer.lineno
1902
- result = s(:lit, val[0])
1903
- result.line = line
1947
+ (lit, line), = val
1948
+ result = s(:lit, lit).line line
1904
1949
  }
1905
1950
  | symbol
1906
- {
1907
- line = lexer.lineno
1908
- result = s(:lit, val[0])
1909
- result.line = line
1910
- }
1911
- | dsym
1912
1951
 
1913
1952
  strings: string
1914
1953
  {
@@ -1919,7 +1958,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1919
1958
 
1920
1959
  string: tCHAR
1921
1960
  {
1922
- debug20 23, val, result
1961
+ debug 37
1923
1962
  }
1924
1963
  | string1
1925
1964
  | string string1
@@ -1929,11 +1968,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1929
1968
 
1930
1969
  string1: tSTRING_BEG string_contents tSTRING_END
1931
1970
  {
1932
- _, str, (_, func) = val
1971
+ (_, line), str, (_, func) = val
1933
1972
 
1934
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1973
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1935
1974
 
1936
- result = str
1975
+ result = str.line line
1937
1976
  }
1938
1977
  | tSTRING
1939
1978
  {
@@ -1953,11 +1992,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1953
1992
 
1954
1993
  words: tWORDS_BEG tSPACE tSTRING_END
1955
1994
  {
1956
- result = s(:array).line lexer.lineno
1995
+ (_, line), _, _ = val
1996
+
1997
+ result = s(:array).line line
1957
1998
  }
1958
1999
  | tWORDS_BEG word_list tSTRING_END
1959
2000
  {
1960
- result = val[1]
2001
+ (_, line), list, _ = val
2002
+
2003
+ result = list.line line
1961
2004
  }
1962
2005
 
1963
2006
  word_list: none
@@ -1977,18 +2020,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1977
2020
 
1978
2021
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1979
2022
  {
1980
- result = s(:array).line lexer.lineno
2023
+ (_, line), _, _ = val
2024
+
2025
+ result = s(:array).line line
1981
2026
  }
1982
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2027
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1983
2028
  {
1984
- _, line, list, _, = val
1985
- list.line = line
2029
+ (_, line), list, _, = val
2030
+ list.line line
1986
2031
  result = list
1987
2032
  }
1988
2033
 
1989
2034
  symbol_list: none
1990
2035
  {
1991
- result = new_symbol_list.line lexer.lineno
2036
+ result = new_symbol_list
1992
2037
  }
1993
2038
  | symbol_list word tSPACE
1994
2039
  {
@@ -1998,20 +2043,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1998
2043
 
1999
2044
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2000
2045
  {
2001
- result = s(:array).line lexer.lineno
2046
+ (_, line), _, _ = val
2047
+
2048
+ result = s(:array).line line
2002
2049
  }
2003
2050
  | tQWORDS_BEG qword_list tSTRING_END
2004
2051
  {
2005
- result = val[1]
2052
+ (_, line), list, _ = val
2053
+
2054
+ result = list.line line
2006
2055
  }
2007
2056
 
2008
2057
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2009
2058
  {
2010
- result = s(:array).line lexer.lineno # FIX
2059
+ (_, line), _, _ = val
2060
+
2061
+ result = s(:array).line line
2011
2062
  }
2012
2063
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2013
2064
  {
2014
- result = val[1]
2065
+ (_, line), list, _ = val
2066
+
2067
+ result = list.line line
2015
2068
  }
2016
2069
 
2017
2070
  qword_list: none
@@ -2034,7 +2087,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2034
2087
 
2035
2088
  string_contents: none
2036
2089
  {
2037
- result = s(:str, "").line lexer.lineno
2090
+ line = prev_value_to_lineno _values.last
2091
+ result = s(:str, +"").line line
2038
2092
  }
2039
2093
  | string_contents string_content
2040
2094
  {
@@ -2109,8 +2163,8 @@ regexp_contents: none
2109
2163
  lexer.brace_nest = brace_nest
2110
2164
  lexer.string_nest = string_nest
2111
2165
 
2112
- lexer.cmdarg.pop
2113
2166
  lexer.cond.pop
2167
+ lexer.cmdarg.pop
2114
2168
 
2115
2169
  lexer.lex_state = oldlex_state
2116
2170
 
@@ -2125,29 +2179,49 @@ regexp_contents: none
2125
2179
  when nil then
2126
2180
  result = s(:evstr).line line
2127
2181
  else
2128
- debug20 25
2182
+ debug 38
2129
2183
  raise "unknown string body: #{stmt.inspect}"
2130
2184
  end
2131
2185
  }
2132
2186
 
2133
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2134
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2135
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2187
+ string_dvar: tGVAR
2188
+ {
2189
+ (id, line), = val
2190
+ result = s(:gvar, id.to_sym).line line
2191
+ }
2192
+ | tIVAR
2193
+ {
2194
+ (id, line), = val
2195
+ result = s(:ivar, id.to_sym).line line
2196
+ }
2197
+ | tCVAR
2198
+ {
2199
+ (id, line), = val
2200
+ result = s(:cvar, id.to_sym).line line
2201
+ }
2136
2202
  | backref
2137
2203
 
2138
- symbol: tSYMBEG sym
2204
+ symbol: ssym
2205
+ | dsym
2206
+
2207
+ ssym: tSYMBEG sym
2139
2208
  {
2209
+ _, (id, line) = val
2210
+
2140
2211
  lexer.lex_state = EXPR_END
2141
- result = val[1].to_sym
2212
+ result = s(:lit, id.to_sym).line line
2142
2213
  }
2143
2214
  | tSYMBOL
2144
2215
  {
2145
- result = val[0].to_sym
2216
+ (id, line), = val
2217
+
2218
+ lexer.lex_state = EXPR_END
2219
+ result = s(:lit, id.to_sym).line line
2146
2220
  }
2147
2221
 
2148
2222
  sym: fname | tIVAR | tGVAR | tCVAR
2149
2223
 
2150
- dsym: tSYMBEG xstring_contents tSTRING_END
2224
+ dsym: tSYMBEG string_contents tSTRING_END
2151
2225
  {
2152
2226
  _, result, _ = val
2153
2227
 
@@ -2163,14 +2237,15 @@ regexp_contents: none
2163
2237
  when :evstr then
2164
2238
  result = s(:dsym, "", result).line result.line
2165
2239
  else
2166
- debug20 26, val, result
2240
+ debug 39
2167
2241
  end
2168
2242
  }
2169
2243
 
2170
2244
  numeric: simple_numeric
2171
- | tUMINUS_NUM simple_numeric
2245
+ | tUMINUS_NUM simple_numeric =tLOWEST
2172
2246
  {
2173
- result = -val[1] # TODO: pt_testcase
2247
+ _, (num, line) = val
2248
+ result = [-num, line]
2174
2249
  }
2175
2250
 
2176
2251
  simple_numeric: tINTEGER
@@ -2203,8 +2278,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2203
2278
 
2204
2279
  var_ref: user_variable
2205
2280
  {
2206
- var = val[0]
2281
+ raise "NO: #{val.inspect}" if Sexp === val.first
2282
+ (var, line), = val
2207
2283
  result = Sexp === var ? var : self.gettable(var)
2284
+ result.line line
2208
2285
  }
2209
2286
  | keyword_variable
2210
2287
  {
@@ -2219,11 +2296,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2219
2296
  | keyword_variable
2220
2297
  {
2221
2298
  result = self.assignable val[0]
2222
- debug20 29, val, result
2299
+ debug 40
2223
2300
  }
2224
2301
 
2225
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2226
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2302
+ backref: tNTH_REF
2303
+ {
2304
+ (ref, line), = val
2305
+ result = s(:nth_ref, ref).line line
2306
+ }
2307
+ | tBACK_REF
2308
+ {
2309
+ (ref, line), = val
2310
+ result = s(:back_ref, ref).line line
2311
+ }
2227
2312
 
2228
2313
  superclass: tLT
2229
2314
  {
@@ -2241,9 +2326,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2241
2326
 
2242
2327
  f_arglist: tLPAREN2 f_args rparen
2243
2328
  {
2244
- result = val[1]
2245
- self.lexer.lex_state = EXPR_BEG
2246
- self.lexer.command_start = true
2329
+ result = end_args val
2247
2330
  }
2248
2331
  | {
2249
2332
  result = self.in_kwarg
@@ -2252,12 +2335,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2252
2335
  }
2253
2336
  f_args term
2254
2337
  {
2255
- kwarg, args, _ = val
2256
-
2257
- self.in_kwarg = kwarg
2258
- result = args
2259
- lexer.lex_state = EXPR_BEG
2260
- lexer.command_start = true
2338
+ result = end_args val
2261
2339
  }
2262
2340
 
2263
2341
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2342,8 +2420,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2342
2420
  |
2343
2421
  {
2344
2422
  result = args val
2423
+ # result.line lexer.lineno
2345
2424
  }
2346
2425
 
2426
+
2347
2427
  f_bad_arg: tCONSTANT
2348
2428
  {
2349
2429
  yyerror "formal argument cannot be a constant"
@@ -2364,31 +2444,24 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2364
2444
  f_norm_arg: f_bad_arg
2365
2445
  | tIDENTIFIER
2366
2446
  {
2367
- identifier = val[0].to_sym
2447
+ (id, line), = val
2448
+ identifier = id.to_sym
2368
2449
  self.env[identifier] = :lvar
2369
2450
 
2370
- result = identifier
2451
+ result = [identifier, line]
2371
2452
  }
2372
2453
 
2373
2454
  f_arg_item: f_norm_arg
2374
2455
  | tLPAREN f_margs rparen
2375
2456
  {
2376
- result = val[1]
2457
+ _, margs, _ = val
2458
+
2459
+ result = margs
2377
2460
  }
2378
2461
 
2379
2462
  f_arg: f_arg_item
2380
2463
  {
2381
- arg, = val
2382
-
2383
- case arg
2384
- when Symbol then
2385
- result = s(:args, arg).line lexer.lineno
2386
- when Sexp then
2387
- result = arg
2388
- else
2389
- debug20 32
2390
- raise "Unknown f_arg type: #{val.inspect}"
2391
- end
2464
+ result = new_arg val
2392
2465
  }
2393
2466
  | f_arg tCOMMA f_arg_item
2394
2467
  {
@@ -2400,7 +2473,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2400
2473
  result = s(:args, list).line list.line
2401
2474
  end
2402
2475
 
2403
- result << item
2476
+ result << (Sexp === item ? item : item.first)
2404
2477
  }
2405
2478
 
2406
2479
  f_label: tLABEL
@@ -2461,26 +2534,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2461
2534
  kwrest_mark: tPOW
2462
2535
  | tDSTAR
2463
2536
 
2537
+
2464
2538
  f_kwrest: kwrest_mark tIDENTIFIER
2465
2539
  {
2466
- name = val[1].to_sym
2467
- self.assignable name
2468
- result = :"**#{name}"
2540
+ _, (id, line) = val
2541
+
2542
+ name = id.to_sym
2543
+ self.assignable [name, line]
2544
+ result = [:"**#{name}", line]
2469
2545
  }
2470
2546
  | kwrest_mark
2471
2547
  {
2472
- result = :"**"
2548
+ id = :"**"
2549
+ self.env[id] = :lvar # TODO: needed?!?
2550
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2473
2551
  }
2474
2552
 
2475
2553
  f_opt: f_norm_arg tEQL arg_value
2476
2554
  {
2477
- result = self.assignable val[0], val[2]
2555
+ lhs, _, rhs = val
2556
+ result = self.assignable lhs, rhs
2478
2557
  # TODO: detect duplicate names
2479
2558
  }
2480
2559
 
2481
2560
  f_block_opt: f_norm_arg tEQL primary_value
2482
2561
  {
2483
- result = self.assignable val[0], val[2]
2562
+ lhs, _, rhs = val
2563
+ result = self.assignable lhs, rhs
2484
2564
  }
2485
2565
 
2486
2566
  f_block_optarg: f_block_opt
@@ -2510,30 +2590,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2510
2590
  f_rest_arg: restarg_mark tIDENTIFIER
2511
2591
  {
2512
2592
  # TODO: differs from parse.y - needs tests
2513
- name = val[1].to_sym
2514
- self.assignable name
2515
- result = :"*#{name}"
2593
+ _, (id, line) = val
2594
+ name = id.to_sym
2595
+ self.assignable [name, line]
2596
+ result = [:"*#{name}", line]
2516
2597
  }
2517
2598
  | restarg_mark
2518
2599
  {
2519
2600
  name = :"*"
2520
2601
  self.env[name] = :lvar
2521
- result = name
2602
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2522
2603
  }
2523
2604
 
2524
2605
  blkarg_mark: tAMPER2 | tAMPER
2525
2606
 
2526
2607
  f_block_arg: blkarg_mark tIDENTIFIER
2527
2608
  {
2528
- identifier = val[1].to_sym
2609
+ _, (id, line) = val
2610
+ identifier = id.to_sym
2529
2611
 
2530
2612
  self.env[identifier] = :lvar
2531
- result = "&#{identifier}".to_sym
2613
+ result = ["&#{identifier}".to_sym, line]
2532
2614
  }
2533
2615
 
2534
2616
  opt_f_block_arg: tCOMMA f_block_arg
2535
2617
  {
2536
- result = val[1]
2618
+ _, arg = val
2619
+ result = arg
2537
2620
  }
2538
2621
  |
2539
2622
  {