ruby_parser 3.15.0 → 3.18.0

Sign up to get free protection for your applications and to get access to all the features.
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
  {