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/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
  {