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