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/ruby26_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
  tLONELY
@@ -80,7 +80,7 @@ rule
80
80
  | klBEGIN
81
81
  {
82
82
  if (self.in_def || self.in_single > 0) then
83
- debug20 1
83
+ debug 11
84
84
  yyerror "BEGIN in method"
85
85
  end
86
86
  self.env.extend
@@ -105,6 +105,8 @@ rule
105
105
  bodystmt: compstmt opt_rescue k_else
106
106
  {
107
107
  res = _values[-2]
108
+ # TODO: move down to main match so I can just use val
109
+
108
110
  yyerror "else without rescue is useless" unless res
109
111
  }
110
112
  compstmt
@@ -135,7 +137,7 @@ rule
135
137
  | error stmt
136
138
  {
137
139
  result = val[1]
138
- debug20 2, val, result
140
+ debug 12
139
141
  }
140
142
 
141
143
  stmt_or_begin: stmt
@@ -143,6 +145,10 @@ rule
143
145
  {
144
146
  yyerror "BEGIN is permitted only at toplevel"
145
147
  }
148
+ begin_block
149
+ {
150
+ result = val[2] # wtf?
151
+ }
146
152
 
147
153
  stmt: kALIAS fitem
148
154
  {
@@ -155,12 +161,12 @@ rule
155
161
  }
156
162
  | kALIAS tGVAR tGVAR
157
163
  {
158
- (_, line), lhs, rhs = val
164
+ (_, line), (lhs, _), (rhs, _) = val
159
165
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
160
166
  }
161
167
  | kALIAS tGVAR tBACK_REF
162
168
  {
163
- (_, line), lhs, rhs = val
169
+ (_, line), (lhs, _), (rhs, _) = val
164
170
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
165
171
  }
166
172
  | kALIAS tGVAR tNTH_REF
@@ -203,7 +209,7 @@ rule
203
209
  (_, line), _, stmt, _ = val
204
210
 
205
211
  if (self.in_def || self.in_single > 0) then
206
- debug20 3
212
+ debug 13
207
213
  yyerror "END in method; use at_exit"
208
214
  end
209
215
 
@@ -243,32 +249,31 @@ rule
243
249
  }
244
250
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
251
  {
246
- prim, _, id, opasgn, rhs = val
247
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
248
- if val[1] == '&.'
249
- result.sexp_type = :safe_op_asgn
250
- end
251
- result.line = val[0].line
252
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
253
+
254
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
255
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
256
+ result.line prim.line
252
257
  }
253
258
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
254
259
  {
255
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
256
- if val[1] == '&.'
257
- result.sexp_type = :safe_op_asgn
258
- end
259
- result.line = val[0].line
260
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
261
+
262
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
263
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
264
+ result.line prim.line
260
265
  }
261
266
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
262
267
  {
263
- lhs1, _, lhs2, op, rhs = val
268
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
269
 
265
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
270
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
266
271
  }
267
272
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
268
273
  {
269
- lhs1, _, lhs2, op, rhs = val
274
+ lhs1, _, (lhs2, line), (id, _), rhs = val
270
275
 
271
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
276
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
272
277
  }
273
278
  | backref tOP_ASGN command_rhs
274
279
  {
@@ -314,7 +319,7 @@ rule
314
319
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
315
320
  # REFACTOR: call_uni_op -- see parse26.y
316
321
  }
317
- | arg
322
+ | arg =tLBRACE_ARG
318
323
 
319
324
  expr_value: expr
320
325
  {
@@ -339,7 +344,7 @@ rule
339
344
  block_command: block_call
340
345
  | block_call call_op2 operation2 command_args
341
346
  {
342
- blk, _, msg, args = val
347
+ blk, _, (msg, _line), args = val
343
348
  result = new_call(blk, msg.to_sym, args).line blk.line
344
349
  }
345
350
 
@@ -353,15 +358,15 @@ rule
353
358
  _, line, body, _ = val
354
359
 
355
360
  result = body
356
- result.line = line
361
+ result.line line
357
362
 
358
363
  # self.env.unextend
359
364
  }
360
365
 
361
366
  fcall: operation
362
367
  {
363
- msg, = val
364
- result = new_call(nil, msg.to_sym).line lexer.lineno
368
+ (msg, line), = val
369
+ result = new_call(nil, msg.to_sym).line line
365
370
  }
366
371
 
367
372
  command: fcall command_args =tLOWEST
@@ -384,12 +389,14 @@ rule
384
389
  }
385
390
  | primary_value call_op operation2 command_args =tLOWEST
386
391
  {
387
- lhs, callop, op, args = val
392
+ lhs, callop, (op, _), args = val
393
+
388
394
  result = new_call lhs, op.to_sym, args, callop
395
+ result.line lhs.line
389
396
  }
390
397
  | primary_value call_op operation2 command_args cmd_brace_block
391
398
  {
392
- recv, _, msg, args, block = val
399
+ recv, _, (msg, _line), args, block = val
393
400
  call = new_call recv, msg.to_sym, args, val[1]
394
401
 
395
402
  block_dup_check call, block
@@ -399,11 +406,14 @@ rule
399
406
  }
400
407
  | primary_value tCOLON2 operation2 command_args =tLOWEST
401
408
  {
402
- result = new_call val[0], val[2].to_sym, val[3]
409
+ lhs, _, (id, line), args = val
410
+
411
+ result = new_call lhs, id.to_sym, args
412
+ result.line line
403
413
  }
404
414
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
405
415
  {
406
- recv, _, msg, args, block = val
416
+ recv, _, (msg, _line), args, block = val
407
417
  call = new_call recv, msg.to_sym, args
408
418
 
409
419
  block_dup_check call, block
@@ -561,25 +571,29 @@ rule
561
571
  }
562
572
  | primary_value call_op tIDENTIFIER
563
573
  {
564
- 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
565
577
  }
566
578
  | primary_value tCOLON2 tIDENTIFIER
567
579
  {
568
- recv, _, id = val
580
+ recv, _, (id, _line) = val
569
581
  result = new_attrasgn recv, id
570
582
  }
571
583
  | primary_value call_op tCONSTANT
572
584
  {
573
- result = new_attrasgn val[0], val[2], val[1]
585
+ lhs, call_op, (id, _line) = val
586
+
587
+ result = new_attrasgn lhs, id, call_op
574
588
  }
575
589
  | primary_value tCOLON2 tCONSTANT
576
590
  {
577
591
  if (self.in_def || self.in_single > 0) then
578
- debug20 7
592
+ debug 14
579
593
  yyerror "dynamic constant assignment"
580
594
  end
581
595
 
582
- expr, _, id = val
596
+ expr, _, (id, _line) = val
583
597
  l = expr.line
584
598
 
585
599
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -587,58 +601,65 @@ rule
587
601
  | tCOLON3 tCONSTANT
588
602
  {
589
603
  if (self.in_def || self.in_single > 0) then
590
- debug20 8
604
+ debug 15
591
605
  yyerror "dynamic constant assignment"
592
606
  end
593
607
 
594
- _, id = val
595
- l = lexer.lineno
608
+ _, (id, l) = val
596
609
 
597
610
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
598
611
  }
599
612
  | backref
600
613
  {
601
- self.backref_assign_error val[0]
614
+ ref, = val
615
+
616
+ self.backref_assign_error ref
602
617
  }
603
618
 
604
619
  lhs: user_variable
605
620
  {
606
- line = lexer.lineno
607
- result = self.assignable val[0]
608
- result.line = line
621
+ var, = val
622
+
623
+ result = self.assignable var
609
624
  }
610
625
  | keyword_variable
611
626
  {
612
- line = lexer.lineno
613
- result = self.assignable val[0]
614
- result.line = line
615
- debug20 9, val, result
627
+ var, = val
628
+
629
+ result = self.assignable var
630
+
631
+ debug 16
616
632
  }
617
633
  | primary_value tLBRACK2 opt_call_args rbracket
618
634
  {
619
635
  lhs, _, args, _ = val
636
+
620
637
  result = self.aryset lhs, args
621
638
  }
622
639
  | primary_value call_op tIDENTIFIER # REFACTOR
623
640
  {
624
- lhs, op, id = val
641
+ lhs, op, (id, _line) = val
642
+
625
643
  result = new_attrasgn lhs, id, op
626
644
  }
627
645
  | primary_value tCOLON2 tIDENTIFIER
628
646
  {
629
- lhs, _, id = val
647
+ lhs, _, (id, _line) = val
648
+
630
649
  result = new_attrasgn lhs, id
631
650
  }
632
651
  | primary_value call_op tCONSTANT # REFACTOR?
633
652
  {
634
- result = new_attrasgn val[0], val[2], val[1]
653
+ lhs, call_op, (id, _line) = val
654
+
655
+ result = new_attrasgn lhs, id, call_op
635
656
  }
636
657
  | primary_value tCOLON2 tCONSTANT
637
658
  {
638
- expr, _, id = val
659
+ expr, _, (id, _line) = val
639
660
 
640
661
  if (self.in_def || self.in_single > 0) then
641
- debug20 10
662
+ debug 17
642
663
  yyerror "dynamic constant assignment"
643
664
  end
644
665
 
@@ -647,14 +668,13 @@ rule
647
668
  }
648
669
  | tCOLON3 tCONSTANT
649
670
  {
650
- _, id = val
671
+ _, (id, l) = val
651
672
 
652
673
  if (self.in_def || self.in_single > 0) then
653
- debug20 11
674
+ debug 18
654
675
  yyerror "dynamic constant assignment"
655
676
  end
656
677
 
657
- l = lexer.lineno
658
678
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
659
679
  }
660
680
  | backref
@@ -670,16 +690,16 @@ rule
670
690
 
671
691
  cpath: tCOLON3 cname
672
692
  {
673
- _, name = val
674
- result = s(:colon3, name.to_sym).line lexer.lineno
693
+ result = wrap :colon3, val[1]
675
694
  }
676
695
  | cname
677
696
  {
678
- result = val[0].to_sym
697
+ (id, line), = val
698
+ result = [id.to_sym, line] # TODO: sexp?
679
699
  }
680
700
  | primary_value tCOLON2 cname
681
701
  {
682
- pval, _, name = val
702
+ pval, _, (name, _line) = val
683
703
 
684
704
  result = s(:colon2, pval, name.to_sym)
685
705
  result.line pval.line
@@ -689,24 +709,15 @@ rule
689
709
  | op
690
710
  {
691
711
  lexer.lex_state = EXPR_END
692
- result = val[0]
693
712
  }
694
713
 
695
714
  | reswords
696
- {
697
- (sym, _line), = val
698
- lexer.lex_state = EXPR_END
699
- result = sym
700
- }
701
-
702
- fsym: fname | symbol
703
715
 
704
- fitem: fsym
716
+ fitem: fname
705
717
  {
706
- id, = val
707
- result = s(:lit, id.to_sym).line lexer.lineno
718
+ result = wrap :lit, val[0]
708
719
  }
709
- | dsym
720
+ | symbol
710
721
 
711
722
  undef_list: fitem
712
723
  {
@@ -727,8 +738,6 @@ rule
727
738
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
728
739
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
729
740
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
730
- # TODO: tUBANG dead?
731
- | tUBANG
732
741
 
733
742
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
734
743
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -762,26 +771,22 @@ rule
762
771
  }
763
772
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
764
773
  {
765
- lhs, _, id, op, rhs = val
774
+ lhs, _, (id, _line), (op, _), rhs = val
766
775
 
767
776
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
768
777
  }
769
778
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
770
779
  {
771
- lhs1, _, lhs2, op, rhs = val
780
+ lhs1, _, (lhs2, _line), op, rhs = val
772
781
 
773
782
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
774
783
  result = new_const_op_asgn [lhs, op, rhs]
775
784
  }
776
- | tCOLON3 tCONSTANT
777
- {
778
- result = self.lexer.lineno
779
- }
780
- tOP_ASGN arg_rhs
785
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
781
786
  {
782
- _, lhs, line, op, rhs = val
787
+ _, lhs, op, rhs = val
783
788
 
784
- lhs = s(:colon3, lhs.to_sym).line line
789
+ lhs = wrap :colon3, lhs
785
790
  result = new_const_op_asgn [lhs, op, rhs]
786
791
  }
787
792
  | backref tOP_ASGN arg_rhs
@@ -793,7 +798,7 @@ rule
793
798
  | arg tDOT2 arg
794
799
  {
795
800
  v1, v2 = val[0], val[2]
796
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
801
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
797
802
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
798
803
  else
799
804
  result = s(:dot2, v1, v2).line v1.line
@@ -802,7 +807,7 @@ rule
802
807
  | arg tDOT3 arg
803
808
  {
804
809
  v1, v2 = val[0], val[2]
805
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
810
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
806
811
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
807
812
  else
808
813
  result = s(:dot3, v1, v2).line v1.line
@@ -850,8 +855,9 @@ rule
850
855
  }
851
856
  | tUMINUS_NUM simple_numeric tPOW arg
852
857
  {
853
- lit = s(:lit, val[1]).line lexer.lineno
854
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
858
+ _, (num, line), _, arg = val
859
+ lit = s(:lit, num).line line
860
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
855
861
 
856
862
  }
857
863
  | tUPLUS arg
@@ -950,12 +956,12 @@ rule
950
956
 
951
957
  rel_expr: arg relop arg =tGT
952
958
  {
953
- lhs, op, rhs = val
959
+ lhs, (op, _), rhs = val
954
960
  result = new_call lhs, op.to_sym, argl(rhs)
955
961
  }
956
962
  | rel_expr relop arg =tGT
957
963
  {
958
- lhs, op, rhs = val
964
+ lhs, (op, _), rhs = val
959
965
  warn "comparison '%s' after comparison", op
960
966
  result = new_call lhs, op.to_sym, argl(rhs)
961
967
  }
@@ -1146,8 +1152,9 @@ rule
1146
1152
  | backref
1147
1153
  | tFID
1148
1154
  {
1149
- msg, = val
1155
+ (msg, line), = val
1150
1156
  result = new_call nil, msg.to_sym
1157
+ result.line line
1151
1158
  }
1152
1159
  | k_begin
1153
1160
  {
@@ -1189,15 +1196,13 @@ rule
1189
1196
  }
1190
1197
  | primary_value tCOLON2 tCONSTANT
1191
1198
  {
1192
- expr, _, id = val
1199
+ expr, _, (id, _line) = val
1193
1200
 
1194
1201
  result = s(:colon2, expr, id.to_sym).line expr.line
1195
1202
  }
1196
1203
  | tCOLON3 tCONSTANT
1197
1204
  {
1198
- _, id = val
1199
-
1200
- result = s(:colon3, id.to_sym).line lexer.lineno
1205
+ result = wrap :colon3, val[1]
1201
1206
  }
1202
1207
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1203
1208
  {
@@ -1221,15 +1226,21 @@ rule
1221
1226
  }
1222
1227
  | kYIELD tLPAREN2 call_args rparen
1223
1228
  {
1224
- result = new_yield val[2]
1229
+ (_, line), _, args, _ = val
1230
+
1231
+ result = new_yield(args).line line
1225
1232
  }
1226
1233
  | kYIELD tLPAREN2 rparen
1227
1234
  {
1228
- result = new_yield
1235
+ (_, line), _, _ = val
1236
+
1237
+ result = new_yield.line line
1229
1238
  }
1230
1239
  | kYIELD
1231
1240
  {
1232
- result = new_yield
1241
+ (_, line), = val
1242
+
1243
+ result = new_yield.line line
1233
1244
  }
1234
1245
  | kDEFINED opt_nl tLPAREN2 expr rparen
1235
1246
  {
@@ -1244,7 +1255,7 @@ rule
1244
1255
  }
1245
1256
  | kNOT tLPAREN2 rparen
1246
1257
  {
1247
- debug20 14, val, result
1258
+ debug 20
1248
1259
  }
1249
1260
  | fcall brace_block
1250
1261
  {
@@ -1262,9 +1273,10 @@ rule
1262
1273
  iter.insert 1, call # FIX
1263
1274
  result = iter
1264
1275
  }
1265
- | tLAMBDA lambda
1276
+ | lambda
1266
1277
  {
1267
- result = val[1] # TODO: fix lineno
1278
+ expr, = val
1279
+ result = expr
1268
1280
  }
1269
1281
  | k_if expr_value then compstmt if_tail k_end
1270
1282
  {
@@ -1307,7 +1319,6 @@ rule
1307
1319
  }
1308
1320
  cpath superclass
1309
1321
  {
1310
- self.comments.push self.lexer.comments
1311
1322
  if (self.in_def || self.in_single > 0) then
1312
1323
  yyerror "class definition in method body"
1313
1324
  end
@@ -1317,7 +1328,7 @@ rule
1317
1328
  {
1318
1329
  result = new_class val
1319
1330
  self.env.unextend
1320
- self.lexer.comments # we don't care about comments in the body
1331
+ self.lexer.ignore_body_comments
1321
1332
  }
1322
1333
  | k_class tLSHFT
1323
1334
  {
@@ -1338,7 +1349,7 @@ rule
1338
1349
  {
1339
1350
  result = new_sclass val
1340
1351
  self.env.unextend
1341
- self.lexer.comments # we don't care about comments in the body
1352
+ self.lexer.ignore_body_comments
1342
1353
  }
1343
1354
  | k_module
1344
1355
  {
@@ -1346,7 +1357,6 @@ rule
1346
1357
  }
1347
1358
  cpath
1348
1359
  {
1349
- self.comments.push self.lexer.comments
1350
1360
  yyerror "module definition in method body" if
1351
1361
  self.in_def or self.in_single > 0
1352
1362
 
@@ -1356,7 +1366,7 @@ rule
1356
1366
  {
1357
1367
  result = new_module val
1358
1368
  self.env.unextend
1359
- self.lexer.comments # we don't care about comments in the body
1369
+ self.lexer.ignore_body_comments
1360
1370
  }
1361
1371
  | k_def fname
1362
1372
  {
@@ -1366,21 +1376,17 @@ rule
1366
1376
  self.env.extend
1367
1377
  lexer.cmdarg.push false
1368
1378
  lexer.cond.push false
1369
-
1370
- self.comments.push self.lexer.comments
1371
1379
  }
1372
- f_arglist bodystmt { result = lexer.lineno } k_end
1380
+ f_arglist bodystmt k_end
1373
1381
  {
1374
- in_def = val[2]
1375
-
1376
- result = new_defn val
1382
+ result, in_def = new_defn val
1377
1383
 
1378
1384
  lexer.cond.pop # group = local_pop
1379
1385
  lexer.cmdarg.pop
1380
1386
  self.env.unextend
1381
1387
  self.in_def = in_def
1382
1388
 
1383
- self.lexer.comments # we don't care about comments in the body
1389
+ self.lexer.ignore_body_comments
1384
1390
  }
1385
1391
  | k_def singleton dot_or_colon
1386
1392
  {
@@ -1388,7 +1394,7 @@ rule
1388
1394
  }
1389
1395
  fname
1390
1396
  {
1391
- result = [self.in_def, lexer.lineno]
1397
+ result = self.in_def
1392
1398
 
1393
1399
  self.in_single += 1 # TODO: remove?
1394
1400
 
@@ -1398,13 +1404,18 @@ rule
1398
1404
  lexer.cond.push false
1399
1405
 
1400
1406
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1401
- self.comments.push self.lexer.comments
1402
1407
  }
1403
1408
  f_arglist bodystmt k_end
1404
1409
  {
1405
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1406
1410
 
1407
- result = new_defs val
1411
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1412
+ # =>
1413
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1414
+
1415
+ val.delete_at 3
1416
+ val.delete_at 2
1417
+
1418
+ result, in_def = new_defs val
1408
1419
 
1409
1420
  lexer.cond.pop # group = local_pop
1410
1421
  lexer.cmdarg.pop
@@ -1415,7 +1426,7 @@ rule
1415
1426
 
1416
1427
  # TODO: restore cur_arg ? what's cur_arg?
1417
1428
 
1418
- self.lexer.comments # we don't care about comments in the body
1429
+ self.lexer.ignore_body_comments
1419
1430
  }
1420
1431
  | kBREAK
1421
1432
  {
@@ -1452,8 +1463,17 @@ rule
1452
1463
  k_case: kCASE
1453
1464
  k_for: kFOR
1454
1465
  k_class: kCLASS
1466
+ {
1467
+ self.comments.push self.lexer.comments
1468
+ }
1455
1469
  k_module: kMODULE
1470
+ {
1471
+ self.comments.push self.lexer.comments
1472
+ }
1456
1473
  k_def: kDEF
1474
+ {
1475
+ self.comments.push self.lexer.comments
1476
+ }
1457
1477
  k_do: kDO
1458
1478
  k_do_block: kDO_BLOCK
1459
1479
  k_rescue: kRESCUE
@@ -1514,51 +1534,42 @@ rule
1514
1534
 
1515
1535
  result = block_var args
1516
1536
  }
1517
- | f_marg_list tCOMMA tSTAR f_norm_arg
1537
+ | f_marg_list tCOMMA f_rest_marg
1518
1538
  {
1519
- args, _, _, splat = val
1539
+ args, _, rest = val
1520
1540
 
1521
- result = block_var args, "*#{splat}".to_sym
1541
+ result = block_var args, rest
1522
1542
  }
1523
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1543
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1524
1544
  {
1525
- args, _, _, splat, _, args2 = val
1545
+ lhs, _, splat, _, rhs = val
1526
1546
 
1527
- result = block_var args, "*#{splat}".to_sym, args2
1547
+ result = block_var lhs, splat, rhs
1528
1548
  }
1529
- | f_marg_list tCOMMA tSTAR
1549
+ | f_rest_marg
1530
1550
  {
1531
- args, _, _ = val
1551
+ rest, = val
1532
1552
 
1533
- result = block_var args, :*
1553
+ result = block_var rest
1534
1554
  }
1535
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1555
+ | f_rest_marg tCOMMA f_marg_list
1536
1556
  {
1537
- args, _, _, _, args2 = val
1557
+ splat, _, rest = val
1538
1558
 
1539
- result = block_var args, :*, args2
1559
+ result = block_var splat, rest
1540
1560
  }
1541
- | tSTAR f_norm_arg
1542
- {
1543
- _, splat = val
1544
1561
 
1545
- result = block_var :"*#{splat}"
1546
- }
1547
- | tSTAR f_norm_arg tCOMMA f_marg_list
1562
+ f_rest_marg: tSTAR f_norm_arg
1548
1563
  {
1549
- _, splat, _, args = val
1564
+ _, (id, line) = val
1550
1565
 
1551
- result = block_var :"*#{splat}", args
1566
+ result = args ["*#{id}".to_sym]
1567
+ result.line line
1552
1568
  }
1553
1569
  | tSTAR
1554
1570
  {
1555
- result = block_var :*
1556
- }
1557
- | tSTAR tCOMMA f_marg_list
1558
- {
1559
- _, _, args = val
1560
-
1561
- result = block_var :*, args
1571
+ result = args [:*]
1572
+ result.line lexer.lineno # FIX: tSTAR -> line
1562
1573
  }
1563
1574
 
1564
1575
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1575,8 +1586,8 @@ rule
1575
1586
  }
1576
1587
  | f_block_arg
1577
1588
  {
1578
- line = lexer.lineno
1579
- result = call_args val # TODO: push line down
1589
+ (id, line), = val
1590
+ result = call_args [id]
1580
1591
  result.line line
1581
1592
  }
1582
1593
 
@@ -1685,13 +1696,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1685
1696
 
1686
1697
  bvar: tIDENTIFIER
1687
1698
  {
1688
- id, = val
1689
- line = lexer.lineno
1690
- result = s(:shadow, id.to_sym).line line
1699
+ result = wrap :shadow, val[0]
1691
1700
  }
1692
1701
  | f_bad_arg
1693
1702
 
1694
- lambda: {
1703
+ lambda: tLAMBDA
1704
+ {
1695
1705
  self.env.extend :dynamic
1696
1706
  result = [lexer.lineno, lexer.lpar_beg]
1697
1707
  lexer.paren_nest += 1
@@ -1703,14 +1713,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1703
1713
  }
1704
1714
  lambda_body
1705
1715
  {
1706
- (line, lpar), args, _cmdarg, body = val
1716
+ _, (line, lpar), args, _cmdarg, body = val
1707
1717
  lexer.lpar_beg = lpar
1708
1718
 
1709
1719
  lexer.cmdarg.pop
1710
1720
 
1711
1721
  call = s(:lambda).line line
1712
1722
  result = new_iter call, args, body
1713
- result.line = line
1723
+ result.line line
1714
1724
  self.env.unextend # TODO: dynapush & dynapop
1715
1725
  }
1716
1726
 
@@ -1745,23 +1755,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1745
1755
  ## if (nd_type($1) == NODE_YIELD) {
1746
1756
  ## compile_error(PARSER_ARG "block given to yield");
1747
1757
 
1748
- syntax_error "Both block arg and actual block given." if
1749
- val[0].block_pass?
1758
+ cmd, blk = val
1750
1759
 
1751
- val = invert_block_call val if inverted? val
1760
+ syntax_error "Both block arg and actual block given." if
1761
+ cmd.block_pass?
1752
1762
 
1753
- cmd, blk = val
1763
+ if inverted? val then
1764
+ val = invert_block_call val
1765
+ cmd, blk = val
1766
+ end
1754
1767
 
1755
1768
  result = blk
1756
1769
  result.insert 1, cmd
1757
1770
  }
1758
1771
  | block_call call_op2 operation2 opt_paren_args
1759
1772
  {
1760
- result = new_call val[0], val[2].to_sym, val[3]
1773
+ lhs, _, (id, _line), args = val
1774
+
1775
+ result = new_call lhs, id.to_sym, args
1761
1776
  }
1762
1777
  | block_call call_op2 operation2 opt_paren_args brace_block
1763
1778
  {
1764
- iter1, _, name, args, iter2 = val
1779
+ iter1, _, (name, _line), args, iter2 = val
1765
1780
 
1766
1781
  call = new_call iter1, name.to_sym, args
1767
1782
  iter2.insert 1, call
@@ -1770,7 +1785,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1770
1785
  }
1771
1786
  | block_call call_op2 operation2 command_args do_block
1772
1787
  {
1773
- iter1, _, name, args, iter2 = val
1788
+ iter1, _, (name, _line), args, iter2 = val
1774
1789
 
1775
1790
  call = new_call iter1, name.to_sym, args
1776
1791
  iter2.insert 1, call
@@ -1778,28 +1793,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1778
1793
  result = iter2
1779
1794
  }
1780
1795
 
1781
- method_call: fcall
1796
+ method_call: fcall paren_args
1782
1797
  {
1783
- result = self.lexer.lineno
1784
- }
1785
- paren_args
1786
- {
1787
- call, lineno, args = val
1798
+ call, args = val
1788
1799
 
1789
1800
  result = call.concat args.sexp_body if args
1790
- result.line lineno
1791
1801
  }
1792
1802
  | primary_value call_op operation2 opt_paren_args
1793
1803
  {
1794
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1804
+ recv, call_op, (op, _line), args = val
1805
+
1806
+ result = new_call recv, op.to_sym, args, call_op
1795
1807
  }
1796
1808
  | primary_value tCOLON2 operation2 paren_args
1797
1809
  {
1798
- result = new_call val[0], val[2].to_sym, val[3]
1810
+ recv, _, (op, _line), args = val
1811
+
1812
+ result = new_call recv, op.to_sym, args
1799
1813
  }
1800
1814
  | primary_value tCOLON2 operation3
1801
1815
  {
1802
- result = new_call val[0], val[2].to_sym
1816
+ lhs, _, (id, _line) = val
1817
+
1818
+ result = new_call lhs, id.to_sym
1803
1819
  }
1804
1820
  | primary_value call_op paren_args
1805
1821
  {
@@ -1832,7 +1848,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1832
1848
  _, line, body, _ = val
1833
1849
 
1834
1850
  result = body
1835
- result.line = line
1851
+ result.line line
1836
1852
 
1837
1853
  self.env.unextend
1838
1854
  }
@@ -1846,7 +1862,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1846
1862
  _, line, body, _ = val
1847
1863
 
1848
1864
  result = body
1849
- result.line = line
1865
+ result.line line
1850
1866
 
1851
1867
  self.env.unextend
1852
1868
  }
@@ -1875,14 +1891,39 @@ opt_block_args_tail: tCOMMA block_args_tail
1875
1891
  self.env.unextend
1876
1892
  }
1877
1893
 
1894
+ case_args: arg_value
1895
+ {
1896
+ arg, = val
1897
+
1898
+ result = s(:array, arg).line arg.line
1899
+ }
1900
+ | tSTAR arg_value
1901
+ {
1902
+ _, arg = val
1903
+
1904
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1905
+ }
1906
+ | case_args tCOMMA arg_value
1907
+ {
1908
+ args, _, id = val
1909
+
1910
+ result = self.list_append args, id
1911
+ }
1912
+ | case_args tCOMMA tSTAR arg_value
1913
+ {
1914
+ args, _, _, id = val
1915
+
1916
+ result = self.list_append args, s(:splat, id).line(id.line)
1917
+ }
1918
+
1878
1919
  case_body: k_when
1879
1920
  {
1880
1921
  result = self.lexer.lineno
1881
1922
  }
1882
- args then compstmt cases
1923
+ case_args then compstmt cases
1883
1924
  {
1884
1925
  result = new_when(val[2], val[4])
1885
- result.line = val[1]
1926
+ result.line val[1]
1886
1927
  result << val[5] if val[5]
1887
1928
  }
1888
1929
 
@@ -1928,17 +1969,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1928
1969
 
1929
1970
  literal: numeric
1930
1971
  {
1931
- line = lexer.lineno
1932
- result = s(:lit, val[0])
1933
- result.line = line
1972
+ (lit, line), = val
1973
+ result = s(:lit, lit).line line
1934
1974
  }
1935
1975
  | symbol
1936
- {
1937
- line = lexer.lineno
1938
- result = s(:lit, val[0])
1939
- result.line = line
1940
- }
1941
- | dsym
1942
1976
 
1943
1977
  strings: string
1944
1978
  {
@@ -1949,7 +1983,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1949
1983
 
1950
1984
  string: tCHAR
1951
1985
  {
1952
- debug20 23, val, result
1986
+ debug 37
1953
1987
  }
1954
1988
  | string1
1955
1989
  | string string1
@@ -1959,11 +1993,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1959
1993
 
1960
1994
  string1: tSTRING_BEG string_contents tSTRING_END
1961
1995
  {
1962
- _, str, (_, func) = val
1996
+ (_, line), str, (_, func) = val
1963
1997
 
1964
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1998
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1965
1999
 
1966
- result = str
2000
+ result = str.line line
1967
2001
  }
1968
2002
  | tSTRING
1969
2003
  {
@@ -1983,11 +2017,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1983
2017
 
1984
2018
  words: tWORDS_BEG tSPACE tSTRING_END
1985
2019
  {
1986
- result = s(:array).line lexer.lineno
2020
+ (_, line), _, _ = val
2021
+
2022
+ result = s(:array).line line
1987
2023
  }
1988
2024
  | tWORDS_BEG word_list tSTRING_END
1989
2025
  {
1990
- result = val[1]
2026
+ (_, line), list, _ = val
2027
+
2028
+ result = list.line line
1991
2029
  }
1992
2030
 
1993
2031
  word_list: none
@@ -2007,18 +2045,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2007
2045
 
2008
2046
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2009
2047
  {
2010
- result = s(:array).line lexer.lineno
2048
+ (_, line), _, _ = val
2049
+
2050
+ result = s(:array).line line
2011
2051
  }
2012
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2052
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2013
2053
  {
2014
- _, line, list, _, = val
2015
- list.line = line
2054
+ (_, line), list, _, = val
2055
+ list.line line
2016
2056
  result = list
2017
2057
  }
2018
2058
 
2019
2059
  symbol_list: none
2020
2060
  {
2021
- result = new_symbol_list.line lexer.lineno
2061
+ result = new_symbol_list
2022
2062
  }
2023
2063
  | symbol_list word tSPACE
2024
2064
  {
@@ -2028,20 +2068,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2028
2068
 
2029
2069
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2030
2070
  {
2031
- result = s(:array).line lexer.lineno
2071
+ (_, line), _, _ = val
2072
+
2073
+ result = s(:array).line line
2032
2074
  }
2033
2075
  | tQWORDS_BEG qword_list tSTRING_END
2034
2076
  {
2035
- result = val[1]
2077
+ (_, line), list, _ = val
2078
+
2079
+ result = list.line line
2036
2080
  }
2037
2081
 
2038
2082
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2039
2083
  {
2040
- result = s(:array).line lexer.lineno # FIX
2084
+ (_, line), _, _ = val
2085
+
2086
+ result = s(:array).line line
2041
2087
  }
2042
2088
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2043
2089
  {
2044
- result = val[1]
2090
+ (_, line), list, _ = val
2091
+
2092
+ result = list.line line
2045
2093
  }
2046
2094
 
2047
2095
  qword_list: none
@@ -2064,7 +2112,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2064
2112
 
2065
2113
  string_contents: none
2066
2114
  {
2067
- result = s(:str, "").line lexer.lineno
2115
+ line = prev_value_to_lineno _values.last
2116
+ result = s(:str, +"").line line
2068
2117
  }
2069
2118
  | string_contents string_content
2070
2119
  {
@@ -2139,8 +2188,8 @@ regexp_contents: none
2139
2188
  lexer.brace_nest = brace_nest
2140
2189
  lexer.string_nest = string_nest
2141
2190
 
2142
- lexer.cmdarg.pop
2143
2191
  lexer.cond.pop
2192
+ lexer.cmdarg.pop
2144
2193
 
2145
2194
  lexer.lex_state = oldlex_state
2146
2195
 
@@ -2155,29 +2204,42 @@ regexp_contents: none
2155
2204
  when nil then
2156
2205
  result = s(:evstr).line line
2157
2206
  else
2158
- debug20 25
2207
+ debug 38
2159
2208
  raise "unknown string body: #{stmt.inspect}"
2160
2209
  end
2161
2210
  }
2162
2211
 
2163
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2164
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2165
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2212
+ string_dvar: tGVAR
2213
+ {
2214
+ result = wrap :gvar, val[0]
2215
+ }
2216
+ | tIVAR
2217
+ {
2218
+ result = wrap :ivar, val[0]
2219
+ }
2220
+ | tCVAR
2221
+ {
2222
+ result = wrap :cvar, val[0]
2223
+ }
2166
2224
  | backref
2167
2225
 
2168
- symbol: tSYMBEG sym
2226
+ symbol: ssym
2227
+ | dsym
2228
+
2229
+ ssym: tSYMBEG sym
2169
2230
  {
2170
2231
  lexer.lex_state = EXPR_END
2171
- result = val[1].to_sym
2232
+ result = wrap :lit, val[1]
2172
2233
  }
2173
2234
  | tSYMBOL
2174
2235
  {
2175
- result = val[0].to_sym
2236
+ lexer.lex_state = EXPR_END
2237
+ result = wrap :lit, val[0]
2176
2238
  }
2177
2239
 
2178
2240
  sym: fname | tIVAR | tGVAR | tCVAR
2179
2241
 
2180
- dsym: tSYMBEG xstring_contents tSTRING_END
2242
+ dsym: tSYMBEG string_contents tSTRING_END
2181
2243
  {
2182
2244
  _, result, _ = val
2183
2245
 
@@ -2193,14 +2255,15 @@ regexp_contents: none
2193
2255
  when :evstr then
2194
2256
  result = s(:dsym, "", result).line result.line
2195
2257
  else
2196
- debug20 26, val, result
2258
+ debug 39
2197
2259
  end
2198
2260
  }
2199
2261
 
2200
2262
  numeric: simple_numeric
2201
- | tUMINUS_NUM simple_numeric
2263
+ | tUMINUS_NUM simple_numeric =tLOWEST
2202
2264
  {
2203
- result = -val[1] # TODO: pt_testcase
2265
+ _, (num, line) = val
2266
+ result = [-num, line]
2204
2267
  }
2205
2268
 
2206
2269
  simple_numeric: tINTEGER
@@ -2233,8 +2296,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2233
2296
 
2234
2297
  var_ref: user_variable
2235
2298
  {
2236
- var = val[0]
2299
+ raise "NO: #{val.inspect}" if Sexp === val.first
2300
+ (var, line), = val
2237
2301
  result = Sexp === var ? var : self.gettable(var)
2302
+ result.line line
2238
2303
  }
2239
2304
  | keyword_variable
2240
2305
  {
@@ -2249,11 +2314,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2249
2314
  | keyword_variable
2250
2315
  {
2251
2316
  result = self.assignable val[0]
2252
- debug20 29, val, result
2317
+ debug 40
2253
2318
  }
2254
2319
 
2255
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2256
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2320
+ backref: tNTH_REF
2321
+ {
2322
+ (ref, line), = val
2323
+ result = s(:nth_ref, ref).line line
2324
+ }
2325
+ | tBACK_REF
2326
+ {
2327
+ (ref, line), = val
2328
+ result = s(:back_ref, ref).line line
2329
+ }
2257
2330
 
2258
2331
  superclass: tLT
2259
2332
  {
@@ -2271,9 +2344,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2271
2344
 
2272
2345
  f_arglist: tLPAREN2 f_args rparen
2273
2346
  {
2274
- result = val[1]
2275
- self.lexer.lex_state = EXPR_BEG
2276
- self.lexer.command_start = true
2347
+ result = end_args val
2277
2348
  }
2278
2349
  | {
2279
2350
  result = self.in_kwarg
@@ -2282,12 +2353,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2282
2353
  }
2283
2354
  f_args term
2284
2355
  {
2285
- kwarg, args, _ = val
2286
-
2287
- self.in_kwarg = kwarg
2288
- result = args
2289
- lexer.lex_state = EXPR_BEG
2290
- lexer.command_start = true
2356
+ result = end_args val
2291
2357
  }
2292
2358
 
2293
2359
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2372,6 +2438,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2372
2438
  |
2373
2439
  {
2374
2440
  result = args val
2441
+ # result.line lexer.lineno
2375
2442
  }
2376
2443
 
2377
2444
 
@@ -2395,10 +2462,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2395
2462
  f_norm_arg: f_bad_arg
2396
2463
  | tIDENTIFIER
2397
2464
  {
2398
- identifier = val[0].to_sym
2465
+ (id, line), = val
2466
+ identifier = id.to_sym
2399
2467
  self.env[identifier] = :lvar
2400
2468
 
2401
- result = identifier
2469
+ result = [identifier, line]
2402
2470
  }
2403
2471
 
2404
2472
  f_arg_asgn: f_norm_arg
@@ -2406,22 +2474,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2406
2474
  f_arg_item: f_arg_asgn
2407
2475
  | tLPAREN f_margs rparen
2408
2476
  {
2409
- result = val[1]
2477
+ _, margs, _ = val
2478
+
2479
+ result = margs
2410
2480
  }
2411
2481
 
2412
2482
  f_arg: f_arg_item
2413
2483
  {
2414
- arg, = val
2415
-
2416
- case arg
2417
- when Symbol then
2418
- result = s(:args, arg).line lexer.lineno
2419
- when Sexp then
2420
- result = arg
2421
- else
2422
- debug20 32
2423
- raise "Unknown f_arg type: #{val.inspect}"
2424
- end
2484
+ result = new_arg val
2425
2485
  }
2426
2486
  | f_arg tCOMMA f_arg_item
2427
2487
  {
@@ -2433,7 +2493,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2433
2493
  result = s(:args, list).line list.line
2434
2494
  end
2435
2495
 
2436
- result << item
2496
+ result << (Sexp === item ? item : item.first)
2437
2497
  }
2438
2498
 
2439
2499
  f_label: tLABEL
@@ -2494,27 +2554,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2494
2554
  kwrest_mark: tPOW
2495
2555
  | tDSTAR
2496
2556
 
2557
+
2497
2558
  f_kwrest: kwrest_mark tIDENTIFIER
2498
2559
  {
2499
- name = val[1].to_sym
2500
- self.assignable name
2501
- result = :"**#{name}"
2560
+ _, (id, line) = val
2561
+
2562
+ name = id.to_sym
2563
+ self.assignable [name, line]
2564
+ result = [:"**#{name}", line]
2502
2565
  }
2503
2566
  | kwrest_mark
2504
2567
  {
2505
- result = :"**"
2506
- self.env[result] = :lvar
2568
+ id = :"**"
2569
+ self.env[id] = :lvar # TODO: needed?!?
2570
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2507
2571
  }
2508
2572
 
2509
2573
  f_opt: f_arg_asgn tEQL arg_value
2510
2574
  {
2511
- result = self.assignable val[0], val[2]
2575
+ lhs, _, rhs = val
2576
+ result = self.assignable lhs, rhs
2512
2577
  # TODO: detect duplicate names
2513
2578
  }
2514
2579
 
2515
2580
  f_block_opt: f_arg_asgn tEQL primary_value
2516
2581
  {
2517
- result = self.assignable val[0], val[2]
2582
+ lhs, _, rhs = val
2583
+ result = self.assignable lhs, rhs
2518
2584
  }
2519
2585
 
2520
2586
  f_block_optarg: f_block_opt
@@ -2544,30 +2610,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2544
2610
  f_rest_arg: restarg_mark tIDENTIFIER
2545
2611
  {
2546
2612
  # TODO: differs from parse.y - needs tests
2547
- name = val[1].to_sym
2548
- self.assignable name
2549
- result = :"*#{name}"
2613
+ _, (id, line) = val
2614
+ name = id.to_sym
2615
+ self.assignable [name, line]
2616
+ result = [:"*#{name}", line]
2550
2617
  }
2551
2618
  | restarg_mark
2552
2619
  {
2553
2620
  name = :"*"
2554
2621
  self.env[name] = :lvar
2555
- result = name
2622
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2556
2623
  }
2557
2624
 
2558
2625
  blkarg_mark: tAMPER2 | tAMPER
2559
2626
 
2560
2627
  f_block_arg: blkarg_mark tIDENTIFIER
2561
2628
  {
2562
- identifier = val[1].to_sym
2629
+ _, (id, line) = val
2630
+ identifier = id.to_sym
2563
2631
 
2564
2632
  self.env[identifier] = :lvar
2565
- result = "&#{identifier}".to_sym
2633
+ result = ["&#{identifier}".to_sym, line]
2566
2634
  }
2567
2635
 
2568
2636
  opt_f_block_arg: tCOMMA f_block_arg
2569
2637
  {
2570
- result = val[1]
2638
+ _, arg = val
2639
+ result = arg
2571
2640
  }
2572
2641
  |
2573
2642
  {
@@ -2609,16 +2678,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2609
2678
  }
2610
2679
  | tLABEL arg_value
2611
2680
  {
2612
- (label, line), arg = val
2681
+ label, arg = val
2613
2682
 
2614
- lit = s(:lit, label.to_sym).line line
2615
- result = s(:array, lit, arg).line line
2683
+ lit = wrap :lit, label
2684
+ result = s(:array, lit, arg).line lit.line
2616
2685
  }
2617
2686
  | tSTRING_BEG string_contents tLABEL_END arg_value
2618
2687
  {
2619
- _, sym, _, value = val
2688
+ (_, line), sym, _, value = val
2689
+
2620
2690
  sym.sexp_type = :dsym
2621
- result = s(:array, sym, value).line sym.line
2691
+
2692
+ result = s(:array, sym, value).line line
2622
2693
  }
2623
2694
  | tDSTAR arg_value
2624
2695
  {