ruby_parser 3.15.0 → 3.18.0

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