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/ruby30_parser.y CHANGED
@@ -18,11 +18,11 @@ 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
- tLONELY
25
- tBDOT2 tBDOT3
24
+ tLONELY
25
+ tBDOT2 tBDOT3
26
26
 
27
27
  preclow
28
28
  nonassoc tLOWEST
@@ -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 1
84
84
  yyerror "BEGIN in method"
85
85
  end
86
86
  self.env.extend
@@ -135,7 +135,7 @@ rule
135
135
  | error stmt
136
136
  {
137
137
  result = val[1]
138
- debug20 2, val, result
138
+ debug 2
139
139
  }
140
140
 
141
141
  stmt_or_begin: stmt
@@ -143,6 +143,10 @@ rule
143
143
  {
144
144
  yyerror "BEGIN is permitted only at toplevel"
145
145
  }
146
+ begin_block
147
+ {
148
+ result = val[2] # wtf?
149
+ }
146
150
 
147
151
  stmt: kALIAS fitem
148
152
  {
@@ -155,12 +159,12 @@ rule
155
159
  }
156
160
  | kALIAS tGVAR tGVAR
157
161
  {
158
- (_, line), lhs, rhs = val
162
+ (_, line), (lhs, _), (rhs, _) = val
159
163
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
160
164
  }
161
165
  | kALIAS tGVAR tBACK_REF
162
166
  {
163
- (_, line), lhs, rhs = val
167
+ (_, line), (lhs, _), (rhs, _) = val
164
168
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
165
169
  }
166
170
  | kALIAS tGVAR tNTH_REF
@@ -203,7 +207,7 @@ rule
203
207
  (_, line), _, stmt, _ = val
204
208
 
205
209
  if (self.in_def || self.in_single > 0) then
206
- debug20 3
210
+ debug 3
207
211
  yyerror "END in method; use at_exit"
208
212
  end
209
213
 
@@ -219,6 +223,15 @@ rule
219
223
  lhs, _, rhs = val
220
224
  result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
221
225
  }
226
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
227
+ {
228
+ # unwraps s(:to_ary, rhs)
229
+ lhs, _, (_, rhs), _, resbody = val
230
+
231
+ resbody = new_resbody s(:array).line(resbody.line), resbody
232
+
233
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
234
+ }
222
235
  | mlhs tEQL mrhs_arg
223
236
  {
224
237
  result = new_masgn val[0], val[2]
@@ -243,32 +256,31 @@ rule
243
256
  }
244
257
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
258
  {
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
259
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
260
+
261
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
262
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
263
+ result.line prim.line
252
264
  }
253
265
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
254
266
  {
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
267
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
268
+
269
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
270
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
271
+ result.line prim.line
260
272
  }
261
273
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
262
274
  {
263
- lhs1, _, lhs2, op, rhs = val
275
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
276
 
265
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
277
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
266
278
  }
267
279
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
268
280
  {
269
- lhs1, _, lhs2, op, rhs = val
281
+ lhs1, _, (lhs2, line), (id, _), rhs = val
270
282
 
271
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
283
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
272
284
  }
273
285
  | backref tOP_ASGN command_rhs
274
286
  {
@@ -314,7 +326,86 @@ rule
314
326
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
315
327
  # REFACTOR: call_uni_op -- see parse26.y
316
328
  }
329
+ | arg tASSOC
330
+ {
331
+ # value_expr($1);
332
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
333
+ self.lexer.command_start = false
334
+ result = self.in_kwarg
335
+ self.in_kwarg = true
336
+ self.env.extend
337
+ }
338
+ p_expr
339
+ {
340
+ lhs, _, in_kwarg, rhs = val
341
+
342
+ self.env.unextend
343
+ self.in_kwarg = in_kwarg
344
+
345
+ rhs = new_in rhs, nil, nil, rhs.line
346
+ result = new_case lhs, rhs, rhs.line
347
+ }
317
348
  | arg
349
+ kIN
350
+ {
351
+ # TODO? value_expr($1);
352
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
353
+ self.lexer.command_start = false
354
+ result = self.in_kwarg
355
+ self.in_kwarg = true
356
+ self.env.extend
357
+ }
358
+ p_expr
359
+ {
360
+ self.env.unextend
361
+
362
+ expr, _, old_kwarg, pat = val
363
+
364
+ expr = value_expr expr
365
+
366
+ self.in_kwarg = old_kwarg
367
+ pat_in = new_in pat, nil, nil, expr.line
368
+ result = new_case expr, pat_in, expr.line
369
+ }
370
+ | arg =tLBRACE_ARG
371
+
372
+ def_name: fname
373
+ {
374
+ # TODO: numparam_name(p, fname);
375
+
376
+ (id, line), = val
377
+ old_in_def = self.in_def
378
+
379
+ self.in_def = true # group = local_push
380
+ self.env.extend
381
+ lexer.cmdarg.push false
382
+ lexer.cond.push false
383
+
384
+ result = [id.to_sym, line, old_in_def]
385
+ }
386
+ defn_head: k_def def_name
387
+ {
388
+ _, name = val
389
+ result = name
390
+ }
391
+ defs_head: k_def singleton dot_or_colon
392
+ {
393
+ lexer.lex_state = EXPR_FNAME
394
+ }
395
+ def_name
396
+ {
397
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
398
+ self.in_single += 1 # TODO: remove?
399
+
400
+ # self.in_def = true # local_push
401
+ # self.env.extend
402
+ # lexer.cmdarg.push false
403
+ # lexer.cond.push false
404
+
405
+ _, recv, _, _, name = val
406
+
407
+ result = [recv, name]
408
+ }
318
409
 
319
410
  expr_value: expr
320
411
  {
@@ -339,7 +430,7 @@ rule
339
430
  block_command: block_call
340
431
  | block_call call_op2 operation2 command_args
341
432
  {
342
- blk, _, msg, args = val
433
+ blk, _, (msg, _line), args = val
343
434
  result = new_call(blk, msg.to_sym, args).line blk.line
344
435
  }
345
436
 
@@ -353,15 +444,15 @@ rule
353
444
  _, line, body, _ = val
354
445
 
355
446
  result = body
356
- result.line = line
447
+ result.line line
357
448
 
358
449
  # self.env.unextend
359
450
  }
360
451
 
361
452
  fcall: operation
362
453
  {
363
- msg, = val
364
- result = new_call(nil, msg.to_sym).line lexer.lineno
454
+ (msg, line), = val
455
+ result = new_call(nil, msg.to_sym).line line
365
456
  }
366
457
 
367
458
  command: fcall command_args =tLOWEST
@@ -384,12 +475,14 @@ rule
384
475
  }
385
476
  | primary_value call_op operation2 command_args =tLOWEST
386
477
  {
387
- lhs, callop, op, args = val
478
+ lhs, callop, (op, _), args = val
479
+
388
480
  result = new_call lhs, op.to_sym, args, callop
481
+ result.line lhs.line
389
482
  }
390
483
  | primary_value call_op operation2 command_args cmd_brace_block
391
484
  {
392
- recv, _, msg, args, block = val
485
+ recv, _, (msg, _line), args, block = val
393
486
  call = new_call recv, msg.to_sym, args, val[1]
394
487
 
395
488
  block_dup_check call, block
@@ -399,11 +492,14 @@ rule
399
492
  }
400
493
  | primary_value tCOLON2 operation2 command_args =tLOWEST
401
494
  {
402
- result = new_call val[0], val[2].to_sym, val[3]
495
+ lhs, _, (id, line), args = val
496
+
497
+ result = new_call lhs, id.to_sym, args
498
+ result.line line
403
499
  }
404
500
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
405
501
  {
406
- recv, _, msg, args, block = val
502
+ recv, _, (msg, _line), args, block = val
407
503
  call = new_call recv, msg.to_sym, args
408
504
 
409
505
  block_dup_check call, block
@@ -561,25 +657,29 @@ rule
561
657
  }
562
658
  | primary_value call_op tIDENTIFIER
563
659
  {
564
- result = new_attrasgn val[0], val[2], val[1]
660
+ lhs, call_op, (id, _line) = val
661
+
662
+ result = new_attrasgn lhs, id, call_op
565
663
  }
566
664
  | primary_value tCOLON2 tIDENTIFIER
567
665
  {
568
- recv, _, id = val
666
+ recv, _, (id, _line) = val
569
667
  result = new_attrasgn recv, id
570
668
  }
571
669
  | primary_value call_op tCONSTANT
572
670
  {
573
- result = new_attrasgn val[0], val[2], val[1]
671
+ lhs, call_op, (id, _line) = val
672
+
673
+ result = new_attrasgn lhs, id, call_op
574
674
  }
575
675
  | primary_value tCOLON2 tCONSTANT
576
676
  {
577
677
  if (self.in_def || self.in_single > 0) then
578
- debug20 7
678
+ debug 4
579
679
  yyerror "dynamic constant assignment"
580
680
  end
581
681
 
582
- expr, _, id = val
682
+ expr, _, (id, _line) = val
583
683
  l = expr.line
584
684
 
585
685
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -587,58 +687,65 @@ rule
587
687
  | tCOLON3 tCONSTANT
588
688
  {
589
689
  if (self.in_def || self.in_single > 0) then
590
- debug20 8
690
+ debug 5
591
691
  yyerror "dynamic constant assignment"
592
692
  end
593
693
 
594
- _, id = val
595
- l = lexer.lineno
694
+ _, (id, l) = val
596
695
 
597
696
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
598
697
  }
599
698
  | backref
600
699
  {
601
- self.backref_assign_error val[0]
700
+ ref, = val
701
+
702
+ self.backref_assign_error ref
602
703
  }
603
704
 
604
705
  lhs: user_variable
605
706
  {
606
- line = lexer.lineno
607
- result = self.assignable val[0]
608
- result.line = line
707
+ var, = val
708
+
709
+ result = self.assignable var
609
710
  }
610
711
  | keyword_variable
611
712
  {
612
- line = lexer.lineno
613
- result = self.assignable val[0]
614
- result.line = line
615
- debug20 9, val, result
713
+ var, = val
714
+
715
+ result = self.assignable var
716
+
717
+ debug 6
616
718
  }
617
719
  | primary_value tLBRACK2 opt_call_args rbracket
618
720
  {
619
721
  lhs, _, args, _ = val
722
+
620
723
  result = self.aryset lhs, args
621
724
  }
622
725
  | primary_value call_op tIDENTIFIER # REFACTOR
623
726
  {
624
- lhs, op, id = val
727
+ lhs, op, (id, _line) = val
728
+
625
729
  result = new_attrasgn lhs, id, op
626
730
  }
627
731
  | primary_value tCOLON2 tIDENTIFIER
628
732
  {
629
- lhs, _, id = val
733
+ lhs, _, (id, _line) = val
734
+
630
735
  result = new_attrasgn lhs, id
631
736
  }
632
737
  | primary_value call_op tCONSTANT # REFACTOR?
633
738
  {
634
- result = new_attrasgn val[0], val[2], val[1]
739
+ lhs, call_op, (id, _line) = val
740
+
741
+ result = new_attrasgn lhs, id, call_op
635
742
  }
636
743
  | primary_value tCOLON2 tCONSTANT
637
744
  {
638
- expr, _, id = val
745
+ expr, _, (id, _line) = val
639
746
 
640
747
  if (self.in_def || self.in_single > 0) then
641
- debug20 10
748
+ debug 7
642
749
  yyerror "dynamic constant assignment"
643
750
  end
644
751
 
@@ -647,14 +754,13 @@ rule
647
754
  }
648
755
  | tCOLON3 tCONSTANT
649
756
  {
650
- _, id = val
757
+ _, (id, l) = val
651
758
 
652
759
  if (self.in_def || self.in_single > 0) then
653
- debug20 11
760
+ debug 8
654
761
  yyerror "dynamic constant assignment"
655
762
  end
656
763
 
657
- l = lexer.lineno
658
764
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
659
765
  }
660
766
  | backref
@@ -670,16 +776,16 @@ rule
670
776
 
671
777
  cpath: tCOLON3 cname
672
778
  {
673
- _, name = val
674
- result = s(:colon3, name.to_sym).line lexer.lineno
779
+ result = wrap :colon3, val[1]
675
780
  }
676
781
  | cname
677
782
  {
678
- result = val[0].to_sym
783
+ (id, line), = val
784
+ result = [id.to_sym, line] # TODO: sexp?
679
785
  }
680
786
  | primary_value tCOLON2 cname
681
787
  {
682
- pval, _, name = val
788
+ pval, _, (name, _line) = val
683
789
 
684
790
  result = s(:colon2, pval, name.to_sym)
685
791
  result.line pval.line
@@ -689,24 +795,15 @@ rule
689
795
  | op
690
796
  {
691
797
  lexer.lex_state = EXPR_END
692
- result = val[0]
693
798
  }
694
799
 
695
800
  | reswords
696
- {
697
- (sym, _line), = val
698
- lexer.lex_state = EXPR_END
699
- result = sym
700
- }
701
-
702
- fsym: fname | symbol
703
801
 
704
- fitem: fsym
802
+ fitem: fname
705
803
  {
706
- id, = val
707
- result = s(:lit, id.to_sym).line lexer.lineno
804
+ result = wrap :lit, val[0]
708
805
  }
709
- | dsym
806
+ | symbol
710
807
 
711
808
  undef_list: fitem
712
809
  {
@@ -727,8 +824,6 @@ rule
727
824
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
728
825
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
729
826
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
730
- # TODO: tUBANG dead?
731
- | tUBANG
732
827
 
733
828
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
734
829
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -762,26 +857,22 @@ rule
762
857
  }
763
858
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
764
859
  {
765
- lhs, _, id, op, rhs = val
860
+ lhs, _, (id, _line), (op, _), rhs = val
766
861
 
767
862
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
768
863
  }
769
864
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
770
865
  {
771
- lhs1, _, lhs2, op, rhs = val
866
+ lhs1, _, (lhs2, _line), op, rhs = val
772
867
 
773
868
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
774
869
  result = new_const_op_asgn [lhs, op, rhs]
775
870
  }
776
- | tCOLON3 tCONSTANT
777
- {
778
- result = self.lexer.lineno
779
- }
780
- tOP_ASGN arg_rhs
871
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
781
872
  {
782
- _, lhs, line, op, rhs = val
873
+ _, lhs, op, rhs = val
783
874
 
784
- lhs = s(:colon3, lhs.to_sym).line line
875
+ lhs = wrap :colon3, lhs
785
876
  result = new_const_op_asgn [lhs, op, rhs]
786
877
  }
787
878
  | backref tOP_ASGN arg_rhs
@@ -793,7 +884,7 @@ rule
793
884
  | arg tDOT2 arg
794
885
  {
795
886
  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
887
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
797
888
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
798
889
  else
799
890
  result = s(:dot2, v1, v2).line v1.line
@@ -802,7 +893,7 @@ rule
802
893
  | arg tDOT3 arg
803
894
  {
804
895
  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
896
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
806
897
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
807
898
  else
808
899
  result = s(:dot3, v1, v2).line v1.line
@@ -864,8 +955,9 @@ rule
864
955
  }
865
956
  | tUMINUS_NUM simple_numeric tPOW arg
866
957
  {
867
- lit = s(:lit, val[1]).line lexer.lineno
868
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
958
+ _, num, _, arg = val
959
+ lit = wrap :lit, num
960
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
869
961
 
870
962
  }
871
963
  | tUPLUS arg
@@ -955,6 +1047,22 @@ rule
955
1047
  c, _, t, _, _, f = val
956
1048
  result = s(:if, c, t, f).line c.line
957
1049
  }
1050
+ | defn_head f_opt_paren_args tEQL arg
1051
+ {
1052
+ result = new_endless_defn val
1053
+ }
1054
+ | defn_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1055
+ {
1056
+ result = new_endless_defn val
1057
+ }
1058
+ | defs_head f_opt_paren_args tEQL arg
1059
+ {
1060
+ result = new_endless_defs val
1061
+ }
1062
+ | defs_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1063
+ {
1064
+ result = new_endless_defs val
1065
+ }
958
1066
  | primary
959
1067
 
960
1068
  relop: tGT
@@ -964,12 +1072,12 @@ rule
964
1072
 
965
1073
  rel_expr: arg relop arg =tGT
966
1074
  {
967
- lhs, op, rhs = val
1075
+ lhs, (op, _), rhs = val
968
1076
  result = new_call lhs, op.to_sym, argl(rhs)
969
1077
  }
970
1078
  | rel_expr relop arg =tGT
971
1079
  {
972
- lhs, op, rhs = val
1080
+ lhs, (op, _), rhs = val
973
1081
  warn "comparison '%s' after comparison", op
974
1082
  result = new_call lhs, op.to_sym, argl(rhs)
975
1083
  }
@@ -1178,8 +1286,9 @@ rule
1178
1286
  | backref
1179
1287
  | tFID
1180
1288
  {
1181
- msg, = val
1289
+ (msg, line), = val
1182
1290
  result = new_call nil, msg.to_sym
1291
+ result.line line
1183
1292
  }
1184
1293
  | k_begin
1185
1294
  {
@@ -1221,15 +1330,13 @@ rule
1221
1330
  }
1222
1331
  | primary_value tCOLON2 tCONSTANT
1223
1332
  {
1224
- expr, _, id = val
1333
+ expr, _, (id, _line) = val
1225
1334
 
1226
1335
  result = s(:colon2, expr, id.to_sym).line expr.line
1227
1336
  }
1228
1337
  | tCOLON3 tCONSTANT
1229
1338
  {
1230
- _, id = val
1231
-
1232
- result = s(:colon3, id.to_sym).line lexer.lineno
1339
+ result = wrap :colon3, val[1]
1233
1340
  }
1234
1341
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1235
1342
  {
@@ -1253,15 +1360,21 @@ rule
1253
1360
  }
1254
1361
  | kYIELD tLPAREN2 call_args rparen
1255
1362
  {
1256
- result = new_yield val[2]
1363
+ (_, line), _, args, _ = val
1364
+
1365
+ result = new_yield(args).line line
1257
1366
  }
1258
1367
  | kYIELD tLPAREN2 rparen
1259
1368
  {
1260
- result = new_yield
1369
+ (_, line), _, _ = val
1370
+
1371
+ result = new_yield.line line
1261
1372
  }
1262
1373
  | kYIELD
1263
1374
  {
1264
- result = new_yield
1375
+ (_, line), = val
1376
+
1377
+ result = new_yield.line line
1265
1378
  }
1266
1379
  | kDEFINED opt_nl tLPAREN2 expr rparen
1267
1380
  {
@@ -1276,7 +1389,7 @@ rule
1276
1389
  }
1277
1390
  | kNOT tLPAREN2 rparen
1278
1391
  {
1279
- debug20 14, val, result
1392
+ debug 9
1280
1393
  }
1281
1394
  | fcall brace_block
1282
1395
  {
@@ -1294,9 +1407,10 @@ rule
1294
1407
  iter.insert 1, call # FIX
1295
1408
  result = iter
1296
1409
  }
1297
- | tLAMBDA lambda
1410
+ | lambda
1298
1411
  {
1299
- result = val[1] # TODO: fix lineno
1412
+ expr, = val
1413
+ result = expr
1300
1414
  }
1301
1415
  | k_if expr_value then compstmt if_tail k_end
1302
1416
  {
@@ -1328,6 +1442,12 @@ rule
1328
1442
  (_, line), _, body, _ = val
1329
1443
  result = new_case nil, body, line
1330
1444
  }
1445
+ | k_case expr_value opt_terms p_case_body k_end
1446
+ {
1447
+ (_, line), expr, _, body, _ = val
1448
+
1449
+ result = new_case expr, body, line
1450
+ }
1331
1451
  | k_for for_var kIN expr_value_do compstmt k_end
1332
1452
  {
1333
1453
  _, var, _, iter, body, _ = val
@@ -1339,7 +1459,6 @@ rule
1339
1459
  }
1340
1460
  cpath superclass
1341
1461
  {
1342
- self.comments.push self.lexer.comments
1343
1462
  if (self.in_def || self.in_single > 0) then
1344
1463
  yyerror "class definition in method body"
1345
1464
  end
@@ -1349,7 +1468,7 @@ rule
1349
1468
  {
1350
1469
  result = new_class val
1351
1470
  self.env.unextend
1352
- self.lexer.comments # we don't care about comments in the body
1471
+ self.lexer.ignore_body_comments
1353
1472
  }
1354
1473
  | k_class tLSHFT
1355
1474
  {
@@ -1370,7 +1489,7 @@ rule
1370
1489
  {
1371
1490
  result = new_sclass val
1372
1491
  self.env.unextend
1373
- self.lexer.comments # we don't care about comments in the body
1492
+ self.lexer.ignore_body_comments
1374
1493
  }
1375
1494
  | k_module
1376
1495
  {
@@ -1378,7 +1497,6 @@ rule
1378
1497
  }
1379
1498
  cpath
1380
1499
  {
1381
- self.comments.push self.lexer.comments
1382
1500
  yyerror "module definition in method body" if
1383
1501
  self.in_def or self.in_single > 0
1384
1502
 
@@ -1388,55 +1506,40 @@ rule
1388
1506
  {
1389
1507
  result = new_module val
1390
1508
  self.env.unextend
1391
- self.lexer.comments # we don't care about comments in the body
1392
- }
1393
- | k_def fname
1394
- {
1395
- result = self.in_def
1396
-
1397
- self.in_def = true # group = local_push
1398
- self.env.extend
1399
- lexer.cmdarg.push false
1400
- lexer.cond.push false
1401
-
1402
- self.comments.push self.lexer.comments
1509
+ self.lexer.ignore_body_comments
1403
1510
  }
1404
- f_arglist bodystmt { result = lexer.lineno } k_end
1511
+ | defn_head f_arglist bodystmt k_end
1405
1512
  {
1406
- in_def = val[2]
1513
+ # [ [:f, 1, false], s(:args)...]
1514
+ # =>
1515
+ # [[:k_def, 666], [:f, 1], false, s(:args)...]
1516
+ val.insert 1, val.first.pop
1517
+ val.insert 0, [:k_def, 666]
1407
1518
 
1408
- result = new_defn val
1519
+ result, in_def = new_defn val
1409
1520
 
1410
1521
  lexer.cond.pop # group = local_pop
1411
1522
  lexer.cmdarg.pop
1412
1523
  self.env.unextend
1413
1524
  self.in_def = in_def
1414
1525
 
1415
- self.lexer.comments # we don't care about comments in the body
1416
- }
1417
- | k_def singleton dot_or_colon
1418
- {
1419
- lexer.lex_state = EXPR_FNAME
1526
+ self.lexer.ignore_body_comments
1420
1527
  }
1421
- fname
1528
+ | defs_head f_arglist bodystmt k_end
1422
1529
  {
1423
- result = [self.in_def, lexer.lineno]
1424
-
1425
- self.in_single += 1 # TODO: remove?
1530
+ # [ [recv, [:name, 1, false]], s(:args...]
1531
+ # =>
1532
+ # [ recv, [:name, 1, false], s(:args...]
1533
+ # =>
1534
+ # [ recv, [:name, 1], false, s(:args...]
1535
+ # =>
1536
+ # [ :k_def, recv, [:name, 1], false, s(:args...]
1426
1537
 
1427
- self.in_def = true # local_push
1428
- self.env.extend
1429
- lexer.cmdarg.push false
1430
- lexer.cond.push false
1431
-
1432
- lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1433
- self.comments.push self.lexer.comments
1434
- }
1435
- f_arglist bodystmt k_end
1436
- {
1437
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1538
+ val.prepend(*val.shift)
1539
+ val.insert 2, val[1].pop
1540
+ val.insert 0, [:k_def, 666]
1438
1541
 
1439
- result = new_defs val
1542
+ result, in_def = new_defs val
1440
1543
 
1441
1544
  lexer.cond.pop # group = local_pop
1442
1545
  lexer.cmdarg.pop
@@ -1447,7 +1550,7 @@ rule
1447
1550
 
1448
1551
  # TODO: restore cur_arg ? what's cur_arg?
1449
1552
 
1450
- self.lexer.comments # we don't care about comments in the body
1553
+ self.lexer.ignore_body_comments
1451
1554
  }
1452
1555
  | kBREAK
1453
1556
  {
@@ -1484,8 +1587,17 @@ rule
1484
1587
  k_case: kCASE
1485
1588
  k_for: kFOR
1486
1589
  k_class: kCLASS
1590
+ {
1591
+ self.comments.push self.lexer.comments
1592
+ }
1487
1593
  k_module: kMODULE
1594
+ {
1595
+ self.comments.push self.lexer.comments
1596
+ }
1488
1597
  k_def: kDEF
1598
+ {
1599
+ self.comments.push self.lexer.comments
1600
+ }
1489
1601
  k_do: kDO
1490
1602
  k_do_block: kDO_BLOCK
1491
1603
  k_rescue: kRESCUE
@@ -1546,52 +1658,47 @@ rule
1546
1658
 
1547
1659
  result = block_var args
1548
1660
  }
1549
- | f_marg_list tCOMMA tSTAR f_norm_arg
1661
+ | f_marg_list tCOMMA f_rest_marg
1550
1662
  {
1551
- args, _, _, splat = val
1663
+ args, _, rest = val
1552
1664
 
1553
- result = block_var args, "*#{splat}".to_sym
1665
+ result = block_var args, rest
1554
1666
  }
1555
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1667
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1556
1668
  {
1557
- args, _, _, splat, _, args2 = val
1669
+ lhs, _, splat, _, rhs = val
1558
1670
 
1559
- result = block_var args, "*#{splat}".to_sym, args2
1671
+ result = block_var lhs, splat, rhs
1560
1672
  }
1561
- | f_marg_list tCOMMA tSTAR
1673
+ | f_rest_marg
1562
1674
  {
1563
- args, _, _ = val
1675
+ rest, = val
1564
1676
 
1565
- result = block_var args, :*
1677
+ result = block_var rest
1566
1678
  }
1567
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1679
+ | f_rest_marg tCOMMA f_marg_list
1568
1680
  {
1569
- args, _, _, _, args2 = val
1681
+ splat, _, rest = val
1570
1682
 
1571
- result = block_var args, :*, args2
1683
+ result = block_var splat, rest
1572
1684
  }
1573
- | tSTAR f_norm_arg
1574
- {
1575
- _, splat = val
1576
1685
 
1577
- result = block_var :"*#{splat}"
1578
- }
1579
- | tSTAR f_norm_arg tCOMMA f_marg_list
1686
+ f_rest_marg: tSTAR f_norm_arg
1580
1687
  {
1581
- _, splat, _, args = val
1688
+ _, (id, line) = val
1582
1689
 
1583
- result = block_var :"*#{splat}", args
1690
+ result = args ["*#{id}".to_sym]
1691
+ result.line line
1584
1692
  }
1585
1693
  | tSTAR
1586
1694
  {
1587
- result = block_var :*
1695
+ result = args [:*]
1696
+ result.line lexer.lineno # FIX: tSTAR -> line
1588
1697
  }
1589
- | tSTAR tCOMMA f_marg_list
1590
- {
1591
- _, _, args = val
1592
1698
 
1593
- result = block_var :*, args
1594
- }
1699
+ f_any_kwrest: f_kwrest
1700
+ | f_no_kwarg
1701
+
1595
1702
 
1596
1703
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1597
1704
  {
@@ -1601,14 +1708,14 @@ rule
1601
1708
  {
1602
1709
  result = call_args val
1603
1710
  }
1604
- | f_kwrest opt_f_block_arg
1711
+ | f_any_kwrest opt_f_block_arg
1605
1712
  {
1606
1713
  result = call_args val
1607
1714
  }
1608
1715
  | f_block_arg
1609
1716
  {
1610
- line = lexer.lineno
1611
- result = call_args val # TODO: push line down
1717
+ (id, line), = val
1718
+ result = call_args [id]
1612
1719
  result.line line
1613
1720
  }
1614
1721
 
@@ -1618,6 +1725,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1618
1725
  }
1619
1726
  | none
1620
1727
 
1728
+ excessed_comma: tCOMMA
1729
+ {
1730
+ result = s(:WTF_COMMA!)
1731
+ }
1732
+
1621
1733
  block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1622
1734
  {
1623
1735
  result = args val
@@ -1638,9 +1750,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1638
1750
  {
1639
1751
  result = args val
1640
1752
  }
1641
- | f_arg tCOMMA
1753
+ | f_arg excessed_comma
1642
1754
  {
1643
- result = args(val) << nil
1755
+ arg, _ = val
1756
+ result = arg << nil
1644
1757
  }
1645
1758
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1646
1759
  {
@@ -1717,13 +1830,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1717
1830
 
1718
1831
  bvar: tIDENTIFIER
1719
1832
  {
1720
- id, = val
1721
- line = lexer.lineno
1722
- result = s(:shadow, id.to_sym).line line
1833
+ result = wrap :shadow, val[0]
1723
1834
  }
1724
1835
  | f_bad_arg
1725
1836
 
1726
- lambda: {
1837
+ lambda: tLAMBDA
1838
+ {
1727
1839
  self.env.extend :dynamic
1728
1840
  result = [lexer.lineno, lexer.lpar_beg]
1729
1841
  lexer.paren_nest += 1
@@ -1735,14 +1847,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1735
1847
  }
1736
1848
  lambda_body
1737
1849
  {
1738
- (line, lpar), args, _cmdarg, body = val
1850
+ _, (line, lpar), args, _cmdarg, body = val
1739
1851
  lexer.lpar_beg = lpar
1740
1852
 
1741
1853
  lexer.cmdarg.pop
1742
1854
 
1743
1855
  call = s(:lambda).line line
1744
1856
  result = new_iter call, args, body
1745
- result.line = line
1857
+ result.line line
1746
1858
  self.env.unextend # TODO: dynapush & dynapop
1747
1859
  }
1748
1860
 
@@ -1777,23 +1889,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1777
1889
  ## if (nd_type($1) == NODE_YIELD) {
1778
1890
  ## compile_error(PARSER_ARG "block given to yield");
1779
1891
 
1780
- syntax_error "Both block arg and actual block given." if
1781
- val[0].block_pass?
1892
+ cmd, blk = val
1782
1893
 
1783
- val = invert_block_call val if inverted? val
1894
+ syntax_error "Both block arg and actual block given." if
1895
+ cmd.block_pass?
1784
1896
 
1785
- cmd, blk = val
1897
+ if inverted? val then
1898
+ val = invert_block_call val
1899
+ cmd, blk = val
1900
+ end
1786
1901
 
1787
1902
  result = blk
1788
1903
  result.insert 1, cmd
1789
1904
  }
1790
1905
  | block_call call_op2 operation2 opt_paren_args
1791
1906
  {
1792
- result = new_call val[0], val[2].to_sym, val[3]
1907
+ lhs, _, (id, _line), args = val
1908
+
1909
+ result = new_call lhs, id.to_sym, args
1793
1910
  }
1794
1911
  | block_call call_op2 operation2 opt_paren_args brace_block
1795
1912
  {
1796
- iter1, _, name, args, iter2 = val
1913
+ iter1, _, (name, _line), args, iter2 = val
1797
1914
 
1798
1915
  call = new_call iter1, name.to_sym, args
1799
1916
  iter2.insert 1, call
@@ -1802,7 +1919,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1919
  }
1803
1920
  | block_call call_op2 operation2 command_args do_block
1804
1921
  {
1805
- iter1, _, name, args, iter2 = val
1922
+ iter1, _, (name, _line), args, iter2 = val
1806
1923
 
1807
1924
  call = new_call iter1, name.to_sym, args
1808
1925
  iter2.insert 1, call
@@ -1810,28 +1927,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1810
1927
  result = iter2
1811
1928
  }
1812
1929
 
1813
- method_call: fcall
1930
+ method_call: fcall paren_args
1814
1931
  {
1815
- result = self.lexer.lineno
1816
- }
1817
- paren_args
1818
- {
1819
- call, lineno, args = val
1932
+ call, args = val
1820
1933
 
1821
1934
  result = call.concat args.sexp_body if args
1822
- result.line lineno
1823
1935
  }
1824
1936
  | primary_value call_op operation2 opt_paren_args
1825
1937
  {
1826
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1938
+ recv, call_op, (op, _line), args = val
1939
+
1940
+ result = new_call recv, op.to_sym, args, call_op
1827
1941
  }
1828
1942
  | primary_value tCOLON2 operation2 paren_args
1829
1943
  {
1830
- result = new_call val[0], val[2].to_sym, val[3]
1944
+ recv, _, (op, _line), args = val
1945
+
1946
+ result = new_call recv, op.to_sym, args
1831
1947
  }
1832
1948
  | primary_value tCOLON2 operation3
1833
1949
  {
1834
- result = new_call val[0], val[2].to_sym
1950
+ lhs, _, (id, _line) = val
1951
+
1952
+ result = new_call lhs, id.to_sym
1835
1953
  }
1836
1954
  | primary_value call_op paren_args
1837
1955
  {
@@ -1864,7 +1982,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1864
1982
  _, line, body, _ = val
1865
1983
 
1866
1984
  result = body
1867
- result.line = line
1985
+ result.line line
1868
1986
 
1869
1987
  self.env.unextend
1870
1988
  }
@@ -1878,7 +1996,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1878
1996
  _, line, body, _ = val
1879
1997
 
1880
1998
  result = body
1881
- result.line = line
1999
+ result.line line
1882
2000
 
1883
2001
  self.env.unextend
1884
2002
  }
@@ -1907,102 +2025,635 @@ opt_block_args_tail: tCOMMA block_args_tail
1907
2025
  self.env.unextend
1908
2026
  }
1909
2027
 
2028
+ case_args: arg_value
2029
+ {
2030
+ arg, = val
2031
+
2032
+ result = s(:array, arg).line arg.line
2033
+ }
2034
+ | tSTAR arg_value
2035
+ {
2036
+ _, arg = val
2037
+
2038
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2039
+ }
2040
+ | case_args tCOMMA arg_value
2041
+ {
2042
+ args, _, id = val
2043
+
2044
+ result = self.list_append args, id
2045
+ }
2046
+ | case_args tCOMMA tSTAR arg_value
2047
+ {
2048
+ args, _, _, id = val
2049
+
2050
+ result = self.list_append args, s(:splat, id).line(id.line)
2051
+ }
2052
+
1910
2053
  case_body: k_when
1911
2054
  {
1912
2055
  result = self.lexer.lineno
1913
2056
  }
1914
- args then compstmt cases
2057
+ case_args then compstmt cases
1915
2058
  {
1916
2059
  result = new_when(val[2], val[4])
1917
- result.line = val[1]
2060
+ result.line val[1]
1918
2061
  result << val[5] if val[5]
1919
2062
  }
1920
2063
 
1921
2064
  cases: opt_else | case_body
2065
+ ######################################################################
1922
2066
 
1923
- opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2067
+ p_case_body: kIN
1924
2068
  {
1925
- (_, line), klasses, var, _, body, rest = val
1926
-
1927
- klasses ||= s(:array)
1928
- klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1929
- klasses.line line
1930
-
1931
- result = new_resbody(klasses, body)
1932
- result << rest if rest # UGH, rewritten above
2069
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2070
+ self.lexer.command_start = false
2071
+ result = self.in_kwarg
2072
+ self.in_kwarg = true
2073
+ push_pvtbl
2074
+ push_pktbl
1933
2075
  }
1934
- |
2076
+ p_top_expr then
1935
2077
  {
1936
- result = nil
2078
+ pop_pktbl
2079
+ pop_pvtbl
2080
+ old_kwargs = _values[-3]
2081
+ self.in_kwarg = old_kwargs
1937
2082
  }
1938
-
1939
- exc_list: arg_value
2083
+ compstmt
2084
+ p_cases
1940
2085
  {
1941
- arg, = val
1942
- result = s(:array, arg).line arg.line
2086
+ (_, line), _, pat, _, _, body, cases = val
2087
+
2088
+ result = new_in pat, body, cases, line
1943
2089
  }
1944
- | mrhs
1945
- | none
1946
2090
 
1947
- exc_var: tASSOC lhs
2091
+ p_cases: opt_else
2092
+ | p_case_body
2093
+
2094
+ p_top_expr: p_top_expr_body
2095
+ | p_top_expr_body kIF_MOD expr_value
1948
2096
  {
1949
- result = val[1]
1950
- }
1951
- | none
2097
+ body, _, cond = val
2098
+ body = remove_begin body
1952
2099
 
1953
- opt_ensure: k_ensure compstmt
2100
+ result = s(:if, cond, body, nil).line body.line
2101
+ }
2102
+ | p_top_expr_body kUNLESS_MOD expr_value
1954
2103
  {
1955
- (_, line), body = val
2104
+ body, _, cond = val
2105
+ body = remove_begin body
1956
2106
 
1957
- result = body || s(:nil).line(line)
2107
+ result = s(:if, cond, nil, body).line body.line
1958
2108
  }
1959
- | none
1960
2109
 
1961
- literal: numeric
2110
+ p_top_expr_body: p_expr
2111
+ | p_expr tCOMMA
1962
2112
  {
1963
- line = lexer.lineno
1964
- result = s(:lit, val[0])
1965
- result.line = line
2113
+ expr, _ = val
2114
+
2115
+ tail = new_array_pattern_tail nil, true, nil, nil
2116
+ result = new_array_pattern nil, expr, tail, expr.line
1966
2117
  }
1967
- | symbol
2118
+ | p_expr tCOMMA p_args
1968
2119
  {
1969
- line = lexer.lineno
1970
- result = s(:lit, val[0])
1971
- result.line = line
1972
- }
1973
- | dsym
2120
+ expr, _, args = val
1974
2121
 
1975
- strings: string
1976
- {
1977
- str, = val
1978
- str = s(:dstr, str.value) if str.sexp_type == :evstr
1979
- result = str
2122
+ result = new_array_pattern nil, expr, args, expr.line
1980
2123
  }
2124
+ | p_find
2125
+ {
2126
+ find, = val
1981
2127
 
1982
- string: tCHAR
2128
+ result = new_find_pattern nil, find
2129
+ }
2130
+ | p_args_tail
1983
2131
  {
1984
- debug20 23, val, result
2132
+ args, = val
2133
+ result = new_array_pattern nil, nil, args, args.line
1985
2134
  }
1986
- | string1
1987
- | string string1
2135
+ | p_kwargs
1988
2136
  {
1989
- result = self.literal_concat val[0], val[1]
2137
+ kwargs, = val
2138
+ result = new_hash_pattern nil, kwargs, kwargs.line
1990
2139
  }
1991
2140
 
1992
- string1: tSTRING_BEG string_contents tSTRING_END
2141
+ p_expr: p_as
2142
+
2143
+ p_as: p_expr tASSOC p_variable
1993
2144
  {
1994
- _, str, (_, func) = val
2145
+ # NODE *n = NEW_LIST($1, &@$);
2146
+ # n = list_append(p, n, $3);
2147
+ # $$ = new_hash(p, n, &@$);
1995
2148
 
1996
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2149
+ expr, _, var = val
1997
2150
 
1998
- result = str
2151
+ id = var.last
2152
+
2153
+ self.env[id] = :lvar # HACK: need to extend env
2154
+ lhs = s(:lasgn, id).line var.line
2155
+
2156
+ result = new_assign lhs, expr
1999
2157
  }
2000
- | tSTRING
2158
+ | p_alt
2159
+
2160
+ p_alt: p_alt tPIPE p_expr_basic
2001
2161
  {
2002
- result = new_string val
2162
+ lhs, _, rhs = val
2163
+
2164
+ result = s(:or, lhs, rhs).line lhs.line
2003
2165
  }
2166
+ | p_expr_basic
2004
2167
 
2005
- xstring: tXSTRING_BEG xstring_contents tSTRING_END
2168
+ p_lparen: tLPAREN2 { push_pktbl }
2169
+ p_lbracket: tLBRACK2 { push_pktbl }
2170
+
2171
+ p_expr_basic: p_value
2172
+ | p_const p_lparen p_args tRPAREN
2173
+ {
2174
+ lhs, _, args, _ = val
2175
+
2176
+ pop_pktbl
2177
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2178
+ }
2179
+ | p_const p_lparen p_find tRPAREN
2180
+ {
2181
+ const, _, find, _ = val
2182
+
2183
+ pop_pktbl
2184
+ result = new_find_pattern(const, find).line const.line
2185
+ }
2186
+ | p_const p_lparen p_kwargs tRPAREN
2187
+ {
2188
+ lhs, _, kwargs, _ = val
2189
+
2190
+ pop_pktbl
2191
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2192
+ }
2193
+ | p_const tLPAREN2 tRPAREN
2194
+ {
2195
+ const, _, _ = val
2196
+
2197
+ tail = new_array_pattern_tail nil, nil, nil, nil
2198
+ result = new_array_pattern const, nil, tail, const.line
2199
+ }
2200
+ | p_const p_lbracket p_args rbracket
2201
+ {
2202
+ const, _, pre_arg, _ = val
2203
+
2204
+ pop_pktbl
2205
+ result = new_array_pattern const, nil, pre_arg, const.line
2206
+ }
2207
+ | p_const p_lbracket p_find rbracket
2208
+ {
2209
+ const, _, find, _ = val
2210
+
2211
+ pop_pktbl
2212
+ result = new_find_pattern(const, find).line const.line
2213
+ }
2214
+ | p_const p_lbracket p_kwargs rbracket
2215
+ {
2216
+ const, _, kwargs, _ = val
2217
+
2218
+ result = new_hash_pattern const, kwargs, const.line
2219
+ }
2220
+ | p_const tLBRACK2 rbracket
2221
+ {
2222
+ const, _, _ = val
2223
+
2224
+ tail = new_array_pattern_tail nil, nil, nil, nil
2225
+ result = new_array_pattern const, nil, tail, const.line
2226
+ }
2227
+ | tLBRACK p_args rbracket
2228
+ {
2229
+ _, pat, _ = val
2230
+
2231
+ result = new_array_pattern nil, nil, pat, pat.line
2232
+ }
2233
+ | tLBRACK p_find rbracket
2234
+ {
2235
+ _, find, _ = val
2236
+
2237
+ result = new_find_pattern nil, find
2238
+ }
2239
+ | tLBRACK rbracket
2240
+ {
2241
+ (_, line), _ = val
2242
+
2243
+ result = s(:array_pat).line line
2244
+ }
2245
+ | tLBRACE
2246
+ {
2247
+ push_pktbl
2248
+ result = self.in_kwarg
2249
+ self.in_kwarg = false
2250
+ }
2251
+ p_kwargs rbrace
2252
+ {
2253
+ _, in_kwarg, kwargs, _ = val
2254
+
2255
+ pop_pktbl
2256
+ self.in_kwarg = in_kwarg
2257
+
2258
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2259
+ }
2260
+ | tLBRACE rbrace
2261
+ {
2262
+ (_, line), _ = val
2263
+
2264
+ tail = new_hash_pattern_tail nil, nil, line
2265
+ result = new_hash_pattern nil, tail, line
2266
+ }
2267
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2268
+ {
2269
+ _, _, expr, _ = val
2270
+
2271
+ pop_pktbl
2272
+ result = expr
2273
+ }
2274
+
2275
+ p_args: p_expr
2276
+ {
2277
+ expr, = val
2278
+
2279
+ ary = s(:array_TAIL, expr).line expr.line
2280
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2281
+ }
2282
+ | p_args_head
2283
+ {
2284
+ head, = val
2285
+
2286
+ result = new_array_pattern_tail head, true, nil, nil
2287
+ }
2288
+ | p_args_head p_arg
2289
+ {
2290
+ head, tail = val
2291
+
2292
+ both = array_pat_concat head, tail
2293
+
2294
+ result = new_array_pattern_tail both, nil, nil, nil
2295
+ result.line head.line
2296
+ }
2297
+ | p_args_head tSTAR tIDENTIFIER
2298
+ {
2299
+ head, _, (id, _line) = val
2300
+
2301
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2302
+ result.line head.line
2303
+ }
2304
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2305
+ {
2306
+ head, _, (id, _line), _, post = val
2307
+
2308
+ result = new_array_pattern_tail head, true, id.to_sym, post
2309
+ result.line head.line
2310
+ }
2311
+ | p_args_head tSTAR
2312
+ {
2313
+ expr, _ = val
2314
+
2315
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2316
+ }
2317
+ | p_args_head tSTAR tCOMMA p_args_post
2318
+ {
2319
+ head, _, _, post = val
2320
+
2321
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2322
+ }
2323
+ | p_args_tail
2324
+
2325
+ p_args_head: p_arg tCOMMA
2326
+ {
2327
+ arg, _ = val
2328
+ result = arg
2329
+ }
2330
+ | p_args_head p_arg tCOMMA
2331
+ {
2332
+ head, tail, _ = val
2333
+
2334
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2335
+ result.line head.line
2336
+ }
2337
+
2338
+ p_args_tail: p_rest
2339
+ {
2340
+ (id, line), = val
2341
+
2342
+ result = new_array_pattern_tail nil, true, id, nil
2343
+ result.line line
2344
+ }
2345
+ | p_rest tCOMMA p_args_post
2346
+ {
2347
+ (id, line), _, rhs = val
2348
+
2349
+ result = new_array_pattern_tail nil, true, id, rhs
2350
+ result.line line
2351
+ }
2352
+
2353
+ p_find: p_rest tCOMMA p_args_post tCOMMA p_rest
2354
+ {
2355
+ lhs, _, mid, _, rhs = val
2356
+
2357
+ result = new_find_pattern_tail lhs, mid, rhs
2358
+ }
2359
+
2360
+ p_rest: tSTAR tIDENTIFIER
2361
+ {
2362
+ _, (id, line) = val
2363
+
2364
+ result = [id.to_sym, line]
2365
+ }
2366
+ | tSTAR
2367
+ {
2368
+ (_id, line), = val
2369
+
2370
+ result = [nil, line]
2371
+ }
2372
+
2373
+ p_args_post: p_arg
2374
+ | p_args_post tCOMMA p_arg
2375
+ {
2376
+ lhs, _, rhs = val
2377
+
2378
+ result = array_pat_concat lhs, rhs
2379
+ }
2380
+
2381
+ p_arg: p_expr
2382
+ {
2383
+ expr, = val
2384
+ expr = s(:array_TAIL, expr).line expr.line unless
2385
+ expr.sexp_type == :array_TAIL
2386
+ result = expr
2387
+ }
2388
+
2389
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2390
+ {
2391
+ kw_arg, _, rest = val
2392
+ # TODO? new_unique_key_hash(p, $1, &@$)
2393
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2394
+ }
2395
+ | p_kwarg
2396
+ {
2397
+ kwarg, = val
2398
+ # TODO? new_unique_key_hash(p, $1, &@$)
2399
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2400
+ }
2401
+ | p_kwarg tCOMMA
2402
+ {
2403
+ kwarg, _ = val
2404
+ # TODO? new_unique_key_hash(p, $1, &@$)
2405
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2406
+ }
2407
+ | p_any_kwrest
2408
+ {
2409
+ rest, = val
2410
+
2411
+ result = new_hash_pattern_tail nil, rest, rest.line
2412
+ }
2413
+
2414
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2415
+ | p_kwarg tCOMMA p_kw
2416
+ {
2417
+ kwarg, _, kw = val
2418
+ kwarg.concat kw.sexp_body
2419
+ result = kwarg
2420
+ }
2421
+
2422
+ p_kw: p_kw_label p_expr
2423
+ {
2424
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2425
+ lhs, rhs = val
2426
+
2427
+ result = s(:PAIR, lhs, rhs).line lhs.line
2428
+ }
2429
+ | p_kw_label
2430
+ {
2431
+ lhs, = val
2432
+
2433
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2434
+
2435
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2436
+ # yyerror1(&@1, "key must be valid as local variables");
2437
+ # }
2438
+
2439
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2440
+ # assignable(p, $1, 0, &@$));
2441
+
2442
+ case lhs.sexp_type
2443
+ when :lit then
2444
+ assignable [lhs.value, lhs.line]
2445
+ else
2446
+ # TODO or done?
2447
+ debug 10
2448
+ end
2449
+
2450
+ # TODO PAIR -> LIST ?
2451
+ result = s(:PAIR, lhs, nil).line lhs.line
2452
+ }
2453
+
2454
+ p_kw_label: tLABEL
2455
+ {
2456
+ result = wrap :lit, val[0]
2457
+ }
2458
+
2459
+ p_kwrest: kwrest_mark tIDENTIFIER
2460
+ {
2461
+ _, (id, line) = val
2462
+
2463
+ name = id.to_sym
2464
+ self.assignable [name, line]
2465
+ result = s(:kwrest, :"**#{name}").line line
2466
+ }
2467
+ | kwrest_mark
2468
+ {
2469
+ (_, line), = val
2470
+
2471
+ result = s(:kwrest, :"**").line line
2472
+ }
2473
+
2474
+ p_kwnorest: kwrest_mark kNIL
2475
+ {
2476
+ (_, line), _ = val
2477
+
2478
+ # TODO: or s(:norest)? s(:**nil)?
2479
+ result = s(:kwrest, :"**nil").line line
2480
+ }
2481
+
2482
+ p_any_kwrest: p_kwrest
2483
+ | p_kwnorest
2484
+
2485
+ p_value: p_primitive
2486
+ | p_primitive tDOT2 p_primitive
2487
+ {
2488
+ lhs, _, rhs = val
2489
+
2490
+ lhs = value_expr lhs
2491
+ rhs = value_expr rhs
2492
+
2493
+ result = s(:dot2, lhs, rhs).line lhs.line
2494
+ }
2495
+ | p_primitive tDOT3 p_primitive
2496
+ {
2497
+ lhs, _, rhs = val
2498
+
2499
+ lhs = value_expr lhs
2500
+ rhs = value_expr rhs
2501
+
2502
+ result = s(:dot3, lhs, rhs).line lhs.line
2503
+ }
2504
+ | p_primitive tDOT2
2505
+ {
2506
+ v1, _ = val
2507
+
2508
+ result = s(:dot2, v1, nil).line v1.line
2509
+ }
2510
+ | p_primitive tDOT3
2511
+ {
2512
+ v1, _ = val
2513
+
2514
+ result = s(:dot3, v1, nil).line v1.line
2515
+ }
2516
+ | p_variable
2517
+ | p_var_ref
2518
+ | p_const
2519
+ | tBDOT2 p_primitive
2520
+ {
2521
+ _, v1 = val
2522
+
2523
+ result = s(:dot2, nil, v1).line v1.line
2524
+ }
2525
+ | tBDOT3 p_primitive
2526
+ {
2527
+ _, v1 = val
2528
+
2529
+ result = s(:dot3, nil, v1).line v1.line
2530
+ }
2531
+
2532
+ p_primitive: literal
2533
+ | strings
2534
+ | xstring
2535
+ | regexp
2536
+ | words
2537
+ | qwords
2538
+ | symbols
2539
+ | qsymbols
2540
+ | keyword_variable
2541
+ {
2542
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2543
+ var, = val
2544
+
2545
+ result = var
2546
+ }
2547
+ | lambda
2548
+
2549
+ p_variable: tIDENTIFIER
2550
+ {
2551
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2552
+ # TODO: assignable(p, $1, 0, &@$);
2553
+ result = wrap :lvar, val[0]
2554
+ }
2555
+
2556
+ p_var_ref: tCARET tIDENTIFIER
2557
+ {
2558
+ # TODO: check id against env for lvar or dvar
2559
+ result = wrap :lvar, val[1]
2560
+ }
2561
+
2562
+
2563
+ p_const: tCOLON3 cname
2564
+ {
2565
+ result = wrap :colon3, val[1]
2566
+ }
2567
+ | p_const tCOLON2 cname
2568
+ {
2569
+ lhs, _, (id, _line) = val
2570
+
2571
+ l = lhs.line
2572
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2573
+ }
2574
+ | tCONSTANT
2575
+ {
2576
+ # TODO $$ = gettable(p, $1, &@$);
2577
+ result = wrap :const, val[0]
2578
+ }
2579
+ ######################################################################
2580
+
2581
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2582
+ {
2583
+ (_, line), klasses, var, _, body, rest = val
2584
+
2585
+ klasses ||= s(:array)
2586
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
2587
+ klasses.line line
2588
+
2589
+ result = new_resbody(klasses, body)
2590
+ result << rest if rest # UGH, rewritten above
2591
+ }
2592
+ |
2593
+ {
2594
+ result = nil
2595
+ }
2596
+
2597
+ exc_list: arg_value
2598
+ {
2599
+ arg, = val
2600
+ result = s(:array, arg).line arg.line
2601
+ }
2602
+ | mrhs
2603
+ | none
2604
+
2605
+ exc_var: tASSOC lhs
2606
+ {
2607
+ result = val[1]
2608
+ }
2609
+ | none
2610
+
2611
+ opt_ensure: k_ensure compstmt
2612
+ {
2613
+ (_, line), body = val
2614
+
2615
+ result = body || s(:nil).line(line)
2616
+ }
2617
+ | none
2618
+
2619
+ literal: numeric
2620
+ {
2621
+ (lit, line), = val
2622
+ result = s(:lit, lit).line line
2623
+ }
2624
+ | symbol
2625
+
2626
+ strings: string
2627
+ {
2628
+ str, = val
2629
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2630
+ result = str
2631
+ }
2632
+
2633
+ string: tCHAR
2634
+ {
2635
+ debug 12
2636
+ }
2637
+ | string1
2638
+ | string string1
2639
+ {
2640
+ result = self.literal_concat val[0], val[1]
2641
+ }
2642
+
2643
+ string1: tSTRING_BEG string_contents tSTRING_END
2644
+ {
2645
+ (_, line), str, (_, func) = val
2646
+
2647
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2648
+
2649
+ result = str.line line
2650
+ }
2651
+ | tSTRING
2652
+ {
2653
+ result = new_string val
2654
+ }
2655
+
2656
+ xstring: tXSTRING_BEG xstring_contents tSTRING_END
2006
2657
  {
2007
2658
  result = new_xstring val
2008
2659
  # TODO: dedent?!?! SERIOUSLY?!?
@@ -2015,11 +2666,15 @@ opt_block_args_tail: tCOMMA block_args_tail
2015
2666
 
2016
2667
  words: tWORDS_BEG tSPACE tSTRING_END
2017
2668
  {
2018
- result = s(:array).line lexer.lineno
2669
+ (_, line), _, _ = val
2670
+
2671
+ result = s(:array).line line
2019
2672
  }
2020
2673
  | tWORDS_BEG word_list tSTRING_END
2021
2674
  {
2022
- result = val[1]
2675
+ (_, line), list, _ = val
2676
+
2677
+ result = list.line line
2023
2678
  }
2024
2679
 
2025
2680
  word_list: none
@@ -2039,18 +2694,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2039
2694
 
2040
2695
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2041
2696
  {
2042
- result = s(:array).line lexer.lineno
2697
+ (_, line), _, _ = val
2698
+
2699
+ result = s(:array).line line
2043
2700
  }
2044
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2701
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2045
2702
  {
2046
- _, line, list, _, = val
2047
- list.line = line
2703
+ (_, line), list, _, = val
2704
+ list.line line
2048
2705
  result = list
2049
2706
  }
2050
2707
 
2051
2708
  symbol_list: none
2052
2709
  {
2053
- result = new_symbol_list.line lexer.lineno
2710
+ result = new_symbol_list
2054
2711
  }
2055
2712
  | symbol_list word tSPACE
2056
2713
  {
@@ -2060,20 +2717,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2060
2717
 
2061
2718
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2062
2719
  {
2063
- result = s(:array).line lexer.lineno
2720
+ (_, line), _, _ = val
2721
+
2722
+ result = s(:array).line line
2064
2723
  }
2065
2724
  | tQWORDS_BEG qword_list tSTRING_END
2066
2725
  {
2067
- result = val[1]
2726
+ (_, line), list, _ = val
2727
+
2728
+ result = list.line line
2068
2729
  }
2069
2730
 
2070
2731
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2071
2732
  {
2072
- result = s(:array).line lexer.lineno # FIX
2733
+ (_, line), _, _ = val
2734
+
2735
+ result = s(:array).line line
2073
2736
  }
2074
2737
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2075
2738
  {
2076
- result = val[1]
2739
+ (_, line), list, _ = val
2740
+
2741
+ result = list.line line
2077
2742
  }
2078
2743
 
2079
2744
  qword_list: none
@@ -2096,7 +2761,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2096
2761
 
2097
2762
  string_contents: none
2098
2763
  {
2099
- result = s(:str, "").line lexer.lineno
2764
+ line = prev_value_to_lineno _values.last
2765
+ result = s(:str, +"").line line
2100
2766
  }
2101
2767
  | string_contents string_content
2102
2768
  {
@@ -2171,8 +2837,8 @@ regexp_contents: none
2171
2837
  lexer.brace_nest = brace_nest
2172
2838
  lexer.string_nest = string_nest
2173
2839
 
2174
- lexer.cmdarg.pop
2175
2840
  lexer.cond.pop
2841
+ lexer.cmdarg.pop
2176
2842
 
2177
2843
  lexer.lex_state = oldlex_state
2178
2844
 
@@ -2187,29 +2853,42 @@ regexp_contents: none
2187
2853
  when nil then
2188
2854
  result = s(:evstr).line line
2189
2855
  else
2190
- debug20 25
2856
+ debug 13
2191
2857
  raise "unknown string body: #{stmt.inspect}"
2192
2858
  end
2193
2859
  }
2194
2860
 
2195
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2196
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2197
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2861
+ string_dvar: tGVAR
2862
+ {
2863
+ result = wrap :gvar, val[0]
2864
+ }
2865
+ | tIVAR
2866
+ {
2867
+ result = wrap :ivar, val[0]
2868
+ }
2869
+ | tCVAR
2870
+ {
2871
+ result = wrap :cvar, val[0]
2872
+ }
2198
2873
  | backref
2199
2874
 
2200
- symbol: tSYMBEG sym
2875
+ symbol: ssym
2876
+ | dsym
2877
+
2878
+ ssym: tSYMBEG sym
2201
2879
  {
2202
2880
  lexer.lex_state = EXPR_END
2203
- result = val[1].to_sym
2881
+ result = wrap :lit, val[1]
2204
2882
  }
2205
2883
  | tSYMBOL
2206
2884
  {
2207
- result = val[0].to_sym
2885
+ lexer.lex_state = EXPR_END
2886
+ result = wrap :lit, val[0]
2208
2887
  }
2209
2888
 
2210
2889
  sym: fname | tIVAR | tGVAR | tCVAR
2211
2890
 
2212
- dsym: tSYMBEG xstring_contents tSTRING_END
2891
+ dsym: tSYMBEG string_contents tSTRING_END
2213
2892
  {
2214
2893
  _, result, _ = val
2215
2894
 
@@ -2225,14 +2904,15 @@ regexp_contents: none
2225
2904
  when :evstr then
2226
2905
  result = s(:dsym, "", result).line result.line
2227
2906
  else
2228
- debug20 26, val, result
2907
+ debug 14
2229
2908
  end
2230
2909
  }
2231
2910
 
2232
2911
  numeric: simple_numeric
2233
- | tUMINUS_NUM simple_numeric
2912
+ | tUMINUS_NUM simple_numeric =tLOWEST
2234
2913
  {
2235
- result = -val[1] # TODO: pt_testcase
2914
+ _, (num, line) = val
2915
+ result = [-num, line]
2236
2916
  }
2237
2917
 
2238
2918
  simple_numeric: tINTEGER
@@ -2240,6 +2920,7 @@ regexp_contents: none
2240
2920
  | tRATIONAL
2241
2921
  | tIMAGINARY
2242
2922
 
2923
+
2243
2924
  user_variable: tIDENTIFIER
2244
2925
  | tIVAR
2245
2926
  | tGVAR
@@ -2265,8 +2946,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2946
 
2266
2947
  var_ref: user_variable
2267
2948
  {
2268
- var = val[0]
2949
+ raise "NO: #{val.inspect}" if Sexp === val.first
2950
+ (var, line), = val
2269
2951
  result = Sexp === var ? var : self.gettable(var)
2952
+
2953
+ result.line line
2270
2954
  }
2271
2955
  | keyword_variable
2272
2956
  {
@@ -2281,11 +2965,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2281
2965
  | keyword_variable
2282
2966
  {
2283
2967
  result = self.assignable val[0]
2284
- debug20 29, val, result
2968
+ debug 15
2285
2969
  }
2286
2970
 
2287
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2288
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2971
+ backref: tNTH_REF
2972
+ {
2973
+ (ref, line), = val
2974
+ result = s(:nth_ref, ref).line line
2975
+ }
2976
+ | tBACK_REF
2977
+ {
2978
+ (ref, line), = val
2979
+ result = s(:back_ref, ref).line line
2980
+ }
2289
2981
 
2290
2982
  superclass: tLT
2291
2983
  {
@@ -2301,26 +2993,26 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2301
2993
  result = nil
2302
2994
  }
2303
2995
 
2304
- f_arglist: tLPAREN2 f_args rparen
2996
+ f_opt_paren_args: f_paren_args
2997
+ | none
2305
2998
  {
2306
- result = val[1]
2307
- self.lexer.lex_state = EXPR_BEG
2308
- self.lexer.command_start = true
2999
+ result = end_args val
3000
+ }
3001
+
3002
+ f_paren_args: tLPAREN2 f_args rparen
3003
+ {
3004
+ result = end_args val
2309
3005
  }
2310
3006
  | tLPAREN2 f_arg tCOMMA args_forward rparen
2311
3007
  {
2312
- result = args val
2313
-
2314
- self.lexer.lex_state = EXPR_BEG
2315
- self.lexer.command_start = true
3008
+ result = end_args val
2316
3009
  }
2317
3010
  | tLPAREN2 args_forward rparen
2318
3011
  {
2319
- result = args val
2320
-
2321
- self.lexer.lex_state = EXPR_BEG
2322
- self.lexer.command_start = true
3012
+ result = end_args val
2323
3013
  }
3014
+
3015
+ f_arglist: f_paren_args
2324
3016
  | {
2325
3017
  result = self.in_kwarg
2326
3018
  self.in_kwarg = true
@@ -2328,12 +3020,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2328
3020
  }
2329
3021
  f_args term
2330
3022
  {
2331
- kwarg, args, _ = val
2332
-
2333
- self.in_kwarg = kwarg
2334
- result = args
2335
- lexer.lex_state = EXPR_BEG
2336
- lexer.command_start = true
3023
+ result = end_args val
2337
3024
  }
2338
3025
 
2339
3026
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2344,7 +3031,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2344
3031
  {
2345
3032
  result = args val
2346
3033
  }
2347
- | f_kwrest opt_f_block_arg
3034
+ | f_any_kwrest opt_f_block_arg
2348
3035
  {
2349
3036
  result = args val
2350
3037
  }
@@ -2418,6 +3105,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2418
3105
  |
2419
3106
  {
2420
3107
  result = args val
3108
+ # result.line lexer.lineno
2421
3109
  }
2422
3110
 
2423
3111
  args_forward: tBDOT3
@@ -2445,10 +3133,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2445
3133
  f_norm_arg: f_bad_arg
2446
3134
  | tIDENTIFIER
2447
3135
  {
2448
- identifier = val[0].to_sym
3136
+ (id, line), = val
3137
+ identifier = id.to_sym
2449
3138
  self.env[identifier] = :lvar
2450
3139
 
2451
- result = identifier
3140
+ result = [identifier, line]
2452
3141
  }
2453
3142
 
2454
3143
  f_arg_asgn: f_norm_arg
@@ -2456,22 +3145,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2456
3145
  f_arg_item: f_arg_asgn
2457
3146
  | tLPAREN f_margs rparen
2458
3147
  {
2459
- result = val[1]
3148
+ _, margs, _ = val
3149
+
3150
+ result = margs
2460
3151
  }
2461
3152
 
2462
3153
  f_arg: f_arg_item
2463
3154
  {
2464
- arg, = val
2465
-
2466
- case arg
2467
- when Symbol then
2468
- result = s(:args, arg).line lexer.lineno
2469
- when Sexp then
2470
- result = arg
2471
- else
2472
- debug20 32
2473
- raise "Unknown f_arg type: #{val.inspect}"
2474
- end
3155
+ result = new_arg val
2475
3156
  }
2476
3157
  | f_arg tCOMMA f_arg_item
2477
3158
  {
@@ -2483,7 +3164,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2483
3164
  result = s(:args, list).line list.line
2484
3165
  end
2485
3166
 
2486
- result << item
3167
+ result << (Sexp === item ? item : item.first)
2487
3168
  }
2488
3169
 
2489
3170
  f_label: tLABEL
@@ -2544,27 +3225,46 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2544
3225
  kwrest_mark: tPOW
2545
3226
  | tDSTAR
2546
3227
 
3228
+ f_no_kwarg: kwrest_mark kNIL
3229
+ {
3230
+ (_, line), _ = val
3231
+ result = [:"**nil", line]
3232
+ }
3233
+
2547
3234
  f_kwrest: kwrest_mark tIDENTIFIER
2548
3235
  {
2549
- name = val[1].to_sym
2550
- self.assignable name
2551
- result = :"**#{name}"
3236
+ _, (id, line) = val
3237
+
3238
+ name = id.to_sym
3239
+ self.assignable [name, line]
3240
+ result = [:"**#{name}", line]
2552
3241
  }
2553
3242
  | kwrest_mark
2554
3243
  {
2555
- result = :"**"
2556
- self.env[result] = :lvar
3244
+ id = :"**"
3245
+ self.env[id] = :lvar # TODO: needed?!?
3246
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2557
3247
  }
2558
3248
 
2559
- f_opt: f_arg_asgn tEQL arg_value
3249
+ f_opt: f_arg_asgn
3250
+ tEQL
3251
+ arg_value
2560
3252
  {
2561
- result = self.assignable val[0], val[2]
3253
+ lhs, _, rhs = val
3254
+ result = self.assignable lhs, rhs
2562
3255
  # TODO: detect duplicate names
3256
+ # TODO? p->cur_arg = 0;
3257
+ # TODO? p->ctxt.in_argdef = 1;
2563
3258
  }
2564
3259
 
2565
- f_block_opt: f_arg_asgn tEQL primary_value
3260
+ f_block_opt: f_arg_asgn
3261
+ tEQL
3262
+ primary_value
2566
3263
  {
2567
- result = self.assignable val[0], val[2]
3264
+ lhs, _, rhs = val
3265
+ result = self.assignable lhs, rhs
3266
+ # TODO? p->cur_arg = 0;
3267
+ # TODO? p->ctxt.in_argdef = 1;
2568
3268
  }
2569
3269
 
2570
3270
  f_block_optarg: f_block_opt
@@ -2594,30 +3294,39 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2594
3294
  f_rest_arg: restarg_mark tIDENTIFIER
2595
3295
  {
2596
3296
  # TODO: differs from parse.y - needs tests
2597
- name = val[1].to_sym
2598
- self.assignable name
2599
- result = :"*#{name}"
3297
+ _, (id, line) = val
3298
+ name = id.to_sym
3299
+ self.assignable [name, line]
3300
+ result = [:"*#{name}", line]
2600
3301
  }
2601
3302
  | restarg_mark
2602
3303
  {
2603
3304
  name = :"*"
2604
3305
  self.env[name] = :lvar
2605
- result = name
3306
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2606
3307
  }
2607
3308
 
2608
3309
  blkarg_mark: tAMPER2 | tAMPER
2609
3310
 
2610
3311
  f_block_arg: blkarg_mark tIDENTIFIER
2611
3312
  {
2612
- identifier = val[1].to_sym
3313
+ _, (id, line) = val
3314
+ identifier = id.to_sym
2613
3315
 
2614
3316
  self.env[identifier] = :lvar
2615
- result = "&#{identifier}".to_sym
3317
+ result = ["&#{identifier}".to_sym, line]
3318
+ }
3319
+ | blkarg_mark
3320
+ {
3321
+ (_, line), = val
3322
+
3323
+ result = [:&, line]
2616
3324
  }
2617
3325
 
2618
3326
  opt_f_block_arg: tCOMMA f_block_arg
2619
3327
  {
2620
- result = val[1]
3328
+ _, arg = val
3329
+ result = arg
2621
3330
  }
2622
3331
  |
2623
3332
  {
@@ -2659,16 +3368,25 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2659
3368
  }
2660
3369
  | tLABEL arg_value
2661
3370
  {
2662
- (label, line), arg = val
3371
+ label, arg = val
3372
+
3373
+ lit = wrap :lit, label
3374
+ result = s(:array, lit, arg).line lit.line
3375
+ }
3376
+ | tLABEL
3377
+ {
3378
+ lit = wrap :lit, val[0]
3379
+ arg = nil
2663
3380
 
2664
- lit = s(:lit, label.to_sym).line line
2665
- result = s(:array, lit, arg).line line
3381
+ result = s(:array, lit, arg).line lit.line
2666
3382
  }
2667
3383
  | tSTRING_BEG string_contents tLABEL_END arg_value
2668
3384
  {
2669
- _, sym, _, value = val
3385
+ (_, line), sym, _, value = val
3386
+
2670
3387
  sym.sexp_type = :dsym
2671
- result = s(:array, sym, value).line sym.line
3388
+
3389
+ result = s(:array, sym, value).line line
2672
3390
  }
2673
3391
  | tDSTAR arg_value
2674
3392
  {
@@ -2690,7 +3408,21 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2690
3408
  opt_terms: | terms
2691
3409
  opt_nl: | tNL
2692
3410
  rparen: opt_nl tRPAREN
3411
+ # TODO:
3412
+ # {
3413
+ # _, close = val
3414
+ # result = [close, lexer.lineno]
3415
+ # }
2693
3416
  rbracket: opt_nl tRBRACK
3417
+ {
3418
+ _, close = val
3419
+ result = [close, lexer.lineno]
3420
+ }
3421
+ rbrace: opt_nl tRCURLY
3422
+ {
3423
+ _, close = val
3424
+ result = [close, lexer.lineno]
3425
+ }
2694
3426
  trailer: | tNL | tCOMMA
2695
3427
 
2696
3428
  term: tSEMI { yyerrok }