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