ruby_parser 3.17.0 → 3.19.0

Sign up to get free protection for your applications and to get access to all the features.
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
  {