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/ruby22_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
 
@@ -32,7 +32,7 @@ preclow
32
32
  right tEQL tOP_ASGN
33
33
  left kRESCUE_MOD
34
34
  right tEH tCOLON
35
- nonassoc tDOT2 tDOT3
35
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
36
36
  left tOROP
37
37
  left tANDOP
38
38
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -55,6 +55,9 @@ rule
55
55
  top_compstmt
56
56
  {
57
57
  result = new_compstmt val
58
+
59
+ lexer.cond.pop # local_pop
60
+ lexer.cmdarg.pop
58
61
  }
59
62
 
60
63
  top_compstmt: top_stmts opt_terms
@@ -75,7 +78,7 @@ rule
75
78
  | klBEGIN
76
79
  {
77
80
  if (self.in_def || self.in_single > 0) then
78
- debug20 1
81
+ debug 11
79
82
  yyerror "BEGIN in method"
80
83
  end
81
84
  self.env.extend
@@ -100,7 +103,9 @@ rule
100
103
  bodystmt: compstmt opt_rescue k_else
101
104
  {
102
105
  res = _values[-2]
103
- yyerror "else without rescue is useless" unless res
106
+ # TODO: move down to main match so I can just use val
107
+
108
+ warn "else without rescue is useless" unless res
104
109
  }
105
110
  compstmt
106
111
  opt_ensure
@@ -130,7 +135,7 @@ rule
130
135
  | error stmt
131
136
  {
132
137
  result = val[1]
133
- debug20 2, val, result
138
+ debug 12
134
139
  }
135
140
 
136
141
  stmt_or_begin: stmt
@@ -138,6 +143,10 @@ rule
138
143
  {
139
144
  yyerror "BEGIN is permitted only at toplevel"
140
145
  }
146
+ begin_block
147
+ {
148
+ result = val[2] # wtf?
149
+ }
141
150
 
142
151
  stmt: kALIAS fitem
143
152
  {
@@ -150,12 +159,12 @@ rule
150
159
  }
151
160
  | kALIAS tGVAR tGVAR
152
161
  {
153
- (_, line), lhs, rhs = val
162
+ (_, line), (lhs, _), (rhs, _) = val
154
163
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
155
164
  }
156
165
  | kALIAS tGVAR tBACK_REF
157
166
  {
158
- (_, line), lhs, rhs = val
167
+ (_, line), (lhs, _), (rhs, _) = val
159
168
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
160
169
  }
161
170
  | kALIAS tGVAR tNTH_REF
@@ -198,7 +207,7 @@ rule
198
207
  (_, line), _, stmt, _ = val
199
208
 
200
209
  if (self.in_def || self.in_single > 0) then
201
- debug20 3
210
+ debug 13
202
211
  yyerror "END in method; use at_exit"
203
212
  end
204
213
 
@@ -238,32 +247,31 @@ rule
238
247
  }
239
248
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
240
249
  {
241
- prim, _, id, opasgn, rhs = val
242
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
243
- if val[1] == '&.'
244
- result.sexp_type = :safe_op_asgn
245
- end
246
- result.line = val[0].line
250
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
251
+
252
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
253
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
254
+ result.line prim.line
247
255
  }
248
256
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
249
257
  {
250
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
251
- if val[1] == '&.'
252
- result.sexp_type = :safe_op_asgn
253
- end
254
- result.line = val[0].line
258
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
259
+
260
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
261
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
262
+ result.line prim.line
255
263
  }
256
264
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
257
265
  {
258
- lhs1, _, lhs2, op, rhs = val
266
+ lhs1, _, (lhs2, line), (id, _), rhs = val
259
267
 
260
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
268
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
261
269
  }
262
270
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
263
271
  {
264
- lhs1, _, lhs2, op, rhs = val
272
+ lhs1, _, (lhs2, line), (id, _), rhs = val
265
273
 
266
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
274
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
267
275
  }
268
276
  | backref tOP_ASGN command_rhs
269
277
  {
@@ -301,7 +309,7 @@ rule
301
309
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
302
310
  # REFACTOR: call_uni_op -- see parse26.y
303
311
  }
304
- | arg
312
+ | arg =tLBRACE_ARG
305
313
 
306
314
  expr_value: expr
307
315
  {
@@ -326,7 +334,7 @@ rule
326
334
  block_command: block_call
327
335
  | block_call call_op2 operation2 command_args
328
336
  {
329
- blk, _, msg, args = val
337
+ blk, _, (msg, _line), args = val
330
338
  result = new_call(blk, msg.to_sym, args).line blk.line
331
339
  }
332
340
 
@@ -340,15 +348,15 @@ rule
340
348
  _, line, body, _ = val
341
349
 
342
350
  result = body
343
- result.line = line
351
+ result.line line
344
352
 
345
353
  # self.env.unextend
346
354
  }
347
355
 
348
356
  fcall: operation
349
357
  {
350
- msg, = val
351
- result = new_call(nil, msg.to_sym).line lexer.lineno
358
+ (msg, line), = val
359
+ result = new_call(nil, msg.to_sym).line line
352
360
  }
353
361
 
354
362
  command: fcall command_args =tLOWEST
@@ -371,12 +379,14 @@ rule
371
379
  }
372
380
  | primary_value call_op operation2 command_args =tLOWEST
373
381
  {
374
- lhs, callop, op, args = val
382
+ lhs, callop, (op, _), args = val
383
+
375
384
  result = new_call lhs, op.to_sym, args, callop
385
+ result.line lhs.line
376
386
  }
377
387
  | primary_value call_op operation2 command_args cmd_brace_block
378
388
  {
379
- recv, _, msg, args, block = val
389
+ recv, _, (msg, _line), args, block = val
380
390
  call = new_call recv, msg.to_sym, args, val[1]
381
391
 
382
392
  block_dup_check call, block
@@ -386,11 +396,14 @@ rule
386
396
  }
387
397
  | primary_value tCOLON2 operation2 command_args =tLOWEST
388
398
  {
389
- result = new_call val[0], val[2].to_sym, val[3]
399
+ lhs, _, (id, line), args = val
400
+
401
+ result = new_call lhs, id.to_sym, args
402
+ result.line line
390
403
  }
391
404
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
392
405
  {
393
- recv, _, msg, args, block = val
406
+ recv, _, (msg, _line), args, block = val
394
407
  call = new_call recv, msg.to_sym, args
395
408
 
396
409
  block_dup_check call, block
@@ -548,25 +561,29 @@ rule
548
561
  }
549
562
  | primary_value call_op tIDENTIFIER
550
563
  {
551
- result = new_attrasgn val[0], val[2], val[1]
564
+ lhs, call_op, (id, _line) = val
565
+
566
+ result = new_attrasgn lhs, id, call_op
552
567
  }
553
568
  | primary_value tCOLON2 tIDENTIFIER
554
569
  {
555
- recv, _, id = val
570
+ recv, _, (id, _line) = val
556
571
  result = new_attrasgn recv, id
557
572
  }
558
573
  | primary_value call_op tCONSTANT
559
574
  {
560
- result = new_attrasgn val[0], val[2], val[1]
575
+ lhs, call_op, (id, _line) = val
576
+
577
+ result = new_attrasgn lhs, id, call_op
561
578
  }
562
579
  | primary_value tCOLON2 tCONSTANT
563
580
  {
564
581
  if (self.in_def || self.in_single > 0) then
565
- debug20 7
582
+ debug 14
566
583
  yyerror "dynamic constant assignment"
567
584
  end
568
585
 
569
- expr, _, id = val
586
+ expr, _, (id, _line) = val
570
587
  l = expr.line
571
588
 
572
589
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -574,58 +591,65 @@ rule
574
591
  | tCOLON3 tCONSTANT
575
592
  {
576
593
  if (self.in_def || self.in_single > 0) then
577
- debug20 8
594
+ debug 15
578
595
  yyerror "dynamic constant assignment"
579
596
  end
580
597
 
581
- _, id = val
582
- l = lexer.lineno
598
+ _, (id, l) = val
583
599
 
584
600
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
585
601
  }
586
602
  | backref
587
603
  {
588
- self.backref_assign_error val[0]
604
+ ref, = val
605
+
606
+ self.backref_assign_error ref
589
607
  }
590
608
 
591
609
  lhs: user_variable
592
610
  {
593
- line = lexer.lineno
594
- result = self.assignable val[0]
595
- result.line = line
611
+ var, = val
612
+
613
+ result = self.assignable var
596
614
  }
597
615
  | keyword_variable
598
616
  {
599
- line = lexer.lineno
600
- result = self.assignable val[0]
601
- result.line = line
602
- debug20 9, val, result
617
+ var, = val
618
+
619
+ result = self.assignable var
620
+
621
+ debug 16
603
622
  }
604
623
  | primary_value tLBRACK2 opt_call_args rbracket
605
624
  {
606
625
  lhs, _, args, _ = val
626
+
607
627
  result = self.aryset lhs, args
608
628
  }
609
629
  | primary_value call_op tIDENTIFIER # REFACTOR
610
630
  {
611
- lhs, op, id = val
631
+ lhs, op, (id, _line) = val
632
+
612
633
  result = new_attrasgn lhs, id, op
613
634
  }
614
635
  | primary_value tCOLON2 tIDENTIFIER
615
636
  {
616
- lhs, _, id = val
637
+ lhs, _, (id, _line) = val
638
+
617
639
  result = new_attrasgn lhs, id
618
640
  }
619
641
  | primary_value call_op tCONSTANT # REFACTOR?
620
642
  {
621
- result = new_attrasgn val[0], val[2], val[1]
643
+ lhs, call_op, (id, _line) = val
644
+
645
+ result = new_attrasgn lhs, id, call_op
622
646
  }
623
647
  | primary_value tCOLON2 tCONSTANT
624
648
  {
625
- expr, _, id = val
649
+ expr, _, (id, _line) = val
626
650
 
627
651
  if (self.in_def || self.in_single > 0) then
628
- debug20 10
652
+ debug 17
629
653
  yyerror "dynamic constant assignment"
630
654
  end
631
655
 
@@ -634,14 +658,13 @@ rule
634
658
  }
635
659
  | tCOLON3 tCONSTANT
636
660
  {
637
- _, id = val
661
+ _, (id, l) = val
638
662
 
639
663
  if (self.in_def || self.in_single > 0) then
640
- debug20 11
664
+ debug 18
641
665
  yyerror "dynamic constant assignment"
642
666
  end
643
667
 
644
- l = lexer.lineno
645
668
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
646
669
  }
647
670
  | backref
@@ -657,16 +680,17 @@ rule
657
680
 
658
681
  cpath: tCOLON3 cname
659
682
  {
660
- _, name = val
661
- result = s(:colon3, name.to_sym).line lexer.lineno
683
+ _, (name, line) = val
684
+ result = s(:colon3, name.to_sym).line line
662
685
  }
663
686
  | cname
664
687
  {
665
- result = val[0].to_sym
688
+ (id, line), = val
689
+ result = [id.to_sym, line] # TODO: sexp?
666
690
  }
667
691
  | primary_value tCOLON2 cname
668
692
  {
669
- pval, _, name = val
693
+ pval, _, (name, _line) = val
670
694
 
671
695
  result = s(:colon2, pval, name.to_sym)
672
696
  result.line pval.line
@@ -676,24 +700,17 @@ rule
676
700
  | op
677
701
  {
678
702
  lexer.lex_state = EXPR_END
679
- result = val[0]
680
703
  }
681
704
 
682
705
  | reswords
683
- {
684
- (sym, _line), = val
685
- lexer.lex_state = EXPR_END
686
- result = sym
687
- }
688
706
 
689
- fsym: fname | symbol
690
-
691
- fitem: fsym
707
+ fitem: fname
692
708
  {
693
- id, = val
694
- result = s(:lit, id.to_sym).line lexer.lineno
709
+ (id, line), = val
710
+
711
+ result = s(:lit, id.to_sym).line line
695
712
  }
696
- | dsym
713
+ | symbol
697
714
 
698
715
  undef_list: fitem
699
716
  {
@@ -714,8 +731,6 @@ rule
714
731
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
715
732
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
716
733
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
717
- # TODO: tUBANG dead?
718
- | tUBANG
719
734
 
720
735
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
721
736
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -749,24 +764,20 @@ rule
749
764
  }
750
765
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
751
766
  {
752
- lhs, _, id, op, rhs = val
767
+ lhs, _, (id, _line), (op, _), rhs = val
753
768
 
754
769
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
755
770
  }
756
771
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
757
772
  {
758
- lhs1, _, lhs2, op, rhs = val
773
+ lhs1, _, (lhs2, _line), op, rhs = val
759
774
 
760
775
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
761
776
  result = new_const_op_asgn [lhs, op, rhs]
762
777
  }
763
- | tCOLON3 tCONSTANT
778
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
764
779
  {
765
- result = self.lexer.lineno
766
- }
767
- tOP_ASGN arg_rhs
768
- {
769
- _, lhs, line, op, rhs = val
780
+ _, (lhs, line), op, rhs = val
770
781
 
771
782
  lhs = s(:colon3, lhs.to_sym).line line
772
783
  result = new_const_op_asgn [lhs, op, rhs]
@@ -780,7 +791,7 @@ rule
780
791
  | arg tDOT2 arg
781
792
  {
782
793
  v1, v2 = val[0], val[2]
783
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
794
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
784
795
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
785
796
  else
786
797
  result = s(:dot2, v1, v2).line v1.line
@@ -789,12 +800,14 @@ rule
789
800
  | arg tDOT3 arg
790
801
  {
791
802
  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
803
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
804
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
794
805
  else
795
806
  result = s(:dot3, v1, v2).line v1.line
796
807
  end
797
808
  }
809
+
810
+
798
811
  | arg tPLUS arg
799
812
  {
800
813
  result = new_call val[0], :+, argl(val[2])
@@ -821,8 +834,9 @@ rule
821
834
  }
822
835
  | tUMINUS_NUM simple_numeric tPOW arg
823
836
  {
824
- lit = s(:lit, val[1]).line lexer.lineno
825
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
837
+ _, (num, line), _, arg = val
838
+ lit = s(:lit, num).line line
839
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
826
840
 
827
841
  }
828
842
  | tUPLUS arg
@@ -921,12 +935,12 @@ rule
921
935
 
922
936
  rel_expr: arg relop arg =tGT
923
937
  {
924
- lhs, op, rhs = val
938
+ lhs, (op, _), rhs = val
925
939
  result = new_call lhs, op.to_sym, argl(rhs)
926
940
  }
927
941
  | rel_expr relop arg =tGT
928
942
  {
929
- lhs, op, rhs = val
943
+ lhs, (op, _), rhs = val
930
944
  warn "comparison '%s' after comparison", op
931
945
  result = new_call lhs, op.to_sym, argl(rhs)
932
946
  }
@@ -1117,8 +1131,9 @@ rule
1117
1131
  | backref
1118
1132
  | tFID
1119
1133
  {
1120
- msg, = val
1134
+ (msg, line), = val
1121
1135
  result = new_call nil, msg.to_sym
1136
+ result.line line
1122
1137
  }
1123
1138
  | k_begin
1124
1139
  {
@@ -1160,15 +1175,15 @@ rule
1160
1175
  }
1161
1176
  | primary_value tCOLON2 tCONSTANT
1162
1177
  {
1163
- expr, _, id = val
1178
+ expr, _, (id, _line) = val
1164
1179
 
1165
1180
  result = s(:colon2, expr, id.to_sym).line expr.line
1166
1181
  }
1167
1182
  | tCOLON3 tCONSTANT
1168
1183
  {
1169
- _, id = val
1184
+ _, (id, line) = val
1170
1185
 
1171
- result = s(:colon3, id.to_sym).line lexer.lineno
1186
+ result = s(:colon3, id.to_sym).line line
1172
1187
  }
1173
1188
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1174
1189
  {
@@ -1192,15 +1207,21 @@ rule
1192
1207
  }
1193
1208
  | kYIELD tLPAREN2 call_args rparen
1194
1209
  {
1195
- result = new_yield val[2]
1210
+ (_, line), _, args, _ = val
1211
+
1212
+ result = new_yield(args).line line
1196
1213
  }
1197
1214
  | kYIELD tLPAREN2 rparen
1198
1215
  {
1199
- result = new_yield
1216
+ (_, line), _, _ = val
1217
+
1218
+ result = new_yield.line line
1200
1219
  }
1201
1220
  | kYIELD
1202
1221
  {
1203
- result = new_yield
1222
+ (_, line), = val
1223
+
1224
+ result = new_yield.line line
1204
1225
  }
1205
1226
  | kDEFINED opt_nl tLPAREN2 expr rparen
1206
1227
  {
@@ -1215,7 +1236,7 @@ rule
1215
1236
  }
1216
1237
  | kNOT tLPAREN2 rparen
1217
1238
  {
1218
- debug20 14, val, result
1239
+ debug 20
1219
1240
  }
1220
1241
  | fcall brace_block
1221
1242
  {
@@ -1233,9 +1254,10 @@ rule
1233
1254
  iter.insert 1, call # FIX
1234
1255
  result = iter
1235
1256
  }
1236
- | tLAMBDA lambda
1257
+ | lambda
1237
1258
  {
1238
- result = val[1] # TODO: fix lineno
1259
+ expr, = val
1260
+ result = expr
1239
1261
  }
1240
1262
  | k_if expr_value then compstmt if_tail k_end
1241
1263
  {
@@ -1278,7 +1300,6 @@ rule
1278
1300
  }
1279
1301
  cpath superclass
1280
1302
  {
1281
- self.comments.push self.lexer.comments
1282
1303
  if (self.in_def || self.in_single > 0) then
1283
1304
  yyerror "class definition in method body"
1284
1305
  end
@@ -1288,7 +1309,7 @@ rule
1288
1309
  {
1289
1310
  result = new_class val
1290
1311
  self.env.unextend
1291
- self.lexer.comments # we don't care about comments in the body
1312
+ self.lexer.ignore_body_comments
1292
1313
  }
1293
1314
  | k_class tLSHFT
1294
1315
  {
@@ -1309,7 +1330,7 @@ rule
1309
1330
  {
1310
1331
  result = new_sclass val
1311
1332
  self.env.unextend
1312
- self.lexer.comments # we don't care about comments in the body
1333
+ self.lexer.ignore_body_comments
1313
1334
  }
1314
1335
  | k_module
1315
1336
  {
@@ -1317,7 +1338,6 @@ rule
1317
1338
  }
1318
1339
  cpath
1319
1340
  {
1320
- self.comments.push self.lexer.comments
1321
1341
  yyerror "module definition in method body" if
1322
1342
  self.in_def or self.in_single > 0
1323
1343
 
@@ -1327,7 +1347,7 @@ rule
1327
1347
  {
1328
1348
  result = new_module val
1329
1349
  self.env.unextend
1330
- self.lexer.comments # we don't care about comments in the body
1350
+ self.lexer.ignore_body_comments
1331
1351
  }
1332
1352
  | k_def fname
1333
1353
  {
@@ -1337,21 +1357,17 @@ rule
1337
1357
  self.env.extend
1338
1358
  lexer.cmdarg.push false
1339
1359
  lexer.cond.push false
1340
-
1341
- self.comments.push self.lexer.comments
1342
1360
  }
1343
- f_arglist bodystmt { result = lexer.lineno } k_end
1361
+ f_arglist bodystmt k_end
1344
1362
  {
1345
- in_def = val[2]
1346
-
1347
- result = new_defn val
1363
+ result, in_def = new_defn val
1348
1364
 
1349
1365
  lexer.cond.pop # group = local_pop
1350
1366
  lexer.cmdarg.pop
1351
1367
  self.env.unextend
1352
1368
  self.in_def = in_def
1353
1369
 
1354
- self.lexer.comments # we don't care about comments in the body
1370
+ self.lexer.ignore_body_comments
1355
1371
  }
1356
1372
  | k_def singleton dot_or_colon
1357
1373
  {
@@ -1359,7 +1375,7 @@ rule
1359
1375
  }
1360
1376
  fname
1361
1377
  {
1362
- result = [self.in_def, lexer.lineno]
1378
+ result = self.in_def
1363
1379
 
1364
1380
  self.in_single += 1 # TODO: remove?
1365
1381
 
@@ -1369,13 +1385,18 @@ rule
1369
1385
  lexer.cond.push false
1370
1386
 
1371
1387
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1372
- self.comments.push self.lexer.comments
1373
1388
  }
1374
1389
  f_arglist bodystmt k_end
1375
1390
  {
1376
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1377
1391
 
1378
- result = new_defs val
1392
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1393
+ # =>
1394
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1395
+
1396
+ val.delete_at 3
1397
+ val.delete_at 2
1398
+
1399
+ result, in_def = new_defs val
1379
1400
 
1380
1401
  lexer.cond.pop # group = local_pop
1381
1402
  lexer.cmdarg.pop
@@ -1386,7 +1407,7 @@ rule
1386
1407
 
1387
1408
  # TODO: restore cur_arg ? what's cur_arg?
1388
1409
 
1389
- self.lexer.comments # we don't care about comments in the body
1410
+ self.lexer.ignore_body_comments
1390
1411
  }
1391
1412
  | kBREAK
1392
1413
  {
@@ -1423,8 +1444,17 @@ rule
1423
1444
  k_case: kCASE
1424
1445
  k_for: kFOR
1425
1446
  k_class: kCLASS
1447
+ {
1448
+ self.comments.push self.lexer.comments
1449
+ }
1426
1450
  k_module: kMODULE
1451
+ {
1452
+ self.comments.push self.lexer.comments
1453
+ }
1427
1454
  k_def: kDEF
1455
+ {
1456
+ self.comments.push self.lexer.comments
1457
+ }
1428
1458
  k_do: kDO
1429
1459
  k_do_block: kDO_BLOCK
1430
1460
  k_rescue: kRESCUE
@@ -1485,51 +1515,42 @@ rule
1485
1515
 
1486
1516
  result = block_var args
1487
1517
  }
1488
- | f_marg_list tCOMMA tSTAR f_norm_arg
1518
+ | f_marg_list tCOMMA f_rest_marg
1489
1519
  {
1490
- args, _, _, splat = val
1520
+ args, _, rest = val
1491
1521
 
1492
- result = block_var args, "*#{splat}".to_sym
1522
+ result = block_var args, rest
1493
1523
  }
1494
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1524
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1495
1525
  {
1496
- args, _, _, splat, _, args2 = val
1526
+ lhs, _, splat, _, rhs = val
1497
1527
 
1498
- result = block_var args, "*#{splat}".to_sym, args2
1528
+ result = block_var lhs, splat, rhs
1499
1529
  }
1500
- | f_marg_list tCOMMA tSTAR
1530
+ | f_rest_marg
1501
1531
  {
1502
- args, _, _ = val
1532
+ rest, = val
1503
1533
 
1504
- result = block_var args, :*
1534
+ result = block_var rest
1505
1535
  }
1506
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1536
+ | f_rest_marg tCOMMA f_marg_list
1507
1537
  {
1508
- args, _, _, _, args2 = val
1538
+ splat, _, rest = val
1509
1539
 
1510
- result = block_var args, :*, args2
1540
+ result = block_var splat, rest
1511
1541
  }
1512
- | tSTAR f_norm_arg
1513
- {
1514
- _, splat = val
1515
1542
 
1516
- result = block_var :"*#{splat}"
1517
- }
1518
- | tSTAR f_norm_arg tCOMMA f_marg_list
1543
+ f_rest_marg: tSTAR f_norm_arg
1519
1544
  {
1520
- _, splat, _, args = val
1545
+ _, (id, line) = val
1521
1546
 
1522
- result = block_var :"*#{splat}", args
1547
+ result = args ["*#{id}".to_sym]
1548
+ result.line line
1523
1549
  }
1524
1550
  | tSTAR
1525
1551
  {
1526
- result = block_var :*
1527
- }
1528
- | tSTAR tCOMMA f_marg_list
1529
- {
1530
- _, _, args = val
1531
-
1532
- result = block_var :*, args
1552
+ result = args [:*]
1553
+ result.line lexer.lineno # FIX: tSTAR -> line
1533
1554
  }
1534
1555
 
1535
1556
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1546,8 +1567,8 @@ rule
1546
1567
  }
1547
1568
  | f_block_arg
1548
1569
  {
1549
- line = lexer.lineno
1550
- result = call_args val # TODO: push line down
1570
+ (id, line), = val
1571
+ result = call_args [id]
1551
1572
  result.line line
1552
1573
  }
1553
1574
 
@@ -1656,13 +1677,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1656
1677
 
1657
1678
  bvar: tIDENTIFIER
1658
1679
  {
1659
- id, = val
1660
- line = lexer.lineno
1680
+ (id, line), = val
1661
1681
  result = s(:shadow, id.to_sym).line line
1662
1682
  }
1663
1683
  | f_bad_arg
1664
1684
 
1665
- lambda: {
1685
+ lambda: tLAMBDA
1686
+ {
1666
1687
  self.env.extend :dynamic
1667
1688
  result = [lexer.lineno, lexer.lpar_beg]
1668
1689
  lexer.paren_nest += 1
@@ -1674,14 +1695,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1674
1695
  }
1675
1696
  lambda_body
1676
1697
  {
1677
- (line, lpar), args, _cmdarg, body = val
1698
+ _, (line, lpar), args, _cmdarg, body = val
1678
1699
  lexer.lpar_beg = lpar
1679
1700
 
1680
1701
  lexer.cmdarg.pop
1681
1702
 
1682
1703
  call = s(:lambda).line line
1683
1704
  result = new_iter call, args, body
1684
- result.line = line
1705
+ result.line line
1685
1706
  self.env.unextend # TODO: dynapush & dynapop
1686
1707
  }
1687
1708
 
@@ -1716,23 +1737,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1716
1737
  ## if (nd_type($1) == NODE_YIELD) {
1717
1738
  ## compile_error(PARSER_ARG "block given to yield");
1718
1739
 
1719
- syntax_error "Both block arg and actual block given." if
1720
- val[0].block_pass?
1740
+ cmd, blk = val
1721
1741
 
1722
- val = invert_block_call val if inverted? val
1742
+ syntax_error "Both block arg and actual block given." if
1743
+ cmd.block_pass?
1723
1744
 
1724
- cmd, blk = val
1745
+ if inverted? val then
1746
+ val = invert_block_call val
1747
+ cmd, blk = val
1748
+ end
1725
1749
 
1726
1750
  result = blk
1727
1751
  result.insert 1, cmd
1728
1752
  }
1729
1753
  | block_call call_op2 operation2 opt_paren_args
1730
1754
  {
1731
- result = new_call val[0], val[2].to_sym, val[3]
1755
+ lhs, _, (id, _line), args = val
1756
+
1757
+ result = new_call lhs, id.to_sym, args
1732
1758
  }
1733
1759
  | block_call call_op2 operation2 opt_paren_args brace_block
1734
1760
  {
1735
- iter1, _, name, args, iter2 = val
1761
+ iter1, _, (name, _line), args, iter2 = val
1736
1762
 
1737
1763
  call = new_call iter1, name.to_sym, args
1738
1764
  iter2.insert 1, call
@@ -1741,7 +1767,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1741
1767
  }
1742
1768
  | block_call call_op2 operation2 command_args do_block
1743
1769
  {
1744
- iter1, _, name, args, iter2 = val
1770
+ iter1, _, (name, _line), args, iter2 = val
1745
1771
 
1746
1772
  call = new_call iter1, name.to_sym, args
1747
1773
  iter2.insert 1, call
@@ -1749,28 +1775,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1749
1775
  result = iter2
1750
1776
  }
1751
1777
 
1752
- method_call: fcall
1753
- {
1754
- result = self.lexer.lineno
1755
- }
1756
- paren_args
1778
+ method_call: fcall paren_args
1757
1779
  {
1758
- call, lineno, args = val
1780
+ call, args = val
1759
1781
 
1760
1782
  result = call.concat args.sexp_body if args
1761
- result.line lineno
1762
1783
  }
1763
1784
  | primary_value call_op operation2 opt_paren_args
1764
1785
  {
1765
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1786
+ recv, call_op, (op, _line), args = val
1787
+
1788
+ result = new_call recv, op.to_sym, args, call_op
1766
1789
  }
1767
1790
  | primary_value tCOLON2 operation2 paren_args
1768
1791
  {
1769
- result = new_call val[0], val[2].to_sym, val[3]
1792
+ recv, _, (op, _line), args = val
1793
+
1794
+ result = new_call recv, op.to_sym, args
1770
1795
  }
1771
1796
  | primary_value tCOLON2 operation3
1772
1797
  {
1773
- result = new_call val[0], val[2].to_sym
1798
+ lhs, _, (id, _line) = val
1799
+
1800
+ result = new_call lhs, id.to_sym
1774
1801
  }
1775
1802
  | primary_value call_op paren_args
1776
1803
  {
@@ -1803,7 +1830,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1803
1830
  _, line, body, _ = val
1804
1831
 
1805
1832
  result = body
1806
- result.line = line
1833
+ result.line line
1807
1834
 
1808
1835
  self.env.unextend
1809
1836
  }
@@ -1817,7 +1844,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1817
1844
  _, line, body, _ = val
1818
1845
 
1819
1846
  result = body
1820
- result.line = line
1847
+ result.line line
1821
1848
 
1822
1849
  self.env.unextend
1823
1850
  }
@@ -1846,14 +1873,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1846
1873
  self.env.unextend
1847
1874
  }
1848
1875
 
1876
+ case_args: arg_value
1877
+ {
1878
+ arg, = val
1879
+
1880
+ result = s(:array, arg).line arg.line
1881
+ }
1882
+ | tSTAR arg_value
1883
+ {
1884
+ _, arg = val
1885
+
1886
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1887
+ }
1888
+ | case_args tCOMMA arg_value
1889
+ {
1890
+ args, _, id = val
1891
+
1892
+ result = self.list_append args, id
1893
+ }
1894
+ | case_args tCOMMA tSTAR arg_value
1895
+ {
1896
+ args, _, _, id = val
1897
+
1898
+ result = self.list_append args, s(:splat, id).line(id.line)
1899
+ }
1900
+
1849
1901
  case_body: k_when
1850
1902
  {
1851
1903
  result = self.lexer.lineno
1852
1904
  }
1853
- args then compstmt cases
1905
+ case_args then compstmt cases
1854
1906
  {
1855
1907
  result = new_when(val[2], val[4])
1856
- result.line = val[1]
1908
+ result.line val[1]
1857
1909
  result << val[5] if val[5]
1858
1910
  }
1859
1911
 
@@ -1899,17 +1951,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1899
1951
 
1900
1952
  literal: numeric
1901
1953
  {
1902
- line = lexer.lineno
1903
- result = s(:lit, val[0])
1904
- result.line = line
1954
+ (lit, line), = val
1955
+ result = s(:lit, lit).line line
1905
1956
  }
1906
1957
  | symbol
1907
- {
1908
- line = lexer.lineno
1909
- result = s(:lit, val[0])
1910
- result.line = line
1911
- }
1912
- | dsym
1913
1958
 
1914
1959
  strings: string
1915
1960
  {
@@ -1920,7 +1965,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1920
1965
 
1921
1966
  string: tCHAR
1922
1967
  {
1923
- debug20 23, val, result
1968
+ debug 37
1924
1969
  }
1925
1970
  | string1
1926
1971
  | string string1
@@ -1930,11 +1975,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1930
1975
 
1931
1976
  string1: tSTRING_BEG string_contents tSTRING_END
1932
1977
  {
1933
- _, str, (_, func) = val
1978
+ (_, line), str, (_, func) = val
1934
1979
 
1935
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1980
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1936
1981
 
1937
- result = str
1982
+ result = str.line line
1938
1983
  }
1939
1984
  | tSTRING
1940
1985
  {
@@ -1954,11 +1999,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1954
1999
 
1955
2000
  words: tWORDS_BEG tSPACE tSTRING_END
1956
2001
  {
1957
- result = s(:array).line lexer.lineno
2002
+ (_, line), _, _ = val
2003
+
2004
+ result = s(:array).line line
1958
2005
  }
1959
2006
  | tWORDS_BEG word_list tSTRING_END
1960
2007
  {
1961
- result = val[1]
2008
+ (_, line), list, _ = val
2009
+
2010
+ result = list.line line
1962
2011
  }
1963
2012
 
1964
2013
  word_list: none
@@ -1978,18 +2027,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1978
2027
 
1979
2028
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1980
2029
  {
1981
- result = s(:array).line lexer.lineno
2030
+ (_, line), _, _ = val
2031
+
2032
+ result = s(:array).line line
1982
2033
  }
1983
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2034
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1984
2035
  {
1985
- _, line, list, _, = val
1986
- list.line = line
2036
+ (_, line), list, _, = val
2037
+ list.line line
1987
2038
  result = list
1988
2039
  }
1989
2040
 
1990
2041
  symbol_list: none
1991
2042
  {
1992
- result = new_symbol_list.line lexer.lineno
2043
+ result = new_symbol_list
1993
2044
  }
1994
2045
  | symbol_list word tSPACE
1995
2046
  {
@@ -1999,20 +2050,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1999
2050
 
2000
2051
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2001
2052
  {
2002
- result = s(:array).line lexer.lineno
2053
+ (_, line), _, _ = val
2054
+
2055
+ result = s(:array).line line
2003
2056
  }
2004
2057
  | tQWORDS_BEG qword_list tSTRING_END
2005
2058
  {
2006
- result = val[1]
2059
+ (_, line), list, _ = val
2060
+
2061
+ result = list.line line
2007
2062
  }
2008
2063
 
2009
2064
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2010
2065
  {
2011
- result = s(:array).line lexer.lineno # FIX
2066
+ (_, line), _, _ = val
2067
+
2068
+ result = s(:array).line line
2012
2069
  }
2013
2070
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2014
2071
  {
2015
- result = val[1]
2072
+ (_, line), list, _ = val
2073
+
2074
+ result = list.line line
2016
2075
  }
2017
2076
 
2018
2077
  qword_list: none
@@ -2035,7 +2094,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2035
2094
 
2036
2095
  string_contents: none
2037
2096
  {
2038
- result = s(:str, "").line lexer.lineno
2097
+ line = prev_value_to_lineno _values.last
2098
+ result = s(:str, +"").line line
2039
2099
  }
2040
2100
  | string_contents string_content
2041
2101
  {
@@ -2110,8 +2170,8 @@ regexp_contents: none
2110
2170
  lexer.brace_nest = brace_nest
2111
2171
  lexer.string_nest = string_nest
2112
2172
 
2113
- lexer.cmdarg.pop
2114
2173
  lexer.cond.pop
2174
+ lexer.cmdarg.pop
2115
2175
 
2116
2176
  lexer.lex_state = oldlex_state
2117
2177
 
@@ -2126,29 +2186,49 @@ regexp_contents: none
2126
2186
  when nil then
2127
2187
  result = s(:evstr).line line
2128
2188
  else
2129
- debug20 25
2189
+ debug 38
2130
2190
  raise "unknown string body: #{stmt.inspect}"
2131
2191
  end
2132
2192
  }
2133
2193
 
2134
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2135
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2136
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2194
+ string_dvar: tGVAR
2195
+ {
2196
+ (id, line), = val
2197
+ result = s(:gvar, id.to_sym).line line
2198
+ }
2199
+ | tIVAR
2200
+ {
2201
+ (id, line), = val
2202
+ result = s(:ivar, id.to_sym).line line
2203
+ }
2204
+ | tCVAR
2205
+ {
2206
+ (id, line), = val
2207
+ result = s(:cvar, id.to_sym).line line
2208
+ }
2137
2209
  | backref
2138
2210
 
2139
- symbol: tSYMBEG sym
2211
+ symbol: ssym
2212
+ | dsym
2213
+
2214
+ ssym: tSYMBEG sym
2140
2215
  {
2216
+ _, (id, line) = val
2217
+
2141
2218
  lexer.lex_state = EXPR_END
2142
- result = val[1].to_sym
2219
+ result = s(:lit, id.to_sym).line line
2143
2220
  }
2144
2221
  | tSYMBOL
2145
2222
  {
2146
- result = val[0].to_sym
2223
+ (id, line), = val
2224
+
2225
+ lexer.lex_state = EXPR_END
2226
+ result = s(:lit, id.to_sym).line line
2147
2227
  }
2148
2228
 
2149
2229
  sym: fname | tIVAR | tGVAR | tCVAR
2150
2230
 
2151
- dsym: tSYMBEG xstring_contents tSTRING_END
2231
+ dsym: tSYMBEG string_contents tSTRING_END
2152
2232
  {
2153
2233
  _, result, _ = val
2154
2234
 
@@ -2164,14 +2244,15 @@ regexp_contents: none
2164
2244
  when :evstr then
2165
2245
  result = s(:dsym, "", result).line result.line
2166
2246
  else
2167
- debug20 26, val, result
2247
+ debug 39
2168
2248
  end
2169
2249
  }
2170
2250
 
2171
2251
  numeric: simple_numeric
2172
- | tUMINUS_NUM simple_numeric
2252
+ | tUMINUS_NUM simple_numeric =tLOWEST
2173
2253
  {
2174
- result = -val[1] # TODO: pt_testcase
2254
+ _, (num, line) = val
2255
+ result = [-num, line]
2175
2256
  }
2176
2257
 
2177
2258
  simple_numeric: tINTEGER
@@ -2204,8 +2285,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2204
2285
 
2205
2286
  var_ref: user_variable
2206
2287
  {
2207
- var = val[0]
2288
+ raise "NO: #{val.inspect}" if Sexp === val.first
2289
+ (var, line), = val
2208
2290
  result = Sexp === var ? var : self.gettable(var)
2291
+ result.line line
2209
2292
  }
2210
2293
  | keyword_variable
2211
2294
  {
@@ -2220,11 +2303,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2220
2303
  | keyword_variable
2221
2304
  {
2222
2305
  result = self.assignable val[0]
2223
- debug20 29, val, result
2306
+ debug 40
2224
2307
  }
2225
2308
 
2226
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2227
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2309
+ backref: tNTH_REF
2310
+ {
2311
+ (ref, line), = val
2312
+ result = s(:nth_ref, ref).line line
2313
+ }
2314
+ | tBACK_REF
2315
+ {
2316
+ (ref, line), = val
2317
+ result = s(:back_ref, ref).line line
2318
+ }
2228
2319
 
2229
2320
  superclass: tLT
2230
2321
  {
@@ -2242,9 +2333,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2242
2333
 
2243
2334
  f_arglist: tLPAREN2 f_args rparen
2244
2335
  {
2245
- result = val[1]
2246
- self.lexer.lex_state = EXPR_BEG
2247
- self.lexer.command_start = true
2336
+ result = end_args val
2248
2337
  }
2249
2338
  | {
2250
2339
  result = self.in_kwarg
@@ -2253,12 +2342,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2253
2342
  }
2254
2343
  f_args term
2255
2344
  {
2256
- kwarg, args, _ = val
2257
-
2258
- self.in_kwarg = kwarg
2259
- result = args
2260
- lexer.lex_state = EXPR_BEG
2261
- lexer.command_start = true
2345
+ result = end_args val
2262
2346
  }
2263
2347
 
2264
2348
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2343,8 +2427,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2343
2427
  |
2344
2428
  {
2345
2429
  result = args val
2430
+ # result.line lexer.lineno
2346
2431
  }
2347
2432
 
2433
+
2348
2434
  f_bad_arg: tCONSTANT
2349
2435
  {
2350
2436
  yyerror "formal argument cannot be a constant"
@@ -2365,10 +2451,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2365
2451
  f_norm_arg: f_bad_arg
2366
2452
  | tIDENTIFIER
2367
2453
  {
2368
- identifier = val[0].to_sym
2454
+ (id, line), = val
2455
+ identifier = id.to_sym
2369
2456
  self.env[identifier] = :lvar
2370
2457
 
2371
- result = identifier
2458
+ result = [identifier, line]
2372
2459
  }
2373
2460
 
2374
2461
  f_arg_asgn: f_norm_arg
@@ -2376,22 +2463,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2376
2463
  f_arg_item: f_arg_asgn
2377
2464
  | tLPAREN f_margs rparen
2378
2465
  {
2379
- result = val[1]
2466
+ _, margs, _ = val
2467
+
2468
+ result = margs
2380
2469
  }
2381
2470
 
2382
2471
  f_arg: f_arg_item
2383
2472
  {
2384
- arg, = val
2385
-
2386
- case arg
2387
- when Symbol then
2388
- result = s(:args, arg).line lexer.lineno
2389
- when Sexp then
2390
- result = arg
2391
- else
2392
- debug20 32
2393
- raise "Unknown f_arg type: #{val.inspect}"
2394
- end
2473
+ result = new_arg val
2395
2474
  }
2396
2475
  | f_arg tCOMMA f_arg_item
2397
2476
  {
@@ -2403,7 +2482,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2403
2482
  result = s(:args, list).line list.line
2404
2483
  end
2405
2484
 
2406
- result << item
2485
+ result << (Sexp === item ? item : item.first)
2407
2486
  }
2408
2487
 
2409
2488
  f_label: tLABEL
@@ -2464,26 +2543,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2464
2543
  kwrest_mark: tPOW
2465
2544
  | tDSTAR
2466
2545
 
2546
+
2467
2547
  f_kwrest: kwrest_mark tIDENTIFIER
2468
2548
  {
2469
- name = val[1].to_sym
2470
- self.assignable name
2471
- result = :"**#{name}"
2549
+ _, (id, line) = val
2550
+
2551
+ name = id.to_sym
2552
+ self.assignable [name, line]
2553
+ result = [:"**#{name}", line]
2472
2554
  }
2473
2555
  | kwrest_mark
2474
2556
  {
2475
- result = :"**"
2557
+ id = :"**"
2558
+ self.env[id] = :lvar # TODO: needed?!?
2559
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2476
2560
  }
2477
2561
 
2478
2562
  f_opt: f_arg_asgn tEQL arg_value
2479
2563
  {
2480
- result = self.assignable val[0], val[2]
2564
+ lhs, _, rhs = val
2565
+ result = self.assignable lhs, rhs
2481
2566
  # TODO: detect duplicate names
2482
2567
  }
2483
2568
 
2484
2569
  f_block_opt: f_arg_asgn tEQL primary_value
2485
2570
  {
2486
- result = self.assignable val[0], val[2]
2571
+ lhs, _, rhs = val
2572
+ result = self.assignable lhs, rhs
2487
2573
  }
2488
2574
 
2489
2575
  f_block_optarg: f_block_opt
@@ -2513,30 +2599,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2513
2599
  f_rest_arg: restarg_mark tIDENTIFIER
2514
2600
  {
2515
2601
  # TODO: differs from parse.y - needs tests
2516
- name = val[1].to_sym
2517
- self.assignable name
2518
- result = :"*#{name}"
2602
+ _, (id, line) = val
2603
+ name = id.to_sym
2604
+ self.assignable [name, line]
2605
+ result = [:"*#{name}", line]
2519
2606
  }
2520
2607
  | restarg_mark
2521
2608
  {
2522
2609
  name = :"*"
2523
2610
  self.env[name] = :lvar
2524
- result = name
2611
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2525
2612
  }
2526
2613
 
2527
2614
  blkarg_mark: tAMPER2 | tAMPER
2528
2615
 
2529
2616
  f_block_arg: blkarg_mark tIDENTIFIER
2530
2617
  {
2531
- identifier = val[1].to_sym
2618
+ _, (id, line) = val
2619
+ identifier = id.to_sym
2532
2620
 
2533
2621
  self.env[identifier] = :lvar
2534
- result = "&#{identifier}".to_sym
2622
+ result = ["&#{identifier}".to_sym, line]
2535
2623
  }
2536
2624
 
2537
2625
  opt_f_block_arg: tCOMMA f_block_arg
2538
2626
  {
2539
- result = val[1]
2627
+ _, arg = val
2628
+ result = arg
2540
2629
  }
2541
2630
  |
2542
2631
  {
@@ -2585,9 +2674,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2585
2674
  }
2586
2675
  | tSTRING_BEG string_contents tLABEL_END arg_value
2587
2676
  {
2588
- _, sym, _, value = val
2677
+ (_, line), sym, _, value = val
2678
+
2589
2679
  sym.sexp_type = :dsym
2590
- result = s(:array, sym, value).line sym.line
2680
+
2681
+ result = s(:array, sym, value).line line
2591
2682
  }
2592
2683
  | tDSTAR arg_value
2593
2684
  {