ruby_parser 3.17.0 → 3.19.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.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +109 -0
  4. data/Manifest.txt +5 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +85 -24
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +6 -1
  9. data/gauntlet.md +108 -0
  10. data/lib/rp_extensions.rb +15 -36
  11. data/lib/rp_stringscanner.rb +20 -51
  12. data/lib/ruby20_parser.rb +7430 -3528
  13. data/lib/ruby20_parser.y +328 -257
  14. data/lib/ruby21_parser.rb +7408 -3572
  15. data/lib/ruby21_parser.y +323 -254
  16. data/lib/ruby22_parser.rb +7543 -3601
  17. data/lib/ruby22_parser.y +327 -256
  18. data/lib/ruby23_parser.rb +7549 -3612
  19. data/lib/ruby23_parser.y +327 -256
  20. data/lib/ruby24_parser.rb +7640 -3624
  21. data/lib/ruby24_parser.y +327 -256
  22. data/lib/ruby25_parser.rb +7640 -3623
  23. data/lib/ruby25_parser.y +327 -256
  24. data/lib/ruby26_parser.rb +7649 -3632
  25. data/lib/ruby26_parser.y +326 -255
  26. data/lib/ruby27_parser.rb +10132 -4545
  27. data/lib/ruby27_parser.y +871 -262
  28. data/lib/ruby30_parser.rb +10504 -4655
  29. data/lib/ruby30_parser.y +1065 -333
  30. data/lib/ruby31_parser.rb +13622 -0
  31. data/lib/ruby31_parser.y +3481 -0
  32. data/lib/ruby3_parser.yy +3536 -0
  33. data/lib/ruby_lexer.rb +261 -609
  34. data/lib/ruby_lexer.rex +27 -20
  35. data/lib/ruby_lexer.rex.rb +59 -23
  36. data/lib/ruby_lexer_strings.rb +638 -0
  37. data/lib/ruby_parser.rb +2 -0
  38. data/lib/ruby_parser.yy +903 -272
  39. data/lib/ruby_parser_extras.rb +333 -113
  40. data/test/test_ruby_lexer.rb +181 -129
  41. data/test/test_ruby_parser.rb +1529 -288
  42. data/tools/munge.rb +34 -6
  43. data/tools/ripper.rb +15 -10
  44. data.tar.gz.sig +0 -0
  45. metadata +27 -23
  46. metadata.gz.sig +0 -0
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
@@ -77,7 +77,7 @@ rule
77
77
  | klBEGIN
78
78
  {
79
79
  if (self.in_def || self.in_single > 0) then
80
- debug20 1
80
+ debug 11
81
81
  yyerror "BEGIN in method"
82
82
  end
83
83
  self.env.extend
@@ -102,7 +102,9 @@ rule
102
102
  bodystmt: compstmt opt_rescue k_else
103
103
  {
104
104
  res = _values[-2]
105
- 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
106
108
  }
107
109
  compstmt
108
110
  opt_ensure
@@ -132,7 +134,7 @@ rule
132
134
  | error stmt
133
135
  {
134
136
  result = val[1]
135
- debug20 2, val, result
137
+ debug 12
136
138
  }
137
139
 
138
140
  stmt_or_begin: stmt
@@ -140,6 +142,10 @@ rule
140
142
  {
141
143
  yyerror "BEGIN is permitted only at toplevel"
142
144
  }
145
+ begin_block
146
+ {
147
+ result = val[2] # wtf?
148
+ }
143
149
 
144
150
  stmt: kALIAS fitem
145
151
  {
@@ -152,12 +158,12 @@ rule
152
158
  }
153
159
  | kALIAS tGVAR tGVAR
154
160
  {
155
- (_, line), lhs, rhs = val
161
+ (_, line), (lhs, _), (rhs, _) = val
156
162
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
157
163
  }
158
164
  | kALIAS tGVAR tBACK_REF
159
165
  {
160
- (_, line), lhs, rhs = val
166
+ (_, line), (lhs, _), (rhs, _) = val
161
167
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
162
168
  }
163
169
  | kALIAS tGVAR tNTH_REF
@@ -200,7 +206,7 @@ rule
200
206
  (_, line), _, stmt, _ = val
201
207
 
202
208
  if (self.in_def || self.in_single > 0) then
203
- debug20 3
209
+ debug 13
204
210
  yyerror "END in method; use at_exit"
205
211
  end
206
212
 
@@ -240,32 +246,31 @@ rule
240
246
  }
241
247
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
242
248
  {
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
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
249
254
  }
250
255
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
251
256
  {
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
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
257
262
  }
258
263
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
259
264
  {
260
- lhs1, _, lhs2, op, rhs = val
265
+ lhs1, _, (lhs2, line), (id, _), rhs = val
261
266
 
262
- 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
263
268
  }
264
269
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
265
270
  {
266
- lhs1, _, lhs2, op, rhs = val
271
+ lhs1, _, (lhs2, line), (id, _), rhs = val
267
272
 
268
- 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
269
274
  }
270
275
  | backref tOP_ASGN command_rhs
271
276
  {
@@ -303,7 +308,7 @@ rule
303
308
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
304
309
  # REFACTOR: call_uni_op -- see parse26.y
305
310
  }
306
- | arg
311
+ | arg =tLBRACE_ARG
307
312
 
308
313
  expr_value: expr
309
314
  {
@@ -328,7 +333,7 @@ rule
328
333
  block_command: block_call
329
334
  | block_call call_op2 operation2 command_args
330
335
  {
331
- blk, _, msg, args = val
336
+ blk, _, (msg, _line), args = val
332
337
  result = new_call(blk, msg.to_sym, args).line blk.line
333
338
  }
334
339
 
@@ -342,15 +347,15 @@ rule
342
347
  _, line, body, _ = val
343
348
 
344
349
  result = body
345
- result.line = line
350
+ result.line line
346
351
 
347
352
  # self.env.unextend
348
353
  }
349
354
 
350
355
  fcall: operation
351
356
  {
352
- msg, = val
353
- result = new_call(nil, msg.to_sym).line lexer.lineno
357
+ (msg, line), = val
358
+ result = new_call(nil, msg.to_sym).line line
354
359
  }
355
360
 
356
361
  command: fcall command_args =tLOWEST
@@ -373,12 +378,14 @@ rule
373
378
  }
374
379
  | primary_value call_op operation2 command_args =tLOWEST
375
380
  {
376
- lhs, callop, op, args = val
381
+ lhs, callop, (op, _), args = val
382
+
377
383
  result = new_call lhs, op.to_sym, args, callop
384
+ result.line lhs.line
378
385
  }
379
386
  | primary_value call_op operation2 command_args cmd_brace_block
380
387
  {
381
- recv, _, msg, args, block = val
388
+ recv, _, (msg, _line), args, block = val
382
389
  call = new_call recv, msg.to_sym, args, val[1]
383
390
 
384
391
  block_dup_check call, block
@@ -388,11 +395,14 @@ rule
388
395
  }
389
396
  | primary_value tCOLON2 operation2 command_args =tLOWEST
390
397
  {
391
- 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
392
402
  }
393
403
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
394
404
  {
395
- recv, _, msg, args, block = val
405
+ recv, _, (msg, _line), args, block = val
396
406
  call = new_call recv, msg.to_sym, args
397
407
 
398
408
  block_dup_check call, block
@@ -550,25 +560,29 @@ rule
550
560
  }
551
561
  | primary_value call_op tIDENTIFIER
552
562
  {
553
- 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
554
566
  }
555
567
  | primary_value tCOLON2 tIDENTIFIER
556
568
  {
557
- recv, _, id = val
569
+ recv, _, (id, _line) = val
558
570
  result = new_attrasgn recv, id
559
571
  }
560
572
  | primary_value call_op tCONSTANT
561
573
  {
562
- 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
563
577
  }
564
578
  | primary_value tCOLON2 tCONSTANT
565
579
  {
566
580
  if (self.in_def || self.in_single > 0) then
567
- debug20 7
581
+ debug 14
568
582
  yyerror "dynamic constant assignment"
569
583
  end
570
584
 
571
- expr, _, id = val
585
+ expr, _, (id, _line) = val
572
586
  l = expr.line
573
587
 
574
588
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -576,58 +590,65 @@ rule
576
590
  | tCOLON3 tCONSTANT
577
591
  {
578
592
  if (self.in_def || self.in_single > 0) then
579
- debug20 8
593
+ debug 15
580
594
  yyerror "dynamic constant assignment"
581
595
  end
582
596
 
583
- _, id = val
584
- l = lexer.lineno
597
+ _, (id, l) = val
585
598
 
586
599
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
587
600
  }
588
601
  | backref
589
602
  {
590
- self.backref_assign_error val[0]
603
+ ref, = val
604
+
605
+ self.backref_assign_error ref
591
606
  }
592
607
 
593
608
  lhs: user_variable
594
609
  {
595
- line = lexer.lineno
596
- result = self.assignable val[0]
597
- result.line = line
610
+ var, = val
611
+
612
+ result = self.assignable var
598
613
  }
599
614
  | keyword_variable
600
615
  {
601
- line = lexer.lineno
602
- result = self.assignable val[0]
603
- result.line = line
604
- debug20 9, val, result
616
+ var, = val
617
+
618
+ result = self.assignable var
619
+
620
+ debug 16
605
621
  }
606
622
  | primary_value tLBRACK2 opt_call_args rbracket
607
623
  {
608
624
  lhs, _, args, _ = val
625
+
609
626
  result = self.aryset lhs, args
610
627
  }
611
628
  | primary_value call_op tIDENTIFIER # REFACTOR
612
629
  {
613
- lhs, op, id = val
630
+ lhs, op, (id, _line) = val
631
+
614
632
  result = new_attrasgn lhs, id, op
615
633
  }
616
634
  | primary_value tCOLON2 tIDENTIFIER
617
635
  {
618
- lhs, _, id = val
636
+ lhs, _, (id, _line) = val
637
+
619
638
  result = new_attrasgn lhs, id
620
639
  }
621
640
  | primary_value call_op tCONSTANT # REFACTOR?
622
641
  {
623
- 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
624
645
  }
625
646
  | primary_value tCOLON2 tCONSTANT
626
647
  {
627
- expr, _, id = val
648
+ expr, _, (id, _line) = val
628
649
 
629
650
  if (self.in_def || self.in_single > 0) then
630
- debug20 10
651
+ debug 17
631
652
  yyerror "dynamic constant assignment"
632
653
  end
633
654
 
@@ -636,14 +657,13 @@ rule
636
657
  }
637
658
  | tCOLON3 tCONSTANT
638
659
  {
639
- _, id = val
660
+ _, (id, l) = val
640
661
 
641
662
  if (self.in_def || self.in_single > 0) then
642
- debug20 11
663
+ debug 18
643
664
  yyerror "dynamic constant assignment"
644
665
  end
645
666
 
646
- l = lexer.lineno
647
667
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
648
668
  }
649
669
  | backref
@@ -659,16 +679,16 @@ rule
659
679
 
660
680
  cpath: tCOLON3 cname
661
681
  {
662
- _, name = val
663
- result = s(:colon3, name.to_sym).line lexer.lineno
682
+ result = wrap :colon3, val[1]
664
683
  }
665
684
  | cname
666
685
  {
667
- result = val[0].to_sym
686
+ (id, line), = val
687
+ result = [id.to_sym, line] # TODO: sexp?
668
688
  }
669
689
  | primary_value tCOLON2 cname
670
690
  {
671
- pval, _, name = val
691
+ pval, _, (name, _line) = val
672
692
 
673
693
  result = s(:colon2, pval, name.to_sym)
674
694
  result.line pval.line
@@ -678,24 +698,15 @@ rule
678
698
  | op
679
699
  {
680
700
  lexer.lex_state = EXPR_END
681
- result = val[0]
682
701
  }
683
702
 
684
703
  | reswords
685
- {
686
- (sym, _line), = val
687
- lexer.lex_state = EXPR_END
688
- result = sym
689
- }
690
-
691
- fsym: fname | symbol
692
704
 
693
- fitem: fsym
705
+ fitem: fname
694
706
  {
695
- id, = val
696
- result = s(:lit, id.to_sym).line lexer.lineno
707
+ result = wrap :lit, val[0]
697
708
  }
698
- | dsym
709
+ | symbol
699
710
 
700
711
  undef_list: fitem
701
712
  {
@@ -716,8 +727,6 @@ rule
716
727
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
717
728
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
718
729
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
719
- # TODO: tUBANG dead?
720
- | tUBANG
721
730
 
722
731
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
723
732
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -751,26 +760,22 @@ rule
751
760
  }
752
761
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
753
762
  {
754
- lhs, _, id, op, rhs = val
763
+ lhs, _, (id, _line), (op, _), rhs = val
755
764
 
756
765
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
757
766
  }
758
767
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
759
768
  {
760
- lhs1, _, lhs2, op, rhs = val
769
+ lhs1, _, (lhs2, _line), op, rhs = val
761
770
 
762
771
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
763
772
  result = new_const_op_asgn [lhs, op, rhs]
764
773
  }
765
- | tCOLON3 tCONSTANT
766
- {
767
- result = self.lexer.lineno
768
- }
769
- tOP_ASGN arg_rhs
774
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
770
775
  {
771
- _, lhs, line, op, rhs = val
776
+ _, lhs, op, rhs = val
772
777
 
773
- lhs = s(:colon3, lhs.to_sym).line line
778
+ lhs = wrap :colon3, lhs
774
779
  result = new_const_op_asgn [lhs, op, rhs]
775
780
  }
776
781
  | backref tOP_ASGN arg_rhs
@@ -782,7 +787,7 @@ rule
782
787
  | arg tDOT2 arg
783
788
  {
784
789
  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
790
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
786
791
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
787
792
  else
788
793
  result = s(:dot2, v1, v2).line v1.line
@@ -791,7 +796,7 @@ rule
791
796
  | arg tDOT3 arg
792
797
  {
793
798
  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
799
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
795
800
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
796
801
  else
797
802
  result = s(:dot3, v1, v2).line v1.line
@@ -825,8 +830,9 @@ rule
825
830
  }
826
831
  | tUMINUS_NUM simple_numeric tPOW arg
827
832
  {
828
- lit = s(:lit, val[1]).line lexer.lineno
829
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
833
+ _, (num, line), _, arg = val
834
+ lit = s(:lit, num).line line
835
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
830
836
 
831
837
  }
832
838
  | tUPLUS arg
@@ -925,12 +931,12 @@ rule
925
931
 
926
932
  rel_expr: arg relop arg =tGT
927
933
  {
928
- lhs, op, rhs = val
934
+ lhs, (op, _), rhs = val
929
935
  result = new_call lhs, op.to_sym, argl(rhs)
930
936
  }
931
937
  | rel_expr relop arg =tGT
932
938
  {
933
- lhs, op, rhs = val
939
+ lhs, (op, _), rhs = val
934
940
  warn "comparison '%s' after comparison", op
935
941
  result = new_call lhs, op.to_sym, argl(rhs)
936
942
  }
@@ -1121,8 +1127,9 @@ rule
1121
1127
  | backref
1122
1128
  | tFID
1123
1129
  {
1124
- msg, = val
1130
+ (msg, line), = val
1125
1131
  result = new_call nil, msg.to_sym
1132
+ result.line line
1126
1133
  }
1127
1134
  | k_begin
1128
1135
  {
@@ -1164,15 +1171,13 @@ rule
1164
1171
  }
1165
1172
  | primary_value tCOLON2 tCONSTANT
1166
1173
  {
1167
- expr, _, id = val
1174
+ expr, _, (id, _line) = val
1168
1175
 
1169
1176
  result = s(:colon2, expr, id.to_sym).line expr.line
1170
1177
  }
1171
1178
  | tCOLON3 tCONSTANT
1172
1179
  {
1173
- _, id = val
1174
-
1175
- result = s(:colon3, id.to_sym).line lexer.lineno
1180
+ result = wrap :colon3, val[1]
1176
1181
  }
1177
1182
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1178
1183
  {
@@ -1196,15 +1201,21 @@ rule
1196
1201
  }
1197
1202
  | kYIELD tLPAREN2 call_args rparen
1198
1203
  {
1199
- result = new_yield val[2]
1204
+ (_, line), _, args, _ = val
1205
+
1206
+ result = new_yield(args).line line
1200
1207
  }
1201
1208
  | kYIELD tLPAREN2 rparen
1202
1209
  {
1203
- result = new_yield
1210
+ (_, line), _, _ = val
1211
+
1212
+ result = new_yield.line line
1204
1213
  }
1205
1214
  | kYIELD
1206
1215
  {
1207
- result = new_yield
1216
+ (_, line), = val
1217
+
1218
+ result = new_yield.line line
1208
1219
  }
1209
1220
  | kDEFINED opt_nl tLPAREN2 expr rparen
1210
1221
  {
@@ -1219,7 +1230,7 @@ rule
1219
1230
  }
1220
1231
  | kNOT tLPAREN2 rparen
1221
1232
  {
1222
- debug20 14, val, result
1233
+ debug 20
1223
1234
  }
1224
1235
  | fcall brace_block
1225
1236
  {
@@ -1237,9 +1248,10 @@ rule
1237
1248
  iter.insert 1, call # FIX
1238
1249
  result = iter
1239
1250
  }
1240
- | tLAMBDA lambda
1251
+ | lambda
1241
1252
  {
1242
- result = val[1] # TODO: fix lineno
1253
+ expr, = val
1254
+ result = expr
1243
1255
  }
1244
1256
  | k_if expr_value then compstmt if_tail k_end
1245
1257
  {
@@ -1282,7 +1294,6 @@ rule
1282
1294
  }
1283
1295
  cpath superclass
1284
1296
  {
1285
- self.comments.push self.lexer.comments
1286
1297
  if (self.in_def || self.in_single > 0) then
1287
1298
  yyerror "class definition in method body"
1288
1299
  end
@@ -1292,7 +1303,7 @@ rule
1292
1303
  {
1293
1304
  result = new_class val
1294
1305
  self.env.unextend
1295
- self.lexer.comments # we don't care about comments in the body
1306
+ self.lexer.ignore_body_comments
1296
1307
  }
1297
1308
  | k_class tLSHFT
1298
1309
  {
@@ -1313,7 +1324,7 @@ rule
1313
1324
  {
1314
1325
  result = new_sclass val
1315
1326
  self.env.unextend
1316
- self.lexer.comments # we don't care about comments in the body
1327
+ self.lexer.ignore_body_comments
1317
1328
  }
1318
1329
  | k_module
1319
1330
  {
@@ -1321,7 +1332,6 @@ rule
1321
1332
  }
1322
1333
  cpath
1323
1334
  {
1324
- self.comments.push self.lexer.comments
1325
1335
  yyerror "module definition in method body" if
1326
1336
  self.in_def or self.in_single > 0
1327
1337
 
@@ -1331,7 +1341,7 @@ rule
1331
1341
  {
1332
1342
  result = new_module val
1333
1343
  self.env.unextend
1334
- self.lexer.comments # we don't care about comments in the body
1344
+ self.lexer.ignore_body_comments
1335
1345
  }
1336
1346
  | k_def fname
1337
1347
  {
@@ -1341,21 +1351,17 @@ rule
1341
1351
  self.env.extend
1342
1352
  lexer.cmdarg.push false
1343
1353
  lexer.cond.push false
1344
-
1345
- self.comments.push self.lexer.comments
1346
1354
  }
1347
- f_arglist bodystmt { result = lexer.lineno } k_end
1355
+ f_arglist bodystmt k_end
1348
1356
  {
1349
- in_def = val[2]
1350
-
1351
- result = new_defn val
1357
+ result, in_def = new_defn val
1352
1358
 
1353
1359
  lexer.cond.pop # group = local_pop
1354
1360
  lexer.cmdarg.pop
1355
1361
  self.env.unextend
1356
1362
  self.in_def = in_def
1357
1363
 
1358
- self.lexer.comments # we don't care about comments in the body
1364
+ self.lexer.ignore_body_comments
1359
1365
  }
1360
1366
  | k_def singleton dot_or_colon
1361
1367
  {
@@ -1363,7 +1369,7 @@ rule
1363
1369
  }
1364
1370
  fname
1365
1371
  {
1366
- result = [self.in_def, lexer.lineno]
1372
+ result = self.in_def
1367
1373
 
1368
1374
  self.in_single += 1 # TODO: remove?
1369
1375
 
@@ -1373,13 +1379,18 @@ rule
1373
1379
  lexer.cond.push false
1374
1380
 
1375
1381
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1376
- self.comments.push self.lexer.comments
1377
1382
  }
1378
1383
  f_arglist bodystmt k_end
1379
1384
  {
1380
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1381
1385
 
1382
- 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
1383
1394
 
1384
1395
  lexer.cond.pop # group = local_pop
1385
1396
  lexer.cmdarg.pop
@@ -1390,7 +1401,7 @@ rule
1390
1401
 
1391
1402
  # TODO: restore cur_arg ? what's cur_arg?
1392
1403
 
1393
- self.lexer.comments # we don't care about comments in the body
1404
+ self.lexer.ignore_body_comments
1394
1405
  }
1395
1406
  | kBREAK
1396
1407
  {
@@ -1427,8 +1438,17 @@ rule
1427
1438
  k_case: kCASE
1428
1439
  k_for: kFOR
1429
1440
  k_class: kCLASS
1441
+ {
1442
+ self.comments.push self.lexer.comments
1443
+ }
1430
1444
  k_module: kMODULE
1445
+ {
1446
+ self.comments.push self.lexer.comments
1447
+ }
1431
1448
  k_def: kDEF
1449
+ {
1450
+ self.comments.push self.lexer.comments
1451
+ }
1432
1452
  k_do: kDO
1433
1453
  k_do_block: kDO_BLOCK
1434
1454
  k_rescue: kRESCUE
@@ -1489,51 +1509,42 @@ rule
1489
1509
 
1490
1510
  result = block_var args
1491
1511
  }
1492
- | f_marg_list tCOMMA tSTAR f_norm_arg
1512
+ | f_marg_list tCOMMA f_rest_marg
1493
1513
  {
1494
- args, _, _, splat = val
1514
+ args, _, rest = val
1495
1515
 
1496
- result = block_var args, "*#{splat}".to_sym
1516
+ result = block_var args, rest
1497
1517
  }
1498
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1518
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1499
1519
  {
1500
- args, _, _, splat, _, args2 = val
1520
+ lhs, _, splat, _, rhs = val
1501
1521
 
1502
- result = block_var args, "*#{splat}".to_sym, args2
1522
+ result = block_var lhs, splat, rhs
1503
1523
  }
1504
- | f_marg_list tCOMMA tSTAR
1524
+ | f_rest_marg
1505
1525
  {
1506
- args, _, _ = val
1526
+ rest, = val
1507
1527
 
1508
- result = block_var args, :*
1528
+ result = block_var rest
1509
1529
  }
1510
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1530
+ | f_rest_marg tCOMMA f_marg_list
1511
1531
  {
1512
- args, _, _, _, args2 = val
1532
+ splat, _, rest = val
1513
1533
 
1514
- result = block_var args, :*, args2
1534
+ result = block_var splat, rest
1515
1535
  }
1516
- | tSTAR f_norm_arg
1517
- {
1518
- _, splat = val
1519
1536
 
1520
- result = block_var :"*#{splat}"
1521
- }
1522
- | tSTAR f_norm_arg tCOMMA f_marg_list
1537
+ f_rest_marg: tSTAR f_norm_arg
1523
1538
  {
1524
- _, splat, _, args = val
1539
+ _, (id, line) = val
1525
1540
 
1526
- result = block_var :"*#{splat}", args
1541
+ result = args ["*#{id}".to_sym]
1542
+ result.line line
1527
1543
  }
1528
1544
  | tSTAR
1529
1545
  {
1530
- result = block_var :*
1531
- }
1532
- | tSTAR tCOMMA f_marg_list
1533
- {
1534
- _, _, args = val
1535
-
1536
- result = block_var :*, args
1546
+ result = args [:*]
1547
+ result.line lexer.lineno # FIX: tSTAR -> line
1537
1548
  }
1538
1549
 
1539
1550
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1550,8 +1561,8 @@ rule
1550
1561
  }
1551
1562
  | f_block_arg
1552
1563
  {
1553
- line = lexer.lineno
1554
- result = call_args val # TODO: push line down
1564
+ (id, line), = val
1565
+ result = call_args [id]
1555
1566
  result.line line
1556
1567
  }
1557
1568
 
@@ -1660,13 +1671,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1660
1671
 
1661
1672
  bvar: tIDENTIFIER
1662
1673
  {
1663
- id, = val
1664
- line = lexer.lineno
1665
- result = s(:shadow, id.to_sym).line line
1674
+ result = wrap :shadow, val[0]
1666
1675
  }
1667
1676
  | f_bad_arg
1668
1677
 
1669
- lambda: {
1678
+ lambda: tLAMBDA
1679
+ {
1670
1680
  self.env.extend :dynamic
1671
1681
  result = [lexer.lineno, lexer.lpar_beg]
1672
1682
  lexer.paren_nest += 1
@@ -1678,14 +1688,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1678
1688
  }
1679
1689
  lambda_body
1680
1690
  {
1681
- (line, lpar), args, _cmdarg, body = val
1691
+ _, (line, lpar), args, _cmdarg, body = val
1682
1692
  lexer.lpar_beg = lpar
1683
1693
 
1684
1694
  lexer.cmdarg.pop
1685
1695
 
1686
1696
  call = s(:lambda).line line
1687
1697
  result = new_iter call, args, body
1688
- result.line = line
1698
+ result.line line
1689
1699
  self.env.unextend # TODO: dynapush & dynapop
1690
1700
  }
1691
1701
 
@@ -1720,23 +1730,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1720
1730
  ## if (nd_type($1) == NODE_YIELD) {
1721
1731
  ## compile_error(PARSER_ARG "block given to yield");
1722
1732
 
1723
- syntax_error "Both block arg and actual block given." if
1724
- val[0].block_pass?
1733
+ cmd, blk = val
1725
1734
 
1726
- val = invert_block_call val if inverted? val
1735
+ syntax_error "Both block arg and actual block given." if
1736
+ cmd.block_pass?
1727
1737
 
1728
- cmd, blk = val
1738
+ if inverted? val then
1739
+ val = invert_block_call val
1740
+ cmd, blk = val
1741
+ end
1729
1742
 
1730
1743
  result = blk
1731
1744
  result.insert 1, cmd
1732
1745
  }
1733
1746
  | block_call call_op2 operation2 opt_paren_args
1734
1747
  {
1735
- result = new_call val[0], val[2].to_sym, val[3]
1748
+ lhs, _, (id, _line), args = val
1749
+
1750
+ result = new_call lhs, id.to_sym, args
1736
1751
  }
1737
1752
  | block_call call_op2 operation2 opt_paren_args brace_block
1738
1753
  {
1739
- iter1, _, name, args, iter2 = val
1754
+ iter1, _, (name, _line), args, iter2 = val
1740
1755
 
1741
1756
  call = new_call iter1, name.to_sym, args
1742
1757
  iter2.insert 1, call
@@ -1745,7 +1760,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1745
1760
  }
1746
1761
  | block_call call_op2 operation2 command_args do_block
1747
1762
  {
1748
- iter1, _, name, args, iter2 = val
1763
+ iter1, _, (name, _line), args, iter2 = val
1749
1764
 
1750
1765
  call = new_call iter1, name.to_sym, args
1751
1766
  iter2.insert 1, call
@@ -1753,28 +1768,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1753
1768
  result = iter2
1754
1769
  }
1755
1770
 
1756
- method_call: fcall
1757
- {
1758
- result = self.lexer.lineno
1759
- }
1760
- paren_args
1771
+ method_call: fcall paren_args
1761
1772
  {
1762
- call, lineno, args = val
1773
+ call, args = val
1763
1774
 
1764
1775
  result = call.concat args.sexp_body if args
1765
- result.line lineno
1766
1776
  }
1767
1777
  | primary_value call_op operation2 opt_paren_args
1768
1778
  {
1769
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1779
+ recv, call_op, (op, _line), args = val
1780
+
1781
+ result = new_call recv, op.to_sym, args, call_op
1770
1782
  }
1771
1783
  | primary_value tCOLON2 operation2 paren_args
1772
1784
  {
1773
- result = new_call val[0], val[2].to_sym, val[3]
1785
+ recv, _, (op, _line), args = val
1786
+
1787
+ result = new_call recv, op.to_sym, args
1774
1788
  }
1775
1789
  | primary_value tCOLON2 operation3
1776
1790
  {
1777
- result = new_call val[0], val[2].to_sym
1791
+ lhs, _, (id, _line) = val
1792
+
1793
+ result = new_call lhs, id.to_sym
1778
1794
  }
1779
1795
  | primary_value call_op paren_args
1780
1796
  {
@@ -1807,7 +1823,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1807
1823
  _, line, body, _ = val
1808
1824
 
1809
1825
  result = body
1810
- result.line = line
1826
+ result.line line
1811
1827
 
1812
1828
  self.env.unextend
1813
1829
  }
@@ -1821,7 +1837,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1821
1837
  _, line, body, _ = val
1822
1838
 
1823
1839
  result = body
1824
- result.line = line
1840
+ result.line line
1825
1841
 
1826
1842
  self.env.unextend
1827
1843
  }
@@ -1850,14 +1866,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1850
1866
  self.env.unextend
1851
1867
  }
1852
1868
 
1869
+ case_args: arg_value
1870
+ {
1871
+ arg, = val
1872
+
1873
+ result = s(:array, arg).line arg.line
1874
+ }
1875
+ | tSTAR arg_value
1876
+ {
1877
+ _, arg = val
1878
+
1879
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1880
+ }
1881
+ | case_args tCOMMA arg_value
1882
+ {
1883
+ args, _, id = val
1884
+
1885
+ result = self.list_append args, id
1886
+ }
1887
+ | case_args tCOMMA tSTAR arg_value
1888
+ {
1889
+ args, _, _, id = val
1890
+
1891
+ result = self.list_append args, s(:splat, id).line(id.line)
1892
+ }
1893
+
1853
1894
  case_body: k_when
1854
1895
  {
1855
1896
  result = self.lexer.lineno
1856
1897
  }
1857
- args then compstmt cases
1898
+ case_args then compstmt cases
1858
1899
  {
1859
1900
  result = new_when(val[2], val[4])
1860
- result.line = val[1]
1901
+ result.line val[1]
1861
1902
  result << val[5] if val[5]
1862
1903
  }
1863
1904
 
@@ -1903,17 +1944,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1903
1944
 
1904
1945
  literal: numeric
1905
1946
  {
1906
- line = lexer.lineno
1907
- result = s(:lit, val[0])
1908
- result.line = line
1947
+ (lit, line), = val
1948
+ result = s(:lit, lit).line line
1909
1949
  }
1910
1950
  | symbol
1911
- {
1912
- line = lexer.lineno
1913
- result = s(:lit, val[0])
1914
- result.line = line
1915
- }
1916
- | dsym
1917
1951
 
1918
1952
  strings: string
1919
1953
  {
@@ -1924,7 +1958,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1924
1958
 
1925
1959
  string: tCHAR
1926
1960
  {
1927
- debug20 23, val, result
1961
+ debug 37
1928
1962
  }
1929
1963
  | string1
1930
1964
  | string string1
@@ -1934,11 +1968,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1934
1968
 
1935
1969
  string1: tSTRING_BEG string_contents tSTRING_END
1936
1970
  {
1937
- _, str, (_, func) = val
1971
+ (_, line), str, (_, func) = val
1938
1972
 
1939
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1973
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1940
1974
 
1941
- result = str
1975
+ result = str.line line
1942
1976
  }
1943
1977
  | tSTRING
1944
1978
  {
@@ -1958,11 +1992,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1958
1992
 
1959
1993
  words: tWORDS_BEG tSPACE tSTRING_END
1960
1994
  {
1961
- result = s(:array).line lexer.lineno
1995
+ (_, line), _, _ = val
1996
+
1997
+ result = s(:array).line line
1962
1998
  }
1963
1999
  | tWORDS_BEG word_list tSTRING_END
1964
2000
  {
1965
- result = val[1]
2001
+ (_, line), list, _ = val
2002
+
2003
+ result = list.line line
1966
2004
  }
1967
2005
 
1968
2006
  word_list: none
@@ -1982,18 +2020,20 @@ opt_block_args_tail: tCOMMA block_args_tail
1982
2020
 
1983
2021
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1984
2022
  {
1985
- result = s(:array).line lexer.lineno
2023
+ (_, line), _, _ = val
2024
+
2025
+ result = s(:array).line line
1986
2026
  }
1987
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2027
+ | tSYMBOLS_BEG symbol_list tSTRING_END
1988
2028
  {
1989
- _, line, list, _, = val
1990
- list.line = line
2029
+ (_, line), list, _, = val
2030
+ list.line line
1991
2031
  result = list
1992
2032
  }
1993
2033
 
1994
2034
  symbol_list: none
1995
2035
  {
1996
- result = new_symbol_list.line lexer.lineno
2036
+ result = new_symbol_list
1997
2037
  }
1998
2038
  | symbol_list word tSPACE
1999
2039
  {
@@ -2003,20 +2043,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2003
2043
 
2004
2044
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2005
2045
  {
2006
- result = s(:array).line lexer.lineno
2046
+ (_, line), _, _ = val
2047
+
2048
+ result = s(:array).line line
2007
2049
  }
2008
2050
  | tQWORDS_BEG qword_list tSTRING_END
2009
2051
  {
2010
- result = val[1]
2052
+ (_, line), list, _ = val
2053
+
2054
+ result = list.line line
2011
2055
  }
2012
2056
 
2013
2057
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2014
2058
  {
2015
- result = s(:array).line lexer.lineno # FIX
2059
+ (_, line), _, _ = val
2060
+
2061
+ result = s(:array).line line
2016
2062
  }
2017
2063
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2018
2064
  {
2019
- result = val[1]
2065
+ (_, line), list, _ = val
2066
+
2067
+ result = list.line line
2020
2068
  }
2021
2069
 
2022
2070
  qword_list: none
@@ -2039,7 +2087,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2039
2087
 
2040
2088
  string_contents: none
2041
2089
  {
2042
- result = s(:str, "").line lexer.lineno
2090
+ line = prev_value_to_lineno _values.last
2091
+ result = s(:str, +"").line line
2043
2092
  }
2044
2093
  | string_contents string_content
2045
2094
  {
@@ -2114,8 +2163,8 @@ regexp_contents: none
2114
2163
  lexer.brace_nest = brace_nest
2115
2164
  lexer.string_nest = string_nest
2116
2165
 
2117
- lexer.cmdarg.pop
2118
2166
  lexer.cond.pop
2167
+ lexer.cmdarg.pop
2119
2168
 
2120
2169
  lexer.lex_state = oldlex_state
2121
2170
 
@@ -2130,29 +2179,42 @@ regexp_contents: none
2130
2179
  when nil then
2131
2180
  result = s(:evstr).line line
2132
2181
  else
2133
- debug20 25
2182
+ debug 38
2134
2183
  raise "unknown string body: #{stmt.inspect}"
2135
2184
  end
2136
2185
  }
2137
2186
 
2138
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2139
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2140
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2187
+ string_dvar: tGVAR
2188
+ {
2189
+ result = wrap :gvar, val[0]
2190
+ }
2191
+ | tIVAR
2192
+ {
2193
+ result = wrap :ivar, val[0]
2194
+ }
2195
+ | tCVAR
2196
+ {
2197
+ result = wrap :cvar, val[0]
2198
+ }
2141
2199
  | backref
2142
2200
 
2143
- symbol: tSYMBEG sym
2201
+ symbol: ssym
2202
+ | dsym
2203
+
2204
+ ssym: tSYMBEG sym
2144
2205
  {
2145
2206
  lexer.lex_state = EXPR_END
2146
- result = val[1].to_sym
2207
+ result = wrap :lit, val[1]
2147
2208
  }
2148
2209
  | tSYMBOL
2149
2210
  {
2150
- result = val[0].to_sym
2211
+ lexer.lex_state = EXPR_END
2212
+ result = wrap :lit, val[0]
2151
2213
  }
2152
2214
 
2153
2215
  sym: fname | tIVAR | tGVAR | tCVAR
2154
2216
 
2155
- dsym: tSYMBEG xstring_contents tSTRING_END
2217
+ dsym: tSYMBEG string_contents tSTRING_END
2156
2218
  {
2157
2219
  _, result, _ = val
2158
2220
 
@@ -2168,14 +2230,15 @@ regexp_contents: none
2168
2230
  when :evstr then
2169
2231
  result = s(:dsym, "", result).line result.line
2170
2232
  else
2171
- debug20 26, val, result
2233
+ debug 39
2172
2234
  end
2173
2235
  }
2174
2236
 
2175
2237
  numeric: simple_numeric
2176
- | tUMINUS_NUM simple_numeric
2238
+ | tUMINUS_NUM simple_numeric =tLOWEST
2177
2239
  {
2178
- result = -val[1] # TODO: pt_testcase
2240
+ _, (num, line) = val
2241
+ result = [-num, line]
2179
2242
  }
2180
2243
 
2181
2244
  simple_numeric: tINTEGER
@@ -2208,8 +2271,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2208
2271
 
2209
2272
  var_ref: user_variable
2210
2273
  {
2211
- var = val[0]
2274
+ raise "NO: #{val.inspect}" if Sexp === val.first
2275
+ (var, line), = val
2212
2276
  result = Sexp === var ? var : self.gettable(var)
2277
+ result.line line
2213
2278
  }
2214
2279
  | keyword_variable
2215
2280
  {
@@ -2224,11 +2289,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2224
2289
  | keyword_variable
2225
2290
  {
2226
2291
  result = self.assignable val[0]
2227
- debug20 29, val, result
2292
+ debug 40
2228
2293
  }
2229
2294
 
2230
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2231
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2295
+ backref: tNTH_REF
2296
+ {
2297
+ (ref, line), = val
2298
+ result = s(:nth_ref, ref).line line
2299
+ }
2300
+ | tBACK_REF
2301
+ {
2302
+ (ref, line), = val
2303
+ result = s(:back_ref, ref).line line
2304
+ }
2232
2305
 
2233
2306
  superclass: tLT
2234
2307
  {
@@ -2246,9 +2319,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2246
2319
 
2247
2320
  f_arglist: tLPAREN2 f_args rparen
2248
2321
  {
2249
- result = val[1]
2250
- self.lexer.lex_state = EXPR_BEG
2251
- self.lexer.command_start = true
2322
+ result = end_args val
2252
2323
  }
2253
2324
  | {
2254
2325
  result = self.in_kwarg
@@ -2257,12 +2328,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2257
2328
  }
2258
2329
  f_args term
2259
2330
  {
2260
- kwarg, args, _ = val
2261
-
2262
- self.in_kwarg = kwarg
2263
- result = args
2264
- lexer.lex_state = EXPR_BEG
2265
- lexer.command_start = true
2331
+ result = end_args val
2266
2332
  }
2267
2333
 
2268
2334
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2347,6 +2413,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2347
2413
  |
2348
2414
  {
2349
2415
  result = args val
2416
+ # result.line lexer.lineno
2350
2417
  }
2351
2418
 
2352
2419
 
@@ -2370,31 +2437,24 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2370
2437
  f_norm_arg: f_bad_arg
2371
2438
  | tIDENTIFIER
2372
2439
  {
2373
- identifier = val[0].to_sym
2440
+ (id, line), = val
2441
+ identifier = id.to_sym
2374
2442
  self.env[identifier] = :lvar
2375
2443
 
2376
- result = identifier
2444
+ result = [identifier, line]
2377
2445
  }
2378
2446
 
2379
2447
  f_arg_item: f_norm_arg
2380
2448
  | tLPAREN f_margs rparen
2381
2449
  {
2382
- result = val[1]
2450
+ _, margs, _ = val
2451
+
2452
+ result = margs
2383
2453
  }
2384
2454
 
2385
2455
  f_arg: f_arg_item
2386
2456
  {
2387
- arg, = val
2388
-
2389
- case arg
2390
- when Symbol then
2391
- result = s(:args, arg).line lexer.lineno
2392
- when Sexp then
2393
- result = arg
2394
- else
2395
- debug20 32
2396
- raise "Unknown f_arg type: #{val.inspect}"
2397
- end
2457
+ result = new_arg val
2398
2458
  }
2399
2459
  | f_arg tCOMMA f_arg_item
2400
2460
  {
@@ -2406,7 +2466,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2406
2466
  result = s(:args, list).line list.line
2407
2467
  end
2408
2468
 
2409
- result << item
2469
+ result << (Sexp === item ? item : item.first)
2410
2470
  }
2411
2471
 
2412
2472
  f_label: tLABEL
@@ -2467,27 +2527,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2467
2527
  kwrest_mark: tPOW
2468
2528
  | tDSTAR
2469
2529
 
2530
+
2470
2531
  f_kwrest: kwrest_mark tIDENTIFIER
2471
2532
  {
2472
- name = val[1].to_sym
2473
- self.assignable name
2474
- result = :"**#{name}"
2533
+ _, (id, line) = val
2534
+
2535
+ name = id.to_sym
2536
+ self.assignable [name, line]
2537
+ result = [:"**#{name}", line]
2475
2538
  }
2476
2539
  | kwrest_mark
2477
2540
  {
2478
- result = :"**"
2479
- self.env[result] = :lvar
2541
+ id = :"**"
2542
+ self.env[id] = :lvar # TODO: needed?!?
2543
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2480
2544
  }
2481
2545
 
2482
2546
  f_opt: f_norm_arg tEQL arg_value
2483
2547
  {
2484
- result = self.assignable val[0], val[2]
2548
+ lhs, _, rhs = val
2549
+ result = self.assignable lhs, rhs
2485
2550
  # TODO: detect duplicate names
2486
2551
  }
2487
2552
 
2488
2553
  f_block_opt: f_norm_arg tEQL primary_value
2489
2554
  {
2490
- result = self.assignable val[0], val[2]
2555
+ lhs, _, rhs = val
2556
+ result = self.assignable lhs, rhs
2491
2557
  }
2492
2558
 
2493
2559
  f_block_optarg: f_block_opt
@@ -2517,30 +2583,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2517
2583
  f_rest_arg: restarg_mark tIDENTIFIER
2518
2584
  {
2519
2585
  # TODO: differs from parse.y - needs tests
2520
- name = val[1].to_sym
2521
- self.assignable name
2522
- result = :"*#{name}"
2586
+ _, (id, line) = val
2587
+ name = id.to_sym
2588
+ self.assignable [name, line]
2589
+ result = [:"*#{name}", line]
2523
2590
  }
2524
2591
  | restarg_mark
2525
2592
  {
2526
2593
  name = :"*"
2527
2594
  self.env[name] = :lvar
2528
- result = name
2595
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2529
2596
  }
2530
2597
 
2531
2598
  blkarg_mark: tAMPER2 | tAMPER
2532
2599
 
2533
2600
  f_block_arg: blkarg_mark tIDENTIFIER
2534
2601
  {
2535
- identifier = val[1].to_sym
2602
+ _, (id, line) = val
2603
+ identifier = id.to_sym
2536
2604
 
2537
2605
  self.env[identifier] = :lvar
2538
- result = "&#{identifier}".to_sym
2606
+ result = ["&#{identifier}".to_sym, line]
2539
2607
  }
2540
2608
 
2541
2609
  opt_f_block_arg: tCOMMA f_block_arg
2542
2610
  {
2543
- result = val[1]
2611
+ _, arg = val
2612
+ result = arg
2544
2613
  }
2545
2614
  |
2546
2615
  {
@@ -2582,10 +2651,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2582
2651
  }
2583
2652
  | tLABEL arg_value
2584
2653
  {
2585
- (label, line), arg = val
2654
+ label, arg = val
2586
2655
 
2587
- lit = s(:lit, label.to_sym).line line
2588
- result = s(:array, lit, arg).line line
2656
+ lit = wrap :lit, label
2657
+ result = s(:array, lit, arg).line lit.line
2589
2658
  }
2590
2659
  | tDSTAR arg_value
2591
2660
  {