ruby_parser 3.17.0 → 3.18.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/ruby20_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
 
23
23
  preclow
24
24
  nonassoc tLOWEST
@@ -76,7 +76,7 @@ rule
76
76
  | klBEGIN
77
77
  {
78
78
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
79
+ debug 11
80
80
  yyerror "BEGIN in method"
81
81
  end
82
82
  self.env.extend
@@ -101,7 +101,9 @@ rule
101
101
  bodystmt: compstmt opt_rescue k_else
102
102
  {
103
103
  res = _values[-2]
104
- yyerror "else without rescue is useless" unless res
104
+ # TODO: move down to main match so I can just use val
105
+
106
+ warn "else without rescue is useless" unless res
105
107
  }
106
108
  compstmt
107
109
  opt_ensure
@@ -131,7 +133,7 @@ rule
131
133
  | error stmt
132
134
  {
133
135
  result = val[1]
134
- debug20 2, val, result
136
+ debug 12
135
137
  }
136
138
 
137
139
  stmt_or_begin: stmt
@@ -139,6 +141,10 @@ rule
139
141
  {
140
142
  yyerror "BEGIN is permitted only at toplevel"
141
143
  }
144
+ begin_block
145
+ {
146
+ result = val[2] # wtf?
147
+ }
142
148
 
143
149
  stmt: kALIAS fitem
144
150
  {
@@ -151,12 +157,12 @@ rule
151
157
  }
152
158
  | kALIAS tGVAR tGVAR
153
159
  {
154
- (_, line), lhs, rhs = val
160
+ (_, line), (lhs, _), (rhs, _) = val
155
161
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
162
  }
157
163
  | kALIAS tGVAR tBACK_REF
158
164
  {
159
- (_, line), lhs, rhs = val
165
+ (_, line), (lhs, _), (rhs, _) = val
160
166
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
167
  }
162
168
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +205,7 @@ rule
199
205
  (_, line), _, stmt, _ = val
200
206
 
201
207
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
208
+ debug 13
203
209
  yyerror "END in method; use at_exit"
204
210
  end
205
211
 
@@ -243,32 +249,31 @@ rule
243
249
  }
244
250
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
251
  {
246
- prim, _, id, opasgn, rhs = val
247
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
248
- if val[1] == '&.'
249
- result.sexp_type = :safe_op_asgn
250
- end
251
- 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
252
257
  }
253
258
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
254
259
  {
255
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
256
- if val[1] == '&.'
257
- result.sexp_type = :safe_op_asgn
258
- end
259
- 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
260
265
  }
261
266
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
262
267
  {
263
- lhs1, _, lhs2, op, rhs = val
268
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
269
 
265
- 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
266
271
  }
267
272
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
268
273
  {
269
- lhs1, _, lhs2, op, rhs = val
274
+ lhs1, _, (lhs2, line), (id, _), rhs = val
270
275
 
271
- 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
272
277
  }
273
278
  | backref tOP_ASGN command_rhs
274
279
  {
@@ -306,7 +311,7 @@ rule
306
311
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
307
312
  # REFACTOR: call_uni_op -- see parse26.y
308
313
  }
309
- | arg
314
+ | arg =tLBRACE_ARG
310
315
 
311
316
  expr_value: expr
312
317
  {
@@ -331,7 +336,7 @@ rule
331
336
  block_command: block_call
332
337
  | block_call call_op2 operation2 command_args
333
338
  {
334
- blk, _, msg, args = val
339
+ blk, _, (msg, _line), args = val
335
340
  result = new_call(blk, msg.to_sym, args).line blk.line
336
341
  }
337
342
 
@@ -345,15 +350,15 @@ rule
345
350
  _, line, body, _ = val
346
351
 
347
352
  result = body
348
- result.line = line
353
+ result.line line
349
354
 
350
355
  # self.env.unextend
351
356
  }
352
357
 
353
358
  fcall: operation
354
359
  {
355
- msg, = val
356
- result = new_call(nil, msg.to_sym).line lexer.lineno
360
+ (msg, line), = val
361
+ result = new_call(nil, msg.to_sym).line line
357
362
  }
358
363
 
359
364
  command: fcall command_args =tLOWEST
@@ -376,12 +381,14 @@ rule
376
381
  }
377
382
  | primary_value call_op operation2 command_args =tLOWEST
378
383
  {
379
- lhs, callop, op, args = val
384
+ lhs, callop, (op, _), args = val
385
+
380
386
  result = new_call lhs, op.to_sym, args, callop
387
+ result.line lhs.line
381
388
  }
382
389
  | primary_value call_op operation2 command_args cmd_brace_block
383
390
  {
384
- recv, _, msg, args, block = val
391
+ recv, _, (msg, _line), args, block = val
385
392
  call = new_call recv, msg.to_sym, args, val[1]
386
393
 
387
394
  block_dup_check call, block
@@ -391,11 +398,14 @@ rule
391
398
  }
392
399
  | primary_value tCOLON2 operation2 command_args =tLOWEST
393
400
  {
394
- result = new_call val[0], val[2].to_sym, val[3]
401
+ lhs, _, (id, line), args = val
402
+
403
+ result = new_call lhs, id.to_sym, args
404
+ result.line line
395
405
  }
396
406
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
397
407
  {
398
- recv, _, msg, args, block = val
408
+ recv, _, (msg, _line), args, block = val
399
409
  call = new_call recv, msg.to_sym, args
400
410
 
401
411
  block_dup_check call, block
@@ -553,25 +563,29 @@ rule
553
563
  }
554
564
  | primary_value call_op tIDENTIFIER
555
565
  {
556
- result = new_attrasgn val[0], val[2], val[1]
566
+ lhs, call_op, (id, _line) = val
567
+
568
+ result = new_attrasgn lhs, id, call_op
557
569
  }
558
570
  | primary_value tCOLON2 tIDENTIFIER
559
571
  {
560
- recv, _, id = val
572
+ recv, _, (id, _line) = val
561
573
  result = new_attrasgn recv, id
562
574
  }
563
575
  | primary_value call_op tCONSTANT
564
576
  {
565
- result = new_attrasgn val[0], val[2], val[1]
577
+ lhs, call_op, (id, _line) = val
578
+
579
+ result = new_attrasgn lhs, id, call_op
566
580
  }
567
581
  | primary_value tCOLON2 tCONSTANT
568
582
  {
569
583
  if (self.in_def || self.in_single > 0) then
570
- debug20 7
584
+ debug 14
571
585
  yyerror "dynamic constant assignment"
572
586
  end
573
587
 
574
- expr, _, id = val
588
+ expr, _, (id, _line) = val
575
589
  l = expr.line
576
590
 
577
591
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -579,58 +593,65 @@ rule
579
593
  | tCOLON3 tCONSTANT
580
594
  {
581
595
  if (self.in_def || self.in_single > 0) then
582
- debug20 8
596
+ debug 15
583
597
  yyerror "dynamic constant assignment"
584
598
  end
585
599
 
586
- _, id = val
587
- l = lexer.lineno
600
+ _, (id, l) = val
588
601
 
589
602
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
590
603
  }
591
604
  | backref
592
605
  {
593
- self.backref_assign_error val[0]
606
+ ref, = val
607
+
608
+ self.backref_assign_error ref
594
609
  }
595
610
 
596
611
  lhs: user_variable
597
612
  {
598
- line = lexer.lineno
599
- result = self.assignable val[0]
600
- result.line = line
613
+ var, = val
614
+
615
+ result = self.assignable var
601
616
  }
602
617
  | keyword_variable
603
618
  {
604
- line = lexer.lineno
605
- result = self.assignable val[0]
606
- result.line = line
607
- debug20 9, val, result
619
+ var, = val
620
+
621
+ result = self.assignable var
622
+
623
+ debug 16
608
624
  }
609
625
  | primary_value tLBRACK2 opt_call_args rbracket
610
626
  {
611
627
  lhs, _, args, _ = val
628
+
612
629
  result = self.aryset lhs, args
613
630
  }
614
631
  | primary_value call_op tIDENTIFIER # REFACTOR
615
632
  {
616
- lhs, op, id = val
633
+ lhs, op, (id, _line) = val
634
+
617
635
  result = new_attrasgn lhs, id, op
618
636
  }
619
637
  | primary_value tCOLON2 tIDENTIFIER
620
638
  {
621
- lhs, _, id = val
639
+ lhs, _, (id, _line) = val
640
+
622
641
  result = new_attrasgn lhs, id
623
642
  }
624
643
  | primary_value call_op tCONSTANT # REFACTOR?
625
644
  {
626
- result = new_attrasgn val[0], val[2], val[1]
645
+ lhs, call_op, (id, _line) = val
646
+
647
+ result = new_attrasgn lhs, id, call_op
627
648
  }
628
649
  | primary_value tCOLON2 tCONSTANT
629
650
  {
630
- expr, _, id = val
651
+ expr, _, (id, _line) = val
631
652
 
632
653
  if (self.in_def || self.in_single > 0) then
633
- debug20 10
654
+ debug 17
634
655
  yyerror "dynamic constant assignment"
635
656
  end
636
657
 
@@ -639,14 +660,13 @@ rule
639
660
  }
640
661
  | tCOLON3 tCONSTANT
641
662
  {
642
- _, id = val
663
+ _, (id, l) = val
643
664
 
644
665
  if (self.in_def || self.in_single > 0) then
645
- debug20 11
666
+ debug 18
646
667
  yyerror "dynamic constant assignment"
647
668
  end
648
669
 
649
- l = lexer.lineno
650
670
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
651
671
  }
652
672
  | backref
@@ -662,16 +682,17 @@ rule
662
682
 
663
683
  cpath: tCOLON3 cname
664
684
  {
665
- _, name = val
666
- result = s(:colon3, name.to_sym).line lexer.lineno
685
+ _, (name, line) = val
686
+ result = s(:colon3, name.to_sym).line line
667
687
  }
668
688
  | cname
669
689
  {
670
- result = val[0].to_sym
690
+ (id, line), = val
691
+ result = [id.to_sym, line] # TODO: sexp?
671
692
  }
672
693
  | primary_value tCOLON2 cname
673
694
  {
674
- pval, _, name = val
695
+ pval, _, (name, _line) = val
675
696
 
676
697
  result = s(:colon2, pval, name.to_sym)
677
698
  result.line pval.line
@@ -681,24 +702,17 @@ rule
681
702
  | op
682
703
  {
683
704
  lexer.lex_state = EXPR_END
684
- result = val[0]
685
705
  }
686
706
 
687
707
  | reswords
688
- {
689
- (sym, _line), = val
690
- lexer.lex_state = EXPR_END
691
- result = sym
692
- }
693
708
 
694
- fsym: fname | symbol
695
-
696
- fitem: fsym
709
+ fitem: fname
697
710
  {
698
- id, = val
699
- result = s(:lit, id.to_sym).line lexer.lineno
711
+ (id, line), = val
712
+
713
+ result = s(:lit, id.to_sym).line line
700
714
  }
701
- | dsym
715
+ | symbol
702
716
 
703
717
  undef_list: fitem
704
718
  {
@@ -719,8 +733,6 @@ rule
719
733
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
720
734
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
721
735
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
722
- # TODO: tUBANG dead?
723
- | tUBANG
724
736
 
725
737
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
726
738
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -754,24 +766,20 @@ rule
754
766
  }
755
767
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
756
768
  {
757
- lhs, _, id, op, rhs = val
769
+ lhs, _, (id, _line), (op, _), rhs = val
758
770
 
759
771
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
760
772
  }
761
773
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
762
774
  {
763
- lhs1, _, lhs2, op, rhs = val
775
+ lhs1, _, (lhs2, _line), op, rhs = val
764
776
 
765
777
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
766
778
  result = new_const_op_asgn [lhs, op, rhs]
767
779
  }
768
- | tCOLON3 tCONSTANT
769
- {
770
- result = self.lexer.lineno
771
- }
772
- tOP_ASGN arg_rhs
780
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
773
781
  {
774
- _, lhs, line, op, rhs = val
782
+ _, (lhs, line), op, rhs = val
775
783
 
776
784
  lhs = s(:colon3, lhs.to_sym).line line
777
785
  result = new_const_op_asgn [lhs, op, rhs]
@@ -785,7 +793,7 @@ rule
785
793
  | arg tDOT2 arg
786
794
  {
787
795
  v1, v2 = val[0], val[2]
788
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
796
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
789
797
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
790
798
  else
791
799
  result = s(:dot2, v1, v2).line v1.line
@@ -794,7 +802,7 @@ rule
794
802
  | arg tDOT3 arg
795
803
  {
796
804
  v1, v2 = val[0], val[2]
797
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
805
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
798
806
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
799
807
  else
800
808
  result = s(:dot3, v1, v2).line v1.line
@@ -828,16 +836,18 @@ rule
828
836
  }
829
837
  | tUMINUS_NUM tINTEGER tPOW arg
830
838
  {
831
- lit = s(:lit, val[1]).line lexer.lineno
832
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
839
+ _, (num, line), _, arg = val
840
+ lit = s(:lit, num).line line
841
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
833
842
  }
834
843
  | tUMINUS_NUM tFLOAT tPOW arg
835
844
  {
836
- lit = s(:lit, val[1]).line lexer.lineno
837
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
845
+ _, (num, line), _, arg = val
846
+ lit = s(:lit, num).line line
847
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
838
848
 
839
849
  ## TODO: why is this 2.0 only?
840
- debug20 12, val, result
850
+ debug 19
841
851
  }
842
852
  | tUPLUS arg
843
853
  {
@@ -935,12 +945,12 @@ rule
935
945
 
936
946
  rel_expr: arg relop arg =tGT
937
947
  {
938
- lhs, op, rhs = val
948
+ lhs, (op, _), rhs = val
939
949
  result = new_call lhs, op.to_sym, argl(rhs)
940
950
  }
941
951
  | rel_expr relop arg =tGT
942
952
  {
943
- lhs, op, rhs = val
953
+ lhs, (op, _), rhs = val
944
954
  warn "comparison '%s' after comparison", op
945
955
  result = new_call lhs, op.to_sym, argl(rhs)
946
956
  }
@@ -1122,8 +1132,9 @@ rule
1122
1132
  | backref
1123
1133
  | tFID
1124
1134
  {
1125
- msg, = val
1135
+ (msg, line), = val
1126
1136
  result = new_call nil, msg.to_sym
1137
+ result.line line
1127
1138
  }
1128
1139
  | k_begin
1129
1140
  {
@@ -1165,15 +1176,15 @@ rule
1165
1176
  }
1166
1177
  | primary_value tCOLON2 tCONSTANT
1167
1178
  {
1168
- expr, _, id = val
1179
+ expr, _, (id, _line) = val
1169
1180
 
1170
1181
  result = s(:colon2, expr, id.to_sym).line expr.line
1171
1182
  }
1172
1183
  | tCOLON3 tCONSTANT
1173
1184
  {
1174
- _, id = val
1185
+ _, (id, line) = val
1175
1186
 
1176
- result = s(:colon3, id.to_sym).line lexer.lineno
1187
+ result = s(:colon3, id.to_sym).line line
1177
1188
  }
1178
1189
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1179
1190
  {
@@ -1220,7 +1231,7 @@ rule
1220
1231
  }
1221
1232
  | kNOT tLPAREN2 rparen
1222
1233
  {
1223
- debug20 14, val, result
1234
+ debug 20
1224
1235
  }
1225
1236
  | fcall brace_block
1226
1237
  {
@@ -1238,9 +1249,10 @@ rule
1238
1249
  iter.insert 1, call # FIX
1239
1250
  result = iter
1240
1251
  }
1241
- | tLAMBDA lambda
1252
+ | lambda
1242
1253
  {
1243
- result = val[1] # TODO: fix lineno
1254
+ expr, = val
1255
+ result = expr
1244
1256
  }
1245
1257
  | k_if expr_value then compstmt if_tail k_end
1246
1258
  {
@@ -1283,7 +1295,6 @@ rule
1283
1295
  }
1284
1296
  cpath superclass
1285
1297
  {
1286
- self.comments.push self.lexer.comments
1287
1298
  if (self.in_def || self.in_single > 0) then
1288
1299
  yyerror "class definition in method body"
1289
1300
  end
@@ -1293,7 +1304,7 @@ rule
1293
1304
  {
1294
1305
  result = new_class val
1295
1306
  self.env.unextend
1296
- self.lexer.comments # we don't care about comments in the body
1307
+ self.lexer.ignore_body_comments
1297
1308
  }
1298
1309
  | k_class tLSHFT
1299
1310
  {
@@ -1314,7 +1325,7 @@ rule
1314
1325
  {
1315
1326
  result = new_sclass val
1316
1327
  self.env.unextend
1317
- self.lexer.comments # we don't care about comments in the body
1328
+ self.lexer.ignore_body_comments
1318
1329
  }
1319
1330
  | k_module
1320
1331
  {
@@ -1322,7 +1333,6 @@ rule
1322
1333
  }
1323
1334
  cpath
1324
1335
  {
1325
- self.comments.push self.lexer.comments
1326
1336
  yyerror "module definition in method body" if
1327
1337
  self.in_def or self.in_single > 0
1328
1338
 
@@ -1332,7 +1342,7 @@ rule
1332
1342
  {
1333
1343
  result = new_module val
1334
1344
  self.env.unextend
1335
- self.lexer.comments # we don't care about comments in the body
1345
+ self.lexer.ignore_body_comments
1336
1346
  }
1337
1347
  | k_def fname
1338
1348
  {
@@ -1342,21 +1352,17 @@ rule
1342
1352
  self.env.extend
1343
1353
  lexer.cmdarg.push false
1344
1354
  lexer.cond.push false
1345
-
1346
- self.comments.push self.lexer.comments
1347
1355
  }
1348
- f_arglist bodystmt { result = lexer.lineno } k_end
1356
+ f_arglist bodystmt k_end
1349
1357
  {
1350
- in_def = val[2]
1351
-
1352
- result = new_defn val
1358
+ result, in_def = new_defn val
1353
1359
 
1354
1360
  lexer.cond.pop # group = local_pop
1355
1361
  lexer.cmdarg.pop
1356
1362
  self.env.unextend
1357
1363
  self.in_def = in_def
1358
1364
 
1359
- self.lexer.comments # we don't care about comments in the body
1365
+ self.lexer.ignore_body_comments
1360
1366
  }
1361
1367
  | k_def singleton dot_or_colon
1362
1368
  {
@@ -1364,7 +1370,7 @@ rule
1364
1370
  }
1365
1371
  fname
1366
1372
  {
1367
- result = [self.in_def, lexer.lineno]
1373
+ result = self.in_def
1368
1374
 
1369
1375
  self.in_single += 1 # TODO: remove?
1370
1376
 
@@ -1374,13 +1380,18 @@ rule
1374
1380
  lexer.cond.push false
1375
1381
 
1376
1382
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1377
- self.comments.push self.lexer.comments
1378
1383
  }
1379
1384
  f_arglist bodystmt k_end
1380
1385
  {
1381
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1382
1386
 
1383
- result = new_defs val
1387
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1388
+ # =>
1389
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1390
+
1391
+ val.delete_at 3
1392
+ val.delete_at 2
1393
+
1394
+ result, in_def = new_defs val
1384
1395
 
1385
1396
  lexer.cond.pop # group = local_pop
1386
1397
  lexer.cmdarg.pop
@@ -1391,7 +1402,7 @@ rule
1391
1402
 
1392
1403
  # TODO: restore cur_arg ? what's cur_arg?
1393
1404
 
1394
- self.lexer.comments # we don't care about comments in the body
1405
+ self.lexer.ignore_body_comments
1395
1406
  }
1396
1407
  | kBREAK
1397
1408
  {
@@ -1428,8 +1439,17 @@ rule
1428
1439
  k_case: kCASE
1429
1440
  k_for: kFOR
1430
1441
  k_class: kCLASS
1442
+ {
1443
+ self.comments.push self.lexer.comments
1444
+ }
1431
1445
  k_module: kMODULE
1446
+ {
1447
+ self.comments.push self.lexer.comments
1448
+ }
1432
1449
  k_def: kDEF
1450
+ {
1451
+ self.comments.push self.lexer.comments
1452
+ }
1433
1453
  k_do: kDO
1434
1454
  k_do_block: kDO_BLOCK
1435
1455
  k_rescue: kRESCUE
@@ -1490,51 +1510,42 @@ rule
1490
1510
 
1491
1511
  result = block_var args
1492
1512
  }
1493
- | f_marg_list tCOMMA tSTAR f_norm_arg
1513
+ | f_marg_list tCOMMA f_rest_marg
1494
1514
  {
1495
- args, _, _, splat = val
1515
+ args, _, rest = val
1496
1516
 
1497
- result = block_var args, "*#{splat}".to_sym
1517
+ result = block_var args, rest
1498
1518
  }
1499
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1519
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1500
1520
  {
1501
- args, _, _, splat, _, args2 = val
1521
+ lhs, _, splat, _, rhs = val
1502
1522
 
1503
- result = block_var args, "*#{splat}".to_sym, args2
1523
+ result = block_var lhs, splat, rhs
1504
1524
  }
1505
- | f_marg_list tCOMMA tSTAR
1525
+ | f_rest_marg
1506
1526
  {
1507
- args, _, _ = val
1527
+ rest, = val
1508
1528
 
1509
- result = block_var args, :*
1529
+ result = block_var rest
1510
1530
  }
1511
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1531
+ | f_rest_marg tCOMMA f_marg_list
1512
1532
  {
1513
- args, _, _, _, args2 = val
1533
+ splat, _, rest = val
1514
1534
 
1515
- result = block_var args, :*, args2
1535
+ result = block_var splat, rest
1516
1536
  }
1517
- | tSTAR f_norm_arg
1518
- {
1519
- _, splat = val
1520
1537
 
1521
- result = block_var :"*#{splat}"
1522
- }
1523
- | tSTAR f_norm_arg tCOMMA f_marg_list
1538
+ f_rest_marg: tSTAR f_norm_arg
1524
1539
  {
1525
- _, splat, _, args = val
1540
+ _, (id, line) = val
1526
1541
 
1527
- result = block_var :"*#{splat}", args
1542
+ result = args ["*#{id}".to_sym]
1543
+ result.line line
1528
1544
  }
1529
1545
  | tSTAR
1530
1546
  {
1531
- result = block_var :*
1532
- }
1533
- | tSTAR tCOMMA f_marg_list
1534
- {
1535
- _, _, args = val
1536
-
1537
- result = block_var :*, args
1547
+ result = args [:*]
1548
+ result.line lexer.lineno # FIX: tSTAR -> line
1538
1549
  }
1539
1550
 
1540
1551
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1551,8 +1562,8 @@ rule
1551
1562
  }
1552
1563
  | f_block_arg
1553
1564
  {
1554
- line = lexer.lineno
1555
- result = call_args val # TODO: push line down
1565
+ (id, line), = val
1566
+ result = call_args [id]
1556
1567
  result.line line
1557
1568
  }
1558
1569
 
@@ -1661,13 +1672,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1661
1672
 
1662
1673
  bvar: tIDENTIFIER
1663
1674
  {
1664
- id, = val
1665
- line = lexer.lineno
1675
+ (id, line), = val
1666
1676
  result = s(:shadow, id.to_sym).line line
1667
1677
  }
1668
1678
  | f_bad_arg
1669
1679
 
1670
- lambda: {
1680
+ lambda: tLAMBDA
1681
+ {
1671
1682
  self.env.extend :dynamic
1672
1683
  result = [lexer.lineno, lexer.lpar_beg]
1673
1684
  lexer.paren_nest += 1
@@ -1679,14 +1690,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1679
1690
  }
1680
1691
  lambda_body
1681
1692
  {
1682
- (line, lpar), args, _cmdarg, body = val
1693
+ _, (line, lpar), args, _cmdarg, body = val
1683
1694
  lexer.lpar_beg = lpar
1684
1695
 
1685
1696
  lexer.cmdarg.pop
1686
1697
 
1687
1698
  call = s(:lambda).line line
1688
1699
  result = new_iter call, args, body
1689
- result.line = line
1700
+ result.line line
1690
1701
  self.env.unextend # TODO: dynapush & dynapop
1691
1702
  }
1692
1703
 
@@ -1721,23 +1732,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1721
1732
  ## if (nd_type($1) == NODE_YIELD) {
1722
1733
  ## compile_error(PARSER_ARG "block given to yield");
1723
1734
 
1724
- syntax_error "Both block arg and actual block given." if
1725
- val[0].block_pass?
1735
+ cmd, blk = val
1726
1736
 
1727
- val = invert_block_call val if inverted? val
1737
+ syntax_error "Both block arg and actual block given." if
1738
+ cmd.block_pass?
1728
1739
 
1729
- cmd, blk = val
1740
+ if inverted? val then
1741
+ val = invert_block_call val
1742
+ cmd, blk = val
1743
+ end
1730
1744
 
1731
1745
  result = blk
1732
1746
  result.insert 1, cmd
1733
1747
  }
1734
1748
  | block_call call_op2 operation2 opt_paren_args
1735
1749
  {
1736
- result = new_call val[0], val[2].to_sym, val[3]
1750
+ lhs, _, (id, _line), args = val
1751
+
1752
+ result = new_call lhs, id.to_sym, args
1737
1753
  }
1738
1754
  | block_call call_op2 operation2 opt_paren_args brace_block
1739
1755
  {
1740
- iter1, _, name, args, iter2 = val
1756
+ iter1, _, (name, _line), args, iter2 = val
1741
1757
 
1742
1758
  call = new_call iter1, name.to_sym, args
1743
1759
  iter2.insert 1, call
@@ -1746,7 +1762,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1746
1762
  }
1747
1763
  | block_call call_op2 operation2 command_args do_block
1748
1764
  {
1749
- iter1, _, name, args, iter2 = val
1765
+ iter1, _, (name, _line), args, iter2 = val
1750
1766
 
1751
1767
  call = new_call iter1, name.to_sym, args
1752
1768
  iter2.insert 1, call
@@ -1754,28 +1770,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1754
1770
  result = iter2
1755
1771
  }
1756
1772
 
1757
- method_call: fcall
1758
- {
1759
- result = self.lexer.lineno
1760
- }
1761
- paren_args
1773
+ method_call: fcall paren_args
1762
1774
  {
1763
- call, lineno, args = val
1775
+ call, args = val
1764
1776
 
1765
1777
  result = call.concat args.sexp_body if args
1766
- result.line lineno
1767
1778
  }
1768
1779
  | primary_value call_op operation2 opt_paren_args
1769
1780
  {
1770
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1781
+ recv, call_op, (op, _line), args = val
1782
+
1783
+ result = new_call recv, op.to_sym, args, call_op
1771
1784
  }
1772
1785
  | primary_value tCOLON2 operation2 paren_args
1773
1786
  {
1774
- result = new_call val[0], val[2].to_sym, val[3]
1787
+ recv, _, (op, _line), args = val
1788
+
1789
+ result = new_call recv, op.to_sym, args
1775
1790
  }
1776
1791
  | primary_value tCOLON2 operation3
1777
1792
  {
1778
- result = new_call val[0], val[2].to_sym
1793
+ lhs, _, (id, _line) = val
1794
+
1795
+ result = new_call lhs, id.to_sym
1779
1796
  }
1780
1797
  | primary_value call_op paren_args
1781
1798
  {
@@ -1808,7 +1825,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1808
1825
  _, line, body, _ = val
1809
1826
 
1810
1827
  result = body
1811
- result.line = line
1828
+ result.line line
1812
1829
 
1813
1830
  self.env.unextend
1814
1831
  }
@@ -1822,7 +1839,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1822
1839
  _, line, body, _ = val
1823
1840
 
1824
1841
  result = body
1825
- result.line = line
1842
+ result.line line
1826
1843
 
1827
1844
  self.env.unextend
1828
1845
  }
@@ -1851,14 +1868,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1851
1868
  self.env.unextend
1852
1869
  }
1853
1870
 
1871
+ case_args: arg_value
1872
+ {
1873
+ arg, = val
1874
+
1875
+ result = s(:array, arg).line arg.line
1876
+ }
1877
+ | tSTAR arg_value
1878
+ {
1879
+ _, arg = val
1880
+
1881
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1882
+ }
1883
+ | case_args tCOMMA arg_value
1884
+ {
1885
+ args, _, id = val
1886
+
1887
+ result = self.list_append args, id
1888
+ }
1889
+ | case_args tCOMMA tSTAR arg_value
1890
+ {
1891
+ args, _, _, id = val
1892
+
1893
+ result = self.list_append args, s(:splat, id).line(id.line)
1894
+ }
1895
+
1854
1896
  case_body: k_when
1855
1897
  {
1856
1898
  result = self.lexer.lineno
1857
1899
  }
1858
- args then compstmt cases
1900
+ case_args then compstmt cases
1859
1901
  {
1860
1902
  result = new_when(val[2], val[4])
1861
- result.line = val[1]
1903
+ result.line val[1]
1862
1904
  result << val[5] if val[5]
1863
1905
  }
1864
1906
 
@@ -1904,17 +1946,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1904
1946
 
1905
1947
  literal: numeric
1906
1948
  {
1907
- line = lexer.lineno
1908
- result = s(:lit, val[0])
1909
- result.line = line
1949
+ (lit, line), = val
1950
+ result = s(:lit, lit).line line
1910
1951
  }
1911
1952
  | symbol
1912
- {
1913
- line = lexer.lineno
1914
- result = s(:lit, val[0])
1915
- result.line = line
1916
- }
1917
- | dsym
1918
1953
 
1919
1954
  strings: string
1920
1955
  {
@@ -1925,7 +1960,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1925
1960
 
1926
1961
  string: tCHAR
1927
1962
  {
1928
- debug20 23, val, result
1963
+ debug 37
1929
1964
  }
1930
1965
  | string1
1931
1966
  | string string1
@@ -1935,11 +1970,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1935
1970
 
1936
1971
  string1: tSTRING_BEG string_contents tSTRING_END
1937
1972
  {
1938
- _, str, (_, func) = val
1973
+ (_, line), str, (_, func) = val
1939
1974
 
1940
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1975
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1941
1976
 
1942
- result = str
1977
+ result = str.line line
1943
1978
  }
1944
1979
  | tSTRING
1945
1980
  {
@@ -1959,11 +1994,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1959
1994
 
1960
1995
  words: tWORDS_BEG tSPACE tSTRING_END
1961
1996
  {
1962
- result = s(:array).line lexer.lineno
1997
+ (_, line), _, _ = val
1998
+
1999
+ result = s(:array).line line
1963
2000
  }
1964
2001
  | tWORDS_BEG word_list tSTRING_END
1965
2002
  {
1966
- result = val[1]
2003
+ (_, line), list, _ = val
2004
+
2005
+ result = list.line line
1967
2006
  }
1968
2007
 
1969
2008
  word_list: none
@@ -1983,18 +2022,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1983
2022
 
1984
2023
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1985
2024
  {
1986
- result = s(:array).line lexer.lineno
2025
+ (_, line), _, _ = val
2026
+
2027
+ result = s(:array).line line
1987
2028
  }
1988
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2029
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1989
2030
  {
1990
- _, line, list, _, = val
1991
- list.line = line
2031
+ (_, line), list, _, = val
2032
+ list.line line
1992
2033
  result = list
1993
2034
  }
1994
2035
 
1995
2036
  symbol_list: none
1996
2037
  {
1997
- result = new_symbol_list.line lexer.lineno
2038
+ result = new_symbol_list
1998
2039
  }
1999
2040
  | symbol_list word tSPACE
2000
2041
  {
@@ -2004,20 +2045,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2004
2045
 
2005
2046
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2006
2047
  {
2007
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2008
2051
  }
2009
2052
  | tQWORDS_BEG qword_list tSTRING_END
2010
2053
  {
2011
- result = val[1]
2054
+ (_, line), list, _ = val
2055
+
2056
+ result = list.line line
2012
2057
  }
2013
2058
 
2014
2059
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2015
2060
  {
2016
- result = s(:array).line lexer.lineno # FIX
2061
+ (_, line), _, _ = val
2062
+
2063
+ result = s(:array).line line
2017
2064
  }
2018
2065
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2019
2066
  {
2020
- result = val[1]
2067
+ (_, line), list, _ = val
2068
+
2069
+ result = list.line line
2021
2070
  }
2022
2071
 
2023
2072
  qword_list: none
@@ -2040,7 +2089,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2040
2089
 
2041
2090
  string_contents: none
2042
2091
  {
2043
- result = s(:str, "").line lexer.lineno
2092
+ line = prev_value_to_lineno _values.last
2093
+ result = s(:str, +"").line line
2044
2094
  }
2045
2095
  | string_contents string_content
2046
2096
  {
@@ -2115,8 +2165,8 @@ regexp_contents: none
2115
2165
  lexer.brace_nest = brace_nest
2116
2166
  lexer.string_nest = string_nest
2117
2167
 
2118
- lexer.cmdarg.pop
2119
2168
  lexer.cond.pop
2169
+ lexer.cmdarg.pop
2120
2170
 
2121
2171
  lexer.lex_state = oldlex_state
2122
2172
 
@@ -2131,29 +2181,49 @@ regexp_contents: none
2131
2181
  when nil then
2132
2182
  result = s(:evstr).line line
2133
2183
  else
2134
- debug20 25
2184
+ debug 38
2135
2185
  raise "unknown string body: #{stmt.inspect}"
2136
2186
  end
2137
2187
  }
2138
2188
 
2139
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2140
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2141
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2189
+ string_dvar: tGVAR
2190
+ {
2191
+ (id, line), = val
2192
+ result = s(:gvar, id.to_sym).line line
2193
+ }
2194
+ | tIVAR
2195
+ {
2196
+ (id, line), = val
2197
+ result = s(:ivar, id.to_sym).line line
2198
+ }
2199
+ | tCVAR
2200
+ {
2201
+ (id, line), = val
2202
+ result = s(:cvar, id.to_sym).line line
2203
+ }
2142
2204
  | backref
2143
2205
 
2144
- symbol: tSYMBEG sym
2206
+ symbol: ssym
2207
+ | dsym
2208
+
2209
+ ssym: tSYMBEG sym
2145
2210
  {
2211
+ _, (id, line) = val
2212
+
2146
2213
  lexer.lex_state = EXPR_END
2147
- result = val[1].to_sym
2214
+ result = s(:lit, id.to_sym).line line
2148
2215
  }
2149
2216
  | tSYMBOL
2150
2217
  {
2151
- result = val[0].to_sym
2218
+ (id, line), = val
2219
+
2220
+ lexer.lex_state = EXPR_END
2221
+ result = s(:lit, id.to_sym).line line
2152
2222
  }
2153
2223
 
2154
2224
  sym: fname | tIVAR | tGVAR | tCVAR
2155
2225
 
2156
- dsym: tSYMBEG xstring_contents tSTRING_END
2226
+ dsym: tSYMBEG string_contents tSTRING_END
2157
2227
  {
2158
2228
  _, result, _ = val
2159
2229
 
@@ -2169,7 +2239,7 @@ regexp_contents: none
2169
2239
  when :evstr then
2170
2240
  result = s(:dsym, "", result).line result.line
2171
2241
  else
2172
- debug20 26, val, result
2242
+ debug 39
2173
2243
  end
2174
2244
  }
2175
2245
 
@@ -2177,11 +2247,13 @@ regexp_contents: none
2177
2247
  | tFLOAT
2178
2248
  | tUMINUS_NUM tINTEGER =tLOWEST
2179
2249
  {
2180
- result = -val[1] # TODO: pt_testcase
2250
+ _, (num, line) = val
2251
+ result = [-num, line]
2181
2252
  }
2182
2253
  | tUMINUS_NUM tFLOAT =tLOWEST
2183
2254
  {
2184
- result = -val[1] # TODO: pt_testcase
2255
+ _, (num, line) = val
2256
+ result = [-num, line]
2185
2257
  }
2186
2258
 
2187
2259
  user_variable: tIDENTIFIER
@@ -2209,8 +2281,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2209
2281
 
2210
2282
  var_ref: user_variable
2211
2283
  {
2212
- var = val[0]
2284
+ raise "NO: #{val.inspect}" if Sexp === val.first
2285
+ (var, line), = val
2213
2286
  result = Sexp === var ? var : self.gettable(var)
2287
+ result.line line
2214
2288
  }
2215
2289
  | keyword_variable
2216
2290
  {
@@ -2225,11 +2299,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2225
2299
  | keyword_variable
2226
2300
  {
2227
2301
  result = self.assignable val[0]
2228
- debug20 29, val, result
2302
+ debug 40
2229
2303
  }
2230
2304
 
2231
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2232
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2305
+ backref: tNTH_REF
2306
+ {
2307
+ (ref, line), = val
2308
+ result = s(:nth_ref, ref).line line
2309
+ }
2310
+ | tBACK_REF
2311
+ {
2312
+ (ref, line), = val
2313
+ result = s(:back_ref, ref).line line
2314
+ }
2233
2315
 
2234
2316
  superclass: tLT
2235
2317
  {
@@ -2247,9 +2329,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2247
2329
 
2248
2330
  f_arglist: tLPAREN2 f_args rparen
2249
2331
  {
2250
- result = val[1]
2251
- self.lexer.lex_state = EXPR_BEG
2252
- self.lexer.command_start = true
2332
+ result = end_args val
2253
2333
  }
2254
2334
  | {
2255
2335
  result = self.in_kwarg
@@ -2258,12 +2338,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2258
2338
  }
2259
2339
  f_args term
2260
2340
  {
2261
- kwarg, args, _ = val
2262
-
2263
- self.in_kwarg = kwarg
2264
- result = args
2265
- lexer.lex_state = EXPR_BEG
2266
- lexer.command_start = true
2341
+ result = end_args val
2267
2342
  }
2268
2343
 
2269
2344
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2348,6 +2423,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2348
2423
  |
2349
2424
  {
2350
2425
  result = args val
2426
+ # result.line lexer.lineno
2351
2427
  }
2352
2428
 
2353
2429
 
@@ -2371,31 +2447,24 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2371
2447
  f_norm_arg: f_bad_arg
2372
2448
  | tIDENTIFIER
2373
2449
  {
2374
- identifier = val[0].to_sym
2450
+ (id, line), = val
2451
+ identifier = id.to_sym
2375
2452
  self.env[identifier] = :lvar
2376
2453
 
2377
- result = identifier
2454
+ result = [identifier, line]
2378
2455
  }
2379
2456
 
2380
2457
  f_arg_item: f_norm_arg
2381
2458
  | tLPAREN f_margs rparen
2382
2459
  {
2383
- result = val[1]
2460
+ _, margs, _ = val
2461
+
2462
+ result = margs
2384
2463
  }
2385
2464
 
2386
2465
  f_arg: f_arg_item
2387
2466
  {
2388
- arg, = val
2389
-
2390
- case arg
2391
- when Symbol then
2392
- result = s(:args, arg).line lexer.lineno
2393
- when Sexp then
2394
- result = arg
2395
- else
2396
- debug20 32
2397
- raise "Unknown f_arg type: #{val.inspect}"
2398
- end
2467
+ result = new_arg val
2399
2468
  }
2400
2469
  | f_arg tCOMMA f_arg_item
2401
2470
  {
@@ -2407,7 +2476,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2407
2476
  result = s(:args, list).line list.line
2408
2477
  end
2409
2478
 
2410
- result << item
2479
+ result << (Sexp === item ? item : item.first)
2411
2480
  }
2412
2481
 
2413
2482
  f_kw: tLABEL arg_value
@@ -2448,27 +2517,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2448
2517
  kwrest_mark: tPOW
2449
2518
  | tDSTAR
2450
2519
 
2520
+
2451
2521
  f_kwrest: kwrest_mark tIDENTIFIER
2452
2522
  {
2453
- name = val[1].to_sym
2454
- self.assignable name
2455
- result = :"**#{name}"
2523
+ _, (id, line) = val
2524
+
2525
+ name = id.to_sym
2526
+ self.assignable [name, line]
2527
+ result = [:"**#{name}", line]
2456
2528
  }
2457
2529
  | kwrest_mark
2458
2530
  {
2459
- result = :"**"
2460
- self.env[result] = :lvar
2531
+ id = :"**"
2532
+ self.env[id] = :lvar # TODO: needed?!?
2533
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2461
2534
  }
2462
2535
 
2463
2536
  f_opt: tIDENTIFIER tEQL arg_value
2464
2537
  {
2465
- result = self.assignable val[0], val[2]
2538
+ lhs, _, rhs = val
2539
+ result = self.assignable lhs, rhs
2466
2540
  # TODO: detect duplicate names
2467
2541
  }
2468
2542
 
2469
2543
  f_block_opt: tIDENTIFIER tEQL primary_value
2470
2544
  {
2471
- result = self.assignable val[0], val[2]
2545
+ lhs, _, rhs = val
2546
+ result = self.assignable lhs, rhs
2472
2547
  }
2473
2548
 
2474
2549
  f_block_optarg: f_block_opt
@@ -2498,30 +2573,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2498
2573
  f_rest_arg: restarg_mark tIDENTIFIER
2499
2574
  {
2500
2575
  # TODO: differs from parse.y - needs tests
2501
- name = val[1].to_sym
2502
- self.assignable name
2503
- result = :"*#{name}"
2576
+ _, (id, line) = val
2577
+ name = id.to_sym
2578
+ self.assignable [name, line]
2579
+ result = [:"*#{name}", line]
2504
2580
  }
2505
2581
  | restarg_mark
2506
2582
  {
2507
2583
  name = :"*"
2508
2584
  self.env[name] = :lvar
2509
- result = name
2585
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2510
2586
  }
2511
2587
 
2512
2588
  blkarg_mark: tAMPER2 | tAMPER
2513
2589
 
2514
2590
  f_block_arg: blkarg_mark tIDENTIFIER
2515
2591
  {
2516
- identifier = val[1].to_sym
2592
+ _, (id, line) = val
2593
+ identifier = id.to_sym
2517
2594
 
2518
2595
  self.env[identifier] = :lvar
2519
- result = "&#{identifier}".to_sym
2596
+ result = ["&#{identifier}".to_sym, line]
2520
2597
  }
2521
2598
 
2522
2599
  opt_f_block_arg: tCOMMA f_block_arg
2523
2600
  {
2524
- result = val[1]
2601
+ _, arg = val
2602
+ result = arg
2525
2603
  }
2526
2604
  |
2527
2605
  {