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