ruby_parser 3.15.1 → 3.18.1

Sign up to get free protection for your applications and to get access to all the features.
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
  {