ruby_parser 3.15.0 → 3.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/ruby_parser.yy CHANGED
@@ -36,7 +36,7 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
36
36
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
37
37
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
38
38
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
39
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
39
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
40
40
  #if V >= 21
41
41
  tRATIONAL tIMAGINARY
42
42
  #endif
@@ -46,6 +46,9 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
46
46
  #if V >= 23
47
47
  tLONELY
48
48
  #endif
49
+ #if V >= 26
50
+ tBDOT2 tBDOT3
51
+ #endif
49
52
 
50
53
  preclow
51
54
  nonassoc tLOWEST
@@ -57,7 +60,7 @@ preclow
57
60
  right tEQL tOP_ASGN
58
61
  left kRESCUE_MOD
59
62
  right tEH tCOLON
60
- nonassoc tDOT2 tDOT3
63
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
61
64
  left tOROP
62
65
  left tANDOP
63
66
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -80,6 +83,9 @@ rule
80
83
  top_compstmt
81
84
  {
82
85
  result = new_compstmt val
86
+
87
+ lexer.cond.pop # local_pop
88
+ lexer.cmdarg.pop
83
89
  }
84
90
 
85
91
  top_compstmt: top_stmts opt_terms
@@ -100,7 +106,7 @@ rule
100
106
  | klBEGIN
101
107
  {
102
108
  if (self.in_def || self.in_single > 0) then
103
- debug20 1
109
+ debug 11
104
110
  yyerror "BEGIN in method"
105
111
  end
106
112
  self.env.extend
@@ -125,7 +131,13 @@ rule
125
131
  bodystmt: compstmt opt_rescue k_else
126
132
  {
127
133
  res = _values[-2]
134
+ # TODO: move down to main match so I can just use val
135
+
136
+ #if V >= 26
128
137
  yyerror "else without rescue is useless" unless res
138
+ #else
139
+ warn "else without rescue is useless" unless res
140
+ #endif
129
141
  }
130
142
  compstmt
131
143
  opt_ensure
@@ -155,7 +167,7 @@ rule
155
167
  | error stmt
156
168
  {
157
169
  result = val[1]
158
- debug20 2, val, result
170
+ debug 12
159
171
  }
160
172
 
161
173
  stmt_or_begin: stmt
@@ -163,6 +175,10 @@ rule
163
175
  {
164
176
  yyerror "BEGIN is permitted only at toplevel"
165
177
  }
178
+ begin_block
179
+ {
180
+ result = val[2] # wtf?
181
+ }
166
182
 
167
183
  stmt: kALIAS fitem
168
184
  {
@@ -175,12 +191,12 @@ rule
175
191
  }
176
192
  | kALIAS tGVAR tGVAR
177
193
  {
178
- (_, line), lhs, rhs = val
194
+ (_, line), (lhs, _), (rhs, _) = val
179
195
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
180
196
  }
181
197
  | kALIAS tGVAR tBACK_REF
182
198
  {
183
- (_, line), lhs, rhs = val
199
+ (_, line), (lhs, _), (rhs, _) = val
184
200
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
185
201
  }
186
202
  | kALIAS tGVAR tNTH_REF
@@ -223,7 +239,7 @@ rule
223
239
  (_, line), _, stmt, _ = val
224
240
 
225
241
  if (self.in_def || self.in_single > 0) then
226
- debug20 3
242
+ debug 13
227
243
  yyerror "END in method; use at_exit"
228
244
  end
229
245
 
@@ -244,6 +260,19 @@ rule
244
260
  {
245
261
  result = new_masgn val[0], val[2], :wrap
246
262
  }
263
+ #endif
264
+ #if V >= 27
265
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
266
+ {
267
+ # unwraps s(:to_ary, rhs)
268
+ lhs, _, (_, rhs), _, resbody = val
269
+
270
+ resbody = new_resbody s(:array).line(resbody.line), resbody
271
+
272
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
273
+ }
274
+ #endif
275
+ #if V == 20
247
276
  | mlhs tEQL mrhs
248
277
  #else
249
278
  | mlhs tEQL mrhs_arg
@@ -271,32 +300,31 @@ rule
271
300
  }
272
301
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
273
302
  {
274
- prim, _, id, opasgn, rhs = val
275
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
276
- if val[1] == '&.'
277
- result.sexp_type = :safe_op_asgn
278
- end
279
- result.line = val[0].line
303
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
304
+
305
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
306
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
307
+ result.line prim.line
280
308
  }
281
309
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
282
310
  {
283
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
284
- if val[1] == '&.'
285
- result.sexp_type = :safe_op_asgn
286
- end
287
- result.line = val[0].line
311
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
312
+
313
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
314
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
315
+ result.line prim.line
288
316
  }
289
317
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
290
318
  {
291
- lhs1, _, lhs2, op, rhs = val
319
+ lhs1, _, (lhs2, line), (id, _), rhs = val
292
320
 
293
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
321
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
294
322
  }
295
323
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
296
324
  {
297
- lhs1, _, lhs2, op, rhs = val
325
+ lhs1, _, (lhs2, line), (id, _), rhs = val
298
326
 
299
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
327
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
300
328
  }
301
329
  | backref tOP_ASGN command_rhs
302
330
  {
@@ -344,7 +372,31 @@ rule
344
372
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
345
373
  # REFACTOR: call_uni_op -- see parse26.y
346
374
  }
375
+ #if V >= 27
347
376
  | arg
377
+ kIN
378
+ {
379
+ # TODO? value_expr($1);
380
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
381
+ self.lexer.command_start = false
382
+ result = self.in_kwarg
383
+ self.in_kwarg = true
384
+ self.env.extend
385
+ }
386
+ p_expr
387
+ {
388
+ self.env.unextend
389
+
390
+ expr, _, old_kwarg, pat = val
391
+
392
+ expr = value_expr expr
393
+
394
+ self.in_kwarg = old_kwarg
395
+ pat_in = new_in pat, nil, nil, expr.line
396
+ result = new_case expr, pat_in, expr.line
397
+ }
398
+ #endif
399
+ | arg =tLBRACE_ARG
348
400
 
349
401
  expr_value: expr
350
402
  {
@@ -369,7 +421,7 @@ rule
369
421
  block_command: block_call
370
422
  | block_call call_op2 operation2 command_args
371
423
  {
372
- blk, _, msg, args = val
424
+ blk, _, (msg, _line), args = val
373
425
  result = new_call(blk, msg.to_sym, args).line blk.line
374
426
  }
375
427
 
@@ -383,15 +435,15 @@ rule
383
435
  _, line, body, _ = val
384
436
 
385
437
  result = body
386
- result.line = line
438
+ result.line line
387
439
 
388
440
  # self.env.unextend
389
441
  }
390
442
 
391
443
  fcall: operation
392
444
  {
393
- msg, = val
394
- result = new_call(nil, msg.to_sym).line lexer.lineno
445
+ (msg, line), = val
446
+ result = new_call(nil, msg.to_sym).line line
395
447
  }
396
448
 
397
449
  command: fcall command_args =tLOWEST
@@ -414,12 +466,14 @@ rule
414
466
  }
415
467
  | primary_value call_op operation2 command_args =tLOWEST
416
468
  {
417
- lhs, callop, op, args = val
469
+ lhs, callop, (op, _), args = val
470
+
418
471
  result = new_call lhs, op.to_sym, args, callop
472
+ result.line lhs.line
419
473
  }
420
474
  | primary_value call_op operation2 command_args cmd_brace_block
421
475
  {
422
- recv, _, msg, args, block = val
476
+ recv, _, (msg, _line), args, block = val
423
477
  call = new_call recv, msg.to_sym, args, val[1]
424
478
 
425
479
  block_dup_check call, block
@@ -429,11 +483,14 @@ rule
429
483
  }
430
484
  | primary_value tCOLON2 operation2 command_args =tLOWEST
431
485
  {
432
- result = new_call val[0], val[2].to_sym, val[3]
486
+ lhs, _, (id, line), args = val
487
+
488
+ result = new_call lhs, id.to_sym, args
489
+ result.line line
433
490
  }
434
491
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
435
492
  {
436
- recv, _, msg, args, block = val
493
+ recv, _, (msg, _line), args, block = val
437
494
  call = new_call recv, msg.to_sym, args
438
495
 
439
496
  block_dup_check call, block
@@ -591,25 +648,29 @@ rule
591
648
  }
592
649
  | primary_value call_op tIDENTIFIER
593
650
  {
594
- result = new_attrasgn val[0], val[2], val[1]
651
+ lhs, call_op, (id, _line) = val
652
+
653
+ result = new_attrasgn lhs, id, call_op
595
654
  }
596
655
  | primary_value tCOLON2 tIDENTIFIER
597
656
  {
598
- recv, _, id = val
657
+ recv, _, (id, _line) = val
599
658
  result = new_attrasgn recv, id
600
659
  }
601
660
  | primary_value call_op tCONSTANT
602
661
  {
603
- result = new_attrasgn val[0], val[2], val[1]
662
+ lhs, call_op, (id, _line) = val
663
+
664
+ result = new_attrasgn lhs, id, call_op
604
665
  }
605
666
  | primary_value tCOLON2 tCONSTANT
606
667
  {
607
668
  if (self.in_def || self.in_single > 0) then
608
- debug20 7
669
+ debug 14
609
670
  yyerror "dynamic constant assignment"
610
671
  end
611
672
 
612
- expr, _, id = val
673
+ expr, _, (id, _line) = val
613
674
  l = expr.line
614
675
 
615
676
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -617,58 +678,65 @@ rule
617
678
  | tCOLON3 tCONSTANT
618
679
  {
619
680
  if (self.in_def || self.in_single > 0) then
620
- debug20 8
681
+ debug 15
621
682
  yyerror "dynamic constant assignment"
622
683
  end
623
684
 
624
- _, id = val
625
- l = lexer.lineno
685
+ _, (id, l) = val
626
686
 
627
687
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
628
688
  }
629
689
  | backref
630
690
  {
631
- self.backref_assign_error val[0]
691
+ ref, = val
692
+
693
+ self.backref_assign_error ref
632
694
  }
633
695
 
634
696
  lhs: user_variable
635
697
  {
636
- line = lexer.lineno
637
- result = self.assignable val[0]
638
- result.line = line
698
+ var, = val
699
+
700
+ result = self.assignable var
639
701
  }
640
702
  | keyword_variable
641
703
  {
642
- line = lexer.lineno
643
- result = self.assignable val[0]
644
- result.line = line
645
- debug20 9, val, result
704
+ var, = val
705
+
706
+ result = self.assignable var
707
+
708
+ debug 16
646
709
  }
647
710
  | primary_value tLBRACK2 opt_call_args rbracket
648
711
  {
649
712
  lhs, _, args, _ = val
713
+
650
714
  result = self.aryset lhs, args
651
715
  }
652
716
  | primary_value call_op tIDENTIFIER # REFACTOR
653
717
  {
654
- lhs, op, id = val
718
+ lhs, op, (id, _line) = val
719
+
655
720
  result = new_attrasgn lhs, id, op
656
721
  }
657
722
  | primary_value tCOLON2 tIDENTIFIER
658
723
  {
659
- lhs, _, id = val
724
+ lhs, _, (id, _line) = val
725
+
660
726
  result = new_attrasgn lhs, id
661
727
  }
662
728
  | primary_value call_op tCONSTANT # REFACTOR?
663
729
  {
664
- result = new_attrasgn val[0], val[2], val[1]
730
+ lhs, call_op, (id, _line) = val
731
+
732
+ result = new_attrasgn lhs, id, call_op
665
733
  }
666
734
  | primary_value tCOLON2 tCONSTANT
667
735
  {
668
- expr, _, id = val
736
+ expr, _, (id, _line) = val
669
737
 
670
738
  if (self.in_def || self.in_single > 0) then
671
- debug20 10
739
+ debug 17
672
740
  yyerror "dynamic constant assignment"
673
741
  end
674
742
 
@@ -677,14 +745,13 @@ rule
677
745
  }
678
746
  | tCOLON3 tCONSTANT
679
747
  {
680
- _, id = val
748
+ _, (id, l) = val
681
749
 
682
750
  if (self.in_def || self.in_single > 0) then
683
- debug20 11
751
+ debug 18
684
752
  yyerror "dynamic constant assignment"
685
753
  end
686
754
 
687
- l = lexer.lineno
688
755
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
689
756
  }
690
757
  | backref
@@ -700,16 +767,17 @@ rule
700
767
 
701
768
  cpath: tCOLON3 cname
702
769
  {
703
- _, name = val
704
- result = s(:colon3, name.to_sym).line lexer.lineno
770
+ _, (name, line) = val
771
+ result = s(:colon3, name.to_sym).line line
705
772
  }
706
773
  | cname
707
774
  {
708
- result = val[0].to_sym
775
+ (id, line), = val
776
+ result = [id.to_sym, line] # TODO: sexp?
709
777
  }
710
778
  | primary_value tCOLON2 cname
711
779
  {
712
- pval, _, name = val
780
+ pval, _, (name, _line) = val
713
781
 
714
782
  result = s(:colon2, pval, name.to_sym)
715
783
  result.line pval.line
@@ -719,24 +787,17 @@ rule
719
787
  | op
720
788
  {
721
789
  lexer.lex_state = EXPR_END
722
- result = val[0]
723
790
  }
724
791
 
725
792
  | reswords
726
- {
727
- (sym, _line), = val
728
- lexer.lex_state = EXPR_END
729
- result = sym
730
- }
731
793
 
732
- fsym: fname | symbol
733
-
734
- fitem: fsym
794
+ fitem: fname
735
795
  {
736
- id, = val
737
- result = s(:lit, id.to_sym).line lexer.lineno
796
+ (id, line), = val
797
+
798
+ result = s(:lit, id.to_sym).line line
738
799
  }
739
- | dsym
800
+ | symbol
740
801
 
741
802
  undef_list: fitem
742
803
  {
@@ -757,10 +818,6 @@ rule
757
818
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
758
819
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
759
820
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
760
- #if V >= 20
761
- # TODO: tUBANG dead?
762
- | tUBANG
763
- #endif
764
821
 
765
822
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
766
823
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -794,24 +851,20 @@ rule
794
851
  }
795
852
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
796
853
  {
797
- lhs, _, id, op, rhs = val
854
+ lhs, _, (id, _line), (op, _), rhs = val
798
855
 
799
856
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
800
857
  }
801
858
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
802
859
  {
803
- lhs1, _, lhs2, op, rhs = val
860
+ lhs1, _, (lhs2, _line), op, rhs = val
804
861
 
805
862
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
806
863
  result = new_const_op_asgn [lhs, op, rhs]
807
864
  }
808
- | tCOLON3 tCONSTANT
809
- {
810
- result = self.lexer.lineno
811
- }
812
- tOP_ASGN arg_rhs
865
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
813
866
  {
814
- _, lhs, line, op, rhs = val
867
+ _, (lhs, line), op, rhs = val
815
868
 
816
869
  lhs = s(:colon3, lhs.to_sym).line line
817
870
  result = new_const_op_asgn [lhs, op, rhs]
@@ -825,7 +878,7 @@ rule
825
878
  | arg tDOT2 arg
826
879
  {
827
880
  v1, v2 = val[0], val[2]
828
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
881
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
829
882
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
830
883
  else
831
884
  result = s(:dot2, v1, v2).line v1.line
@@ -834,7 +887,7 @@ rule
834
887
  | arg tDOT3 arg
835
888
  {
836
889
  v1, v2 = val[0], val[2]
837
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
890
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
838
891
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
839
892
  else
840
893
  result = s(:dot3, v1, v2).line v1.line
@@ -856,6 +909,24 @@ rule
856
909
  result = s(:dot3, v1, v2).line v1.line
857
910
  }
858
911
  #endif
912
+
913
+ #if V >= 27
914
+ | tBDOT2 arg
915
+ {
916
+ _, v2, = val
917
+ v1 = nil
918
+
919
+ result = s(:dot2, v1, v2).line v2.line
920
+ }
921
+ | tBDOT3 arg
922
+ {
923
+ _, v2 = val
924
+ v1 = nil
925
+
926
+ result = s(:dot3, v1, v2).line v2.line
927
+ }
928
+ #endif
929
+
859
930
  | arg tPLUS arg
860
931
  {
861
932
  result = new_call val[0], :+, argl(val[2])
@@ -883,20 +954,22 @@ rule
883
954
  #if V == 20
884
955
  | tUMINUS_NUM tINTEGER tPOW arg
885
956
  {
886
- lit = s(:lit, val[1]).line lexer.lineno
887
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
957
+ _, (num, line), _, arg = val
958
+ lit = s(:lit, num).line line
959
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
888
960
  }
889
961
  | tUMINUS_NUM tFLOAT tPOW arg
890
962
  #else
891
963
  | tUMINUS_NUM simple_numeric tPOW arg
892
964
  #endif
893
965
  {
894
- lit = s(:lit, val[1]).line lexer.lineno
895
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
966
+ _, (num, line), _, arg = val
967
+ lit = s(:lit, num).line line
968
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
896
969
 
897
970
  #if V == 20
898
971
  ## TODO: why is this 2.0 only?
899
- debug20 12, val, result
972
+ debug 19
900
973
  #endif
901
974
  }
902
975
  | tUPLUS arg
@@ -995,12 +1068,12 @@ rule
995
1068
 
996
1069
  rel_expr: arg relop arg =tGT
997
1070
  {
998
- lhs, op, rhs = val
1071
+ lhs, (op, _), rhs = val
999
1072
  result = new_call lhs, op.to_sym, argl(rhs)
1000
1073
  }
1001
1074
  | rel_expr relop arg =tGT
1002
1075
  {
1003
- lhs, op, rhs = val
1076
+ lhs, (op, _), rhs = val
1004
1077
  warn "comparison '%s' after comparison", op
1005
1078
  result = new_call lhs, op.to_sym, argl(rhs)
1006
1079
  }
@@ -1040,6 +1113,26 @@ rule
1040
1113
  _, args, _ = val
1041
1114
  result = args
1042
1115
  }
1116
+ #if V >= 27
1117
+ | tLPAREN2 args tCOMMA args_forward rparen
1118
+ {
1119
+ yyerror "Unexpected ..." unless
1120
+ self.lexer.is_local_id(:"*") &&
1121
+ self.lexer.is_local_id(:"**") &&
1122
+ self.lexer.is_local_id(:"&")
1123
+
1124
+ result = call_args val
1125
+ }
1126
+ | tLPAREN2 args_forward rparen
1127
+ {
1128
+ yyerror "Unexpected ..." unless
1129
+ self.lexer.is_local_id(:"*") &&
1130
+ self.lexer.is_local_id(:"**") &&
1131
+ self.lexer.is_local_id(:"&")
1132
+
1133
+ result = call_args val
1134
+ }
1135
+ #endif
1043
1136
 
1044
1137
  opt_paren_args: none
1045
1138
  | paren_args
@@ -1193,8 +1286,9 @@ rule
1193
1286
  | backref
1194
1287
  | tFID
1195
1288
  {
1196
- msg, = val
1289
+ (msg, line), = val
1197
1290
  result = new_call nil, msg.to_sym
1291
+ result.line line
1198
1292
  }
1199
1293
  | k_begin
1200
1294
  {
@@ -1236,15 +1330,15 @@ rule
1236
1330
  }
1237
1331
  | primary_value tCOLON2 tCONSTANT
1238
1332
  {
1239
- expr, _, id = val
1333
+ expr, _, (id, _line) = val
1240
1334
 
1241
1335
  result = s(:colon2, expr, id.to_sym).line expr.line
1242
1336
  }
1243
1337
  | tCOLON3 tCONSTANT
1244
1338
  {
1245
- _, id = val
1339
+ _, (id, line) = val
1246
1340
 
1247
- result = s(:colon3, id.to_sym).line lexer.lineno
1341
+ result = s(:colon3, id.to_sym).line line
1248
1342
  }
1249
1343
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1250
1344
  {
@@ -1291,7 +1385,7 @@ rule
1291
1385
  }
1292
1386
  | kNOT tLPAREN2 rparen
1293
1387
  {
1294
- debug20 14, val, result
1388
+ debug 20
1295
1389
  }
1296
1390
  | fcall brace_block
1297
1391
  {
@@ -1309,9 +1403,10 @@ rule
1309
1403
  iter.insert 1, call # FIX
1310
1404
  result = iter
1311
1405
  }
1312
- | tLAMBDA lambda
1406
+ | lambda
1313
1407
  {
1314
- result = val[1] # TODO: fix lineno
1408
+ expr, = val
1409
+ result = expr
1315
1410
  }
1316
1411
  | k_if expr_value then compstmt if_tail k_end
1317
1412
  {
@@ -1343,6 +1438,14 @@ rule
1343
1438
  (_, line), _, body, _ = val
1344
1439
  result = new_case nil, body, line
1345
1440
  }
1441
+ #if V >= 27
1442
+ | k_case expr_value opt_terms p_case_body k_end
1443
+ {
1444
+ (_, line), expr, _, body, _ = val
1445
+
1446
+ result = new_case expr, body, line
1447
+ }
1448
+ #endif
1346
1449
  | k_for for_var kIN expr_value_do compstmt k_end
1347
1450
  {
1348
1451
  _, var, _, iter, body, _ = val
@@ -1354,7 +1457,6 @@ rule
1354
1457
  }
1355
1458
  cpath superclass
1356
1459
  {
1357
- self.comments.push self.lexer.comments
1358
1460
  if (self.in_def || self.in_single > 0) then
1359
1461
  yyerror "class definition in method body"
1360
1462
  end
@@ -1364,7 +1466,7 @@ rule
1364
1466
  {
1365
1467
  result = new_class val
1366
1468
  self.env.unextend
1367
- self.lexer.comments # we don't care about comments in the body
1469
+ self.lexer.ignore_body_comments
1368
1470
  }
1369
1471
  | k_class tLSHFT
1370
1472
  {
@@ -1385,7 +1487,7 @@ rule
1385
1487
  {
1386
1488
  result = new_sclass val
1387
1489
  self.env.unextend
1388
- self.lexer.comments # we don't care about comments in the body
1490
+ self.lexer.ignore_body_comments
1389
1491
  }
1390
1492
  | k_module
1391
1493
  {
@@ -1393,7 +1495,6 @@ rule
1393
1495
  }
1394
1496
  cpath
1395
1497
  {
1396
- self.comments.push self.lexer.comments
1397
1498
  yyerror "module definition in method body" if
1398
1499
  self.in_def or self.in_single > 0
1399
1500
 
@@ -1403,7 +1504,7 @@ rule
1403
1504
  {
1404
1505
  result = new_module val
1405
1506
  self.env.unextend
1406
- self.lexer.comments # we don't care about comments in the body
1507
+ self.lexer.ignore_body_comments
1407
1508
  }
1408
1509
  | k_def fname
1409
1510
  {
@@ -1413,21 +1514,17 @@ rule
1413
1514
  self.env.extend
1414
1515
  lexer.cmdarg.push false
1415
1516
  lexer.cond.push false
1416
-
1417
- self.comments.push self.lexer.comments
1418
1517
  }
1419
- f_arglist bodystmt { result = lexer.lineno } k_end
1518
+ f_arglist bodystmt k_end
1420
1519
  {
1421
- in_def = val[2]
1422
-
1423
- result = new_defn val
1520
+ result, in_def = new_defn val
1424
1521
 
1425
1522
  lexer.cond.pop # group = local_pop
1426
1523
  lexer.cmdarg.pop
1427
1524
  self.env.unextend
1428
1525
  self.in_def = in_def
1429
1526
 
1430
- self.lexer.comments # we don't care about comments in the body
1527
+ self.lexer.ignore_body_comments
1431
1528
  }
1432
1529
  | k_def singleton dot_or_colon
1433
1530
  {
@@ -1435,7 +1532,7 @@ rule
1435
1532
  }
1436
1533
  fname
1437
1534
  {
1438
- result = [self.in_def, lexer.lineno]
1535
+ result = self.in_def
1439
1536
 
1440
1537
  self.in_single += 1 # TODO: remove?
1441
1538
 
@@ -1445,13 +1542,18 @@ rule
1445
1542
  lexer.cond.push false
1446
1543
 
1447
1544
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1448
- self.comments.push self.lexer.comments
1449
1545
  }
1450
1546
  f_arglist bodystmt k_end
1451
1547
  {
1452
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1453
1548
 
1454
- result = new_defs val
1549
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1550
+ # =>
1551
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1552
+
1553
+ val.delete_at 3
1554
+ val.delete_at 2
1555
+
1556
+ result, in_def = new_defs val
1455
1557
 
1456
1558
  lexer.cond.pop # group = local_pop
1457
1559
  lexer.cmdarg.pop
@@ -1462,7 +1564,7 @@ rule
1462
1564
 
1463
1565
  # TODO: restore cur_arg ? what's cur_arg?
1464
1566
 
1465
- self.lexer.comments # we don't care about comments in the body
1567
+ self.lexer.ignore_body_comments
1466
1568
  }
1467
1569
  | kBREAK
1468
1570
  {
@@ -1499,8 +1601,17 @@ rule
1499
1601
  k_case: kCASE
1500
1602
  k_for: kFOR
1501
1603
  k_class: kCLASS
1604
+ {
1605
+ self.comments.push self.lexer.comments
1606
+ }
1502
1607
  k_module: kMODULE
1608
+ {
1609
+ self.comments.push self.lexer.comments
1610
+ }
1503
1611
  k_def: kDEF
1612
+ {
1613
+ self.comments.push self.lexer.comments
1614
+ }
1504
1615
  k_do: kDO
1505
1616
  k_do_block: kDO_BLOCK
1506
1617
  k_rescue: kRESCUE
@@ -1561,51 +1672,42 @@ rule
1561
1672
 
1562
1673
  result = block_var args
1563
1674
  }
1564
- | f_marg_list tCOMMA tSTAR f_norm_arg
1675
+ | f_marg_list tCOMMA f_rest_marg
1565
1676
  {
1566
- args, _, _, splat = val
1677
+ args, _, rest = val
1567
1678
 
1568
- result = block_var args, "*#{splat}".to_sym
1679
+ result = block_var args, rest
1569
1680
  }
1570
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1681
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1571
1682
  {
1572
- args, _, _, splat, _, args2 = val
1683
+ lhs, _, splat, _, rhs = val
1573
1684
 
1574
- result = block_var args, "*#{splat}".to_sym, args2
1685
+ result = block_var lhs, splat, rhs
1575
1686
  }
1576
- | f_marg_list tCOMMA tSTAR
1687
+ | f_rest_marg
1577
1688
  {
1578
- args, _, _ = val
1689
+ rest, = val
1579
1690
 
1580
- result = block_var args, :*
1691
+ result = block_var rest
1581
1692
  }
1582
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1693
+ | f_rest_marg tCOMMA f_marg_list
1583
1694
  {
1584
- args, _, _, _, args2 = val
1695
+ splat, _, rest = val
1585
1696
 
1586
- result = block_var args, :*, args2
1697
+ result = block_var splat, rest
1587
1698
  }
1588
- | tSTAR f_norm_arg
1589
- {
1590
- _, splat = val
1591
1699
 
1592
- result = block_var :"*#{splat}"
1593
- }
1594
- | tSTAR f_norm_arg tCOMMA f_marg_list
1700
+ f_rest_marg: tSTAR f_norm_arg
1595
1701
  {
1596
- _, splat, _, args = val
1702
+ _, (id, line) = val
1597
1703
 
1598
- result = block_var :"*#{splat}", args
1704
+ result = args ["*#{id}".to_sym]
1705
+ result.line line
1599
1706
  }
1600
1707
  | tSTAR
1601
1708
  {
1602
- result = block_var :*
1603
- }
1604
- | tSTAR tCOMMA f_marg_list
1605
- {
1606
- _, _, args = val
1607
-
1608
- result = block_var :*, args
1709
+ result = args [:*]
1710
+ result.line lexer.lineno # FIX: tSTAR -> line
1609
1711
  }
1610
1712
 
1611
1713
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1620,10 +1722,16 @@ rule
1620
1722
  {
1621
1723
  result = call_args val
1622
1724
  }
1725
+ #if V >= 27
1726
+ | f_no_kwarg opt_f_block_arg
1727
+ {
1728
+ result = args val
1729
+ }
1730
+ #endif
1623
1731
  | f_block_arg
1624
1732
  {
1625
- line = lexer.lineno
1626
- result = call_args val # TODO: push line down
1733
+ (id, line), = val
1734
+ result = call_args [id]
1627
1735
  result.line line
1628
1736
  }
1629
1737
 
@@ -1732,13 +1840,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1732
1840
 
1733
1841
  bvar: tIDENTIFIER
1734
1842
  {
1735
- id, = val
1736
- line = lexer.lineno
1843
+ (id, line), = val
1737
1844
  result = s(:shadow, id.to_sym).line line
1738
1845
  }
1739
1846
  | f_bad_arg
1740
1847
 
1741
- lambda: {
1848
+ lambda: tLAMBDA
1849
+ {
1742
1850
  self.env.extend :dynamic
1743
1851
  result = [lexer.lineno, lexer.lpar_beg]
1744
1852
  lexer.paren_nest += 1
@@ -1750,14 +1858,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1750
1858
  }
1751
1859
  lambda_body
1752
1860
  {
1753
- (line, lpar), args, _cmdarg, body = val
1861
+ _, (line, lpar), args, _cmdarg, body = val
1754
1862
  lexer.lpar_beg = lpar
1755
1863
 
1756
1864
  lexer.cmdarg.pop
1757
1865
 
1758
1866
  call = s(:lambda).line line
1759
1867
  result = new_iter call, args, body
1760
- result.line = line
1868
+ result.line line
1761
1869
  self.env.unextend # TODO: dynapush & dynapop
1762
1870
  }
1763
1871
 
@@ -1792,23 +1900,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1792
1900
  ## if (nd_type($1) == NODE_YIELD) {
1793
1901
  ## compile_error(PARSER_ARG "block given to yield");
1794
1902
 
1795
- syntax_error "Both block arg and actual block given." if
1796
- val[0].block_pass?
1903
+ cmd, blk = val
1797
1904
 
1798
- val = invert_block_call val if inverted? val
1905
+ syntax_error "Both block arg and actual block given." if
1906
+ cmd.block_pass?
1799
1907
 
1800
- cmd, blk = val
1908
+ if inverted? val then
1909
+ val = invert_block_call val
1910
+ cmd, blk = val
1911
+ end
1801
1912
 
1802
1913
  result = blk
1803
1914
  result.insert 1, cmd
1804
1915
  }
1805
1916
  | block_call call_op2 operation2 opt_paren_args
1806
1917
  {
1807
- result = new_call val[0], val[2].to_sym, val[3]
1918
+ lhs, _, (id, _line), args = val
1919
+
1920
+ result = new_call lhs, id.to_sym, args
1808
1921
  }
1809
1922
  | block_call call_op2 operation2 opt_paren_args brace_block
1810
1923
  {
1811
- iter1, _, name, args, iter2 = val
1924
+ iter1, _, (name, _line), args, iter2 = val
1812
1925
 
1813
1926
  call = new_call iter1, name.to_sym, args
1814
1927
  iter2.insert 1, call
@@ -1817,7 +1930,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1817
1930
  }
1818
1931
  | block_call call_op2 operation2 command_args do_block
1819
1932
  {
1820
- iter1, _, name, args, iter2 = val
1933
+ iter1, _, (name, _line), args, iter2 = val
1821
1934
 
1822
1935
  call = new_call iter1, name.to_sym, args
1823
1936
  iter2.insert 1, call
@@ -1825,28 +1938,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1825
1938
  result = iter2
1826
1939
  }
1827
1940
 
1828
- method_call: fcall
1829
- {
1830
- result = self.lexer.lineno
1831
- }
1832
- paren_args
1941
+ method_call: fcall paren_args
1833
1942
  {
1834
- call, lineno, args = val
1943
+ call, args = val
1835
1944
 
1836
1945
  result = call.concat args.sexp_body if args
1837
- result.line lineno
1838
1946
  }
1839
1947
  | primary_value call_op operation2 opt_paren_args
1840
1948
  {
1841
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1949
+ recv, call_op, (op, _line), args = val
1950
+
1951
+ result = new_call recv, op.to_sym, args, call_op
1842
1952
  }
1843
1953
  | primary_value tCOLON2 operation2 paren_args
1844
1954
  {
1845
- result = new_call val[0], val[2].to_sym, val[3]
1955
+ recv, _, (op, _line), args = val
1956
+
1957
+ result = new_call recv, op.to_sym, args
1846
1958
  }
1847
1959
  | primary_value tCOLON2 operation3
1848
1960
  {
1849
- result = new_call val[0], val[2].to_sym
1961
+ lhs, _, (id, _line) = val
1962
+
1963
+ result = new_call lhs, id.to_sym
1850
1964
  }
1851
1965
  | primary_value call_op paren_args
1852
1966
  {
@@ -1879,7 +1993,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1879
1993
  _, line, body, _ = val
1880
1994
 
1881
1995
  result = body
1882
- result.line = line
1996
+ result.line line
1883
1997
 
1884
1998
  self.env.unextend
1885
1999
  }
@@ -1893,7 +2007,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1893
2007
  _, line, body, _ = val
1894
2008
 
1895
2009
  result = body
1896
- result.line = line
2010
+ result.line line
1897
2011
 
1898
2012
  self.env.unextend
1899
2013
  }
@@ -1926,18 +2040,548 @@ opt_block_args_tail: tCOMMA block_args_tail
1926
2040
  self.env.unextend
1927
2041
  }
1928
2042
 
2043
+ case_args: arg_value
2044
+ {
2045
+ arg, = val
2046
+
2047
+ result = s(:array, arg).line arg.line
2048
+ }
2049
+ | tSTAR arg_value
2050
+ {
2051
+ _, arg = val
2052
+
2053
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2054
+ }
2055
+ | case_args tCOMMA arg_value
2056
+ {
2057
+ args, _, id = val
2058
+
2059
+ result = self.list_append args, id
2060
+ }
2061
+ | case_args tCOMMA tSTAR arg_value
2062
+ {
2063
+ args, _, _, id = val
2064
+
2065
+ result = self.list_append args, s(:splat, id).line(id.line)
2066
+ }
2067
+
1929
2068
  case_body: k_when
1930
2069
  {
1931
2070
  result = self.lexer.lineno
1932
2071
  }
1933
- args then compstmt cases
2072
+ case_args then compstmt cases
1934
2073
  {
1935
2074
  result = new_when(val[2], val[4])
1936
- result.line = val[1]
2075
+ result.line val[1]
1937
2076
  result << val[5] if val[5]
1938
2077
  }
1939
2078
 
1940
2079
  cases: opt_else | case_body
2080
+ #if V >= 27
2081
+ ######################################################################
2082
+
2083
+ p_case_body: kIN
2084
+ {
2085
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2086
+ self.lexer.command_start = false
2087
+ result = self.in_kwarg
2088
+ self.in_kwarg = true
2089
+ push_pvtbl
2090
+ push_pktbl
2091
+ }
2092
+ p_top_expr then
2093
+ {
2094
+ pop_pktbl
2095
+ pop_pvtbl
2096
+ old_kwargs = _values[-3]
2097
+ self.in_kwarg = old_kwargs
2098
+ }
2099
+ compstmt
2100
+ p_cases
2101
+ {
2102
+ (_, line), _, pat, _, _, body, cases = val
2103
+
2104
+ result = new_in pat, body, cases, line
2105
+ }
2106
+
2107
+ p_cases: opt_else
2108
+ | p_case_body
2109
+
2110
+ p_top_expr: p_top_expr_body
2111
+ | p_top_expr_body kIF_MOD expr_value
2112
+ {
2113
+ body, _, cond = val
2114
+ body = remove_begin body
2115
+
2116
+ result = s(:if, cond, body, nil).line body.line
2117
+ }
2118
+ | p_top_expr_body kUNLESS_MOD expr_value
2119
+ {
2120
+ body, _, cond = val
2121
+ body = remove_begin body
2122
+
2123
+ result = s(:if, cond, nil, body).line body.line
2124
+ }
2125
+
2126
+ p_top_expr_body: p_expr
2127
+ | p_expr tCOMMA
2128
+ {
2129
+ expr, _ = val
2130
+
2131
+ tail = new_array_pattern_tail nil, true, nil, nil
2132
+ result = new_array_pattern nil, expr, tail, expr.line
2133
+ }
2134
+ | p_expr tCOMMA p_args
2135
+ {
2136
+ expr, _, args = val
2137
+
2138
+ result = new_array_pattern nil, expr, args, expr.line
2139
+ }
2140
+ | p_args_tail
2141
+ {
2142
+ args, = val
2143
+ result = new_array_pattern nil, nil, args, args.line
2144
+ }
2145
+ | p_kwargs
2146
+ {
2147
+ kwargs, = val
2148
+ result = new_hash_pattern nil, kwargs, kwargs.line
2149
+ }
2150
+
2151
+ p_expr: p_as
2152
+
2153
+ p_as: p_expr tASSOC p_variable
2154
+ {
2155
+ # NODE *n = NEW_LIST($1, &@$);
2156
+ # n = list_append(p, n, $3);
2157
+ # $$ = new_hash(p, n, &@$);
2158
+
2159
+ expr, _, var = val
2160
+
2161
+ id = var.last
2162
+
2163
+ self.env[id] = :lvar # HACK: need to extend env
2164
+ lhs = s(:lasgn, id).line var.line
2165
+
2166
+ result = new_assign lhs, expr
2167
+ }
2168
+ | p_alt
2169
+
2170
+ p_alt: p_alt tPIPE p_expr_basic
2171
+ {
2172
+ lhs, _, rhs = val
2173
+
2174
+ result = s(:or, lhs, rhs).line lhs.line
2175
+ }
2176
+ | p_expr_basic
2177
+
2178
+ p_lparen: tLPAREN2 { push_pktbl }
2179
+ p_lbracket: tLBRACK2 { push_pktbl }
2180
+
2181
+ p_expr_basic: p_value
2182
+ | p_const p_lparen p_args tRPAREN
2183
+ {
2184
+ lhs, _, args, _ = val
2185
+
2186
+ pop_pktbl
2187
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2188
+ }
2189
+ | p_const p_lparen p_kwargs tRPAREN
2190
+ {
2191
+ lhs, _, kwargs, _ = val
2192
+
2193
+ pop_pktbl
2194
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2195
+ }
2196
+ | p_const tLPAREN2 tRPAREN
2197
+ {
2198
+ const, _, _ = val
2199
+
2200
+ tail = new_array_pattern_tail nil, nil, nil, nil
2201
+ result = new_array_pattern const, nil, tail, const.line
2202
+ }
2203
+ | p_const p_lbracket p_args rbracket
2204
+ {
2205
+ const, _, pre_arg, _ = val
2206
+
2207
+ pop_pktbl
2208
+ result = new_array_pattern const, nil, pre_arg, const.line
2209
+ }
2210
+ | p_const p_lbracket p_kwargs rbracket
2211
+ {
2212
+ const, _, kwargs, _ = val
2213
+
2214
+ result = new_hash_pattern const, kwargs, const.line
2215
+ }
2216
+ | p_const tLBRACK2 rbracket
2217
+ {
2218
+ const, _, _ = val
2219
+
2220
+ tail = new_array_pattern_tail nil, nil, nil, nil
2221
+ result = new_array_pattern const, nil, tail, const.line
2222
+ }
2223
+ | tLBRACK { push_pktbl } p_args rbracket
2224
+ {
2225
+ _, _, pat, _ = val
2226
+
2227
+ pop_pktbl
2228
+ result = new_array_pattern nil, nil, pat, pat.line
2229
+ }
2230
+ | tLBRACK rbracket
2231
+ {
2232
+ (_, line), _ = val
2233
+
2234
+ result = s(:array_pat).line line
2235
+ }
2236
+ | tLBRACE
2237
+ {
2238
+ push_pktbl
2239
+ result = self.in_kwarg
2240
+ self.in_kwarg = false
2241
+ }
2242
+ p_kwargs rbrace
2243
+ {
2244
+ _, in_kwarg, kwargs, _ = val
2245
+
2246
+ pop_pktbl
2247
+ self.in_kwarg = in_kwarg
2248
+
2249
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2250
+ }
2251
+ | tLBRACE rbrace
2252
+ {
2253
+ (_, line), _ = val
2254
+
2255
+ tail = new_hash_pattern_tail nil, nil, line
2256
+ result = new_hash_pattern nil, tail, line
2257
+ }
2258
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2259
+ {
2260
+ _, _, expr, _ = val
2261
+
2262
+ pop_pktbl
2263
+ result = expr
2264
+ }
2265
+
2266
+ p_args: p_expr
2267
+ {
2268
+ expr, = val
2269
+
2270
+ ary = s(:array_TAIL, expr).line expr.line
2271
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2272
+ }
2273
+ | p_args_head
2274
+ {
2275
+ head, = val
2276
+
2277
+ result = new_array_pattern_tail head, true, nil, nil
2278
+ }
2279
+ | p_args_head p_arg
2280
+ {
2281
+ head, tail = val
2282
+
2283
+ both = array_pat_concat head, tail
2284
+
2285
+ result = new_array_pattern_tail both, nil, nil, nil
2286
+ result.line head.line
2287
+ }
2288
+ | p_args_head tSTAR tIDENTIFIER
2289
+ {
2290
+ head, _, (id, _line) = val
2291
+
2292
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2293
+ result.line head.line
2294
+ }
2295
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2296
+ {
2297
+ head, _, (id, _line), _, post = val
2298
+
2299
+ result = new_array_pattern_tail head, true, id.to_sym, post
2300
+ result.line head.line
2301
+ }
2302
+ | p_args_head tSTAR
2303
+ {
2304
+ expr, _ = val
2305
+
2306
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2307
+ }
2308
+ | p_args_head tSTAR tCOMMA p_args_post
2309
+ {
2310
+ head, _, _, post = val
2311
+
2312
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2313
+ }
2314
+ | p_args_tail
2315
+
2316
+ p_args_head: p_arg tCOMMA
2317
+ {
2318
+ arg, _ = val
2319
+ result = arg
2320
+ }
2321
+ | p_args_head p_arg tCOMMA
2322
+ {
2323
+ head, tail, _ = val
2324
+
2325
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2326
+ result.line head.line
2327
+ }
2328
+
2329
+ p_args_tail: tSTAR tIDENTIFIER
2330
+ {
2331
+ _, (id, line) = val
2332
+
2333
+ result = new_array_pattern_tail nil, true, id.to_sym, nil
2334
+ result.line line
2335
+ }
2336
+ | tSTAR tIDENTIFIER tCOMMA p_args_post
2337
+ {
2338
+ _, (id, line), _, rhs = val
2339
+
2340
+ result = new_array_pattern_tail nil, true, id.to_sym, rhs
2341
+ result.line line
2342
+ }
2343
+ | tSTAR
2344
+ {
2345
+ (_, line), = val
2346
+
2347
+ result = new_array_pattern_tail nil, true, nil, nil
2348
+ result.line line
2349
+ }
2350
+ | tSTAR tCOMMA p_args_post
2351
+ {
2352
+ (_, line), _, args = val
2353
+
2354
+ result = new_array_pattern_tail nil, true, nil, args
2355
+ result.line line
2356
+ }
2357
+
2358
+ p_args_post: p_arg
2359
+ | p_args_post tCOMMA p_arg
2360
+ {
2361
+ lhs, _, rhs = val
2362
+
2363
+ result = array_pat_concat lhs, rhs
2364
+ }
2365
+
2366
+ p_arg: p_expr
2367
+ {
2368
+ expr, = val
2369
+ expr = s(:array_TAIL, expr).line expr.line unless
2370
+ expr.sexp_type == :array_TAIL
2371
+ result = expr
2372
+ }
2373
+
2374
+ p_kwargs: p_kwarg tCOMMA p_kwrest
2375
+ {
2376
+ kw_arg, _, rest = val
2377
+ # TODO? new_unique_key_hash(p, $1, &@$)
2378
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2379
+ }
2380
+ | p_kwarg
2381
+ {
2382
+ kwarg, = val
2383
+ # TODO? new_unique_key_hash(p, $1, &@$)
2384
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2385
+ }
2386
+ | p_kwarg tCOMMA
2387
+ {
2388
+ kwarg, _ = val
2389
+ # TODO? new_unique_key_hash(p, $1, &@$)
2390
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2391
+ }
2392
+ | p_kwrest
2393
+ {
2394
+ rest, = val
2395
+
2396
+ result = new_hash_pattern_tail nil, rest, rest.line
2397
+ }
2398
+ | p_kwarg tCOMMA p_kwnorest
2399
+ {
2400
+ kwarg, _, norest = val
2401
+
2402
+ # TODO? new_unique_key_hash(p, $1, &@$)
2403
+ result = new_hash_pattern_tail kwarg, norest, kwarg.line
2404
+ }
2405
+ | p_kwnorest
2406
+ {
2407
+ norest, = val
2408
+
2409
+ result = new_hash_pattern_tail nil, norest, norest.line
2410
+ }
2411
+
2412
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2413
+ | p_kwarg tCOMMA p_kw
2414
+ {
2415
+ kwarg, _, kw = val
2416
+ kwarg.concat kw.sexp_body
2417
+ result = kwarg
2418
+ }
2419
+
2420
+ p_kw: p_kw_label p_expr
2421
+ {
2422
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2423
+ lhs, rhs = val
2424
+
2425
+ result = s(:PAIR, lhs, rhs).line lhs.line
2426
+ }
2427
+ | p_kw_label
2428
+ {
2429
+ lhs, = val
2430
+
2431
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2432
+
2433
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2434
+ # yyerror1(&@1, "key must be valid as local variables");
2435
+ # }
2436
+
2437
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2438
+ # assignable(p, $1, 0, &@$));
2439
+
2440
+
2441
+ case lhs.sexp_type
2442
+ when :lit then
2443
+ assignable [lhs.value, lhs.line]
2444
+ else
2445
+ # TODO or done?
2446
+ debug 666
2447
+ end
2448
+
2449
+ # TODO PAIR -> LIST ?
2450
+ result = s(:PAIR, lhs, nil).line lhs.line
2451
+ }
2452
+
2453
+ p_kw_label: tLABEL
2454
+ {
2455
+ (id, line), = val
2456
+
2457
+ result = s(:lit, id.to_sym).line line
2458
+ }
2459
+
2460
+ p_kwrest: kwrest_mark tIDENTIFIER
2461
+ {
2462
+ _, (id, line) = val
2463
+
2464
+ name = id.to_sym
2465
+ self.assignable [name, line]
2466
+ result = s(:kwrest, :"**#{name}").line line
2467
+ }
2468
+ | kwrest_mark
2469
+ {
2470
+ (_, line), = val
2471
+
2472
+ result = s(:kwrest, :"**").line line
2473
+ }
2474
+
2475
+ p_kwnorest: kwrest_mark kNIL
2476
+ {
2477
+ (_, line), _ = val
2478
+
2479
+ # TODO: or s(:norest)? s(:**nil)?
2480
+ result = s(:kwrest, :"**nil").line line
2481
+ }
2482
+
2483
+ p_value: p_primitive
2484
+ | p_primitive tDOT2 p_primitive
2485
+ {
2486
+ lhs, _, rhs = val
2487
+
2488
+ lhs = value_expr lhs
2489
+ rhs = value_expr rhs
2490
+
2491
+ result = s(:dot2, lhs, rhs).line lhs.line
2492
+ }
2493
+ | p_primitive tDOT3 p_primitive
2494
+ {
2495
+ lhs, _, rhs = val
2496
+
2497
+ lhs = value_expr lhs
2498
+ rhs = value_expr rhs
2499
+
2500
+ result = s(:dot3, lhs, rhs).line lhs.line
2501
+ }
2502
+ | p_primitive tDOT2
2503
+ {
2504
+ v1, _ = val
2505
+
2506
+ result = s(:dot2, v1, nil).line v1.line
2507
+ }
2508
+ | p_primitive tDOT3
2509
+ {
2510
+ v1, _ = val
2511
+
2512
+ result = s(:dot3, v1, nil).line v1.line
2513
+ }
2514
+ | p_variable
2515
+ | p_var_ref
2516
+ | p_const
2517
+ | tBDOT2 p_primitive
2518
+ {
2519
+ _, v1 = val
2520
+
2521
+ result = s(:dot2, nil, v1).line v1.line
2522
+ }
2523
+ | tBDOT3 p_primitive
2524
+ {
2525
+ _, v1 = val
2526
+
2527
+ result = s(:dot3, nil, v1).line v1.line
2528
+ }
2529
+
2530
+ p_primitive: literal
2531
+ | strings
2532
+ | xstring
2533
+ | regexp
2534
+ | words
2535
+ | qwords
2536
+ | symbols
2537
+ | qsymbols
2538
+ | keyword_variable
2539
+ {
2540
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2541
+ var, = val
2542
+
2543
+ result = var
2544
+ }
2545
+ | lambda
2546
+
2547
+ p_variable: tIDENTIFIER
2548
+ {
2549
+ (id, line), = val
2550
+
2551
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2552
+ # TODO: assignable(p, $1, 0, &@$);
2553
+ result = s(:lvar, id.to_sym).line line
2554
+ }
2555
+
2556
+ p_var_ref: tCARET tIDENTIFIER
2557
+ {
2558
+ _, (id, line) = val
2559
+
2560
+ # TODO: check id against env for lvar or dvar
2561
+
2562
+ result = s(:lvar, id.to_sym).line line
2563
+ }
2564
+
2565
+ p_const: tCOLON3 cname
2566
+ {
2567
+ _, (id, line) = val
2568
+ result = s(:colon3, id.to_sym).line line
2569
+ }
2570
+ | p_const tCOLON2 cname
2571
+ {
2572
+ lhs, _, (id, _line) = val
2573
+
2574
+ l = lhs.line
2575
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2576
+ }
2577
+ | tCONSTANT
2578
+ {
2579
+ # TODO $$ = gettable(p, $1, &@$);
2580
+ (id, line), = val
2581
+ result = s(:const, id.to_sym).line line
2582
+ }
2583
+ ######################################################################
2584
+ #endif
1941
2585
 
1942
2586
  opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1943
2587
  {
@@ -1979,17 +2623,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1979
2623
 
1980
2624
  literal: numeric
1981
2625
  {
1982
- line = lexer.lineno
1983
- result = s(:lit, val[0])
1984
- result.line = line
2626
+ (lit, line), = val
2627
+ result = s(:lit, lit).line line
1985
2628
  }
1986
2629
  | symbol
1987
- {
1988
- line = lexer.lineno
1989
- result = s(:lit, val[0])
1990
- result.line = line
1991
- }
1992
- | dsym
1993
2630
 
1994
2631
  strings: string
1995
2632
  {
@@ -2000,7 +2637,7 @@ opt_block_args_tail: tCOMMA block_args_tail
2000
2637
 
2001
2638
  string: tCHAR
2002
2639
  {
2003
- debug20 23, val, result
2640
+ debug 37
2004
2641
  }
2005
2642
  | string1
2006
2643
  | string string1
@@ -2010,11 +2647,11 @@ opt_block_args_tail: tCOMMA block_args_tail
2010
2647
 
2011
2648
  string1: tSTRING_BEG string_contents tSTRING_END
2012
2649
  {
2013
- _, str, (_, func) = val
2650
+ (_, line), str, (_, func) = val
2014
2651
 
2015
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2652
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2016
2653
 
2017
- result = str
2654
+ result = str.line line
2018
2655
  }
2019
2656
  | tSTRING
2020
2657
  {
@@ -2034,11 +2671,15 @@ opt_block_args_tail: tCOMMA block_args_tail
2034
2671
 
2035
2672
  words: tWORDS_BEG tSPACE tSTRING_END
2036
2673
  {
2037
- result = s(:array).line lexer.lineno
2674
+ (_, line), _, _ = val
2675
+
2676
+ result = s(:array).line line
2038
2677
  }
2039
2678
  | tWORDS_BEG word_list tSTRING_END
2040
2679
  {
2041
- result = val[1]
2680
+ (_, line), list, _ = val
2681
+
2682
+ result = list.line line
2042
2683
  }
2043
2684
 
2044
2685
  word_list: none
@@ -2058,18 +2699,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2058
2699
 
2059
2700
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2060
2701
  {
2061
- result = s(:array).line lexer.lineno
2702
+ (_, line), _, _ = val
2703
+
2704
+ result = s(:array).line line
2062
2705
  }
2063
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2706
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2064
2707
  {
2065
- _, line, list, _, = val
2066
- list.line = line
2708
+ (_, line), list, _, = val
2709
+ list.line line
2067
2710
  result = list
2068
2711
  }
2069
2712
 
2070
2713
  symbol_list: none
2071
2714
  {
2072
- result = new_symbol_list.line lexer.lineno
2715
+ result = new_symbol_list
2073
2716
  }
2074
2717
  | symbol_list word tSPACE
2075
2718
  {
@@ -2079,20 +2722,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2079
2722
 
2080
2723
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2081
2724
  {
2082
- result = s(:array).line lexer.lineno
2725
+ (_, line), _, _ = val
2726
+
2727
+ result = s(:array).line line
2083
2728
  }
2084
2729
  | tQWORDS_BEG qword_list tSTRING_END
2085
2730
  {
2086
- result = val[1]
2731
+ (_, line), list, _ = val
2732
+
2733
+ result = list.line line
2087
2734
  }
2088
2735
 
2089
2736
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2090
2737
  {
2091
- result = s(:array).line lexer.lineno # FIX
2738
+ (_, line), _, _ = val
2739
+
2740
+ result = s(:array).line line
2092
2741
  }
2093
2742
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2094
2743
  {
2095
- result = val[1]
2744
+ (_, line), list, _ = val
2745
+
2746
+ result = list.line line
2096
2747
  }
2097
2748
 
2098
2749
  qword_list: none
@@ -2115,7 +2766,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2115
2766
 
2116
2767
  string_contents: none
2117
2768
  {
2118
- result = s(:str, "").line lexer.lineno
2769
+ line = prev_value_to_lineno _values.last
2770
+ result = s(:str, +"").line line
2119
2771
  }
2120
2772
  | string_contents string_content
2121
2773
  {
@@ -2190,8 +2842,8 @@ regexp_contents: none
2190
2842
  lexer.brace_nest = brace_nest
2191
2843
  lexer.string_nest = string_nest
2192
2844
 
2193
- lexer.cmdarg.pop
2194
2845
  lexer.cond.pop
2846
+ lexer.cmdarg.pop
2195
2847
 
2196
2848
  lexer.lex_state = oldlex_state
2197
2849
 
@@ -2206,29 +2858,49 @@ regexp_contents: none
2206
2858
  when nil then
2207
2859
  result = s(:evstr).line line
2208
2860
  else
2209
- debug20 25
2861
+ debug 38
2210
2862
  raise "unknown string body: #{stmt.inspect}"
2211
2863
  end
2212
2864
  }
2213
2865
 
2214
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2215
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2216
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2866
+ string_dvar: tGVAR
2867
+ {
2868
+ (id, line), = val
2869
+ result = s(:gvar, id.to_sym).line line
2870
+ }
2871
+ | tIVAR
2872
+ {
2873
+ (id, line), = val
2874
+ result = s(:ivar, id.to_sym).line line
2875
+ }
2876
+ | tCVAR
2877
+ {
2878
+ (id, line), = val
2879
+ result = s(:cvar, id.to_sym).line line
2880
+ }
2217
2881
  | backref
2218
2882
 
2219
- symbol: tSYMBEG sym
2883
+ symbol: ssym
2884
+ | dsym
2885
+
2886
+ ssym: tSYMBEG sym
2220
2887
  {
2888
+ _, (id, line) = val
2889
+
2221
2890
  lexer.lex_state = EXPR_END
2222
- result = val[1].to_sym
2891
+ result = s(:lit, id.to_sym).line line
2223
2892
  }
2224
2893
  | tSYMBOL
2225
2894
  {
2226
- result = val[0].to_sym
2895
+ (id, line), = val
2896
+
2897
+ lexer.lex_state = EXPR_END
2898
+ result = s(:lit, id.to_sym).line line
2227
2899
  }
2228
2900
 
2229
2901
  sym: fname | tIVAR | tGVAR | tCVAR
2230
2902
 
2231
- dsym: tSYMBEG xstring_contents tSTRING_END
2903
+ dsym: tSYMBEG string_contents tSTRING_END
2232
2904
  {
2233
2905
  _, result, _ = val
2234
2906
 
@@ -2244,7 +2916,7 @@ regexp_contents: none
2244
2916
  when :evstr then
2245
2917
  result = s(:dsym, "", result).line result.line
2246
2918
  else
2247
- debug20 26, val, result
2919
+ debug 39
2248
2920
  end
2249
2921
  }
2250
2922
 
@@ -2254,15 +2926,17 @@ regexp_contents: none
2254
2926
  | tUMINUS_NUM tINTEGER =tLOWEST
2255
2927
  #else
2256
2928
  numeric: simple_numeric
2257
- | tUMINUS_NUM simple_numeric
2929
+ | tUMINUS_NUM simple_numeric =tLOWEST
2258
2930
  #endif
2259
2931
  {
2260
- result = -val[1] # TODO: pt_testcase
2932
+ _, (num, line) = val
2933
+ result = [-num, line]
2261
2934
  #if V == 20
2262
2935
  }
2263
2936
  | tUMINUS_NUM tFLOAT =tLOWEST
2264
2937
  {
2265
- result = -val[1] # TODO: pt_testcase
2938
+ _, (num, line) = val
2939
+ result = [-num, line]
2266
2940
  #endif
2267
2941
  }
2268
2942
 
@@ -2298,8 +2972,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2298
2972
 
2299
2973
  var_ref: user_variable
2300
2974
  {
2301
- var = val[0]
2975
+ raise "NO: #{val.inspect}" if Sexp === val.first
2976
+ (var, line), = val
2302
2977
  result = Sexp === var ? var : self.gettable(var)
2978
+ result.line line
2303
2979
  }
2304
2980
  | keyword_variable
2305
2981
  {
@@ -2314,11 +2990,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2314
2990
  | keyword_variable
2315
2991
  {
2316
2992
  result = self.assignable val[0]
2317
- debug20 29, val, result
2993
+ debug 40
2318
2994
  }
2319
2995
 
2320
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2321
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2996
+ backref: tNTH_REF
2997
+ {
2998
+ (ref, line), = val
2999
+ result = s(:nth_ref, ref).line line
3000
+ }
3001
+ | tBACK_REF
3002
+ {
3003
+ (ref, line), = val
3004
+ result = s(:back_ref, ref).line line
3005
+ }
2322
3006
 
2323
3007
  superclass: tLT
2324
3008
  {
@@ -2336,10 +3020,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2336
3020
 
2337
3021
  f_arglist: tLPAREN2 f_args rparen
2338
3022
  {
2339
- result = val[1]
2340
- self.lexer.lex_state = EXPR_BEG
2341
- self.lexer.command_start = true
3023
+ result = end_args val
3024
+ }
3025
+ #if V == 27
3026
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
3027
+ {
3028
+ result = end_args val
2342
3029
  }
3030
+ | tLPAREN2 args_forward rparen
3031
+ {
3032
+ result = end_args val
3033
+ }
3034
+ #endif
2343
3035
  | {
2344
3036
  result = self.in_kwarg
2345
3037
  self.in_kwarg = true
@@ -2347,12 +3039,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2347
3039
  }
2348
3040
  f_args term
2349
3041
  {
2350
- kwarg, args, _ = val
2351
-
2352
- self.in_kwarg = kwarg
2353
- result = args
2354
- lexer.lex_state = EXPR_BEG
2355
- lexer.command_start = true
3042
+ result = end_args val
2356
3043
  }
2357
3044
 
2358
3045
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2367,6 +3054,12 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2367
3054
  {
2368
3055
  result = args val
2369
3056
  }
3057
+ #if V >= 27
3058
+ | f_no_kwarg opt_f_block_arg
3059
+ {
3060
+ result = args val
3061
+ }
3062
+ #endif
2370
3063
  | f_block_arg
2371
3064
 
2372
3065
  opt_args_tail: tCOMMA args_tail
@@ -2437,7 +3130,15 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2437
3130
  |
2438
3131
  {
2439
3132
  result = args val
3133
+ # result.line lexer.lineno
3134
+ }
3135
+
3136
+ #if V >= 27
3137
+ args_forward: tBDOT3
3138
+ {
3139
+ result = s(:forward_args).line lexer.lineno
2440
3140
  }
3141
+ #endif
2441
3142
 
2442
3143
  f_bad_arg: tCONSTANT
2443
3144
  {
@@ -2459,10 +3160,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2459
3160
  f_norm_arg: f_bad_arg
2460
3161
  | tIDENTIFIER
2461
3162
  {
2462
- identifier = val[0].to_sym
3163
+ (id, line), = val
3164
+ identifier = id.to_sym
2463
3165
  self.env[identifier] = :lvar
2464
3166
 
2465
- result = identifier
3167
+ result = [identifier, line]
2466
3168
  }
2467
3169
 
2468
3170
  #if V >= 22
@@ -2471,29 +3173,23 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2471
3173
  f_arg_item: f_arg_asgn
2472
3174
  | tLPAREN f_margs rparen
2473
3175
  {
2474
- result = val[1]
3176
+ _, margs, _ = val
3177
+
3178
+ result = margs
2475
3179
  }
2476
3180
  #else
2477
3181
  f_arg_item: f_norm_arg
2478
3182
  | tLPAREN f_margs rparen
2479
3183
  {
2480
- result = val[1]
3184
+ _, margs, _ = val
3185
+
3186
+ result = margs
2481
3187
  }
2482
3188
  #endif
2483
3189
 
2484
3190
  f_arg: f_arg_item
2485
3191
  {
2486
- arg, = val
2487
-
2488
- case arg
2489
- when Symbol then
2490
- result = s(:args, arg).line lexer.lineno
2491
- when Sexp then
2492
- result = arg
2493
- else
2494
- debug20 32
2495
- raise "Unknown f_arg type: #{val.inspect}"
2496
- end
3192
+ result = new_arg val
2497
3193
  }
2498
3194
  | f_arg tCOMMA f_arg_item
2499
3195
  {
@@ -2505,7 +3201,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2505
3201
  result = s(:args, list).line list.line
2506
3202
  end
2507
3203
 
2508
- result << item
3204
+ result << (Sexp === item ? item : item.first)
2509
3205
  }
2510
3206
 
2511
3207
  #if V == 20
@@ -2578,15 +3274,26 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2578
3274
  kwrest_mark: tPOW
2579
3275
  | tDSTAR
2580
3276
 
3277
+ #if V >= 27
3278
+ f_no_kwarg: kwrest_mark kNIL
3279
+ {
3280
+ result = :"**nil"
3281
+ }
3282
+ #endif
3283
+
2581
3284
  f_kwrest: kwrest_mark tIDENTIFIER
2582
3285
  {
2583
- name = val[1].to_sym
2584
- self.assignable name
2585
- result = :"**#{name}"
3286
+ _, (id, line) = val
3287
+
3288
+ name = id.to_sym
3289
+ self.assignable [name, line]
3290
+ result = [:"**#{name}", line]
2586
3291
  }
2587
3292
  | kwrest_mark
2588
3293
  {
2589
- result = :"**"
3294
+ id = :"**"
3295
+ self.env[id] = :lvar # TODO: needed?!?
3296
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2590
3297
  }
2591
3298
 
2592
3299
  #if V == 20
@@ -2597,7 +3304,8 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2597
3304
  f_opt: f_arg_asgn tEQL arg_value
2598
3305
  #endif
2599
3306
  {
2600
- result = self.assignable val[0], val[2]
3307
+ lhs, _, rhs = val
3308
+ result = self.assignable lhs, rhs
2601
3309
  # TODO: detect duplicate names
2602
3310
  }
2603
3311
 
@@ -2609,7 +3317,8 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2609
3317
  f_block_opt: f_arg_asgn tEQL primary_value
2610
3318
  #endif
2611
3319
  {
2612
- result = self.assignable val[0], val[2]
3320
+ lhs, _, rhs = val
3321
+ result = self.assignable lhs, rhs
2613
3322
  }
2614
3323
 
2615
3324
  f_block_optarg: f_block_opt
@@ -2639,30 +3348,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2639
3348
  f_rest_arg: restarg_mark tIDENTIFIER
2640
3349
  {
2641
3350
  # TODO: differs from parse.y - needs tests
2642
- name = val[1].to_sym
2643
- self.assignable name
2644
- result = :"*#{name}"
3351
+ _, (id, line) = val
3352
+ name = id.to_sym
3353
+ self.assignable [name, line]
3354
+ result = [:"*#{name}", line]
2645
3355
  }
2646
3356
  | restarg_mark
2647
3357
  {
2648
3358
  name = :"*"
2649
3359
  self.env[name] = :lvar
2650
- result = name
3360
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2651
3361
  }
2652
3362
 
2653
3363
  blkarg_mark: tAMPER2 | tAMPER
2654
3364
 
2655
3365
  f_block_arg: blkarg_mark tIDENTIFIER
2656
3366
  {
2657
- identifier = val[1].to_sym
3367
+ _, (id, line) = val
3368
+ identifier = id.to_sym
2658
3369
 
2659
3370
  self.env[identifier] = :lvar
2660
- result = "&#{identifier}".to_sym
3371
+ result = ["&#{identifier}".to_sym, line]
2661
3372
  }
2662
3373
 
2663
3374
  opt_f_block_arg: tCOMMA f_block_arg
2664
3375
  {
2665
- result = val[1]
3376
+ _, arg = val
3377
+ result = arg
2666
3378
  }
2667
3379
  |
2668
3380
  {
@@ -2712,9 +3424,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2712
3424
  #if V >= 22
2713
3425
  | tSTRING_BEG string_contents tLABEL_END arg_value
2714
3426
  {
2715
- _, sym, _, value = val
3427
+ (_, line), sym, _, value = val
3428
+
2716
3429
  sym.sexp_type = :dsym
2717
- result = s(:array, sym, value).line sym.line
3430
+
3431
+ result = s(:array, sym, value).line line
2718
3432
  }
2719
3433
  #endif
2720
3434
  | tDSTAR arg_value
@@ -2740,6 +3454,9 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2740
3454
  opt_nl: | tNL
2741
3455
  rparen: opt_nl tRPAREN
2742
3456
  rbracket: opt_nl tRBRACK
3457
+ #if V >= 27
3458
+ rbrace: opt_nl tRCURLY
3459
+ #endif
2743
3460
  trailer: | tNL | tCOMMA
2744
3461
 
2745
3462
  term: tSEMI { yyerrok }