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/ruby26_parser.y CHANGED
@@ -18,10 +18,11 @@ 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
25
+ tBDOT2 tBDOT3
25
26
 
26
27
  preclow
27
28
  nonassoc tLOWEST
@@ -33,7 +34,7 @@ preclow
33
34
  right tEQL tOP_ASGN
34
35
  left kRESCUE_MOD
35
36
  right tEH tCOLON
36
- nonassoc tDOT2 tDOT3
37
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
38
  left tOROP
38
39
  left tANDOP
39
40
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -56,6 +57,9 @@ rule
56
57
  top_compstmt
57
58
  {
58
59
  result = new_compstmt val
60
+
61
+ lexer.cond.pop # local_pop
62
+ lexer.cmdarg.pop
59
63
  }
60
64
 
61
65
  top_compstmt: top_stmts opt_terms
@@ -76,7 +80,7 @@ rule
76
80
  | klBEGIN
77
81
  {
78
82
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
83
+ debug 11
80
84
  yyerror "BEGIN in method"
81
85
  end
82
86
  self.env.extend
@@ -101,6 +105,8 @@ rule
101
105
  bodystmt: compstmt opt_rescue k_else
102
106
  {
103
107
  res = _values[-2]
108
+ # TODO: move down to main match so I can just use val
109
+
104
110
  yyerror "else without rescue is useless" unless res
105
111
  }
106
112
  compstmt
@@ -131,7 +137,7 @@ rule
131
137
  | error stmt
132
138
  {
133
139
  result = val[1]
134
- debug20 2, val, result
140
+ debug 12
135
141
  }
136
142
 
137
143
  stmt_or_begin: stmt
@@ -139,6 +145,10 @@ rule
139
145
  {
140
146
  yyerror "BEGIN is permitted only at toplevel"
141
147
  }
148
+ begin_block
149
+ {
150
+ result = val[2] # wtf?
151
+ }
142
152
 
143
153
  stmt: kALIAS fitem
144
154
  {
@@ -151,12 +161,12 @@ rule
151
161
  }
152
162
  | kALIAS tGVAR tGVAR
153
163
  {
154
- (_, line), lhs, rhs = val
164
+ (_, line), (lhs, _), (rhs, _) = val
155
165
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
166
  }
157
167
  | kALIAS tGVAR tBACK_REF
158
168
  {
159
- (_, line), lhs, rhs = val
169
+ (_, line), (lhs, _), (rhs, _) = val
160
170
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
171
  }
162
172
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +209,7 @@ rule
199
209
  (_, line), _, stmt, _ = val
200
210
 
201
211
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
212
+ debug 13
203
213
  yyerror "END in method; use at_exit"
204
214
  end
205
215
 
@@ -239,32 +249,31 @@ rule
239
249
  }
240
250
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
241
251
  {
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
252
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
253
+
254
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
255
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
256
+ result.line prim.line
248
257
  }
249
258
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
250
259
  {
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
260
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
261
+
262
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
263
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
264
+ result.line prim.line
256
265
  }
257
266
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
258
267
  {
259
- lhs1, _, lhs2, op, rhs = val
268
+ lhs1, _, (lhs2, line), (id, _), rhs = val
260
269
 
261
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
270
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
262
271
  }
263
272
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
264
273
  {
265
- lhs1, _, lhs2, op, rhs = val
274
+ lhs1, _, (lhs2, line), (id, _), rhs = val
266
275
 
267
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
276
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
268
277
  }
269
278
  | backref tOP_ASGN command_rhs
270
279
  {
@@ -310,7 +319,7 @@ rule
310
319
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
320
  # REFACTOR: call_uni_op -- see parse26.y
312
321
  }
313
- | arg
322
+ | arg =tLBRACE_ARG
314
323
 
315
324
  expr_value: expr
316
325
  {
@@ -335,7 +344,7 @@ rule
335
344
  block_command: block_call
336
345
  | block_call call_op2 operation2 command_args
337
346
  {
338
- blk, _, msg, args = val
347
+ blk, _, (msg, _line), args = val
339
348
  result = new_call(blk, msg.to_sym, args).line blk.line
340
349
  }
341
350
 
@@ -349,15 +358,15 @@ rule
349
358
  _, line, body, _ = val
350
359
 
351
360
  result = body
352
- result.line = line
361
+ result.line line
353
362
 
354
363
  # self.env.unextend
355
364
  }
356
365
 
357
366
  fcall: operation
358
367
  {
359
- msg, = val
360
- result = new_call(nil, msg.to_sym).line lexer.lineno
368
+ (msg, line), = val
369
+ result = new_call(nil, msg.to_sym).line line
361
370
  }
362
371
 
363
372
  command: fcall command_args =tLOWEST
@@ -380,12 +389,14 @@ rule
380
389
  }
381
390
  | primary_value call_op operation2 command_args =tLOWEST
382
391
  {
383
- lhs, callop, op, args = val
392
+ lhs, callop, (op, _), args = val
393
+
384
394
  result = new_call lhs, op.to_sym, args, callop
395
+ result.line lhs.line
385
396
  }
386
397
  | primary_value call_op operation2 command_args cmd_brace_block
387
398
  {
388
- recv, _, msg, args, block = val
399
+ recv, _, (msg, _line), args, block = val
389
400
  call = new_call recv, msg.to_sym, args, val[1]
390
401
 
391
402
  block_dup_check call, block
@@ -395,11 +406,14 @@ rule
395
406
  }
396
407
  | primary_value tCOLON2 operation2 command_args =tLOWEST
397
408
  {
398
- result = new_call val[0], val[2].to_sym, val[3]
409
+ lhs, _, (id, line), args = val
410
+
411
+ result = new_call lhs, id.to_sym, args
412
+ result.line line
399
413
  }
400
414
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
401
415
  {
402
- recv, _, msg, args, block = val
416
+ recv, _, (msg, _line), args, block = val
403
417
  call = new_call recv, msg.to_sym, args
404
418
 
405
419
  block_dup_check call, block
@@ -557,25 +571,29 @@ rule
557
571
  }
558
572
  | primary_value call_op tIDENTIFIER
559
573
  {
560
- result = new_attrasgn val[0], val[2], val[1]
574
+ lhs, call_op, (id, _line) = val
575
+
576
+ result = new_attrasgn lhs, id, call_op
561
577
  }
562
578
  | primary_value tCOLON2 tIDENTIFIER
563
579
  {
564
- recv, _, id = val
580
+ recv, _, (id, _line) = val
565
581
  result = new_attrasgn recv, id
566
582
  }
567
583
  | primary_value call_op tCONSTANT
568
584
  {
569
- result = new_attrasgn val[0], val[2], val[1]
585
+ lhs, call_op, (id, _line) = val
586
+
587
+ result = new_attrasgn lhs, id, call_op
570
588
  }
571
589
  | primary_value tCOLON2 tCONSTANT
572
590
  {
573
591
  if (self.in_def || self.in_single > 0) then
574
- debug20 7
592
+ debug 14
575
593
  yyerror "dynamic constant assignment"
576
594
  end
577
595
 
578
- expr, _, id = val
596
+ expr, _, (id, _line) = val
579
597
  l = expr.line
580
598
 
581
599
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -583,58 +601,65 @@ rule
583
601
  | tCOLON3 tCONSTANT
584
602
  {
585
603
  if (self.in_def || self.in_single > 0) then
586
- debug20 8
604
+ debug 15
587
605
  yyerror "dynamic constant assignment"
588
606
  end
589
607
 
590
- _, id = val
591
- l = lexer.lineno
608
+ _, (id, l) = val
592
609
 
593
610
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
594
611
  }
595
612
  | backref
596
613
  {
597
- self.backref_assign_error val[0]
614
+ ref, = val
615
+
616
+ self.backref_assign_error ref
598
617
  }
599
618
 
600
619
  lhs: user_variable
601
620
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
621
+ var, = val
622
+
623
+ result = self.assignable var
605
624
  }
606
625
  | keyword_variable
607
626
  {
608
- line = lexer.lineno
609
- result = self.assignable val[0]
610
- result.line = line
611
- debug20 9, val, result
627
+ var, = val
628
+
629
+ result = self.assignable var
630
+
631
+ debug 16
612
632
  }
613
633
  | primary_value tLBRACK2 opt_call_args rbracket
614
634
  {
615
635
  lhs, _, args, _ = val
636
+
616
637
  result = self.aryset lhs, args
617
638
  }
618
639
  | primary_value call_op tIDENTIFIER # REFACTOR
619
640
  {
620
- lhs, op, id = val
641
+ lhs, op, (id, _line) = val
642
+
621
643
  result = new_attrasgn lhs, id, op
622
644
  }
623
645
  | primary_value tCOLON2 tIDENTIFIER
624
646
  {
625
- lhs, _, id = val
647
+ lhs, _, (id, _line) = val
648
+
626
649
  result = new_attrasgn lhs, id
627
650
  }
628
651
  | primary_value call_op tCONSTANT # REFACTOR?
629
652
  {
630
- result = new_attrasgn val[0], val[2], val[1]
653
+ lhs, call_op, (id, _line) = val
654
+
655
+ result = new_attrasgn lhs, id, call_op
631
656
  }
632
657
  | primary_value tCOLON2 tCONSTANT
633
658
  {
634
- expr, _, id = val
659
+ expr, _, (id, _line) = val
635
660
 
636
661
  if (self.in_def || self.in_single > 0) then
637
- debug20 10
662
+ debug 17
638
663
  yyerror "dynamic constant assignment"
639
664
  end
640
665
 
@@ -643,14 +668,13 @@ rule
643
668
  }
644
669
  | tCOLON3 tCONSTANT
645
670
  {
646
- _, id = val
671
+ _, (id, l) = val
647
672
 
648
673
  if (self.in_def || self.in_single > 0) then
649
- debug20 11
674
+ debug 18
650
675
  yyerror "dynamic constant assignment"
651
676
  end
652
677
 
653
- l = lexer.lineno
654
678
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
655
679
  }
656
680
  | backref
@@ -666,16 +690,17 @@ rule
666
690
 
667
691
  cpath: tCOLON3 cname
668
692
  {
669
- _, name = val
670
- result = s(:colon3, name.to_sym).line lexer.lineno
693
+ _, (name, line) = val
694
+ result = s(:colon3, name.to_sym).line line
671
695
  }
672
696
  | cname
673
697
  {
674
- result = val[0].to_sym
698
+ (id, line), = val
699
+ result = [id.to_sym, line] # TODO: sexp?
675
700
  }
676
701
  | primary_value tCOLON2 cname
677
702
  {
678
- pval, _, name = val
703
+ pval, _, (name, _line) = val
679
704
 
680
705
  result = s(:colon2, pval, name.to_sym)
681
706
  result.line pval.line
@@ -685,24 +710,17 @@ rule
685
710
  | op
686
711
  {
687
712
  lexer.lex_state = EXPR_END
688
- result = val[0]
689
713
  }
690
714
 
691
715
  | reswords
692
- {
693
- (sym, _line), = val
694
- lexer.lex_state = EXPR_END
695
- result = sym
696
- }
697
716
 
698
- fsym: fname | symbol
699
-
700
- fitem: fsym
717
+ fitem: fname
701
718
  {
702
- id, = val
703
- result = s(:lit, id.to_sym).line lexer.lineno
719
+ (id, line), = val
720
+
721
+ result = s(:lit, id.to_sym).line line
704
722
  }
705
- | dsym
723
+ | symbol
706
724
 
707
725
  undef_list: fitem
708
726
  {
@@ -723,8 +741,6 @@ rule
723
741
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
724
742
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
725
743
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
- # TODO: tUBANG dead?
727
- | tUBANG
728
744
 
729
745
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
730
746
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -758,24 +774,20 @@ rule
758
774
  }
759
775
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
760
776
  {
761
- lhs, _, id, op, rhs = val
777
+ lhs, _, (id, _line), (op, _), rhs = val
762
778
 
763
779
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
764
780
  }
765
781
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
766
782
  {
767
- lhs1, _, lhs2, op, rhs = val
783
+ lhs1, _, (lhs2, _line), op, rhs = val
768
784
 
769
785
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
786
  result = new_const_op_asgn [lhs, op, rhs]
771
787
  }
772
- | tCOLON3 tCONSTANT
788
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
773
789
  {
774
- result = self.lexer.lineno
775
- }
776
- tOP_ASGN arg_rhs
777
- {
778
- _, lhs, line, op, rhs = val
790
+ _, (lhs, line), op, rhs = val
779
791
 
780
792
  lhs = s(:colon3, lhs.to_sym).line line
781
793
  result = new_const_op_asgn [lhs, op, rhs]
@@ -789,7 +801,7 @@ rule
789
801
  | arg tDOT2 arg
790
802
  {
791
803
  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
804
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
805
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
794
806
  else
795
807
  result = s(:dot2, v1, v2).line v1.line
@@ -798,7 +810,7 @@ rule
798
810
  | arg tDOT3 arg
799
811
  {
800
812
  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
813
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
814
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
803
815
  else
804
816
  result = s(:dot3, v1, v2).line v1.line
@@ -818,6 +830,8 @@ rule
818
830
 
819
831
  result = s(:dot3, v1, v2).line v1.line
820
832
  }
833
+
834
+
821
835
  | arg tPLUS arg
822
836
  {
823
837
  result = new_call val[0], :+, argl(val[2])
@@ -844,8 +858,9 @@ rule
844
858
  }
845
859
  | tUMINUS_NUM simple_numeric tPOW arg
846
860
  {
847
- lit = s(:lit, val[1]).line lexer.lineno
848
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
861
+ _, (num, line), _, arg = val
862
+ lit = s(:lit, num).line line
863
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
849
864
 
850
865
  }
851
866
  | tUPLUS arg
@@ -944,12 +959,12 @@ rule
944
959
 
945
960
  rel_expr: arg relop arg =tGT
946
961
  {
947
- lhs, op, rhs = val
962
+ lhs, (op, _), rhs = val
948
963
  result = new_call lhs, op.to_sym, argl(rhs)
949
964
  }
950
965
  | rel_expr relop arg =tGT
951
966
  {
952
- lhs, op, rhs = val
967
+ lhs, (op, _), rhs = val
953
968
  warn "comparison '%s' after comparison", op
954
969
  result = new_call lhs, op.to_sym, argl(rhs)
955
970
  }
@@ -1140,8 +1155,9 @@ rule
1140
1155
  | backref
1141
1156
  | tFID
1142
1157
  {
1143
- msg, = val
1158
+ (msg, line), = val
1144
1159
  result = new_call nil, msg.to_sym
1160
+ result.line line
1145
1161
  }
1146
1162
  | k_begin
1147
1163
  {
@@ -1183,15 +1199,15 @@ rule
1183
1199
  }
1184
1200
  | primary_value tCOLON2 tCONSTANT
1185
1201
  {
1186
- expr, _, id = val
1202
+ expr, _, (id, _line) = val
1187
1203
 
1188
1204
  result = s(:colon2, expr, id.to_sym).line expr.line
1189
1205
  }
1190
1206
  | tCOLON3 tCONSTANT
1191
1207
  {
1192
- _, id = val
1208
+ _, (id, line) = val
1193
1209
 
1194
- result = s(:colon3, id.to_sym).line lexer.lineno
1210
+ result = s(:colon3, id.to_sym).line line
1195
1211
  }
1196
1212
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1197
1213
  {
@@ -1215,15 +1231,21 @@ rule
1215
1231
  }
1216
1232
  | kYIELD tLPAREN2 call_args rparen
1217
1233
  {
1218
- result = new_yield val[2]
1234
+ (_, line), _, args, _ = val
1235
+
1236
+ result = new_yield(args).line line
1219
1237
  }
1220
1238
  | kYIELD tLPAREN2 rparen
1221
1239
  {
1222
- result = new_yield
1240
+ (_, line), _, _ = val
1241
+
1242
+ result = new_yield.line line
1223
1243
  }
1224
1244
  | kYIELD
1225
1245
  {
1226
- result = new_yield
1246
+ (_, line), = val
1247
+
1248
+ result = new_yield.line line
1227
1249
  }
1228
1250
  | kDEFINED opt_nl tLPAREN2 expr rparen
1229
1251
  {
@@ -1238,7 +1260,7 @@ rule
1238
1260
  }
1239
1261
  | kNOT tLPAREN2 rparen
1240
1262
  {
1241
- debug20 14, val, result
1263
+ debug 20
1242
1264
  }
1243
1265
  | fcall brace_block
1244
1266
  {
@@ -1256,9 +1278,10 @@ rule
1256
1278
  iter.insert 1, call # FIX
1257
1279
  result = iter
1258
1280
  }
1259
- | tLAMBDA lambda
1281
+ | lambda
1260
1282
  {
1261
- result = val[1] # TODO: fix lineno
1283
+ expr, = val
1284
+ result = expr
1262
1285
  }
1263
1286
  | k_if expr_value then compstmt if_tail k_end
1264
1287
  {
@@ -1301,7 +1324,6 @@ rule
1301
1324
  }
1302
1325
  cpath superclass
1303
1326
  {
1304
- self.comments.push self.lexer.comments
1305
1327
  if (self.in_def || self.in_single > 0) then
1306
1328
  yyerror "class definition in method body"
1307
1329
  end
@@ -1311,7 +1333,7 @@ rule
1311
1333
  {
1312
1334
  result = new_class val
1313
1335
  self.env.unextend
1314
- self.lexer.comments # we don't care about comments in the body
1336
+ self.lexer.ignore_body_comments
1315
1337
  }
1316
1338
  | k_class tLSHFT
1317
1339
  {
@@ -1332,7 +1354,7 @@ rule
1332
1354
  {
1333
1355
  result = new_sclass val
1334
1356
  self.env.unextend
1335
- self.lexer.comments # we don't care about comments in the body
1357
+ self.lexer.ignore_body_comments
1336
1358
  }
1337
1359
  | k_module
1338
1360
  {
@@ -1340,7 +1362,6 @@ rule
1340
1362
  }
1341
1363
  cpath
1342
1364
  {
1343
- self.comments.push self.lexer.comments
1344
1365
  yyerror "module definition in method body" if
1345
1366
  self.in_def or self.in_single > 0
1346
1367
 
@@ -1350,7 +1371,7 @@ rule
1350
1371
  {
1351
1372
  result = new_module val
1352
1373
  self.env.unextend
1353
- self.lexer.comments # we don't care about comments in the body
1374
+ self.lexer.ignore_body_comments
1354
1375
  }
1355
1376
  | k_def fname
1356
1377
  {
@@ -1360,21 +1381,17 @@ rule
1360
1381
  self.env.extend
1361
1382
  lexer.cmdarg.push false
1362
1383
  lexer.cond.push false
1363
-
1364
- self.comments.push self.lexer.comments
1365
1384
  }
1366
- f_arglist bodystmt { result = lexer.lineno } k_end
1385
+ f_arglist bodystmt k_end
1367
1386
  {
1368
- in_def = val[2]
1369
-
1370
- result = new_defn val
1387
+ result, in_def = new_defn val
1371
1388
 
1372
1389
  lexer.cond.pop # group = local_pop
1373
1390
  lexer.cmdarg.pop
1374
1391
  self.env.unextend
1375
1392
  self.in_def = in_def
1376
1393
 
1377
- self.lexer.comments # we don't care about comments in the body
1394
+ self.lexer.ignore_body_comments
1378
1395
  }
1379
1396
  | k_def singleton dot_or_colon
1380
1397
  {
@@ -1382,7 +1399,7 @@ rule
1382
1399
  }
1383
1400
  fname
1384
1401
  {
1385
- result = [self.in_def, lexer.lineno]
1402
+ result = self.in_def
1386
1403
 
1387
1404
  self.in_single += 1 # TODO: remove?
1388
1405
 
@@ -1392,13 +1409,18 @@ rule
1392
1409
  lexer.cond.push false
1393
1410
 
1394
1411
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1395
- self.comments.push self.lexer.comments
1396
1412
  }
1397
1413
  f_arglist bodystmt k_end
1398
1414
  {
1399
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1400
1415
 
1401
- result = new_defs val
1416
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1417
+ # =>
1418
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1419
+
1420
+ val.delete_at 3
1421
+ val.delete_at 2
1422
+
1423
+ result, in_def = new_defs val
1402
1424
 
1403
1425
  lexer.cond.pop # group = local_pop
1404
1426
  lexer.cmdarg.pop
@@ -1409,7 +1431,7 @@ rule
1409
1431
 
1410
1432
  # TODO: restore cur_arg ? what's cur_arg?
1411
1433
 
1412
- self.lexer.comments # we don't care about comments in the body
1434
+ self.lexer.ignore_body_comments
1413
1435
  }
1414
1436
  | kBREAK
1415
1437
  {
@@ -1446,8 +1468,17 @@ rule
1446
1468
  k_case: kCASE
1447
1469
  k_for: kFOR
1448
1470
  k_class: kCLASS
1471
+ {
1472
+ self.comments.push self.lexer.comments
1473
+ }
1449
1474
  k_module: kMODULE
1475
+ {
1476
+ self.comments.push self.lexer.comments
1477
+ }
1450
1478
  k_def: kDEF
1479
+ {
1480
+ self.comments.push self.lexer.comments
1481
+ }
1451
1482
  k_do: kDO
1452
1483
  k_do_block: kDO_BLOCK
1453
1484
  k_rescue: kRESCUE
@@ -1508,51 +1539,42 @@ rule
1508
1539
 
1509
1540
  result = block_var args
1510
1541
  }
1511
- | f_marg_list tCOMMA tSTAR f_norm_arg
1542
+ | f_marg_list tCOMMA f_rest_marg
1512
1543
  {
1513
- args, _, _, splat = val
1544
+ args, _, rest = val
1514
1545
 
1515
- result = block_var args, "*#{splat}".to_sym
1546
+ result = block_var args, rest
1516
1547
  }
1517
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1548
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1518
1549
  {
1519
- args, _, _, splat, _, args2 = val
1550
+ lhs, _, splat, _, rhs = val
1520
1551
 
1521
- result = block_var args, "*#{splat}".to_sym, args2
1552
+ result = block_var lhs, splat, rhs
1522
1553
  }
1523
- | f_marg_list tCOMMA tSTAR
1554
+ | f_rest_marg
1524
1555
  {
1525
- args, _, _ = val
1556
+ rest, = val
1526
1557
 
1527
- result = block_var args, :*
1558
+ result = block_var rest
1528
1559
  }
1529
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1560
+ | f_rest_marg tCOMMA f_marg_list
1530
1561
  {
1531
- args, _, _, _, args2 = val
1562
+ splat, _, rest = val
1532
1563
 
1533
- result = block_var args, :*, args2
1564
+ result = block_var splat, rest
1534
1565
  }
1535
- | tSTAR f_norm_arg
1536
- {
1537
- _, splat = val
1538
1566
 
1539
- result = block_var :"*#{splat}"
1540
- }
1541
- | tSTAR f_norm_arg tCOMMA f_marg_list
1567
+ f_rest_marg: tSTAR f_norm_arg
1542
1568
  {
1543
- _, splat, _, args = val
1569
+ _, (id, line) = val
1544
1570
 
1545
- result = block_var :"*#{splat}", args
1571
+ result = args ["*#{id}".to_sym]
1572
+ result.line line
1546
1573
  }
1547
1574
  | tSTAR
1548
1575
  {
1549
- result = block_var :*
1550
- }
1551
- | tSTAR tCOMMA f_marg_list
1552
- {
1553
- _, _, args = val
1554
-
1555
- result = block_var :*, args
1576
+ result = args [:*]
1577
+ result.line lexer.lineno # FIX: tSTAR -> line
1556
1578
  }
1557
1579
 
1558
1580
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1569,8 +1591,8 @@ rule
1569
1591
  }
1570
1592
  | f_block_arg
1571
1593
  {
1572
- line = lexer.lineno
1573
- result = call_args val # TODO: push line down
1594
+ (id, line), = val
1595
+ result = call_args [id]
1574
1596
  result.line line
1575
1597
  }
1576
1598
 
@@ -1679,13 +1701,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1679
1701
 
1680
1702
  bvar: tIDENTIFIER
1681
1703
  {
1682
- id, = val
1683
- line = lexer.lineno
1704
+ (id, line), = val
1684
1705
  result = s(:shadow, id.to_sym).line line
1685
1706
  }
1686
1707
  | f_bad_arg
1687
1708
 
1688
- lambda: {
1709
+ lambda: tLAMBDA
1710
+ {
1689
1711
  self.env.extend :dynamic
1690
1712
  result = [lexer.lineno, lexer.lpar_beg]
1691
1713
  lexer.paren_nest += 1
@@ -1697,14 +1719,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1697
1719
  }
1698
1720
  lambda_body
1699
1721
  {
1700
- (line, lpar), args, _cmdarg, body = val
1722
+ _, (line, lpar), args, _cmdarg, body = val
1701
1723
  lexer.lpar_beg = lpar
1702
1724
 
1703
1725
  lexer.cmdarg.pop
1704
1726
 
1705
1727
  call = s(:lambda).line line
1706
1728
  result = new_iter call, args, body
1707
- result.line = line
1729
+ result.line line
1708
1730
  self.env.unextend # TODO: dynapush & dynapop
1709
1731
  }
1710
1732
 
@@ -1739,23 +1761,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1739
1761
  ## if (nd_type($1) == NODE_YIELD) {
1740
1762
  ## compile_error(PARSER_ARG "block given to yield");
1741
1763
 
1742
- syntax_error "Both block arg and actual block given." if
1743
- val[0].block_pass?
1764
+ cmd, blk = val
1744
1765
 
1745
- val = invert_block_call val if inverted? val
1766
+ syntax_error "Both block arg and actual block given." if
1767
+ cmd.block_pass?
1746
1768
 
1747
- cmd, blk = val
1769
+ if inverted? val then
1770
+ val = invert_block_call val
1771
+ cmd, blk = val
1772
+ end
1748
1773
 
1749
1774
  result = blk
1750
1775
  result.insert 1, cmd
1751
1776
  }
1752
1777
  | block_call call_op2 operation2 opt_paren_args
1753
1778
  {
1754
- result = new_call val[0], val[2].to_sym, val[3]
1779
+ lhs, _, (id, _line), args = val
1780
+
1781
+ result = new_call lhs, id.to_sym, args
1755
1782
  }
1756
1783
  | block_call call_op2 operation2 opt_paren_args brace_block
1757
1784
  {
1758
- iter1, _, name, args, iter2 = val
1785
+ iter1, _, (name, _line), args, iter2 = val
1759
1786
 
1760
1787
  call = new_call iter1, name.to_sym, args
1761
1788
  iter2.insert 1, call
@@ -1764,7 +1791,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1764
1791
  }
1765
1792
  | block_call call_op2 operation2 command_args do_block
1766
1793
  {
1767
- iter1, _, name, args, iter2 = val
1794
+ iter1, _, (name, _line), args, iter2 = val
1768
1795
 
1769
1796
  call = new_call iter1, name.to_sym, args
1770
1797
  iter2.insert 1, call
@@ -1772,28 +1799,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1772
1799
  result = iter2
1773
1800
  }
1774
1801
 
1775
- method_call: fcall
1776
- {
1777
- result = self.lexer.lineno
1778
- }
1779
- paren_args
1802
+ method_call: fcall paren_args
1780
1803
  {
1781
- call, lineno, args = val
1804
+ call, args = val
1782
1805
 
1783
1806
  result = call.concat args.sexp_body if args
1784
- result.line lineno
1785
1807
  }
1786
1808
  | primary_value call_op operation2 opt_paren_args
1787
1809
  {
1788
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1810
+ recv, call_op, (op, _line), args = val
1811
+
1812
+ result = new_call recv, op.to_sym, args, call_op
1789
1813
  }
1790
1814
  | primary_value tCOLON2 operation2 paren_args
1791
1815
  {
1792
- result = new_call val[0], val[2].to_sym, val[3]
1816
+ recv, _, (op, _line), args = val
1817
+
1818
+ result = new_call recv, op.to_sym, args
1793
1819
  }
1794
1820
  | primary_value tCOLON2 operation3
1795
1821
  {
1796
- result = new_call val[0], val[2].to_sym
1822
+ lhs, _, (id, _line) = val
1823
+
1824
+ result = new_call lhs, id.to_sym
1797
1825
  }
1798
1826
  | primary_value call_op paren_args
1799
1827
  {
@@ -1826,7 +1854,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1854
  _, line, body, _ = val
1827
1855
 
1828
1856
  result = body
1829
- result.line = line
1857
+ result.line line
1830
1858
 
1831
1859
  self.env.unextend
1832
1860
  }
@@ -1840,7 +1868,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1840
1868
  _, line, body, _ = val
1841
1869
 
1842
1870
  result = body
1843
- result.line = line
1871
+ result.line line
1844
1872
 
1845
1873
  self.env.unextend
1846
1874
  }
@@ -1869,14 +1897,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1869
1897
  self.env.unextend
1870
1898
  }
1871
1899
 
1900
+ case_args: arg_value
1901
+ {
1902
+ arg, = val
1903
+
1904
+ result = s(:array, arg).line arg.line
1905
+ }
1906
+ | tSTAR arg_value
1907
+ {
1908
+ _, arg = val
1909
+
1910
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1911
+ }
1912
+ | case_args tCOMMA arg_value
1913
+ {
1914
+ args, _, id = val
1915
+
1916
+ result = self.list_append args, id
1917
+ }
1918
+ | case_args tCOMMA tSTAR arg_value
1919
+ {
1920
+ args, _, _, id = val
1921
+
1922
+ result = self.list_append args, s(:splat, id).line(id.line)
1923
+ }
1924
+
1872
1925
  case_body: k_when
1873
1926
  {
1874
1927
  result = self.lexer.lineno
1875
1928
  }
1876
- args then compstmt cases
1929
+ case_args then compstmt cases
1877
1930
  {
1878
1931
  result = new_when(val[2], val[4])
1879
- result.line = val[1]
1932
+ result.line val[1]
1880
1933
  result << val[5] if val[5]
1881
1934
  }
1882
1935
 
@@ -1922,17 +1975,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1922
1975
 
1923
1976
  literal: numeric
1924
1977
  {
1925
- line = lexer.lineno
1926
- result = s(:lit, val[0])
1927
- result.line = line
1978
+ (lit, line), = val
1979
+ result = s(:lit, lit).line line
1928
1980
  }
1929
1981
  | symbol
1930
- {
1931
- line = lexer.lineno
1932
- result = s(:lit, val[0])
1933
- result.line = line
1934
- }
1935
- | dsym
1936
1982
 
1937
1983
  strings: string
1938
1984
  {
@@ -1943,7 +1989,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1943
1989
 
1944
1990
  string: tCHAR
1945
1991
  {
1946
- debug20 23, val, result
1992
+ debug 37
1947
1993
  }
1948
1994
  | string1
1949
1995
  | string string1
@@ -1953,11 +1999,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1953
1999
 
1954
2000
  string1: tSTRING_BEG string_contents tSTRING_END
1955
2001
  {
1956
- _, str, (_, func) = val
2002
+ (_, line), str, (_, func) = val
1957
2003
 
1958
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2004
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1959
2005
 
1960
- result = str
2006
+ result = str.line line
1961
2007
  }
1962
2008
  | tSTRING
1963
2009
  {
@@ -1977,11 +2023,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1977
2023
 
1978
2024
  words: tWORDS_BEG tSPACE tSTRING_END
1979
2025
  {
1980
- result = s(:array).line lexer.lineno
2026
+ (_, line), _, _ = val
2027
+
2028
+ result = s(:array).line line
1981
2029
  }
1982
2030
  | tWORDS_BEG word_list tSTRING_END
1983
2031
  {
1984
- result = val[1]
2032
+ (_, line), list, _ = val
2033
+
2034
+ result = list.line line
1985
2035
  }
1986
2036
 
1987
2037
  word_list: none
@@ -2001,18 +2051,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2001
2051
 
2002
2052
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2003
2053
  {
2004
- result = s(:array).line lexer.lineno
2054
+ (_, line), _, _ = val
2055
+
2056
+ result = s(:array).line line
2005
2057
  }
2006
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2058
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2007
2059
  {
2008
- _, line, list, _, = val
2009
- list.line = line
2060
+ (_, line), list, _, = val
2061
+ list.line line
2010
2062
  result = list
2011
2063
  }
2012
2064
 
2013
2065
  symbol_list: none
2014
2066
  {
2015
- result = new_symbol_list.line lexer.lineno
2067
+ result = new_symbol_list
2016
2068
  }
2017
2069
  | symbol_list word tSPACE
2018
2070
  {
@@ -2022,20 +2074,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2022
2074
 
2023
2075
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2024
2076
  {
2025
- result = s(:array).line lexer.lineno
2077
+ (_, line), _, _ = val
2078
+
2079
+ result = s(:array).line line
2026
2080
  }
2027
2081
  | tQWORDS_BEG qword_list tSTRING_END
2028
2082
  {
2029
- result = val[1]
2083
+ (_, line), list, _ = val
2084
+
2085
+ result = list.line line
2030
2086
  }
2031
2087
 
2032
2088
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2033
2089
  {
2034
- result = s(:array).line lexer.lineno # FIX
2090
+ (_, line), _, _ = val
2091
+
2092
+ result = s(:array).line line
2035
2093
  }
2036
2094
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2037
2095
  {
2038
- result = val[1]
2096
+ (_, line), list, _ = val
2097
+
2098
+ result = list.line line
2039
2099
  }
2040
2100
 
2041
2101
  qword_list: none
@@ -2058,7 +2118,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2058
2118
 
2059
2119
  string_contents: none
2060
2120
  {
2061
- result = s(:str, "").line lexer.lineno
2121
+ line = prev_value_to_lineno _values.last
2122
+ result = s(:str, +"").line line
2062
2123
  }
2063
2124
  | string_contents string_content
2064
2125
  {
@@ -2133,8 +2194,8 @@ regexp_contents: none
2133
2194
  lexer.brace_nest = brace_nest
2134
2195
  lexer.string_nest = string_nest
2135
2196
 
2136
- lexer.cmdarg.pop
2137
2197
  lexer.cond.pop
2198
+ lexer.cmdarg.pop
2138
2199
 
2139
2200
  lexer.lex_state = oldlex_state
2140
2201
 
@@ -2149,29 +2210,49 @@ regexp_contents: none
2149
2210
  when nil then
2150
2211
  result = s(:evstr).line line
2151
2212
  else
2152
- debug20 25
2213
+ debug 38
2153
2214
  raise "unknown string body: #{stmt.inspect}"
2154
2215
  end
2155
2216
  }
2156
2217
 
2157
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2158
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2159
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2218
+ string_dvar: tGVAR
2219
+ {
2220
+ (id, line), = val
2221
+ result = s(:gvar, id.to_sym).line line
2222
+ }
2223
+ | tIVAR
2224
+ {
2225
+ (id, line), = val
2226
+ result = s(:ivar, id.to_sym).line line
2227
+ }
2228
+ | tCVAR
2229
+ {
2230
+ (id, line), = val
2231
+ result = s(:cvar, id.to_sym).line line
2232
+ }
2160
2233
  | backref
2161
2234
 
2162
- symbol: tSYMBEG sym
2235
+ symbol: ssym
2236
+ | dsym
2237
+
2238
+ ssym: tSYMBEG sym
2163
2239
  {
2240
+ _, (id, line) = val
2241
+
2164
2242
  lexer.lex_state = EXPR_END
2165
- result = val[1].to_sym
2243
+ result = s(:lit, id.to_sym).line line
2166
2244
  }
2167
2245
  | tSYMBOL
2168
2246
  {
2169
- result = val[0].to_sym
2247
+ (id, line), = val
2248
+
2249
+ lexer.lex_state = EXPR_END
2250
+ result = s(:lit, id.to_sym).line line
2170
2251
  }
2171
2252
 
2172
2253
  sym: fname | tIVAR | tGVAR | tCVAR
2173
2254
 
2174
- dsym: tSYMBEG xstring_contents tSTRING_END
2255
+ dsym: tSYMBEG string_contents tSTRING_END
2175
2256
  {
2176
2257
  _, result, _ = val
2177
2258
 
@@ -2187,14 +2268,15 @@ regexp_contents: none
2187
2268
  when :evstr then
2188
2269
  result = s(:dsym, "", result).line result.line
2189
2270
  else
2190
- debug20 26, val, result
2271
+ debug 39
2191
2272
  end
2192
2273
  }
2193
2274
 
2194
2275
  numeric: simple_numeric
2195
- | tUMINUS_NUM simple_numeric
2276
+ | tUMINUS_NUM simple_numeric =tLOWEST
2196
2277
  {
2197
- result = -val[1] # TODO: pt_testcase
2278
+ _, (num, line) = val
2279
+ result = [-num, line]
2198
2280
  }
2199
2281
 
2200
2282
  simple_numeric: tINTEGER
@@ -2227,8 +2309,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2227
2309
 
2228
2310
  var_ref: user_variable
2229
2311
  {
2230
- var = val[0]
2312
+ raise "NO: #{val.inspect}" if Sexp === val.first
2313
+ (var, line), = val
2231
2314
  result = Sexp === var ? var : self.gettable(var)
2315
+ result.line line
2232
2316
  }
2233
2317
  | keyword_variable
2234
2318
  {
@@ -2243,11 +2327,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2243
2327
  | keyword_variable
2244
2328
  {
2245
2329
  result = self.assignable val[0]
2246
- debug20 29, val, result
2330
+ debug 40
2247
2331
  }
2248
2332
 
2249
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2250
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2333
+ backref: tNTH_REF
2334
+ {
2335
+ (ref, line), = val
2336
+ result = s(:nth_ref, ref).line line
2337
+ }
2338
+ | tBACK_REF
2339
+ {
2340
+ (ref, line), = val
2341
+ result = s(:back_ref, ref).line line
2342
+ }
2251
2343
 
2252
2344
  superclass: tLT
2253
2345
  {
@@ -2265,9 +2357,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2357
 
2266
2358
  f_arglist: tLPAREN2 f_args rparen
2267
2359
  {
2268
- result = val[1]
2269
- self.lexer.lex_state = EXPR_BEG
2270
- self.lexer.command_start = true
2360
+ result = end_args val
2271
2361
  }
2272
2362
  | {
2273
2363
  result = self.in_kwarg
@@ -2276,12 +2366,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2276
2366
  }
2277
2367
  f_args term
2278
2368
  {
2279
- kwarg, args, _ = val
2280
-
2281
- self.in_kwarg = kwarg
2282
- result = args
2283
- lexer.lex_state = EXPR_BEG
2284
- lexer.command_start = true
2369
+ result = end_args val
2285
2370
  }
2286
2371
 
2287
2372
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2366,8 +2451,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2366
2451
  |
2367
2452
  {
2368
2453
  result = args val
2454
+ # result.line lexer.lineno
2369
2455
  }
2370
2456
 
2457
+
2371
2458
  f_bad_arg: tCONSTANT
2372
2459
  {
2373
2460
  yyerror "formal argument cannot be a constant"
@@ -2388,10 +2475,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2388
2475
  f_norm_arg: f_bad_arg
2389
2476
  | tIDENTIFIER
2390
2477
  {
2391
- identifier = val[0].to_sym
2478
+ (id, line), = val
2479
+ identifier = id.to_sym
2392
2480
  self.env[identifier] = :lvar
2393
2481
 
2394
- result = identifier
2482
+ result = [identifier, line]
2395
2483
  }
2396
2484
 
2397
2485
  f_arg_asgn: f_norm_arg
@@ -2399,22 +2487,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2399
2487
  f_arg_item: f_arg_asgn
2400
2488
  | tLPAREN f_margs rparen
2401
2489
  {
2402
- result = val[1]
2490
+ _, margs, _ = val
2491
+
2492
+ result = margs
2403
2493
  }
2404
2494
 
2405
2495
  f_arg: f_arg_item
2406
2496
  {
2407
- arg, = val
2408
-
2409
- case arg
2410
- when Symbol then
2411
- result = s(:args, arg).line lexer.lineno
2412
- when Sexp then
2413
- result = arg
2414
- else
2415
- debug20 32
2416
- raise "Unknown f_arg type: #{val.inspect}"
2417
- end
2497
+ result = new_arg val
2418
2498
  }
2419
2499
  | f_arg tCOMMA f_arg_item
2420
2500
  {
@@ -2426,7 +2506,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2426
2506
  result = s(:args, list).line list.line
2427
2507
  end
2428
2508
 
2429
- result << item
2509
+ result << (Sexp === item ? item : item.first)
2430
2510
  }
2431
2511
 
2432
2512
  f_label: tLABEL
@@ -2487,26 +2567,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2487
2567
  kwrest_mark: tPOW
2488
2568
  | tDSTAR
2489
2569
 
2570
+
2490
2571
  f_kwrest: kwrest_mark tIDENTIFIER
2491
2572
  {
2492
- name = val[1].to_sym
2493
- self.assignable name
2494
- result = :"**#{name}"
2573
+ _, (id, line) = val
2574
+
2575
+ name = id.to_sym
2576
+ self.assignable [name, line]
2577
+ result = [:"**#{name}", line]
2495
2578
  }
2496
2579
  | kwrest_mark
2497
2580
  {
2498
- result = :"**"
2581
+ id = :"**"
2582
+ self.env[id] = :lvar # TODO: needed?!?
2583
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2499
2584
  }
2500
2585
 
2501
2586
  f_opt: f_arg_asgn tEQL arg_value
2502
2587
  {
2503
- result = self.assignable val[0], val[2]
2588
+ lhs, _, rhs = val
2589
+ result = self.assignable lhs, rhs
2504
2590
  # TODO: detect duplicate names
2505
2591
  }
2506
2592
 
2507
2593
  f_block_opt: f_arg_asgn tEQL primary_value
2508
2594
  {
2509
- result = self.assignable val[0], val[2]
2595
+ lhs, _, rhs = val
2596
+ result = self.assignable lhs, rhs
2510
2597
  }
2511
2598
 
2512
2599
  f_block_optarg: f_block_opt
@@ -2536,30 +2623,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2536
2623
  f_rest_arg: restarg_mark tIDENTIFIER
2537
2624
  {
2538
2625
  # TODO: differs from parse.y - needs tests
2539
- name = val[1].to_sym
2540
- self.assignable name
2541
- result = :"*#{name}"
2626
+ _, (id, line) = val
2627
+ name = id.to_sym
2628
+ self.assignable [name, line]
2629
+ result = [:"*#{name}", line]
2542
2630
  }
2543
2631
  | restarg_mark
2544
2632
  {
2545
2633
  name = :"*"
2546
2634
  self.env[name] = :lvar
2547
- result = name
2635
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2548
2636
  }
2549
2637
 
2550
2638
  blkarg_mark: tAMPER2 | tAMPER
2551
2639
 
2552
2640
  f_block_arg: blkarg_mark tIDENTIFIER
2553
2641
  {
2554
- identifier = val[1].to_sym
2642
+ _, (id, line) = val
2643
+ identifier = id.to_sym
2555
2644
 
2556
2645
  self.env[identifier] = :lvar
2557
- result = "&#{identifier}".to_sym
2646
+ result = ["&#{identifier}".to_sym, line]
2558
2647
  }
2559
2648
 
2560
2649
  opt_f_block_arg: tCOMMA f_block_arg
2561
2650
  {
2562
- result = val[1]
2651
+ _, arg = val
2652
+ result = arg
2563
2653
  }
2564
2654
  |
2565
2655
  {
@@ -2608,9 +2698,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2608
2698
  }
2609
2699
  | tSTRING_BEG string_contents tLABEL_END arg_value
2610
2700
  {
2611
- _, sym, _, value = val
2701
+ (_, line), sym, _, value = val
2702
+
2612
2703
  sym.sexp_type = :dsym
2613
- result = s(:array, sym, value).line sym.line
2704
+
2705
+ result = s(:array, sym, value).line line
2614
2706
  }
2615
2707
  | tDSTAR arg_value
2616
2708
  {