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/ruby24_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
  tLABEL_END
24
24
  tLONELY
@@ -33,7 +33,7 @@ preclow
33
33
  right tEQL tOP_ASGN
34
34
  left kRESCUE_MOD
35
35
  right tEH tCOLON
36
- nonassoc tDOT2 tDOT3
36
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
37
  left tOROP
38
38
  left tANDOP
39
39
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -56,6 +56,9 @@ rule
56
56
  top_compstmt
57
57
  {
58
58
  result = new_compstmt val
59
+
60
+ lexer.cond.pop # local_pop
61
+ lexer.cmdarg.pop
59
62
  }
60
63
 
61
64
  top_compstmt: top_stmts opt_terms
@@ -76,7 +79,7 @@ rule
76
79
  | klBEGIN
77
80
  {
78
81
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
82
+ debug 11
80
83
  yyerror "BEGIN in method"
81
84
  end
82
85
  self.env.extend
@@ -101,7 +104,9 @@ rule
101
104
  bodystmt: compstmt opt_rescue k_else
102
105
  {
103
106
  res = _values[-2]
104
- yyerror "else without rescue is useless" unless res
107
+ # TODO: move down to main match so I can just use val
108
+
109
+ warn "else without rescue is useless" unless res
105
110
  }
106
111
  compstmt
107
112
  opt_ensure
@@ -131,7 +136,7 @@ rule
131
136
  | error stmt
132
137
  {
133
138
  result = val[1]
134
- debug20 2, val, result
139
+ debug 12
135
140
  }
136
141
 
137
142
  stmt_or_begin: stmt
@@ -139,6 +144,10 @@ rule
139
144
  {
140
145
  yyerror "BEGIN is permitted only at toplevel"
141
146
  }
147
+ begin_block
148
+ {
149
+ result = val[2] # wtf?
150
+ }
142
151
 
143
152
  stmt: kALIAS fitem
144
153
  {
@@ -151,12 +160,12 @@ rule
151
160
  }
152
161
  | kALIAS tGVAR tGVAR
153
162
  {
154
- (_, line), lhs, rhs = val
163
+ (_, line), (lhs, _), (rhs, _) = val
155
164
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
165
  }
157
166
  | kALIAS tGVAR tBACK_REF
158
167
  {
159
- (_, line), lhs, rhs = val
168
+ (_, line), (lhs, _), (rhs, _) = val
160
169
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
170
  }
162
171
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +208,7 @@ rule
199
208
  (_, line), _, stmt, _ = val
200
209
 
201
210
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
211
+ debug 13
203
212
  yyerror "END in method; use at_exit"
204
213
  end
205
214
 
@@ -239,32 +248,31 @@ rule
239
248
  }
240
249
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
241
250
  {
242
- prim, _, id, opasgn, rhs = val
243
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
244
- if val[1] == '&.'
245
- result.sexp_type = :safe_op_asgn
246
- end
247
- result.line = val[0].line
251
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
252
+
253
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
254
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
255
+ result.line prim.line
248
256
  }
249
257
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
250
258
  {
251
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
252
- if val[1] == '&.'
253
- result.sexp_type = :safe_op_asgn
254
- end
255
- result.line = val[0].line
259
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
260
+
261
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
262
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
263
+ result.line prim.line
256
264
  }
257
265
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
258
266
  {
259
- lhs1, _, lhs2, op, rhs = val
267
+ lhs1, _, (lhs2, line), (id, _), rhs = val
260
268
 
261
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
269
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
262
270
  }
263
271
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
264
272
  {
265
- lhs1, _, lhs2, op, rhs = val
273
+ lhs1, _, (lhs2, line), (id, _), rhs = val
266
274
 
267
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
275
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
268
276
  }
269
277
  | backref tOP_ASGN command_rhs
270
278
  {
@@ -310,7 +318,7 @@ rule
310
318
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
319
  # REFACTOR: call_uni_op -- see parse26.y
312
320
  }
313
- | arg
321
+ | arg =tLBRACE_ARG
314
322
 
315
323
  expr_value: expr
316
324
  {
@@ -335,7 +343,7 @@ rule
335
343
  block_command: block_call
336
344
  | block_call call_op2 operation2 command_args
337
345
  {
338
- blk, _, msg, args = val
346
+ blk, _, (msg, _line), args = val
339
347
  result = new_call(blk, msg.to_sym, args).line blk.line
340
348
  }
341
349
 
@@ -349,15 +357,15 @@ rule
349
357
  _, line, body, _ = val
350
358
 
351
359
  result = body
352
- result.line = line
360
+ result.line line
353
361
 
354
362
  # self.env.unextend
355
363
  }
356
364
 
357
365
  fcall: operation
358
366
  {
359
- msg, = val
360
- result = new_call(nil, msg.to_sym).line lexer.lineno
367
+ (msg, line), = val
368
+ result = new_call(nil, msg.to_sym).line line
361
369
  }
362
370
 
363
371
  command: fcall command_args =tLOWEST
@@ -380,12 +388,14 @@ rule
380
388
  }
381
389
  | primary_value call_op operation2 command_args =tLOWEST
382
390
  {
383
- lhs, callop, op, args = val
391
+ lhs, callop, (op, _), args = val
392
+
384
393
  result = new_call lhs, op.to_sym, args, callop
394
+ result.line lhs.line
385
395
  }
386
396
  | primary_value call_op operation2 command_args cmd_brace_block
387
397
  {
388
- recv, _, msg, args, block = val
398
+ recv, _, (msg, _line), args, block = val
389
399
  call = new_call recv, msg.to_sym, args, val[1]
390
400
 
391
401
  block_dup_check call, block
@@ -395,11 +405,14 @@ rule
395
405
  }
396
406
  | primary_value tCOLON2 operation2 command_args =tLOWEST
397
407
  {
398
- result = new_call val[0], val[2].to_sym, val[3]
408
+ lhs, _, (id, line), args = val
409
+
410
+ result = new_call lhs, id.to_sym, args
411
+ result.line line
399
412
  }
400
413
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
401
414
  {
402
- recv, _, msg, args, block = val
415
+ recv, _, (msg, _line), args, block = val
403
416
  call = new_call recv, msg.to_sym, args
404
417
 
405
418
  block_dup_check call, block
@@ -557,25 +570,29 @@ rule
557
570
  }
558
571
  | primary_value call_op tIDENTIFIER
559
572
  {
560
- result = new_attrasgn val[0], val[2], val[1]
573
+ lhs, call_op, (id, _line) = val
574
+
575
+ result = new_attrasgn lhs, id, call_op
561
576
  }
562
577
  | primary_value tCOLON2 tIDENTIFIER
563
578
  {
564
- recv, _, id = val
579
+ recv, _, (id, _line) = val
565
580
  result = new_attrasgn recv, id
566
581
  }
567
582
  | primary_value call_op tCONSTANT
568
583
  {
569
- result = new_attrasgn val[0], val[2], val[1]
584
+ lhs, call_op, (id, _line) = val
585
+
586
+ result = new_attrasgn lhs, id, call_op
570
587
  }
571
588
  | primary_value tCOLON2 tCONSTANT
572
589
  {
573
590
  if (self.in_def || self.in_single > 0) then
574
- debug20 7
591
+ debug 14
575
592
  yyerror "dynamic constant assignment"
576
593
  end
577
594
 
578
- expr, _, id = val
595
+ expr, _, (id, _line) = val
579
596
  l = expr.line
580
597
 
581
598
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -583,58 +600,65 @@ rule
583
600
  | tCOLON3 tCONSTANT
584
601
  {
585
602
  if (self.in_def || self.in_single > 0) then
586
- debug20 8
603
+ debug 15
587
604
  yyerror "dynamic constant assignment"
588
605
  end
589
606
 
590
- _, id = val
591
- l = lexer.lineno
607
+ _, (id, l) = val
592
608
 
593
609
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
594
610
  }
595
611
  | backref
596
612
  {
597
- self.backref_assign_error val[0]
613
+ ref, = val
614
+
615
+ self.backref_assign_error ref
598
616
  }
599
617
 
600
618
  lhs: user_variable
601
619
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
620
+ var, = val
621
+
622
+ result = self.assignable var
605
623
  }
606
624
  | keyword_variable
607
625
  {
608
- line = lexer.lineno
609
- result = self.assignable val[0]
610
- result.line = line
611
- debug20 9, val, result
626
+ var, = val
627
+
628
+ result = self.assignable var
629
+
630
+ debug 16
612
631
  }
613
632
  | primary_value tLBRACK2 opt_call_args rbracket
614
633
  {
615
634
  lhs, _, args, _ = val
635
+
616
636
  result = self.aryset lhs, args
617
637
  }
618
638
  | primary_value call_op tIDENTIFIER # REFACTOR
619
639
  {
620
- lhs, op, id = val
640
+ lhs, op, (id, _line) = val
641
+
621
642
  result = new_attrasgn lhs, id, op
622
643
  }
623
644
  | primary_value tCOLON2 tIDENTIFIER
624
645
  {
625
- lhs, _, id = val
646
+ lhs, _, (id, _line) = val
647
+
626
648
  result = new_attrasgn lhs, id
627
649
  }
628
650
  | primary_value call_op tCONSTANT # REFACTOR?
629
651
  {
630
- result = new_attrasgn val[0], val[2], val[1]
652
+ lhs, call_op, (id, _line) = val
653
+
654
+ result = new_attrasgn lhs, id, call_op
631
655
  }
632
656
  | primary_value tCOLON2 tCONSTANT
633
657
  {
634
- expr, _, id = val
658
+ expr, _, (id, _line) = val
635
659
 
636
660
  if (self.in_def || self.in_single > 0) then
637
- debug20 10
661
+ debug 17
638
662
  yyerror "dynamic constant assignment"
639
663
  end
640
664
 
@@ -643,14 +667,13 @@ rule
643
667
  }
644
668
  | tCOLON3 tCONSTANT
645
669
  {
646
- _, id = val
670
+ _, (id, l) = val
647
671
 
648
672
  if (self.in_def || self.in_single > 0) then
649
- debug20 11
673
+ debug 18
650
674
  yyerror "dynamic constant assignment"
651
675
  end
652
676
 
653
- l = lexer.lineno
654
677
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
655
678
  }
656
679
  | backref
@@ -666,16 +689,17 @@ rule
666
689
 
667
690
  cpath: tCOLON3 cname
668
691
  {
669
- _, name = val
670
- result = s(:colon3, name.to_sym).line lexer.lineno
692
+ _, (name, line) = val
693
+ result = s(:colon3, name.to_sym).line line
671
694
  }
672
695
  | cname
673
696
  {
674
- result = val[0].to_sym
697
+ (id, line), = val
698
+ result = [id.to_sym, line] # TODO: sexp?
675
699
  }
676
700
  | primary_value tCOLON2 cname
677
701
  {
678
- pval, _, name = val
702
+ pval, _, (name, _line) = val
679
703
 
680
704
  result = s(:colon2, pval, name.to_sym)
681
705
  result.line pval.line
@@ -685,24 +709,17 @@ rule
685
709
  | op
686
710
  {
687
711
  lexer.lex_state = EXPR_END
688
- result = val[0]
689
712
  }
690
713
 
691
714
  | reswords
692
- {
693
- (sym, _line), = val
694
- lexer.lex_state = EXPR_END
695
- result = sym
696
- }
697
-
698
- fsym: fname | symbol
699
715
 
700
- fitem: fsym
716
+ fitem: fname
701
717
  {
702
- id, = val
703
- result = s(:lit, id.to_sym).line lexer.lineno
718
+ (id, line), = val
719
+
720
+ result = s(:lit, id.to_sym).line line
704
721
  }
705
- | dsym
722
+ | symbol
706
723
 
707
724
  undef_list: fitem
708
725
  {
@@ -723,8 +740,6 @@ rule
723
740
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
724
741
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
725
742
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
- # TODO: tUBANG dead?
727
- | tUBANG
728
743
 
729
744
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
730
745
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -758,24 +773,20 @@ rule
758
773
  }
759
774
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
760
775
  {
761
- lhs, _, id, op, rhs = val
776
+ lhs, _, (id, _line), (op, _), rhs = val
762
777
 
763
778
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
764
779
  }
765
780
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
766
781
  {
767
- lhs1, _, lhs2, op, rhs = val
782
+ lhs1, _, (lhs2, _line), op, rhs = val
768
783
 
769
784
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
785
  result = new_const_op_asgn [lhs, op, rhs]
771
786
  }
772
- | tCOLON3 tCONSTANT
787
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
773
788
  {
774
- result = self.lexer.lineno
775
- }
776
- tOP_ASGN arg_rhs
777
- {
778
- _, lhs, line, op, rhs = val
789
+ _, (lhs, line), op, rhs = val
779
790
 
780
791
  lhs = s(:colon3, lhs.to_sym).line line
781
792
  result = new_const_op_asgn [lhs, op, rhs]
@@ -789,7 +800,7 @@ rule
789
800
  | arg tDOT2 arg
790
801
  {
791
802
  v1, v2 = val[0], val[2]
792
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
803
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
804
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
794
805
  else
795
806
  result = s(:dot2, v1, v2).line v1.line
@@ -798,12 +809,14 @@ rule
798
809
  | arg tDOT3 arg
799
810
  {
800
811
  v1, v2 = val[0], val[2]
801
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
812
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
813
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
803
814
  else
804
815
  result = s(:dot3, v1, v2).line v1.line
805
816
  end
806
817
  }
818
+
819
+
807
820
  | arg tPLUS arg
808
821
  {
809
822
  result = new_call val[0], :+, argl(val[2])
@@ -830,8 +843,9 @@ rule
830
843
  }
831
844
  | tUMINUS_NUM simple_numeric tPOW arg
832
845
  {
833
- lit = s(:lit, val[1]).line lexer.lineno
834
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
846
+ _, (num, line), _, arg = val
847
+ lit = s(:lit, num).line line
848
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
835
849
 
836
850
  }
837
851
  | tUPLUS arg
@@ -930,12 +944,12 @@ rule
930
944
 
931
945
  rel_expr: arg relop arg =tGT
932
946
  {
933
- lhs, op, rhs = val
947
+ lhs, (op, _), rhs = val
934
948
  result = new_call lhs, op.to_sym, argl(rhs)
935
949
  }
936
950
  | rel_expr relop arg =tGT
937
951
  {
938
- lhs, op, rhs = val
952
+ lhs, (op, _), rhs = val
939
953
  warn "comparison '%s' after comparison", op
940
954
  result = new_call lhs, op.to_sym, argl(rhs)
941
955
  }
@@ -1126,8 +1140,9 @@ rule
1126
1140
  | backref
1127
1141
  | tFID
1128
1142
  {
1129
- msg, = val
1143
+ (msg, line), = val
1130
1144
  result = new_call nil, msg.to_sym
1145
+ result.line line
1131
1146
  }
1132
1147
  | k_begin
1133
1148
  {
@@ -1169,15 +1184,15 @@ rule
1169
1184
  }
1170
1185
  | primary_value tCOLON2 tCONSTANT
1171
1186
  {
1172
- expr, _, id = val
1187
+ expr, _, (id, _line) = val
1173
1188
 
1174
1189
  result = s(:colon2, expr, id.to_sym).line expr.line
1175
1190
  }
1176
1191
  | tCOLON3 tCONSTANT
1177
1192
  {
1178
- _, id = val
1193
+ _, (id, line) = val
1179
1194
 
1180
- result = s(:colon3, id.to_sym).line lexer.lineno
1195
+ result = s(:colon3, id.to_sym).line line
1181
1196
  }
1182
1197
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1183
1198
  {
@@ -1224,7 +1239,7 @@ rule
1224
1239
  }
1225
1240
  | kNOT tLPAREN2 rparen
1226
1241
  {
1227
- debug20 14, val, result
1242
+ debug 20
1228
1243
  }
1229
1244
  | fcall brace_block
1230
1245
  {
@@ -1242,9 +1257,10 @@ rule
1242
1257
  iter.insert 1, call # FIX
1243
1258
  result = iter
1244
1259
  }
1245
- | tLAMBDA lambda
1260
+ | lambda
1246
1261
  {
1247
- result = val[1] # TODO: fix lineno
1262
+ expr, = val
1263
+ result = expr
1248
1264
  }
1249
1265
  | k_if expr_value then compstmt if_tail k_end
1250
1266
  {
@@ -1287,7 +1303,6 @@ rule
1287
1303
  }
1288
1304
  cpath superclass
1289
1305
  {
1290
- self.comments.push self.lexer.comments
1291
1306
  if (self.in_def || self.in_single > 0) then
1292
1307
  yyerror "class definition in method body"
1293
1308
  end
@@ -1297,7 +1312,7 @@ rule
1297
1312
  {
1298
1313
  result = new_class val
1299
1314
  self.env.unextend
1300
- self.lexer.comments # we don't care about comments in the body
1315
+ self.lexer.ignore_body_comments
1301
1316
  }
1302
1317
  | k_class tLSHFT
1303
1318
  {
@@ -1318,7 +1333,7 @@ rule
1318
1333
  {
1319
1334
  result = new_sclass val
1320
1335
  self.env.unextend
1321
- self.lexer.comments # we don't care about comments in the body
1336
+ self.lexer.ignore_body_comments
1322
1337
  }
1323
1338
  | k_module
1324
1339
  {
@@ -1326,7 +1341,6 @@ rule
1326
1341
  }
1327
1342
  cpath
1328
1343
  {
1329
- self.comments.push self.lexer.comments
1330
1344
  yyerror "module definition in method body" if
1331
1345
  self.in_def or self.in_single > 0
1332
1346
 
@@ -1336,7 +1350,7 @@ rule
1336
1350
  {
1337
1351
  result = new_module val
1338
1352
  self.env.unextend
1339
- self.lexer.comments # we don't care about comments in the body
1353
+ self.lexer.ignore_body_comments
1340
1354
  }
1341
1355
  | k_def fname
1342
1356
  {
@@ -1346,21 +1360,17 @@ rule
1346
1360
  self.env.extend
1347
1361
  lexer.cmdarg.push false
1348
1362
  lexer.cond.push false
1349
-
1350
- self.comments.push self.lexer.comments
1351
1363
  }
1352
- f_arglist bodystmt { result = lexer.lineno } k_end
1364
+ f_arglist bodystmt k_end
1353
1365
  {
1354
- in_def = val[2]
1355
-
1356
- result = new_defn val
1366
+ result, in_def = new_defn val
1357
1367
 
1358
1368
  lexer.cond.pop # group = local_pop
1359
1369
  lexer.cmdarg.pop
1360
1370
  self.env.unextend
1361
1371
  self.in_def = in_def
1362
1372
 
1363
- self.lexer.comments # we don't care about comments in the body
1373
+ self.lexer.ignore_body_comments
1364
1374
  }
1365
1375
  | k_def singleton dot_or_colon
1366
1376
  {
@@ -1368,7 +1378,7 @@ rule
1368
1378
  }
1369
1379
  fname
1370
1380
  {
1371
- result = [self.in_def, lexer.lineno]
1381
+ result = self.in_def
1372
1382
 
1373
1383
  self.in_single += 1 # TODO: remove?
1374
1384
 
@@ -1378,13 +1388,18 @@ rule
1378
1388
  lexer.cond.push false
1379
1389
 
1380
1390
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1381
- self.comments.push self.lexer.comments
1382
1391
  }
1383
1392
  f_arglist bodystmt k_end
1384
1393
  {
1385
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1386
1394
 
1387
- result = new_defs val
1395
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1396
+ # =>
1397
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1398
+
1399
+ val.delete_at 3
1400
+ val.delete_at 2
1401
+
1402
+ result, in_def = new_defs val
1388
1403
 
1389
1404
  lexer.cond.pop # group = local_pop
1390
1405
  lexer.cmdarg.pop
@@ -1395,7 +1410,7 @@ rule
1395
1410
 
1396
1411
  # TODO: restore cur_arg ? what's cur_arg?
1397
1412
 
1398
- self.lexer.comments # we don't care about comments in the body
1413
+ self.lexer.ignore_body_comments
1399
1414
  }
1400
1415
  | kBREAK
1401
1416
  {
@@ -1432,8 +1447,17 @@ rule
1432
1447
  k_case: kCASE
1433
1448
  k_for: kFOR
1434
1449
  k_class: kCLASS
1450
+ {
1451
+ self.comments.push self.lexer.comments
1452
+ }
1435
1453
  k_module: kMODULE
1454
+ {
1455
+ self.comments.push self.lexer.comments
1456
+ }
1436
1457
  k_def: kDEF
1458
+ {
1459
+ self.comments.push self.lexer.comments
1460
+ }
1437
1461
  k_do: kDO
1438
1462
  k_do_block: kDO_BLOCK
1439
1463
  k_rescue: kRESCUE
@@ -1494,51 +1518,42 @@ rule
1494
1518
 
1495
1519
  result = block_var args
1496
1520
  }
1497
- | f_marg_list tCOMMA tSTAR f_norm_arg
1521
+ | f_marg_list tCOMMA f_rest_marg
1498
1522
  {
1499
- args, _, _, splat = val
1523
+ args, _, rest = val
1500
1524
 
1501
- result = block_var args, "*#{splat}".to_sym
1525
+ result = block_var args, rest
1502
1526
  }
1503
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1527
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1504
1528
  {
1505
- args, _, _, splat, _, args2 = val
1529
+ lhs, _, splat, _, rhs = val
1506
1530
 
1507
- result = block_var args, "*#{splat}".to_sym, args2
1531
+ result = block_var lhs, splat, rhs
1508
1532
  }
1509
- | f_marg_list tCOMMA tSTAR
1533
+ | f_rest_marg
1510
1534
  {
1511
- args, _, _ = val
1535
+ rest, = val
1512
1536
 
1513
- result = block_var args, :*
1537
+ result = block_var rest
1514
1538
  }
1515
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1539
+ | f_rest_marg tCOMMA f_marg_list
1516
1540
  {
1517
- args, _, _, _, args2 = val
1541
+ splat, _, rest = val
1518
1542
 
1519
- result = block_var args, :*, args2
1543
+ result = block_var splat, rest
1520
1544
  }
1521
- | tSTAR f_norm_arg
1522
- {
1523
- _, splat = val
1524
1545
 
1525
- result = block_var :"*#{splat}"
1526
- }
1527
- | tSTAR f_norm_arg tCOMMA f_marg_list
1546
+ f_rest_marg: tSTAR f_norm_arg
1528
1547
  {
1529
- _, splat, _, args = val
1548
+ _, (id, line) = val
1530
1549
 
1531
- result = block_var :"*#{splat}", args
1550
+ result = args ["*#{id}".to_sym]
1551
+ result.line line
1532
1552
  }
1533
1553
  | tSTAR
1534
1554
  {
1535
- result = block_var :*
1536
- }
1537
- | tSTAR tCOMMA f_marg_list
1538
- {
1539
- _, _, args = val
1540
-
1541
- result = block_var :*, args
1555
+ result = args [:*]
1556
+ result.line lexer.lineno # FIX: tSTAR -> line
1542
1557
  }
1543
1558
 
1544
1559
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1555,8 +1570,8 @@ rule
1555
1570
  }
1556
1571
  | f_block_arg
1557
1572
  {
1558
- line = lexer.lineno
1559
- result = call_args val # TODO: push line down
1573
+ (id, line), = val
1574
+ result = call_args [id]
1560
1575
  result.line line
1561
1576
  }
1562
1577
 
@@ -1665,13 +1680,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1665
1680
 
1666
1681
  bvar: tIDENTIFIER
1667
1682
  {
1668
- id, = val
1669
- line = lexer.lineno
1683
+ (id, line), = val
1670
1684
  result = s(:shadow, id.to_sym).line line
1671
1685
  }
1672
1686
  | f_bad_arg
1673
1687
 
1674
- lambda: {
1688
+ lambda: tLAMBDA
1689
+ {
1675
1690
  self.env.extend :dynamic
1676
1691
  result = [lexer.lineno, lexer.lpar_beg]
1677
1692
  lexer.paren_nest += 1
@@ -1683,14 +1698,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1683
1698
  }
1684
1699
  lambda_body
1685
1700
  {
1686
- (line, lpar), args, _cmdarg, body = val
1701
+ _, (line, lpar), args, _cmdarg, body = val
1687
1702
  lexer.lpar_beg = lpar
1688
1703
 
1689
1704
  lexer.cmdarg.pop
1690
1705
 
1691
1706
  call = s(:lambda).line line
1692
1707
  result = new_iter call, args, body
1693
- result.line = line
1708
+ result.line line
1694
1709
  self.env.unextend # TODO: dynapush & dynapop
1695
1710
  }
1696
1711
 
@@ -1725,23 +1740,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1725
1740
  ## if (nd_type($1) == NODE_YIELD) {
1726
1741
  ## compile_error(PARSER_ARG "block given to yield");
1727
1742
 
1728
- syntax_error "Both block arg and actual block given." if
1729
- val[0].block_pass?
1743
+ cmd, blk = val
1730
1744
 
1731
- val = invert_block_call val if inverted? val
1745
+ syntax_error "Both block arg and actual block given." if
1746
+ cmd.block_pass?
1732
1747
 
1733
- cmd, blk = val
1748
+ if inverted? val then
1749
+ val = invert_block_call val
1750
+ cmd, blk = val
1751
+ end
1734
1752
 
1735
1753
  result = blk
1736
1754
  result.insert 1, cmd
1737
1755
  }
1738
1756
  | block_call call_op2 operation2 opt_paren_args
1739
1757
  {
1740
- result = new_call val[0], val[2].to_sym, val[3]
1758
+ lhs, _, (id, _line), args = val
1759
+
1760
+ result = new_call lhs, id.to_sym, args
1741
1761
  }
1742
1762
  | block_call call_op2 operation2 opt_paren_args brace_block
1743
1763
  {
1744
- iter1, _, name, args, iter2 = val
1764
+ iter1, _, (name, _line), args, iter2 = val
1745
1765
 
1746
1766
  call = new_call iter1, name.to_sym, args
1747
1767
  iter2.insert 1, call
@@ -1750,7 +1770,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1750
1770
  }
1751
1771
  | block_call call_op2 operation2 command_args do_block
1752
1772
  {
1753
- iter1, _, name, args, iter2 = val
1773
+ iter1, _, (name, _line), args, iter2 = val
1754
1774
 
1755
1775
  call = new_call iter1, name.to_sym, args
1756
1776
  iter2.insert 1, call
@@ -1758,28 +1778,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1758
1778
  result = iter2
1759
1779
  }
1760
1780
 
1761
- method_call: fcall
1781
+ method_call: fcall paren_args
1762
1782
  {
1763
- result = self.lexer.lineno
1764
- }
1765
- paren_args
1766
- {
1767
- call, lineno, args = val
1783
+ call, args = val
1768
1784
 
1769
1785
  result = call.concat args.sexp_body if args
1770
- result.line lineno
1771
1786
  }
1772
1787
  | primary_value call_op operation2 opt_paren_args
1773
1788
  {
1774
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1789
+ recv, call_op, (op, _line), args = val
1790
+
1791
+ result = new_call recv, op.to_sym, args, call_op
1775
1792
  }
1776
1793
  | primary_value tCOLON2 operation2 paren_args
1777
1794
  {
1778
- result = new_call val[0], val[2].to_sym, val[3]
1795
+ recv, _, (op, _line), args = val
1796
+
1797
+ result = new_call recv, op.to_sym, args
1779
1798
  }
1780
1799
  | primary_value tCOLON2 operation3
1781
1800
  {
1782
- result = new_call val[0], val[2].to_sym
1801
+ lhs, _, (id, _line) = val
1802
+
1803
+ result = new_call lhs, id.to_sym
1783
1804
  }
1784
1805
  | primary_value call_op paren_args
1785
1806
  {
@@ -1812,7 +1833,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1812
1833
  _, line, body, _ = val
1813
1834
 
1814
1835
  result = body
1815
- result.line = line
1836
+ result.line line
1816
1837
 
1817
1838
  self.env.unextend
1818
1839
  }
@@ -1826,7 +1847,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1847
  _, line, body, _ = val
1827
1848
 
1828
1849
  result = body
1829
- result.line = line
1850
+ result.line line
1830
1851
 
1831
1852
  self.env.unextend
1832
1853
  }
@@ -1855,14 +1876,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1855
1876
  self.env.unextend
1856
1877
  }
1857
1878
 
1879
+ case_args: arg_value
1880
+ {
1881
+ arg, = val
1882
+
1883
+ result = s(:array, arg).line arg.line
1884
+ }
1885
+ | tSTAR arg_value
1886
+ {
1887
+ _, arg = val
1888
+
1889
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1890
+ }
1891
+ | case_args tCOMMA arg_value
1892
+ {
1893
+ args, _, id = val
1894
+
1895
+ result = self.list_append args, id
1896
+ }
1897
+ | case_args tCOMMA tSTAR arg_value
1898
+ {
1899
+ args, _, _, id = val
1900
+
1901
+ result = self.list_append args, s(:splat, id).line(id.line)
1902
+ }
1903
+
1858
1904
  case_body: k_when
1859
1905
  {
1860
1906
  result = self.lexer.lineno
1861
1907
  }
1862
- args then compstmt cases
1908
+ case_args then compstmt cases
1863
1909
  {
1864
1910
  result = new_when(val[2], val[4])
1865
- result.line = val[1]
1911
+ result.line val[1]
1866
1912
  result << val[5] if val[5]
1867
1913
  }
1868
1914
 
@@ -1908,17 +1954,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1908
1954
 
1909
1955
  literal: numeric
1910
1956
  {
1911
- line = lexer.lineno
1912
- result = s(:lit, val[0])
1913
- result.line = line
1957
+ (lit, line), = val
1958
+ result = s(:lit, lit).line line
1914
1959
  }
1915
1960
  | symbol
1916
- {
1917
- line = lexer.lineno
1918
- result = s(:lit, val[0])
1919
- result.line = line
1920
- }
1921
- | dsym
1922
1961
 
1923
1962
  strings: string
1924
1963
  {
@@ -1929,7 +1968,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1929
1968
 
1930
1969
  string: tCHAR
1931
1970
  {
1932
- debug20 23, val, result
1971
+ debug 37
1933
1972
  }
1934
1973
  | string1
1935
1974
  | string string1
@@ -1939,11 +1978,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1939
1978
 
1940
1979
  string1: tSTRING_BEG string_contents tSTRING_END
1941
1980
  {
1942
- _, str, (_, func) = val
1981
+ (_, line), str, (_, func) = val
1943
1982
 
1944
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1983
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1945
1984
 
1946
- result = str
1985
+ result = str.line line
1947
1986
  }
1948
1987
  | tSTRING
1949
1988
  {
@@ -1963,11 +2002,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1963
2002
 
1964
2003
  words: tWORDS_BEG tSPACE tSTRING_END
1965
2004
  {
1966
- result = s(:array).line lexer.lineno
2005
+ (_, line), _, _ = val
2006
+
2007
+ result = s(:array).line line
1967
2008
  }
1968
2009
  | tWORDS_BEG word_list tSTRING_END
1969
2010
  {
1970
- result = val[1]
2011
+ (_, line), list, _ = val
2012
+
2013
+ result = list.line line
1971
2014
  }
1972
2015
 
1973
2016
  word_list: none
@@ -1987,18 +2030,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1987
2030
 
1988
2031
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1989
2032
  {
1990
- result = s(:array).line lexer.lineno
2033
+ (_, line), _, _ = val
2034
+
2035
+ result = s(:array).line line
1991
2036
  }
1992
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2037
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1993
2038
  {
1994
- _, line, list, _, = val
1995
- list.line = line
2039
+ (_, line), list, _, = val
2040
+ list.line line
1996
2041
  result = list
1997
2042
  }
1998
2043
 
1999
2044
  symbol_list: none
2000
2045
  {
2001
- result = new_symbol_list.line lexer.lineno
2046
+ result = new_symbol_list
2002
2047
  }
2003
2048
  | symbol_list word tSPACE
2004
2049
  {
@@ -2008,20 +2053,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2008
2053
 
2009
2054
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2010
2055
  {
2011
- result = s(:array).line lexer.lineno
2056
+ (_, line), _, _ = val
2057
+
2058
+ result = s(:array).line line
2012
2059
  }
2013
2060
  | tQWORDS_BEG qword_list tSTRING_END
2014
2061
  {
2015
- result = val[1]
2062
+ (_, line), list, _ = val
2063
+
2064
+ result = list.line line
2016
2065
  }
2017
2066
 
2018
2067
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2019
2068
  {
2020
- result = s(:array).line lexer.lineno # FIX
2069
+ (_, line), _, _ = val
2070
+
2071
+ result = s(:array).line line
2021
2072
  }
2022
2073
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2023
2074
  {
2024
- result = val[1]
2075
+ (_, line), list, _ = val
2076
+
2077
+ result = list.line line
2025
2078
  }
2026
2079
 
2027
2080
  qword_list: none
@@ -2044,7 +2097,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2044
2097
 
2045
2098
  string_contents: none
2046
2099
  {
2047
- result = s(:str, "").line lexer.lineno
2100
+ line = prev_value_to_lineno _values.last
2101
+ result = s(:str, +"").line line
2048
2102
  }
2049
2103
  | string_contents string_content
2050
2104
  {
@@ -2119,8 +2173,8 @@ regexp_contents: none
2119
2173
  lexer.brace_nest = brace_nest
2120
2174
  lexer.string_nest = string_nest
2121
2175
 
2122
- lexer.cmdarg.pop
2123
2176
  lexer.cond.pop
2177
+ lexer.cmdarg.pop
2124
2178
 
2125
2179
  lexer.lex_state = oldlex_state
2126
2180
 
@@ -2135,29 +2189,49 @@ regexp_contents: none
2135
2189
  when nil then
2136
2190
  result = s(:evstr).line line
2137
2191
  else
2138
- debug20 25
2192
+ debug 38
2139
2193
  raise "unknown string body: #{stmt.inspect}"
2140
2194
  end
2141
2195
  }
2142
2196
 
2143
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2144
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2145
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2197
+ string_dvar: tGVAR
2198
+ {
2199
+ (id, line), = val
2200
+ result = s(:gvar, id.to_sym).line line
2201
+ }
2202
+ | tIVAR
2203
+ {
2204
+ (id, line), = val
2205
+ result = s(:ivar, id.to_sym).line line
2206
+ }
2207
+ | tCVAR
2208
+ {
2209
+ (id, line), = val
2210
+ result = s(:cvar, id.to_sym).line line
2211
+ }
2146
2212
  | backref
2147
2213
 
2148
- symbol: tSYMBEG sym
2214
+ symbol: ssym
2215
+ | dsym
2216
+
2217
+ ssym: tSYMBEG sym
2149
2218
  {
2219
+ _, (id, line) = val
2220
+
2150
2221
  lexer.lex_state = EXPR_END
2151
- result = val[1].to_sym
2222
+ result = s(:lit, id.to_sym).line line
2152
2223
  }
2153
2224
  | tSYMBOL
2154
2225
  {
2155
- result = val[0].to_sym
2226
+ (id, line), = val
2227
+
2228
+ lexer.lex_state = EXPR_END
2229
+ result = s(:lit, id.to_sym).line line
2156
2230
  }
2157
2231
 
2158
2232
  sym: fname | tIVAR | tGVAR | tCVAR
2159
2233
 
2160
- dsym: tSYMBEG xstring_contents tSTRING_END
2234
+ dsym: tSYMBEG string_contents tSTRING_END
2161
2235
  {
2162
2236
  _, result, _ = val
2163
2237
 
@@ -2173,14 +2247,15 @@ regexp_contents: none
2173
2247
  when :evstr then
2174
2248
  result = s(:dsym, "", result).line result.line
2175
2249
  else
2176
- debug20 26, val, result
2250
+ debug 39
2177
2251
  end
2178
2252
  }
2179
2253
 
2180
2254
  numeric: simple_numeric
2181
- | tUMINUS_NUM simple_numeric
2255
+ | tUMINUS_NUM simple_numeric =tLOWEST
2182
2256
  {
2183
- result = -val[1] # TODO: pt_testcase
2257
+ _, (num, line) = val
2258
+ result = [-num, line]
2184
2259
  }
2185
2260
 
2186
2261
  simple_numeric: tINTEGER
@@ -2213,8 +2288,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2213
2288
 
2214
2289
  var_ref: user_variable
2215
2290
  {
2216
- var = val[0]
2291
+ raise "NO: #{val.inspect}" if Sexp === val.first
2292
+ (var, line), = val
2217
2293
  result = Sexp === var ? var : self.gettable(var)
2294
+ result.line line
2218
2295
  }
2219
2296
  | keyword_variable
2220
2297
  {
@@ -2229,11 +2306,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2229
2306
  | keyword_variable
2230
2307
  {
2231
2308
  result = self.assignable val[0]
2232
- debug20 29, val, result
2309
+ debug 40
2233
2310
  }
2234
2311
 
2235
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2236
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2312
+ backref: tNTH_REF
2313
+ {
2314
+ (ref, line), = val
2315
+ result = s(:nth_ref, ref).line line
2316
+ }
2317
+ | tBACK_REF
2318
+ {
2319
+ (ref, line), = val
2320
+ result = s(:back_ref, ref).line line
2321
+ }
2237
2322
 
2238
2323
  superclass: tLT
2239
2324
  {
@@ -2251,9 +2336,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2251
2336
 
2252
2337
  f_arglist: tLPAREN2 f_args rparen
2253
2338
  {
2254
- result = val[1]
2255
- self.lexer.lex_state = EXPR_BEG
2256
- self.lexer.command_start = true
2339
+ result = end_args val
2257
2340
  }
2258
2341
  | {
2259
2342
  result = self.in_kwarg
@@ -2262,12 +2345,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2262
2345
  }
2263
2346
  f_args term
2264
2347
  {
2265
- kwarg, args, _ = val
2266
-
2267
- self.in_kwarg = kwarg
2268
- result = args
2269
- lexer.lex_state = EXPR_BEG
2270
- lexer.command_start = true
2348
+ result = end_args val
2271
2349
  }
2272
2350
 
2273
2351
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2352,8 +2430,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2352
2430
  |
2353
2431
  {
2354
2432
  result = args val
2433
+ # result.line lexer.lineno
2355
2434
  }
2356
2435
 
2436
+
2357
2437
  f_bad_arg: tCONSTANT
2358
2438
  {
2359
2439
  yyerror "formal argument cannot be a constant"
@@ -2374,10 +2454,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2374
2454
  f_norm_arg: f_bad_arg
2375
2455
  | tIDENTIFIER
2376
2456
  {
2377
- identifier = val[0].to_sym
2457
+ (id, line), = val
2458
+ identifier = id.to_sym
2378
2459
  self.env[identifier] = :lvar
2379
2460
 
2380
- result = identifier
2461
+ result = [identifier, line]
2381
2462
  }
2382
2463
 
2383
2464
  f_arg_asgn: f_norm_arg
@@ -2385,22 +2466,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2385
2466
  f_arg_item: f_arg_asgn
2386
2467
  | tLPAREN f_margs rparen
2387
2468
  {
2388
- result = val[1]
2469
+ _, margs, _ = val
2470
+
2471
+ result = margs
2389
2472
  }
2390
2473
 
2391
2474
  f_arg: f_arg_item
2392
2475
  {
2393
- arg, = val
2394
-
2395
- case arg
2396
- when Symbol then
2397
- result = s(:args, arg).line lexer.lineno
2398
- when Sexp then
2399
- result = arg
2400
- else
2401
- debug20 32
2402
- raise "Unknown f_arg type: #{val.inspect}"
2403
- end
2476
+ result = new_arg val
2404
2477
  }
2405
2478
  | f_arg tCOMMA f_arg_item
2406
2479
  {
@@ -2412,7 +2485,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2412
2485
  result = s(:args, list).line list.line
2413
2486
  end
2414
2487
 
2415
- result << item
2488
+ result << (Sexp === item ? item : item.first)
2416
2489
  }
2417
2490
 
2418
2491
  f_label: tLABEL
@@ -2473,26 +2546,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2473
2546
  kwrest_mark: tPOW
2474
2547
  | tDSTAR
2475
2548
 
2549
+
2476
2550
  f_kwrest: kwrest_mark tIDENTIFIER
2477
2551
  {
2478
- name = val[1].to_sym
2479
- self.assignable name
2480
- result = :"**#{name}"
2552
+ _, (id, line) = val
2553
+
2554
+ name = id.to_sym
2555
+ self.assignable [name, line]
2556
+ result = [:"**#{name}", line]
2481
2557
  }
2482
2558
  | kwrest_mark
2483
2559
  {
2484
- result = :"**"
2560
+ id = :"**"
2561
+ self.env[id] = :lvar # TODO: needed?!?
2562
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2485
2563
  }
2486
2564
 
2487
2565
  f_opt: f_arg_asgn tEQL arg_value
2488
2566
  {
2489
- result = self.assignable val[0], val[2]
2567
+ lhs, _, rhs = val
2568
+ result = self.assignable lhs, rhs
2490
2569
  # TODO: detect duplicate names
2491
2570
  }
2492
2571
 
2493
2572
  f_block_opt: f_arg_asgn tEQL primary_value
2494
2573
  {
2495
- result = self.assignable val[0], val[2]
2574
+ lhs, _, rhs = val
2575
+ result = self.assignable lhs, rhs
2496
2576
  }
2497
2577
 
2498
2578
  f_block_optarg: f_block_opt
@@ -2522,30 +2602,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2522
2602
  f_rest_arg: restarg_mark tIDENTIFIER
2523
2603
  {
2524
2604
  # TODO: differs from parse.y - needs tests
2525
- name = val[1].to_sym
2526
- self.assignable name
2527
- result = :"*#{name}"
2605
+ _, (id, line) = val
2606
+ name = id.to_sym
2607
+ self.assignable [name, line]
2608
+ result = [:"*#{name}", line]
2528
2609
  }
2529
2610
  | restarg_mark
2530
2611
  {
2531
2612
  name = :"*"
2532
2613
  self.env[name] = :lvar
2533
- result = name
2614
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2534
2615
  }
2535
2616
 
2536
2617
  blkarg_mark: tAMPER2 | tAMPER
2537
2618
 
2538
2619
  f_block_arg: blkarg_mark tIDENTIFIER
2539
2620
  {
2540
- identifier = val[1].to_sym
2621
+ _, (id, line) = val
2622
+ identifier = id.to_sym
2541
2623
 
2542
2624
  self.env[identifier] = :lvar
2543
- result = "&#{identifier}".to_sym
2625
+ result = ["&#{identifier}".to_sym, line]
2544
2626
  }
2545
2627
 
2546
2628
  opt_f_block_arg: tCOMMA f_block_arg
2547
2629
  {
2548
- result = val[1]
2630
+ _, arg = val
2631
+ result = arg
2549
2632
  }
2550
2633
  |
2551
2634
  {
@@ -2594,9 +2677,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2594
2677
  }
2595
2678
  | tSTRING_BEG string_contents tLABEL_END arg_value
2596
2679
  {
2597
- _, sym, _, value = val
2680
+ (_, line), sym, _, value = val
2681
+
2598
2682
  sym.sexp_type = :dsym
2599
- result = s(:array, sym, value).line sym.line
2683
+
2684
+ result = s(:array, sym, value).line line
2600
2685
  }
2601
2686
  | tDSTAR arg_value
2602
2687
  {