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/ruby23_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
  {
@@ -302,7 +310,7 @@ rule
302
310
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
303
311
  # REFACTOR: call_uni_op -- see parse26.y
304
312
  }
305
- | arg
313
+ | arg =tLBRACE_ARG
306
314
 
307
315
  expr_value: expr
308
316
  {
@@ -327,7 +335,7 @@ rule
327
335
  block_command: block_call
328
336
  | block_call call_op2 operation2 command_args
329
337
  {
330
- blk, _, msg, args = val
338
+ blk, _, (msg, _line), args = val
331
339
  result = new_call(blk, msg.to_sym, args).line blk.line
332
340
  }
333
341
 
@@ -341,15 +349,15 @@ rule
341
349
  _, line, body, _ = val
342
350
 
343
351
  result = body
344
- result.line = line
352
+ result.line line
345
353
 
346
354
  # self.env.unextend
347
355
  }
348
356
 
349
357
  fcall: operation
350
358
  {
351
- msg, = val
352
- result = new_call(nil, msg.to_sym).line lexer.lineno
359
+ (msg, line), = val
360
+ result = new_call(nil, msg.to_sym).line line
353
361
  }
354
362
 
355
363
  command: fcall command_args =tLOWEST
@@ -372,12 +380,14 @@ rule
372
380
  }
373
381
  | primary_value call_op operation2 command_args =tLOWEST
374
382
  {
375
- lhs, callop, op, args = val
383
+ lhs, callop, (op, _), args = val
384
+
376
385
  result = new_call lhs, op.to_sym, args, callop
386
+ result.line lhs.line
377
387
  }
378
388
  | primary_value call_op operation2 command_args cmd_brace_block
379
389
  {
380
- recv, _, msg, args, block = val
390
+ recv, _, (msg, _line), args, block = val
381
391
  call = new_call recv, msg.to_sym, args, val[1]
382
392
 
383
393
  block_dup_check call, block
@@ -387,11 +397,14 @@ rule
387
397
  }
388
398
  | primary_value tCOLON2 operation2 command_args =tLOWEST
389
399
  {
390
- result = new_call val[0], val[2].to_sym, val[3]
400
+ lhs, _, (id, line), args = val
401
+
402
+ result = new_call lhs, id.to_sym, args
403
+ result.line line
391
404
  }
392
405
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
393
406
  {
394
- recv, _, msg, args, block = val
407
+ recv, _, (msg, _line), args, block = val
395
408
  call = new_call recv, msg.to_sym, args
396
409
 
397
410
  block_dup_check call, block
@@ -549,25 +562,29 @@ rule
549
562
  }
550
563
  | primary_value call_op tIDENTIFIER
551
564
  {
552
- result = new_attrasgn val[0], val[2], val[1]
565
+ lhs, call_op, (id, _line) = val
566
+
567
+ result = new_attrasgn lhs, id, call_op
553
568
  }
554
569
  | primary_value tCOLON2 tIDENTIFIER
555
570
  {
556
- recv, _, id = val
571
+ recv, _, (id, _line) = val
557
572
  result = new_attrasgn recv, id
558
573
  }
559
574
  | primary_value call_op tCONSTANT
560
575
  {
561
- result = new_attrasgn val[0], val[2], val[1]
576
+ lhs, call_op, (id, _line) = val
577
+
578
+ result = new_attrasgn lhs, id, call_op
562
579
  }
563
580
  | primary_value tCOLON2 tCONSTANT
564
581
  {
565
582
  if (self.in_def || self.in_single > 0) then
566
- debug20 7
583
+ debug 14
567
584
  yyerror "dynamic constant assignment"
568
585
  end
569
586
 
570
- expr, _, id = val
587
+ expr, _, (id, _line) = val
571
588
  l = expr.line
572
589
 
573
590
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -575,58 +592,65 @@ rule
575
592
  | tCOLON3 tCONSTANT
576
593
  {
577
594
  if (self.in_def || self.in_single > 0) then
578
- debug20 8
595
+ debug 15
579
596
  yyerror "dynamic constant assignment"
580
597
  end
581
598
 
582
- _, id = val
583
- l = lexer.lineno
599
+ _, (id, l) = val
584
600
 
585
601
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
586
602
  }
587
603
  | backref
588
604
  {
589
- self.backref_assign_error val[0]
605
+ ref, = val
606
+
607
+ self.backref_assign_error ref
590
608
  }
591
609
 
592
610
  lhs: user_variable
593
611
  {
594
- line = lexer.lineno
595
- result = self.assignable val[0]
596
- result.line = line
612
+ var, = val
613
+
614
+ result = self.assignable var
597
615
  }
598
616
  | keyword_variable
599
617
  {
600
- line = lexer.lineno
601
- result = self.assignable val[0]
602
- result.line = line
603
- debug20 9, val, result
618
+ var, = val
619
+
620
+ result = self.assignable var
621
+
622
+ debug 16
604
623
  }
605
624
  | primary_value tLBRACK2 opt_call_args rbracket
606
625
  {
607
626
  lhs, _, args, _ = val
627
+
608
628
  result = self.aryset lhs, args
609
629
  }
610
630
  | primary_value call_op tIDENTIFIER # REFACTOR
611
631
  {
612
- lhs, op, id = val
632
+ lhs, op, (id, _line) = val
633
+
613
634
  result = new_attrasgn lhs, id, op
614
635
  }
615
636
  | primary_value tCOLON2 tIDENTIFIER
616
637
  {
617
- lhs, _, id = val
638
+ lhs, _, (id, _line) = val
639
+
618
640
  result = new_attrasgn lhs, id
619
641
  }
620
642
  | primary_value call_op tCONSTANT # REFACTOR?
621
643
  {
622
- result = new_attrasgn val[0], val[2], val[1]
644
+ lhs, call_op, (id, _line) = val
645
+
646
+ result = new_attrasgn lhs, id, call_op
623
647
  }
624
648
  | primary_value tCOLON2 tCONSTANT
625
649
  {
626
- expr, _, id = val
650
+ expr, _, (id, _line) = val
627
651
 
628
652
  if (self.in_def || self.in_single > 0) then
629
- debug20 10
653
+ debug 17
630
654
  yyerror "dynamic constant assignment"
631
655
  end
632
656
 
@@ -635,14 +659,13 @@ rule
635
659
  }
636
660
  | tCOLON3 tCONSTANT
637
661
  {
638
- _, id = val
662
+ _, (id, l) = val
639
663
 
640
664
  if (self.in_def || self.in_single > 0) then
641
- debug20 11
665
+ debug 18
642
666
  yyerror "dynamic constant assignment"
643
667
  end
644
668
 
645
- l = lexer.lineno
646
669
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
647
670
  }
648
671
  | backref
@@ -658,16 +681,17 @@ rule
658
681
 
659
682
  cpath: tCOLON3 cname
660
683
  {
661
- _, name = val
662
- result = s(:colon3, name.to_sym).line lexer.lineno
684
+ _, (name, line) = val
685
+ result = s(:colon3, name.to_sym).line line
663
686
  }
664
687
  | cname
665
688
  {
666
- result = val[0].to_sym
689
+ (id, line), = val
690
+ result = [id.to_sym, line] # TODO: sexp?
667
691
  }
668
692
  | primary_value tCOLON2 cname
669
693
  {
670
- pval, _, name = val
694
+ pval, _, (name, _line) = val
671
695
 
672
696
  result = s(:colon2, pval, name.to_sym)
673
697
  result.line pval.line
@@ -677,24 +701,17 @@ rule
677
701
  | op
678
702
  {
679
703
  lexer.lex_state = EXPR_END
680
- result = val[0]
681
704
  }
682
705
 
683
706
  | reswords
684
- {
685
- (sym, _line), = val
686
- lexer.lex_state = EXPR_END
687
- result = sym
688
- }
689
-
690
- fsym: fname | symbol
691
707
 
692
- fitem: fsym
708
+ fitem: fname
693
709
  {
694
- id, = val
695
- result = s(:lit, id.to_sym).line lexer.lineno
710
+ (id, line), = val
711
+
712
+ result = s(:lit, id.to_sym).line line
696
713
  }
697
- | dsym
714
+ | symbol
698
715
 
699
716
  undef_list: fitem
700
717
  {
@@ -715,8 +732,6 @@ rule
715
732
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
716
733
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
717
734
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
718
- # TODO: tUBANG dead?
719
- | tUBANG
720
735
 
721
736
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
722
737
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -750,24 +765,20 @@ rule
750
765
  }
751
766
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
752
767
  {
753
- lhs, _, id, op, rhs = val
768
+ lhs, _, (id, _line), (op, _), rhs = val
754
769
 
755
770
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
756
771
  }
757
772
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
758
773
  {
759
- lhs1, _, lhs2, op, rhs = val
774
+ lhs1, _, (lhs2, _line), op, rhs = val
760
775
 
761
776
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
762
777
  result = new_const_op_asgn [lhs, op, rhs]
763
778
  }
764
- | tCOLON3 tCONSTANT
779
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
765
780
  {
766
- result = self.lexer.lineno
767
- }
768
- tOP_ASGN arg_rhs
769
- {
770
- _, lhs, line, op, rhs = val
781
+ _, (lhs, line), op, rhs = val
771
782
 
772
783
  lhs = s(:colon3, lhs.to_sym).line line
773
784
  result = new_const_op_asgn [lhs, op, rhs]
@@ -781,7 +792,7 @@ rule
781
792
  | arg tDOT2 arg
782
793
  {
783
794
  v1, v2 = val[0], val[2]
784
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
795
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
785
796
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
786
797
  else
787
798
  result = s(:dot2, v1, v2).line v1.line
@@ -790,12 +801,14 @@ rule
790
801
  | arg tDOT3 arg
791
802
  {
792
803
  v1, v2 = val[0], val[2]
793
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
804
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
794
805
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
795
806
  else
796
807
  result = s(:dot3, v1, v2).line v1.line
797
808
  end
798
809
  }
810
+
811
+
799
812
  | arg tPLUS arg
800
813
  {
801
814
  result = new_call val[0], :+, argl(val[2])
@@ -822,8 +835,9 @@ rule
822
835
  }
823
836
  | tUMINUS_NUM simple_numeric tPOW arg
824
837
  {
825
- lit = s(:lit, val[1]).line lexer.lineno
826
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
838
+ _, (num, line), _, arg = val
839
+ lit = s(:lit, num).line line
840
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
827
841
 
828
842
  }
829
843
  | tUPLUS arg
@@ -922,12 +936,12 @@ rule
922
936
 
923
937
  rel_expr: arg relop arg =tGT
924
938
  {
925
- lhs, op, rhs = val
939
+ lhs, (op, _), rhs = val
926
940
  result = new_call lhs, op.to_sym, argl(rhs)
927
941
  }
928
942
  | rel_expr relop arg =tGT
929
943
  {
930
- lhs, op, rhs = val
944
+ lhs, (op, _), rhs = val
931
945
  warn "comparison '%s' after comparison", op
932
946
  result = new_call lhs, op.to_sym, argl(rhs)
933
947
  }
@@ -1118,8 +1132,9 @@ rule
1118
1132
  | backref
1119
1133
  | tFID
1120
1134
  {
1121
- msg, = val
1135
+ (msg, line), = val
1122
1136
  result = new_call nil, msg.to_sym
1137
+ result.line line
1123
1138
  }
1124
1139
  | k_begin
1125
1140
  {
@@ -1161,15 +1176,15 @@ rule
1161
1176
  }
1162
1177
  | primary_value tCOLON2 tCONSTANT
1163
1178
  {
1164
- expr, _, id = val
1179
+ expr, _, (id, _line) = val
1165
1180
 
1166
1181
  result = s(:colon2, expr, id.to_sym).line expr.line
1167
1182
  }
1168
1183
  | tCOLON3 tCONSTANT
1169
1184
  {
1170
- _, id = val
1185
+ _, (id, line) = val
1171
1186
 
1172
- result = s(:colon3, id.to_sym).line lexer.lineno
1187
+ result = s(:colon3, id.to_sym).line line
1173
1188
  }
1174
1189
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1175
1190
  {
@@ -1216,7 +1231,7 @@ rule
1216
1231
  }
1217
1232
  | kNOT tLPAREN2 rparen
1218
1233
  {
1219
- debug20 14, val, result
1234
+ debug 20
1220
1235
  }
1221
1236
  | fcall brace_block
1222
1237
  {
@@ -1234,9 +1249,10 @@ rule
1234
1249
  iter.insert 1, call # FIX
1235
1250
  result = iter
1236
1251
  }
1237
- | tLAMBDA lambda
1252
+ | lambda
1238
1253
  {
1239
- result = val[1] # TODO: fix lineno
1254
+ expr, = val
1255
+ result = expr
1240
1256
  }
1241
1257
  | k_if expr_value then compstmt if_tail k_end
1242
1258
  {
@@ -1279,7 +1295,6 @@ rule
1279
1295
  }
1280
1296
  cpath superclass
1281
1297
  {
1282
- self.comments.push self.lexer.comments
1283
1298
  if (self.in_def || self.in_single > 0) then
1284
1299
  yyerror "class definition in method body"
1285
1300
  end
@@ -1289,7 +1304,7 @@ rule
1289
1304
  {
1290
1305
  result = new_class val
1291
1306
  self.env.unextend
1292
- self.lexer.comments # we don't care about comments in the body
1307
+ self.lexer.ignore_body_comments
1293
1308
  }
1294
1309
  | k_class tLSHFT
1295
1310
  {
@@ -1310,7 +1325,7 @@ rule
1310
1325
  {
1311
1326
  result = new_sclass val
1312
1327
  self.env.unextend
1313
- self.lexer.comments # we don't care about comments in the body
1328
+ self.lexer.ignore_body_comments
1314
1329
  }
1315
1330
  | k_module
1316
1331
  {
@@ -1318,7 +1333,6 @@ rule
1318
1333
  }
1319
1334
  cpath
1320
1335
  {
1321
- self.comments.push self.lexer.comments
1322
1336
  yyerror "module definition in method body" if
1323
1337
  self.in_def or self.in_single > 0
1324
1338
 
@@ -1328,7 +1342,7 @@ rule
1328
1342
  {
1329
1343
  result = new_module val
1330
1344
  self.env.unextend
1331
- self.lexer.comments # we don't care about comments in the body
1345
+ self.lexer.ignore_body_comments
1332
1346
  }
1333
1347
  | k_def fname
1334
1348
  {
@@ -1338,21 +1352,17 @@ rule
1338
1352
  self.env.extend
1339
1353
  lexer.cmdarg.push false
1340
1354
  lexer.cond.push false
1341
-
1342
- self.comments.push self.lexer.comments
1343
1355
  }
1344
- f_arglist bodystmt { result = lexer.lineno } k_end
1356
+ f_arglist bodystmt k_end
1345
1357
  {
1346
- in_def = val[2]
1347
-
1348
- result = new_defn val
1358
+ result, in_def = new_defn val
1349
1359
 
1350
1360
  lexer.cond.pop # group = local_pop
1351
1361
  lexer.cmdarg.pop
1352
1362
  self.env.unextend
1353
1363
  self.in_def = in_def
1354
1364
 
1355
- self.lexer.comments # we don't care about comments in the body
1365
+ self.lexer.ignore_body_comments
1356
1366
  }
1357
1367
  | k_def singleton dot_or_colon
1358
1368
  {
@@ -1360,7 +1370,7 @@ rule
1360
1370
  }
1361
1371
  fname
1362
1372
  {
1363
- result = [self.in_def, lexer.lineno]
1373
+ result = self.in_def
1364
1374
 
1365
1375
  self.in_single += 1 # TODO: remove?
1366
1376
 
@@ -1370,13 +1380,18 @@ rule
1370
1380
  lexer.cond.push false
1371
1381
 
1372
1382
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1373
- self.comments.push self.lexer.comments
1374
1383
  }
1375
1384
  f_arglist bodystmt k_end
1376
1385
  {
1377
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1378
1386
 
1379
- 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
1380
1395
 
1381
1396
  lexer.cond.pop # group = local_pop
1382
1397
  lexer.cmdarg.pop
@@ -1387,7 +1402,7 @@ rule
1387
1402
 
1388
1403
  # TODO: restore cur_arg ? what's cur_arg?
1389
1404
 
1390
- self.lexer.comments # we don't care about comments in the body
1405
+ self.lexer.ignore_body_comments
1391
1406
  }
1392
1407
  | kBREAK
1393
1408
  {
@@ -1424,8 +1439,17 @@ rule
1424
1439
  k_case: kCASE
1425
1440
  k_for: kFOR
1426
1441
  k_class: kCLASS
1442
+ {
1443
+ self.comments.push self.lexer.comments
1444
+ }
1427
1445
  k_module: kMODULE
1446
+ {
1447
+ self.comments.push self.lexer.comments
1448
+ }
1428
1449
  k_def: kDEF
1450
+ {
1451
+ self.comments.push self.lexer.comments
1452
+ }
1429
1453
  k_do: kDO
1430
1454
  k_do_block: kDO_BLOCK
1431
1455
  k_rescue: kRESCUE
@@ -1486,51 +1510,42 @@ rule
1486
1510
 
1487
1511
  result = block_var args
1488
1512
  }
1489
- | f_marg_list tCOMMA tSTAR f_norm_arg
1513
+ | f_marg_list tCOMMA f_rest_marg
1490
1514
  {
1491
- args, _, _, splat = val
1515
+ args, _, rest = val
1492
1516
 
1493
- result = block_var args, "*#{splat}".to_sym
1517
+ result = block_var args, rest
1494
1518
  }
1495
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1519
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1496
1520
  {
1497
- args, _, _, splat, _, args2 = val
1521
+ lhs, _, splat, _, rhs = val
1498
1522
 
1499
- result = block_var args, "*#{splat}".to_sym, args2
1523
+ result = block_var lhs, splat, rhs
1500
1524
  }
1501
- | f_marg_list tCOMMA tSTAR
1525
+ | f_rest_marg
1502
1526
  {
1503
- args, _, _ = val
1527
+ rest, = val
1504
1528
 
1505
- result = block_var args, :*
1529
+ result = block_var rest
1506
1530
  }
1507
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1531
+ | f_rest_marg tCOMMA f_marg_list
1508
1532
  {
1509
- args, _, _, _, args2 = val
1533
+ splat, _, rest = val
1510
1534
 
1511
- result = block_var args, :*, args2
1535
+ result = block_var splat, rest
1512
1536
  }
1513
- | tSTAR f_norm_arg
1514
- {
1515
- _, splat = val
1516
1537
 
1517
- result = block_var :"*#{splat}"
1518
- }
1519
- | tSTAR f_norm_arg tCOMMA f_marg_list
1538
+ f_rest_marg: tSTAR f_norm_arg
1520
1539
  {
1521
- _, splat, _, args = val
1540
+ _, (id, line) = val
1522
1541
 
1523
- result = block_var :"*#{splat}", args
1542
+ result = args ["*#{id}".to_sym]
1543
+ result.line line
1524
1544
  }
1525
1545
  | tSTAR
1526
1546
  {
1527
- result = block_var :*
1528
- }
1529
- | tSTAR tCOMMA f_marg_list
1530
- {
1531
- _, _, args = val
1532
-
1533
- result = block_var :*, args
1547
+ result = args [:*]
1548
+ result.line lexer.lineno # FIX: tSTAR -> line
1534
1549
  }
1535
1550
 
1536
1551
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1547,8 +1562,8 @@ rule
1547
1562
  }
1548
1563
  | f_block_arg
1549
1564
  {
1550
- line = lexer.lineno
1551
- result = call_args val # TODO: push line down
1565
+ (id, line), = val
1566
+ result = call_args [id]
1552
1567
  result.line line
1553
1568
  }
1554
1569
 
@@ -1657,13 +1672,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1657
1672
 
1658
1673
  bvar: tIDENTIFIER
1659
1674
  {
1660
- id, = val
1661
- line = lexer.lineno
1675
+ (id, line), = val
1662
1676
  result = s(:shadow, id.to_sym).line line
1663
1677
  }
1664
1678
  | f_bad_arg
1665
1679
 
1666
- lambda: {
1680
+ lambda: tLAMBDA
1681
+ {
1667
1682
  self.env.extend :dynamic
1668
1683
  result = [lexer.lineno, lexer.lpar_beg]
1669
1684
  lexer.paren_nest += 1
@@ -1675,14 +1690,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1675
1690
  }
1676
1691
  lambda_body
1677
1692
  {
1678
- (line, lpar), args, _cmdarg, body = val
1693
+ _, (line, lpar), args, _cmdarg, body = val
1679
1694
  lexer.lpar_beg = lpar
1680
1695
 
1681
1696
  lexer.cmdarg.pop
1682
1697
 
1683
1698
  call = s(:lambda).line line
1684
1699
  result = new_iter call, args, body
1685
- result.line = line
1700
+ result.line line
1686
1701
  self.env.unextend # TODO: dynapush & dynapop
1687
1702
  }
1688
1703
 
@@ -1717,23 +1732,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1717
1732
  ## if (nd_type($1) == NODE_YIELD) {
1718
1733
  ## compile_error(PARSER_ARG "block given to yield");
1719
1734
 
1720
- syntax_error "Both block arg and actual block given." if
1721
- val[0].block_pass?
1735
+ cmd, blk = val
1722
1736
 
1723
- val = invert_block_call val if inverted? val
1737
+ syntax_error "Both block arg and actual block given." if
1738
+ cmd.block_pass?
1724
1739
 
1725
- cmd, blk = val
1740
+ if inverted? val then
1741
+ val = invert_block_call val
1742
+ cmd, blk = val
1743
+ end
1726
1744
 
1727
1745
  result = blk
1728
1746
  result.insert 1, cmd
1729
1747
  }
1730
1748
  | block_call call_op2 operation2 opt_paren_args
1731
1749
  {
1732
- 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
1733
1753
  }
1734
1754
  | block_call call_op2 operation2 opt_paren_args brace_block
1735
1755
  {
1736
- iter1, _, name, args, iter2 = val
1756
+ iter1, _, (name, _line), args, iter2 = val
1737
1757
 
1738
1758
  call = new_call iter1, name.to_sym, args
1739
1759
  iter2.insert 1, call
@@ -1742,7 +1762,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1742
1762
  }
1743
1763
  | block_call call_op2 operation2 command_args do_block
1744
1764
  {
1745
- iter1, _, name, args, iter2 = val
1765
+ iter1, _, (name, _line), args, iter2 = val
1746
1766
 
1747
1767
  call = new_call iter1, name.to_sym, args
1748
1768
  iter2.insert 1, call
@@ -1750,28 +1770,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1750
1770
  result = iter2
1751
1771
  }
1752
1772
 
1753
- method_call: fcall
1773
+ method_call: fcall paren_args
1754
1774
  {
1755
- result = self.lexer.lineno
1756
- }
1757
- paren_args
1758
- {
1759
- call, lineno, args = val
1775
+ call, args = val
1760
1776
 
1761
1777
  result = call.concat args.sexp_body if args
1762
- result.line lineno
1763
1778
  }
1764
1779
  | primary_value call_op operation2 opt_paren_args
1765
1780
  {
1766
- 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
1767
1784
  }
1768
1785
  | primary_value tCOLON2 operation2 paren_args
1769
1786
  {
1770
- 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
1771
1790
  }
1772
1791
  | primary_value tCOLON2 operation3
1773
1792
  {
1774
- result = new_call val[0], val[2].to_sym
1793
+ lhs, _, (id, _line) = val
1794
+
1795
+ result = new_call lhs, id.to_sym
1775
1796
  }
1776
1797
  | primary_value call_op paren_args
1777
1798
  {
@@ -1804,7 +1825,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1804
1825
  _, line, body, _ = val
1805
1826
 
1806
1827
  result = body
1807
- result.line = line
1828
+ result.line line
1808
1829
 
1809
1830
  self.env.unextend
1810
1831
  }
@@ -1818,7 +1839,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1818
1839
  _, line, body, _ = val
1819
1840
 
1820
1841
  result = body
1821
- result.line = line
1842
+ result.line line
1822
1843
 
1823
1844
  self.env.unextend
1824
1845
  }
@@ -1847,14 +1868,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1847
1868
  self.env.unextend
1848
1869
  }
1849
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
+
1850
1896
  case_body: k_when
1851
1897
  {
1852
1898
  result = self.lexer.lineno
1853
1899
  }
1854
- args then compstmt cases
1900
+ case_args then compstmt cases
1855
1901
  {
1856
1902
  result = new_when(val[2], val[4])
1857
- result.line = val[1]
1903
+ result.line val[1]
1858
1904
  result << val[5] if val[5]
1859
1905
  }
1860
1906
 
@@ -1900,17 +1946,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1900
1946
 
1901
1947
  literal: numeric
1902
1948
  {
1903
- line = lexer.lineno
1904
- result = s(:lit, val[0])
1905
- result.line = line
1949
+ (lit, line), = val
1950
+ result = s(:lit, lit).line line
1906
1951
  }
1907
1952
  | symbol
1908
- {
1909
- line = lexer.lineno
1910
- result = s(:lit, val[0])
1911
- result.line = line
1912
- }
1913
- | dsym
1914
1953
 
1915
1954
  strings: string
1916
1955
  {
@@ -1921,7 +1960,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1921
1960
 
1922
1961
  string: tCHAR
1923
1962
  {
1924
- debug20 23, val, result
1963
+ debug 37
1925
1964
  }
1926
1965
  | string1
1927
1966
  | string string1
@@ -1931,11 +1970,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1931
1970
 
1932
1971
  string1: tSTRING_BEG string_contents tSTRING_END
1933
1972
  {
1934
- _, str, (_, func) = val
1973
+ (_, line), str, (_, func) = val
1935
1974
 
1936
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1975
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1937
1976
 
1938
- result = str
1977
+ result = str.line line
1939
1978
  }
1940
1979
  | tSTRING
1941
1980
  {
@@ -1955,11 +1994,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1955
1994
 
1956
1995
  words: tWORDS_BEG tSPACE tSTRING_END
1957
1996
  {
1958
- result = s(:array).line lexer.lineno
1997
+ (_, line), _, _ = val
1998
+
1999
+ result = s(:array).line line
1959
2000
  }
1960
2001
  | tWORDS_BEG word_list tSTRING_END
1961
2002
  {
1962
- result = val[1]
2003
+ (_, line), list, _ = val
2004
+
2005
+ result = list.line line
1963
2006
  }
1964
2007
 
1965
2008
  word_list: none
@@ -1979,18 +2022,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1979
2022
 
1980
2023
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1981
2024
  {
1982
- result = s(:array).line lexer.lineno
2025
+ (_, line), _, _ = val
2026
+
2027
+ result = s(:array).line line
1983
2028
  }
1984
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2029
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1985
2030
  {
1986
- _, line, list, _, = val
1987
- list.line = line
2031
+ (_, line), list, _, = val
2032
+ list.line line
1988
2033
  result = list
1989
2034
  }
1990
2035
 
1991
2036
  symbol_list: none
1992
2037
  {
1993
- result = new_symbol_list.line lexer.lineno
2038
+ result = new_symbol_list
1994
2039
  }
1995
2040
  | symbol_list word tSPACE
1996
2041
  {
@@ -2000,20 +2045,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2000
2045
 
2001
2046
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2002
2047
  {
2003
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2004
2051
  }
2005
2052
  | tQWORDS_BEG qword_list tSTRING_END
2006
2053
  {
2007
- result = val[1]
2054
+ (_, line), list, _ = val
2055
+
2056
+ result = list.line line
2008
2057
  }
2009
2058
 
2010
2059
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2011
2060
  {
2012
- result = s(:array).line lexer.lineno # FIX
2061
+ (_, line), _, _ = val
2062
+
2063
+ result = s(:array).line line
2013
2064
  }
2014
2065
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2015
2066
  {
2016
- result = val[1]
2067
+ (_, line), list, _ = val
2068
+
2069
+ result = list.line line
2017
2070
  }
2018
2071
 
2019
2072
  qword_list: none
@@ -2036,7 +2089,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2036
2089
 
2037
2090
  string_contents: none
2038
2091
  {
2039
- result = s(:str, "").line lexer.lineno
2092
+ line = prev_value_to_lineno _values.last
2093
+ result = s(:str, +"").line line
2040
2094
  }
2041
2095
  | string_contents string_content
2042
2096
  {
@@ -2111,8 +2165,8 @@ regexp_contents: none
2111
2165
  lexer.brace_nest = brace_nest
2112
2166
  lexer.string_nest = string_nest
2113
2167
 
2114
- lexer.cmdarg.pop
2115
2168
  lexer.cond.pop
2169
+ lexer.cmdarg.pop
2116
2170
 
2117
2171
  lexer.lex_state = oldlex_state
2118
2172
 
@@ -2127,29 +2181,49 @@ regexp_contents: none
2127
2181
  when nil then
2128
2182
  result = s(:evstr).line line
2129
2183
  else
2130
- debug20 25
2184
+ debug 38
2131
2185
  raise "unknown string body: #{stmt.inspect}"
2132
2186
  end
2133
2187
  }
2134
2188
 
2135
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2136
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2137
- | 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
+ }
2138
2204
  | backref
2139
2205
 
2140
- symbol: tSYMBEG sym
2206
+ symbol: ssym
2207
+ | dsym
2208
+
2209
+ ssym: tSYMBEG sym
2141
2210
  {
2211
+ _, (id, line) = val
2212
+
2142
2213
  lexer.lex_state = EXPR_END
2143
- result = val[1].to_sym
2214
+ result = s(:lit, id.to_sym).line line
2144
2215
  }
2145
2216
  | tSYMBOL
2146
2217
  {
2147
- 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
2148
2222
  }
2149
2223
 
2150
2224
  sym: fname | tIVAR | tGVAR | tCVAR
2151
2225
 
2152
- dsym: tSYMBEG xstring_contents tSTRING_END
2226
+ dsym: tSYMBEG string_contents tSTRING_END
2153
2227
  {
2154
2228
  _, result, _ = val
2155
2229
 
@@ -2165,14 +2239,15 @@ regexp_contents: none
2165
2239
  when :evstr then
2166
2240
  result = s(:dsym, "", result).line result.line
2167
2241
  else
2168
- debug20 26, val, result
2242
+ debug 39
2169
2243
  end
2170
2244
  }
2171
2245
 
2172
2246
  numeric: simple_numeric
2173
- | tUMINUS_NUM simple_numeric
2247
+ | tUMINUS_NUM simple_numeric =tLOWEST
2174
2248
  {
2175
- result = -val[1] # TODO: pt_testcase
2249
+ _, (num, line) = val
2250
+ result = [-num, line]
2176
2251
  }
2177
2252
 
2178
2253
  simple_numeric: tINTEGER
@@ -2205,8 +2280,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2205
2280
 
2206
2281
  var_ref: user_variable
2207
2282
  {
2208
- var = val[0]
2283
+ raise "NO: #{val.inspect}" if Sexp === val.first
2284
+ (var, line), = val
2209
2285
  result = Sexp === var ? var : self.gettable(var)
2286
+ result.line line
2210
2287
  }
2211
2288
  | keyword_variable
2212
2289
  {
@@ -2221,11 +2298,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2221
2298
  | keyword_variable
2222
2299
  {
2223
2300
  result = self.assignable val[0]
2224
- debug20 29, val, result
2301
+ debug 40
2225
2302
  }
2226
2303
 
2227
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2228
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2304
+ backref: tNTH_REF
2305
+ {
2306
+ (ref, line), = val
2307
+ result = s(:nth_ref, ref).line line
2308
+ }
2309
+ | tBACK_REF
2310
+ {
2311
+ (ref, line), = val
2312
+ result = s(:back_ref, ref).line line
2313
+ }
2229
2314
 
2230
2315
  superclass: tLT
2231
2316
  {
@@ -2243,9 +2328,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2243
2328
 
2244
2329
  f_arglist: tLPAREN2 f_args rparen
2245
2330
  {
2246
- result = val[1]
2247
- self.lexer.lex_state = EXPR_BEG
2248
- self.lexer.command_start = true
2331
+ result = end_args val
2249
2332
  }
2250
2333
  | {
2251
2334
  result = self.in_kwarg
@@ -2254,12 +2337,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2254
2337
  }
2255
2338
  f_args term
2256
2339
  {
2257
- kwarg, args, _ = val
2258
-
2259
- self.in_kwarg = kwarg
2260
- result = args
2261
- lexer.lex_state = EXPR_BEG
2262
- lexer.command_start = true
2340
+ result = end_args val
2263
2341
  }
2264
2342
 
2265
2343
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2344,8 +2422,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2344
2422
  |
2345
2423
  {
2346
2424
  result = args val
2425
+ # result.line lexer.lineno
2347
2426
  }
2348
2427
 
2428
+
2349
2429
  f_bad_arg: tCONSTANT
2350
2430
  {
2351
2431
  yyerror "formal argument cannot be a constant"
@@ -2366,10 +2446,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2366
2446
  f_norm_arg: f_bad_arg
2367
2447
  | tIDENTIFIER
2368
2448
  {
2369
- identifier = val[0].to_sym
2449
+ (id, line), = val
2450
+ identifier = id.to_sym
2370
2451
  self.env[identifier] = :lvar
2371
2452
 
2372
- result = identifier
2453
+ result = [identifier, line]
2373
2454
  }
2374
2455
 
2375
2456
  f_arg_asgn: f_norm_arg
@@ -2377,22 +2458,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2377
2458
  f_arg_item: f_arg_asgn
2378
2459
  | tLPAREN f_margs rparen
2379
2460
  {
2380
- result = val[1]
2461
+ _, margs, _ = val
2462
+
2463
+ result = margs
2381
2464
  }
2382
2465
 
2383
2466
  f_arg: f_arg_item
2384
2467
  {
2385
- arg, = val
2386
-
2387
- case arg
2388
- when Symbol then
2389
- result = s(:args, arg).line lexer.lineno
2390
- when Sexp then
2391
- result = arg
2392
- else
2393
- debug20 32
2394
- raise "Unknown f_arg type: #{val.inspect}"
2395
- end
2468
+ result = new_arg val
2396
2469
  }
2397
2470
  | f_arg tCOMMA f_arg_item
2398
2471
  {
@@ -2404,7 +2477,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2404
2477
  result = s(:args, list).line list.line
2405
2478
  end
2406
2479
 
2407
- result << item
2480
+ result << (Sexp === item ? item : item.first)
2408
2481
  }
2409
2482
 
2410
2483
  f_label: tLABEL
@@ -2465,26 +2538,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2465
2538
  kwrest_mark: tPOW
2466
2539
  | tDSTAR
2467
2540
 
2541
+
2468
2542
  f_kwrest: kwrest_mark tIDENTIFIER
2469
2543
  {
2470
- name = val[1].to_sym
2471
- self.assignable name
2472
- result = :"**#{name}"
2544
+ _, (id, line) = val
2545
+
2546
+ name = id.to_sym
2547
+ self.assignable [name, line]
2548
+ result = [:"**#{name}", line]
2473
2549
  }
2474
2550
  | kwrest_mark
2475
2551
  {
2476
- result = :"**"
2552
+ id = :"**"
2553
+ self.env[id] = :lvar # TODO: needed?!?
2554
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2477
2555
  }
2478
2556
 
2479
2557
  f_opt: f_arg_asgn tEQL arg_value
2480
2558
  {
2481
- result = self.assignable val[0], val[2]
2559
+ lhs, _, rhs = val
2560
+ result = self.assignable lhs, rhs
2482
2561
  # TODO: detect duplicate names
2483
2562
  }
2484
2563
 
2485
2564
  f_block_opt: f_arg_asgn tEQL primary_value
2486
2565
  {
2487
- result = self.assignable val[0], val[2]
2566
+ lhs, _, rhs = val
2567
+ result = self.assignable lhs, rhs
2488
2568
  }
2489
2569
 
2490
2570
  f_block_optarg: f_block_opt
@@ -2514,30 +2594,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2514
2594
  f_rest_arg: restarg_mark tIDENTIFIER
2515
2595
  {
2516
2596
  # TODO: differs from parse.y - needs tests
2517
- name = val[1].to_sym
2518
- self.assignable name
2519
- result = :"*#{name}"
2597
+ _, (id, line) = val
2598
+ name = id.to_sym
2599
+ self.assignable [name, line]
2600
+ result = [:"*#{name}", line]
2520
2601
  }
2521
2602
  | restarg_mark
2522
2603
  {
2523
2604
  name = :"*"
2524
2605
  self.env[name] = :lvar
2525
- result = name
2606
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2526
2607
  }
2527
2608
 
2528
2609
  blkarg_mark: tAMPER2 | tAMPER
2529
2610
 
2530
2611
  f_block_arg: blkarg_mark tIDENTIFIER
2531
2612
  {
2532
- identifier = val[1].to_sym
2613
+ _, (id, line) = val
2614
+ identifier = id.to_sym
2533
2615
 
2534
2616
  self.env[identifier] = :lvar
2535
- result = "&#{identifier}".to_sym
2617
+ result = ["&#{identifier}".to_sym, line]
2536
2618
  }
2537
2619
 
2538
2620
  opt_f_block_arg: tCOMMA f_block_arg
2539
2621
  {
2540
- result = val[1]
2622
+ _, arg = val
2623
+ result = arg
2541
2624
  }
2542
2625
  |
2543
2626
  {
@@ -2586,9 +2669,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2586
2669
  }
2587
2670
  | tSTRING_BEG string_contents tLABEL_END arg_value
2588
2671
  {
2589
- _, sym, _, value = val
2672
+ (_, line), sym, _, value = val
2673
+
2590
2674
  sym.sexp_type = :dsym
2591
- result = s(:array, sym, value).line sym.line
2675
+
2676
+ result = s(:array, sym, value).line line
2592
2677
  }
2593
2678
  | tDSTAR arg_value
2594
2679
  {