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