ruby_parser 3.15.1 → 3.18.1

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
707
 
690
- fsym: fname | symbol
691
-
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
  {
@@ -1193,15 +1208,21 @@ rule
1193
1208
  }
1194
1209
  | kYIELD tLPAREN2 call_args rparen
1195
1210
  {
1196
- result = new_yield val[2]
1211
+ (_, line), _, args, _ = val
1212
+
1213
+ result = new_yield(args).line line
1197
1214
  }
1198
1215
  | kYIELD tLPAREN2 rparen
1199
1216
  {
1200
- result = new_yield
1217
+ (_, line), _, _ = val
1218
+
1219
+ result = new_yield.line line
1201
1220
  }
1202
1221
  | kYIELD
1203
1222
  {
1204
- result = new_yield
1223
+ (_, line), = val
1224
+
1225
+ result = new_yield.line line
1205
1226
  }
1206
1227
  | kDEFINED opt_nl tLPAREN2 expr rparen
1207
1228
  {
@@ -1216,7 +1237,7 @@ rule
1216
1237
  }
1217
1238
  | kNOT tLPAREN2 rparen
1218
1239
  {
1219
- debug20 14, val, result
1240
+ debug 20
1220
1241
  }
1221
1242
  | fcall brace_block
1222
1243
  {
@@ -1234,9 +1255,10 @@ rule
1234
1255
  iter.insert 1, call # FIX
1235
1256
  result = iter
1236
1257
  }
1237
- | tLAMBDA lambda
1258
+ | lambda
1238
1259
  {
1239
- result = val[1] # TODO: fix lineno
1260
+ expr, = val
1261
+ result = expr
1240
1262
  }
1241
1263
  | k_if expr_value then compstmt if_tail k_end
1242
1264
  {
@@ -1279,7 +1301,6 @@ rule
1279
1301
  }
1280
1302
  cpath superclass
1281
1303
  {
1282
- self.comments.push self.lexer.comments
1283
1304
  if (self.in_def || self.in_single > 0) then
1284
1305
  yyerror "class definition in method body"
1285
1306
  end
@@ -1289,7 +1310,7 @@ rule
1289
1310
  {
1290
1311
  result = new_class val
1291
1312
  self.env.unextend
1292
- self.lexer.comments # we don't care about comments in the body
1313
+ self.lexer.ignore_body_comments
1293
1314
  }
1294
1315
  | k_class tLSHFT
1295
1316
  {
@@ -1310,7 +1331,7 @@ rule
1310
1331
  {
1311
1332
  result = new_sclass val
1312
1333
  self.env.unextend
1313
- self.lexer.comments # we don't care about comments in the body
1334
+ self.lexer.ignore_body_comments
1314
1335
  }
1315
1336
  | k_module
1316
1337
  {
@@ -1318,7 +1339,6 @@ rule
1318
1339
  }
1319
1340
  cpath
1320
1341
  {
1321
- self.comments.push self.lexer.comments
1322
1342
  yyerror "module definition in method body" if
1323
1343
  self.in_def or self.in_single > 0
1324
1344
 
@@ -1328,7 +1348,7 @@ rule
1328
1348
  {
1329
1349
  result = new_module val
1330
1350
  self.env.unextend
1331
- self.lexer.comments # we don't care about comments in the body
1351
+ self.lexer.ignore_body_comments
1332
1352
  }
1333
1353
  | k_def fname
1334
1354
  {
@@ -1338,21 +1358,17 @@ rule
1338
1358
  self.env.extend
1339
1359
  lexer.cmdarg.push false
1340
1360
  lexer.cond.push false
1341
-
1342
- self.comments.push self.lexer.comments
1343
1361
  }
1344
- f_arglist bodystmt { result = lexer.lineno } k_end
1362
+ f_arglist bodystmt k_end
1345
1363
  {
1346
- in_def = val[2]
1347
-
1348
- result = new_defn val
1364
+ result, in_def = new_defn val
1349
1365
 
1350
1366
  lexer.cond.pop # group = local_pop
1351
1367
  lexer.cmdarg.pop
1352
1368
  self.env.unextend
1353
1369
  self.in_def = in_def
1354
1370
 
1355
- self.lexer.comments # we don't care about comments in the body
1371
+ self.lexer.ignore_body_comments
1356
1372
  }
1357
1373
  | k_def singleton dot_or_colon
1358
1374
  {
@@ -1360,7 +1376,7 @@ rule
1360
1376
  }
1361
1377
  fname
1362
1378
  {
1363
- result = [self.in_def, lexer.lineno]
1379
+ result = self.in_def
1364
1380
 
1365
1381
  self.in_single += 1 # TODO: remove?
1366
1382
 
@@ -1370,13 +1386,18 @@ rule
1370
1386
  lexer.cond.push false
1371
1387
 
1372
1388
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1373
- self.comments.push self.lexer.comments
1374
1389
  }
1375
1390
  f_arglist bodystmt k_end
1376
1391
  {
1377
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1378
1392
 
1379
- result = new_defs val
1393
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1394
+ # =>
1395
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1396
+
1397
+ val.delete_at 3
1398
+ val.delete_at 2
1399
+
1400
+ result, in_def = new_defs val
1380
1401
 
1381
1402
  lexer.cond.pop # group = local_pop
1382
1403
  lexer.cmdarg.pop
@@ -1387,7 +1408,7 @@ rule
1387
1408
 
1388
1409
  # TODO: restore cur_arg ? what's cur_arg?
1389
1410
 
1390
- self.lexer.comments # we don't care about comments in the body
1411
+ self.lexer.ignore_body_comments
1391
1412
  }
1392
1413
  | kBREAK
1393
1414
  {
@@ -1424,8 +1445,17 @@ rule
1424
1445
  k_case: kCASE
1425
1446
  k_for: kFOR
1426
1447
  k_class: kCLASS
1448
+ {
1449
+ self.comments.push self.lexer.comments
1450
+ }
1427
1451
  k_module: kMODULE
1452
+ {
1453
+ self.comments.push self.lexer.comments
1454
+ }
1428
1455
  k_def: kDEF
1456
+ {
1457
+ self.comments.push self.lexer.comments
1458
+ }
1429
1459
  k_do: kDO
1430
1460
  k_do_block: kDO_BLOCK
1431
1461
  k_rescue: kRESCUE
@@ -1486,51 +1516,42 @@ rule
1486
1516
 
1487
1517
  result = block_var args
1488
1518
  }
1489
- | f_marg_list tCOMMA tSTAR f_norm_arg
1519
+ | f_marg_list tCOMMA f_rest_marg
1490
1520
  {
1491
- args, _, _, splat = val
1521
+ args, _, rest = val
1492
1522
 
1493
- result = block_var args, "*#{splat}".to_sym
1523
+ result = block_var args, rest
1494
1524
  }
1495
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1525
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1496
1526
  {
1497
- args, _, _, splat, _, args2 = val
1527
+ lhs, _, splat, _, rhs = val
1498
1528
 
1499
- result = block_var args, "*#{splat}".to_sym, args2
1529
+ result = block_var lhs, splat, rhs
1500
1530
  }
1501
- | f_marg_list tCOMMA tSTAR
1531
+ | f_rest_marg
1502
1532
  {
1503
- args, _, _ = val
1533
+ rest, = val
1504
1534
 
1505
- result = block_var args, :*
1535
+ result = block_var rest
1506
1536
  }
1507
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1537
+ | f_rest_marg tCOMMA f_marg_list
1508
1538
  {
1509
- args, _, _, _, args2 = val
1539
+ splat, _, rest = val
1510
1540
 
1511
- result = block_var args, :*, args2
1541
+ result = block_var splat, rest
1512
1542
  }
1513
- | tSTAR f_norm_arg
1514
- {
1515
- _, splat = val
1516
1543
 
1517
- result = block_var :"*#{splat}"
1518
- }
1519
- | tSTAR f_norm_arg tCOMMA f_marg_list
1544
+ f_rest_marg: tSTAR f_norm_arg
1520
1545
  {
1521
- _, splat, _, args = val
1546
+ _, (id, line) = val
1522
1547
 
1523
- result = block_var :"*#{splat}", args
1548
+ result = args ["*#{id}".to_sym]
1549
+ result.line line
1524
1550
  }
1525
1551
  | tSTAR
1526
1552
  {
1527
- result = block_var :*
1528
- }
1529
- | tSTAR tCOMMA f_marg_list
1530
- {
1531
- _, _, args = val
1532
-
1533
- result = block_var :*, args
1553
+ result = args [:*]
1554
+ result.line lexer.lineno # FIX: tSTAR -> line
1534
1555
  }
1535
1556
 
1536
1557
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1547,8 +1568,8 @@ rule
1547
1568
  }
1548
1569
  | f_block_arg
1549
1570
  {
1550
- line = lexer.lineno
1551
- result = call_args val # TODO: push line down
1571
+ (id, line), = val
1572
+ result = call_args [id]
1552
1573
  result.line line
1553
1574
  }
1554
1575
 
@@ -1657,13 +1678,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1657
1678
 
1658
1679
  bvar: tIDENTIFIER
1659
1680
  {
1660
- id, = val
1661
- line = lexer.lineno
1681
+ (id, line), = val
1662
1682
  result = s(:shadow, id.to_sym).line line
1663
1683
  }
1664
1684
  | f_bad_arg
1665
1685
 
1666
- lambda: {
1686
+ lambda: tLAMBDA
1687
+ {
1667
1688
  self.env.extend :dynamic
1668
1689
  result = [lexer.lineno, lexer.lpar_beg]
1669
1690
  lexer.paren_nest += 1
@@ -1675,14 +1696,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1675
1696
  }
1676
1697
  lambda_body
1677
1698
  {
1678
- (line, lpar), args, _cmdarg, body = val
1699
+ _, (line, lpar), args, _cmdarg, body = val
1679
1700
  lexer.lpar_beg = lpar
1680
1701
 
1681
1702
  lexer.cmdarg.pop
1682
1703
 
1683
1704
  call = s(:lambda).line line
1684
1705
  result = new_iter call, args, body
1685
- result.line = line
1706
+ result.line line
1686
1707
  self.env.unextend # TODO: dynapush & dynapop
1687
1708
  }
1688
1709
 
@@ -1717,23 +1738,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1717
1738
  ## if (nd_type($1) == NODE_YIELD) {
1718
1739
  ## compile_error(PARSER_ARG "block given to yield");
1719
1740
 
1720
- syntax_error "Both block arg and actual block given." if
1721
- val[0].block_pass?
1741
+ cmd, blk = val
1722
1742
 
1723
- val = invert_block_call val if inverted? val
1743
+ syntax_error "Both block arg and actual block given." if
1744
+ cmd.block_pass?
1724
1745
 
1725
- cmd, blk = val
1746
+ if inverted? val then
1747
+ val = invert_block_call val
1748
+ cmd, blk = val
1749
+ end
1726
1750
 
1727
1751
  result = blk
1728
1752
  result.insert 1, cmd
1729
1753
  }
1730
1754
  | block_call call_op2 operation2 opt_paren_args
1731
1755
  {
1732
- result = new_call val[0], val[2].to_sym, val[3]
1756
+ lhs, _, (id, _line), args = val
1757
+
1758
+ result = new_call lhs, id.to_sym, args
1733
1759
  }
1734
1760
  | block_call call_op2 operation2 opt_paren_args brace_block
1735
1761
  {
1736
- iter1, _, name, args, iter2 = val
1762
+ iter1, _, (name, _line), args, iter2 = val
1737
1763
 
1738
1764
  call = new_call iter1, name.to_sym, args
1739
1765
  iter2.insert 1, call
@@ -1742,7 +1768,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1742
1768
  }
1743
1769
  | block_call call_op2 operation2 command_args do_block
1744
1770
  {
1745
- iter1, _, name, args, iter2 = val
1771
+ iter1, _, (name, _line), args, iter2 = val
1746
1772
 
1747
1773
  call = new_call iter1, name.to_sym, args
1748
1774
  iter2.insert 1, call
@@ -1750,28 +1776,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1750
1776
  result = iter2
1751
1777
  }
1752
1778
 
1753
- method_call: fcall
1754
- {
1755
- result = self.lexer.lineno
1756
- }
1757
- paren_args
1779
+ method_call: fcall paren_args
1758
1780
  {
1759
- call, lineno, args = val
1781
+ call, args = val
1760
1782
 
1761
1783
  result = call.concat args.sexp_body if args
1762
- result.line lineno
1763
1784
  }
1764
1785
  | primary_value call_op operation2 opt_paren_args
1765
1786
  {
1766
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1787
+ recv, call_op, (op, _line), args = val
1788
+
1789
+ result = new_call recv, op.to_sym, args, call_op
1767
1790
  }
1768
1791
  | primary_value tCOLON2 operation2 paren_args
1769
1792
  {
1770
- result = new_call val[0], val[2].to_sym, val[3]
1793
+ recv, _, (op, _line), args = val
1794
+
1795
+ result = new_call recv, op.to_sym, args
1771
1796
  }
1772
1797
  | primary_value tCOLON2 operation3
1773
1798
  {
1774
- result = new_call val[0], val[2].to_sym
1799
+ lhs, _, (id, _line) = val
1800
+
1801
+ result = new_call lhs, id.to_sym
1775
1802
  }
1776
1803
  | primary_value call_op paren_args
1777
1804
  {
@@ -1804,7 +1831,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1804
1831
  _, line, body, _ = val
1805
1832
 
1806
1833
  result = body
1807
- result.line = line
1834
+ result.line line
1808
1835
 
1809
1836
  self.env.unextend
1810
1837
  }
@@ -1818,7 +1845,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1818
1845
  _, line, body, _ = val
1819
1846
 
1820
1847
  result = body
1821
- result.line = line
1848
+ result.line line
1822
1849
 
1823
1850
  self.env.unextend
1824
1851
  }
@@ -1847,14 +1874,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1847
1874
  self.env.unextend
1848
1875
  }
1849
1876
 
1877
+ case_args: arg_value
1878
+ {
1879
+ arg, = val
1880
+
1881
+ result = s(:array, arg).line arg.line
1882
+ }
1883
+ | tSTAR arg_value
1884
+ {
1885
+ _, arg = val
1886
+
1887
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1888
+ }
1889
+ | case_args tCOMMA arg_value
1890
+ {
1891
+ args, _, id = val
1892
+
1893
+ result = self.list_append args, id
1894
+ }
1895
+ | case_args tCOMMA tSTAR arg_value
1896
+ {
1897
+ args, _, _, id = val
1898
+
1899
+ result = self.list_append args, s(:splat, id).line(id.line)
1900
+ }
1901
+
1850
1902
  case_body: k_when
1851
1903
  {
1852
1904
  result = self.lexer.lineno
1853
1905
  }
1854
- args then compstmt cases
1906
+ case_args then compstmt cases
1855
1907
  {
1856
1908
  result = new_when(val[2], val[4])
1857
- result.line = val[1]
1909
+ result.line val[1]
1858
1910
  result << val[5] if val[5]
1859
1911
  }
1860
1912
 
@@ -1900,17 +1952,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1900
1952
 
1901
1953
  literal: numeric
1902
1954
  {
1903
- line = lexer.lineno
1904
- result = s(:lit, val[0])
1905
- result.line = line
1955
+ (lit, line), = val
1956
+ result = s(:lit, lit).line line
1906
1957
  }
1907
1958
  | symbol
1908
- {
1909
- line = lexer.lineno
1910
- result = s(:lit, val[0])
1911
- result.line = line
1912
- }
1913
- | dsym
1914
1959
 
1915
1960
  strings: string
1916
1961
  {
@@ -1921,7 +1966,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1921
1966
 
1922
1967
  string: tCHAR
1923
1968
  {
1924
- debug20 23, val, result
1969
+ debug 37
1925
1970
  }
1926
1971
  | string1
1927
1972
  | string string1
@@ -1931,11 +1976,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1931
1976
 
1932
1977
  string1: tSTRING_BEG string_contents tSTRING_END
1933
1978
  {
1934
- _, str, (_, func) = val
1979
+ (_, line), str, (_, func) = val
1935
1980
 
1936
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1981
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1937
1982
 
1938
- result = str
1983
+ result = str.line line
1939
1984
  }
1940
1985
  | tSTRING
1941
1986
  {
@@ -1955,11 +2000,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1955
2000
 
1956
2001
  words: tWORDS_BEG tSPACE tSTRING_END
1957
2002
  {
1958
- result = s(:array).line lexer.lineno
2003
+ (_, line), _, _ = val
2004
+
2005
+ result = s(:array).line line
1959
2006
  }
1960
2007
  | tWORDS_BEG word_list tSTRING_END
1961
2008
  {
1962
- result = val[1]
2009
+ (_, line), list, _ = val
2010
+
2011
+ result = list.line line
1963
2012
  }
1964
2013
 
1965
2014
  word_list: none
@@ -1979,18 +2028,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1979
2028
 
1980
2029
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1981
2030
  {
1982
- result = s(:array).line lexer.lineno
2031
+ (_, line), _, _ = val
2032
+
2033
+ result = s(:array).line line
1983
2034
  }
1984
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2035
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1985
2036
  {
1986
- _, line, list, _, = val
1987
- list.line = line
2037
+ (_, line), list, _, = val
2038
+ list.line line
1988
2039
  result = list
1989
2040
  }
1990
2041
 
1991
2042
  symbol_list: none
1992
2043
  {
1993
- result = new_symbol_list.line lexer.lineno
2044
+ result = new_symbol_list
1994
2045
  }
1995
2046
  | symbol_list word tSPACE
1996
2047
  {
@@ -2000,20 +2051,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2000
2051
 
2001
2052
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2002
2053
  {
2003
- result = s(:array).line lexer.lineno
2054
+ (_, line), _, _ = val
2055
+
2056
+ result = s(:array).line line
2004
2057
  }
2005
2058
  | tQWORDS_BEG qword_list tSTRING_END
2006
2059
  {
2007
- result = val[1]
2060
+ (_, line), list, _ = val
2061
+
2062
+ result = list.line line
2008
2063
  }
2009
2064
 
2010
2065
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2011
2066
  {
2012
- result = s(:array).line lexer.lineno # FIX
2067
+ (_, line), _, _ = val
2068
+
2069
+ result = s(:array).line line
2013
2070
  }
2014
2071
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2015
2072
  {
2016
- result = val[1]
2073
+ (_, line), list, _ = val
2074
+
2075
+ result = list.line line
2017
2076
  }
2018
2077
 
2019
2078
  qword_list: none
@@ -2036,7 +2095,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2036
2095
 
2037
2096
  string_contents: none
2038
2097
  {
2039
- result = s(:str, "").line lexer.lineno
2098
+ line = prev_value_to_lineno _values.last
2099
+ result = s(:str, +"").line line
2040
2100
  }
2041
2101
  | string_contents string_content
2042
2102
  {
@@ -2111,8 +2171,8 @@ regexp_contents: none
2111
2171
  lexer.brace_nest = brace_nest
2112
2172
  lexer.string_nest = string_nest
2113
2173
 
2114
- lexer.cmdarg.pop
2115
2174
  lexer.cond.pop
2175
+ lexer.cmdarg.pop
2116
2176
 
2117
2177
  lexer.lex_state = oldlex_state
2118
2178
 
@@ -2127,29 +2187,49 @@ regexp_contents: none
2127
2187
  when nil then
2128
2188
  result = s(:evstr).line line
2129
2189
  else
2130
- debug20 25
2190
+ debug 38
2131
2191
  raise "unknown string body: #{stmt.inspect}"
2132
2192
  end
2133
2193
  }
2134
2194
 
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 }
2195
+ string_dvar: tGVAR
2196
+ {
2197
+ (id, line), = val
2198
+ result = s(:gvar, id.to_sym).line line
2199
+ }
2200
+ | tIVAR
2201
+ {
2202
+ (id, line), = val
2203
+ result = s(:ivar, id.to_sym).line line
2204
+ }
2205
+ | tCVAR
2206
+ {
2207
+ (id, line), = val
2208
+ result = s(:cvar, id.to_sym).line line
2209
+ }
2138
2210
  | backref
2139
2211
 
2140
- symbol: tSYMBEG sym
2212
+ symbol: ssym
2213
+ | dsym
2214
+
2215
+ ssym: tSYMBEG sym
2141
2216
  {
2217
+ _, (id, line) = val
2218
+
2142
2219
  lexer.lex_state = EXPR_END
2143
- result = val[1].to_sym
2220
+ result = s(:lit, id.to_sym).line line
2144
2221
  }
2145
2222
  | tSYMBOL
2146
2223
  {
2147
- result = val[0].to_sym
2224
+ (id, line), = val
2225
+
2226
+ lexer.lex_state = EXPR_END
2227
+ result = s(:lit, id.to_sym).line line
2148
2228
  }
2149
2229
 
2150
2230
  sym: fname | tIVAR | tGVAR | tCVAR
2151
2231
 
2152
- dsym: tSYMBEG xstring_contents tSTRING_END
2232
+ dsym: tSYMBEG string_contents tSTRING_END
2153
2233
  {
2154
2234
  _, result, _ = val
2155
2235
 
@@ -2165,14 +2245,15 @@ regexp_contents: none
2165
2245
  when :evstr then
2166
2246
  result = s(:dsym, "", result).line result.line
2167
2247
  else
2168
- debug20 26, val, result
2248
+ debug 39
2169
2249
  end
2170
2250
  }
2171
2251
 
2172
2252
  numeric: simple_numeric
2173
- | tUMINUS_NUM simple_numeric
2253
+ | tUMINUS_NUM simple_numeric =tLOWEST
2174
2254
  {
2175
- result = -val[1] # TODO: pt_testcase
2255
+ _, (num, line) = val
2256
+ result = [-num, line]
2176
2257
  }
2177
2258
 
2178
2259
  simple_numeric: tINTEGER
@@ -2205,8 +2286,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2205
2286
 
2206
2287
  var_ref: user_variable
2207
2288
  {
2208
- var = val[0]
2289
+ raise "NO: #{val.inspect}" if Sexp === val.first
2290
+ (var, line), = val
2209
2291
  result = Sexp === var ? var : self.gettable(var)
2292
+ result.line line
2210
2293
  }
2211
2294
  | keyword_variable
2212
2295
  {
@@ -2221,11 +2304,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2221
2304
  | keyword_variable
2222
2305
  {
2223
2306
  result = self.assignable val[0]
2224
- debug20 29, val, result
2307
+ debug 40
2225
2308
  }
2226
2309
 
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 }
2310
+ backref: tNTH_REF
2311
+ {
2312
+ (ref, line), = val
2313
+ result = s(:nth_ref, ref).line line
2314
+ }
2315
+ | tBACK_REF
2316
+ {
2317
+ (ref, line), = val
2318
+ result = s(:back_ref, ref).line line
2319
+ }
2229
2320
 
2230
2321
  superclass: tLT
2231
2322
  {
@@ -2243,9 +2334,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2243
2334
 
2244
2335
  f_arglist: tLPAREN2 f_args rparen
2245
2336
  {
2246
- result = val[1]
2247
- self.lexer.lex_state = EXPR_BEG
2248
- self.lexer.command_start = true
2337
+ result = end_args val
2249
2338
  }
2250
2339
  | {
2251
2340
  result = self.in_kwarg
@@ -2254,12 +2343,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2254
2343
  }
2255
2344
  f_args term
2256
2345
  {
2257
- kwarg, args, _ = val
2258
-
2259
- self.in_kwarg = kwarg
2260
- result = args
2261
- lexer.lex_state = EXPR_BEG
2262
- lexer.command_start = true
2346
+ result = end_args val
2263
2347
  }
2264
2348
 
2265
2349
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2344,8 +2428,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2344
2428
  |
2345
2429
  {
2346
2430
  result = args val
2431
+ # result.line lexer.lineno
2347
2432
  }
2348
2433
 
2434
+
2349
2435
  f_bad_arg: tCONSTANT
2350
2436
  {
2351
2437
  yyerror "formal argument cannot be a constant"
@@ -2366,10 +2452,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2366
2452
  f_norm_arg: f_bad_arg
2367
2453
  | tIDENTIFIER
2368
2454
  {
2369
- identifier = val[0].to_sym
2455
+ (id, line), = val
2456
+ identifier = id.to_sym
2370
2457
  self.env[identifier] = :lvar
2371
2458
 
2372
- result = identifier
2459
+ result = [identifier, line]
2373
2460
  }
2374
2461
 
2375
2462
  f_arg_asgn: f_norm_arg
@@ -2377,22 +2464,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2377
2464
  f_arg_item: f_arg_asgn
2378
2465
  | tLPAREN f_margs rparen
2379
2466
  {
2380
- result = val[1]
2467
+ _, margs, _ = val
2468
+
2469
+ result = margs
2381
2470
  }
2382
2471
 
2383
2472
  f_arg: f_arg_item
2384
2473
  {
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
2474
+ result = new_arg val
2396
2475
  }
2397
2476
  | f_arg tCOMMA f_arg_item
2398
2477
  {
@@ -2404,7 +2483,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2404
2483
  result = s(:args, list).line list.line
2405
2484
  end
2406
2485
 
2407
- result << item
2486
+ result << (Sexp === item ? item : item.first)
2408
2487
  }
2409
2488
 
2410
2489
  f_label: tLABEL
@@ -2465,26 +2544,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2465
2544
  kwrest_mark: tPOW
2466
2545
  | tDSTAR
2467
2546
 
2547
+
2468
2548
  f_kwrest: kwrest_mark tIDENTIFIER
2469
2549
  {
2470
- name = val[1].to_sym
2471
- self.assignable name
2472
- result = :"**#{name}"
2550
+ _, (id, line) = val
2551
+
2552
+ name = id.to_sym
2553
+ self.assignable [name, line]
2554
+ result = [:"**#{name}", line]
2473
2555
  }
2474
2556
  | kwrest_mark
2475
2557
  {
2476
- result = :"**"
2558
+ id = :"**"
2559
+ self.env[id] = :lvar # TODO: needed?!?
2560
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2477
2561
  }
2478
2562
 
2479
2563
  f_opt: f_arg_asgn tEQL arg_value
2480
2564
  {
2481
- result = self.assignable val[0], val[2]
2565
+ lhs, _, rhs = val
2566
+ result = self.assignable lhs, rhs
2482
2567
  # TODO: detect duplicate names
2483
2568
  }
2484
2569
 
2485
2570
  f_block_opt: f_arg_asgn tEQL primary_value
2486
2571
  {
2487
- result = self.assignable val[0], val[2]
2572
+ lhs, _, rhs = val
2573
+ result = self.assignable lhs, rhs
2488
2574
  }
2489
2575
 
2490
2576
  f_block_optarg: f_block_opt
@@ -2514,30 +2600,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2514
2600
  f_rest_arg: restarg_mark tIDENTIFIER
2515
2601
  {
2516
2602
  # TODO: differs from parse.y - needs tests
2517
- name = val[1].to_sym
2518
- self.assignable name
2519
- result = :"*#{name}"
2603
+ _, (id, line) = val
2604
+ name = id.to_sym
2605
+ self.assignable [name, line]
2606
+ result = [:"*#{name}", line]
2520
2607
  }
2521
2608
  | restarg_mark
2522
2609
  {
2523
2610
  name = :"*"
2524
2611
  self.env[name] = :lvar
2525
- result = name
2612
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2526
2613
  }
2527
2614
 
2528
2615
  blkarg_mark: tAMPER2 | tAMPER
2529
2616
 
2530
2617
  f_block_arg: blkarg_mark tIDENTIFIER
2531
2618
  {
2532
- identifier = val[1].to_sym
2619
+ _, (id, line) = val
2620
+ identifier = id.to_sym
2533
2621
 
2534
2622
  self.env[identifier] = :lvar
2535
- result = "&#{identifier}".to_sym
2623
+ result = ["&#{identifier}".to_sym, line]
2536
2624
  }
2537
2625
 
2538
2626
  opt_f_block_arg: tCOMMA f_block_arg
2539
2627
  {
2540
- result = val[1]
2628
+ _, arg = val
2629
+ result = arg
2541
2630
  }
2542
2631
  |
2543
2632
  {
@@ -2586,9 +2675,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2586
2675
  }
2587
2676
  | tSTRING_BEG string_contents tLABEL_END arg_value
2588
2677
  {
2589
- _, sym, _, value = val
2678
+ (_, line), sym, _, value = val
2679
+
2590
2680
  sym.sexp_type = :dsym
2591
- result = s(:array, sym, value).line sym.line
2681
+
2682
+ result = s(:array, sym, value).line line
2592
2683
  }
2593
2684
  | tDSTAR arg_value
2594
2685
  {