ruby_parser 3.15.0 → 3.19.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.rdoc +151 -0
  4. data/Manifest.txt +7 -0
  5. data/README.rdoc +9 -6
  6. data/Rakefile +141 -31
  7. data/bin/ruby_parse_extract_error +1 -1
  8. data/compare/normalize.rb +8 -3
  9. data/debugging.md +133 -0
  10. data/gauntlet.md +107 -0
  11. data/lib/rp_extensions.rb +15 -36
  12. data/lib/rp_stringscanner.rb +20 -51
  13. data/lib/ruby20_parser.rb +7544 -3633
  14. data/lib/ruby20_parser.y +335 -257
  15. data/lib/ruby21_parser.rb +7518 -3678
  16. data/lib/ruby21_parser.y +330 -254
  17. data/lib/ruby22_parser.rb +7652 -3689
  18. data/lib/ruby22_parser.y +334 -256
  19. data/lib/ruby23_parser.rb +7659 -3702
  20. data/lib/ruby23_parser.y +334 -256
  21. data/lib/ruby24_parser.rb +7748 -3721
  22. data/lib/ruby24_parser.y +334 -256
  23. data/lib/ruby25_parser.rb +7748 -3721
  24. data/lib/ruby25_parser.y +334 -256
  25. data/lib/ruby26_parser.rb +7755 -3726
  26. data/lib/ruby26_parser.y +334 -255
  27. data/lib/ruby27_parser.rb +10290 -4518
  28. data/lib/ruby27_parser.y +933 -254
  29. data/lib/ruby30_parser.rb +13258 -0
  30. data/lib/ruby30_parser.y +3459 -0
  31. data/lib/ruby31_parser.rb +13638 -0
  32. data/lib/ruby31_parser.y +3493 -0
  33. data/lib/ruby3_parser.yy +3548 -0
  34. data/lib/ruby_lexer.rb +277 -599
  35. data/lib/ruby_lexer.rex +28 -21
  36. data/lib/ruby_lexer.rex.rb +60 -24
  37. data/lib/ruby_lexer_strings.rb +638 -0
  38. data/lib/ruby_parser.rb +4 -0
  39. data/lib/ruby_parser.yy +974 -261
  40. data/lib/ruby_parser_extras.rb +355 -114
  41. data/test/test_ruby_lexer.rb +226 -129
  42. data/test/test_ruby_parser.rb +1653 -267
  43. data/tools/munge.rb +36 -8
  44. data/tools/ripper.rb +15 -10
  45. data.tar.gz.sig +0 -0
  46. metadata +55 -37
  47. metadata.gz.sig +0 -0
data/lib/ruby27_parser.y CHANGED
@@ -18,10 +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
24
  tLONELY
25
+ tBDOT2 tBDOT3
25
26
 
26
27
  preclow
27
28
  nonassoc tLOWEST
@@ -33,7 +34,7 @@ preclow
33
34
  right tEQL tOP_ASGN
34
35
  left kRESCUE_MOD
35
36
  right tEH tCOLON
36
- nonassoc tDOT2 tDOT3
37
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
38
  left tOROP
38
39
  left tANDOP
39
40
  nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
@@ -56,6 +57,9 @@ rule
56
57
  top_compstmt
57
58
  {
58
59
  result = new_compstmt val
60
+
61
+ lexer.cond.pop # local_pop
62
+ lexer.cmdarg.pop
59
63
  }
60
64
 
61
65
  top_compstmt: top_stmts opt_terms
@@ -76,7 +80,7 @@ rule
76
80
  | klBEGIN
77
81
  {
78
82
  if (self.in_def || self.in_single > 0) then
79
- debug20 1
83
+ debug 11
80
84
  yyerror "BEGIN in method"
81
85
  end
82
86
  self.env.extend
@@ -101,6 +105,8 @@ rule
101
105
  bodystmt: compstmt opt_rescue k_else
102
106
  {
103
107
  res = _values[-2]
108
+ # TODO: move down to main match so I can just use val
109
+
104
110
  yyerror "else without rescue is useless" unless res
105
111
  }
106
112
  compstmt
@@ -131,7 +137,7 @@ rule
131
137
  | error stmt
132
138
  {
133
139
  result = val[1]
134
- debug20 2, val, result
140
+ debug 12
135
141
  }
136
142
 
137
143
  stmt_or_begin: stmt
@@ -139,6 +145,10 @@ rule
139
145
  {
140
146
  yyerror "BEGIN is permitted only at toplevel"
141
147
  }
148
+ begin_block
149
+ {
150
+ result = val[2] # wtf?
151
+ }
142
152
 
143
153
  stmt: kALIAS fitem
144
154
  {
@@ -151,12 +161,12 @@ rule
151
161
  }
152
162
  | kALIAS tGVAR tGVAR
153
163
  {
154
- (_, line), lhs, rhs = val
164
+ (_, line), (lhs, _), (rhs, _) = val
155
165
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
156
166
  }
157
167
  | kALIAS tGVAR tBACK_REF
158
168
  {
159
- (_, line), lhs, rhs = val
169
+ (_, line), (lhs, _), (rhs, _) = val
160
170
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
161
171
  }
162
172
  | kALIAS tGVAR tNTH_REF
@@ -199,7 +209,7 @@ rule
199
209
  (_, line), _, stmt, _ = val
200
210
 
201
211
  if (self.in_def || self.in_single > 0) then
202
- debug20 3
212
+ debug 13
203
213
  yyerror "END in method; use at_exit"
204
214
  end
205
215
 
@@ -215,6 +225,15 @@ rule
215
225
  lhs, _, rhs = val
216
226
  result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
217
227
  }
228
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
229
+ {
230
+ # unwraps s(:to_ary, rhs)
231
+ lhs, _, (_, rhs), _, resbody = val
232
+
233
+ resbody = new_resbody s(:array).line(resbody.line), resbody
234
+
235
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
236
+ }
218
237
  | mlhs tEQL mrhs_arg
219
238
  {
220
239
  result = new_masgn val[0], val[2]
@@ -239,32 +258,31 @@ rule
239
258
  }
240
259
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
241
260
  {
242
- prim, _, id, opasgn, rhs = val
243
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
244
- if val[1] == '&.'
245
- result.sexp_type = :safe_op_asgn
246
- end
247
- result.line = val[0].line
261
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
262
+
263
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
264
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
265
+ result.line prim.line
248
266
  }
249
267
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
250
268
  {
251
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
252
- if val[1] == '&.'
253
- result.sexp_type = :safe_op_asgn
254
- end
255
- result.line = val[0].line
269
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
270
+
271
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
272
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
273
+ result.line prim.line
256
274
  }
257
275
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
258
276
  {
259
- lhs1, _, lhs2, op, rhs = val
277
+ lhs1, _, (lhs2, line), (id, _), rhs = val
260
278
 
261
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
279
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
262
280
  }
263
281
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
264
282
  {
265
- lhs1, _, lhs2, op, rhs = val
283
+ lhs1, _, (lhs2, line), (id, _), rhs = val
266
284
 
267
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
285
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
268
286
  }
269
287
  | backref tOP_ASGN command_rhs
270
288
  {
@@ -311,6 +329,28 @@ rule
311
329
  # REFACTOR: call_uni_op -- see parse26.y
312
330
  }
313
331
  | arg
332
+ kIN
333
+ {
334
+ # TODO? value_expr($1);
335
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
336
+ self.lexer.command_start = false
337
+ result = self.in_kwarg
338
+ self.in_kwarg = true
339
+ self.env.extend
340
+ }
341
+ p_expr
342
+ {
343
+ self.env.unextend
344
+
345
+ expr, _, old_kwarg, pat = val
346
+
347
+ expr = value_expr expr
348
+
349
+ self.in_kwarg = old_kwarg
350
+ pat_in = new_in pat, nil, nil, expr.line
351
+ result = new_case expr, pat_in, expr.line
352
+ }
353
+ | arg =tLBRACE_ARG
314
354
 
315
355
  expr_value: expr
316
356
  {
@@ -335,7 +375,7 @@ rule
335
375
  block_command: block_call
336
376
  | block_call call_op2 operation2 command_args
337
377
  {
338
- blk, _, msg, args = val
378
+ blk, _, (msg, _line), args = val
339
379
  result = new_call(blk, msg.to_sym, args).line blk.line
340
380
  }
341
381
 
@@ -349,15 +389,15 @@ rule
349
389
  _, line, body, _ = val
350
390
 
351
391
  result = body
352
- result.line = line
392
+ result.line line
353
393
 
354
394
  # self.env.unextend
355
395
  }
356
396
 
357
397
  fcall: operation
358
398
  {
359
- msg, = val
360
- result = new_call(nil, msg.to_sym).line lexer.lineno
399
+ (msg, line), = val
400
+ result = new_call(nil, msg.to_sym).line line
361
401
  }
362
402
 
363
403
  command: fcall command_args =tLOWEST
@@ -380,12 +420,14 @@ rule
380
420
  }
381
421
  | primary_value call_op operation2 command_args =tLOWEST
382
422
  {
383
- lhs, callop, op, args = val
423
+ lhs, callop, (op, _), args = val
424
+
384
425
  result = new_call lhs, op.to_sym, args, callop
426
+ result.line lhs.line
385
427
  }
386
428
  | primary_value call_op operation2 command_args cmd_brace_block
387
429
  {
388
- recv, _, msg, args, block = val
430
+ recv, _, (msg, _line), args, block = val
389
431
  call = new_call recv, msg.to_sym, args, val[1]
390
432
 
391
433
  block_dup_check call, block
@@ -395,11 +437,14 @@ rule
395
437
  }
396
438
  | primary_value tCOLON2 operation2 command_args =tLOWEST
397
439
  {
398
- result = new_call val[0], val[2].to_sym, val[3]
440
+ lhs, _, (id, line), args = val
441
+
442
+ result = new_call lhs, id.to_sym, args
443
+ result.line line
399
444
  }
400
445
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
401
446
  {
402
- recv, _, msg, args, block = val
447
+ recv, _, (msg, _line), args, block = val
403
448
  call = new_call recv, msg.to_sym, args
404
449
 
405
450
  block_dup_check call, block
@@ -557,25 +602,29 @@ rule
557
602
  }
558
603
  | primary_value call_op tIDENTIFIER
559
604
  {
560
- result = new_attrasgn val[0], val[2], val[1]
605
+ lhs, call_op, (id, _line) = val
606
+
607
+ result = new_attrasgn lhs, id, call_op
561
608
  }
562
609
  | primary_value tCOLON2 tIDENTIFIER
563
610
  {
564
- recv, _, id = val
611
+ recv, _, (id, _line) = val
565
612
  result = new_attrasgn recv, id
566
613
  }
567
614
  | primary_value call_op tCONSTANT
568
615
  {
569
- result = new_attrasgn val[0], val[2], val[1]
616
+ lhs, call_op, (id, _line) = val
617
+
618
+ result = new_attrasgn lhs, id, call_op
570
619
  }
571
620
  | primary_value tCOLON2 tCONSTANT
572
621
  {
573
622
  if (self.in_def || self.in_single > 0) then
574
- debug20 7
623
+ debug 14
575
624
  yyerror "dynamic constant assignment"
576
625
  end
577
626
 
578
- expr, _, id = val
627
+ expr, _, (id, _line) = val
579
628
  l = expr.line
580
629
 
581
630
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -583,58 +632,65 @@ rule
583
632
  | tCOLON3 tCONSTANT
584
633
  {
585
634
  if (self.in_def || self.in_single > 0) then
586
- debug20 8
635
+ debug 15
587
636
  yyerror "dynamic constant assignment"
588
637
  end
589
638
 
590
- _, id = val
591
- l = lexer.lineno
639
+ _, (id, l) = val
592
640
 
593
641
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
594
642
  }
595
643
  | backref
596
644
  {
597
- self.backref_assign_error val[0]
645
+ ref, = val
646
+
647
+ self.backref_assign_error ref
598
648
  }
599
649
 
600
650
  lhs: user_variable
601
651
  {
602
- line = lexer.lineno
603
- result = self.assignable val[0]
604
- result.line = line
652
+ var, = val
653
+
654
+ result = self.assignable var
605
655
  }
606
656
  | keyword_variable
607
657
  {
608
- line = lexer.lineno
609
- result = self.assignable val[0]
610
- result.line = line
611
- debug20 9, val, result
658
+ var, = val
659
+
660
+ result = self.assignable var
661
+
662
+ debug 16
612
663
  }
613
664
  | primary_value tLBRACK2 opt_call_args rbracket
614
665
  {
615
666
  lhs, _, args, _ = val
667
+
616
668
  result = self.aryset lhs, args
617
669
  }
618
670
  | primary_value call_op tIDENTIFIER # REFACTOR
619
671
  {
620
- lhs, op, id = val
672
+ lhs, op, (id, _line) = val
673
+
621
674
  result = new_attrasgn lhs, id, op
622
675
  }
623
676
  | primary_value tCOLON2 tIDENTIFIER
624
677
  {
625
- lhs, _, id = val
678
+ lhs, _, (id, _line) = val
679
+
626
680
  result = new_attrasgn lhs, id
627
681
  }
628
682
  | primary_value call_op tCONSTANT # REFACTOR?
629
683
  {
630
- result = new_attrasgn val[0], val[2], val[1]
684
+ lhs, call_op, (id, _line) = val
685
+
686
+ result = new_attrasgn lhs, id, call_op
631
687
  }
632
688
  | primary_value tCOLON2 tCONSTANT
633
689
  {
634
- expr, _, id = val
690
+ expr, _, (id, _line) = val
635
691
 
636
692
  if (self.in_def || self.in_single > 0) then
637
- debug20 10
693
+ debug 17
638
694
  yyerror "dynamic constant assignment"
639
695
  end
640
696
 
@@ -643,14 +699,13 @@ rule
643
699
  }
644
700
  | tCOLON3 tCONSTANT
645
701
  {
646
- _, id = val
702
+ _, (id, l) = val
647
703
 
648
704
  if (self.in_def || self.in_single > 0) then
649
- debug20 11
705
+ debug 18
650
706
  yyerror "dynamic constant assignment"
651
707
  end
652
708
 
653
- l = lexer.lineno
654
709
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
655
710
  }
656
711
  | backref
@@ -666,16 +721,16 @@ rule
666
721
 
667
722
  cpath: tCOLON3 cname
668
723
  {
669
- _, name = val
670
- result = s(:colon3, name.to_sym).line lexer.lineno
724
+ result = wrap :colon3, val[1]
671
725
  }
672
726
  | cname
673
727
  {
674
- result = val[0].to_sym
728
+ (id, line), = val
729
+ result = [id.to_sym, line] # TODO: sexp?
675
730
  }
676
731
  | primary_value tCOLON2 cname
677
732
  {
678
- pval, _, name = val
733
+ pval, _, (name, _line) = val
679
734
 
680
735
  result = s(:colon2, pval, name.to_sym)
681
736
  result.line pval.line
@@ -685,24 +740,15 @@ rule
685
740
  | op
686
741
  {
687
742
  lexer.lex_state = EXPR_END
688
- result = val[0]
689
743
  }
690
744
 
691
745
  | reswords
692
- {
693
- (sym, _line), = val
694
- lexer.lex_state = EXPR_END
695
- result = sym
696
- }
697
-
698
- fsym: fname | symbol
699
746
 
700
- fitem: fsym
747
+ fitem: fname
701
748
  {
702
- id, = val
703
- result = s(:lit, id.to_sym).line lexer.lineno
749
+ result = wrap :lit, val[0]
704
750
  }
705
- | dsym
751
+ | symbol
706
752
 
707
753
  undef_list: fitem
708
754
  {
@@ -723,8 +769,6 @@ rule
723
769
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
724
770
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
725
771
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
- # TODO: tUBANG dead?
727
- | tUBANG
728
772
 
729
773
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
730
774
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -758,26 +802,22 @@ rule
758
802
  }
759
803
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
760
804
  {
761
- lhs, _, id, op, rhs = val
805
+ lhs, _, (id, _line), (op, _), rhs = val
762
806
 
763
807
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
764
808
  }
765
809
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
766
810
  {
767
- lhs1, _, lhs2, op, rhs = val
811
+ lhs1, _, (lhs2, _line), op, rhs = val
768
812
 
769
813
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
814
  result = new_const_op_asgn [lhs, op, rhs]
771
815
  }
772
- | tCOLON3 tCONSTANT
773
- {
774
- result = self.lexer.lineno
775
- }
776
- tOP_ASGN arg_rhs
816
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
777
817
  {
778
- _, lhs, line, op, rhs = val
818
+ _, lhs, op, rhs = val
779
819
 
780
- lhs = s(:colon3, lhs.to_sym).line line
820
+ lhs = wrap :colon3, lhs
781
821
  result = new_const_op_asgn [lhs, op, rhs]
782
822
  }
783
823
  | backref tOP_ASGN arg_rhs
@@ -789,7 +829,7 @@ rule
789
829
  | arg tDOT2 arg
790
830
  {
791
831
  v1, v2 = val[0], val[2]
792
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
832
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
793
833
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
794
834
  else
795
835
  result = s(:dot2, v1, v2).line v1.line
@@ -798,7 +838,7 @@ rule
798
838
  | arg tDOT3 arg
799
839
  {
800
840
  v1, v2 = val[0], val[2]
801
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
841
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
802
842
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
803
843
  else
804
844
  result = s(:dot3, v1, v2).line v1.line
@@ -818,6 +858,22 @@ rule
818
858
 
819
859
  result = s(:dot3, v1, v2).line v1.line
820
860
  }
861
+
862
+ | tBDOT2 arg
863
+ {
864
+ _, v2, = val
865
+ v1 = nil
866
+
867
+ result = s(:dot2, v1, v2).line v2.line
868
+ }
869
+ | tBDOT3 arg
870
+ {
871
+ _, v2 = val
872
+ v1 = nil
873
+
874
+ result = s(:dot3, v1, v2).line v2.line
875
+ }
876
+
821
877
  | arg tPLUS arg
822
878
  {
823
879
  result = new_call val[0], :+, argl(val[2])
@@ -844,8 +900,9 @@ rule
844
900
  }
845
901
  | tUMINUS_NUM simple_numeric tPOW arg
846
902
  {
847
- lit = s(:lit, val[1]).line lexer.lineno
848
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
903
+ _, (num, line), _, arg = val
904
+ lit = s(:lit, num).line line
905
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
849
906
 
850
907
  }
851
908
  | tUPLUS arg
@@ -944,12 +1001,12 @@ rule
944
1001
 
945
1002
  rel_expr: arg relop arg =tGT
946
1003
  {
947
- lhs, op, rhs = val
1004
+ lhs, (op, _), rhs = val
948
1005
  result = new_call lhs, op.to_sym, argl(rhs)
949
1006
  }
950
1007
  | rel_expr relop arg =tGT
951
1008
  {
952
- lhs, op, rhs = val
1009
+ lhs, (op, _), rhs = val
953
1010
  warn "comparison '%s' after comparison", op
954
1011
  result = new_call lhs, op.to_sym, argl(rhs)
955
1012
  }
@@ -989,6 +1046,24 @@ rule
989
1046
  _, args, _ = val
990
1047
  result = args
991
1048
  }
1049
+ | tLPAREN2 args tCOMMA args_forward rparen
1050
+ {
1051
+ yyerror "Unexpected ..." unless
1052
+ self.lexer.is_local_id(:"*") &&
1053
+ self.lexer.is_local_id(:"**") &&
1054
+ self.lexer.is_local_id(:"&")
1055
+
1056
+ result = call_args val
1057
+ }
1058
+ | tLPAREN2 args_forward rparen
1059
+ {
1060
+ yyerror "Unexpected ..." unless
1061
+ self.lexer.is_local_id(:"*") &&
1062
+ self.lexer.is_local_id(:"**") &&
1063
+ self.lexer.is_local_id(:"&")
1064
+
1065
+ result = call_args val
1066
+ }
992
1067
 
993
1068
  opt_paren_args: none
994
1069
  | paren_args
@@ -1140,8 +1215,9 @@ rule
1140
1215
  | backref
1141
1216
  | tFID
1142
1217
  {
1143
- msg, = val
1218
+ (msg, line), = val
1144
1219
  result = new_call nil, msg.to_sym
1220
+ result.line line
1145
1221
  }
1146
1222
  | k_begin
1147
1223
  {
@@ -1183,15 +1259,13 @@ rule
1183
1259
  }
1184
1260
  | primary_value tCOLON2 tCONSTANT
1185
1261
  {
1186
- expr, _, id = val
1262
+ expr, _, (id, _line) = val
1187
1263
 
1188
1264
  result = s(:colon2, expr, id.to_sym).line expr.line
1189
1265
  }
1190
1266
  | tCOLON3 tCONSTANT
1191
1267
  {
1192
- _, id = val
1193
-
1194
- result = s(:colon3, id.to_sym).line lexer.lineno
1268
+ result = wrap :colon3, val[1]
1195
1269
  }
1196
1270
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1197
1271
  {
@@ -1215,15 +1289,21 @@ rule
1215
1289
  }
1216
1290
  | kYIELD tLPAREN2 call_args rparen
1217
1291
  {
1218
- result = new_yield val[2]
1292
+ (_, line), _, args, _ = val
1293
+
1294
+ result = new_yield(args).line line
1219
1295
  }
1220
1296
  | kYIELD tLPAREN2 rparen
1221
1297
  {
1222
- result = new_yield
1298
+ (_, line), _, _ = val
1299
+
1300
+ result = new_yield.line line
1223
1301
  }
1224
1302
  | kYIELD
1225
1303
  {
1226
- result = new_yield
1304
+ (_, line), = val
1305
+
1306
+ result = new_yield.line line
1227
1307
  }
1228
1308
  | kDEFINED opt_nl tLPAREN2 expr rparen
1229
1309
  {
@@ -1238,7 +1318,7 @@ rule
1238
1318
  }
1239
1319
  | kNOT tLPAREN2 rparen
1240
1320
  {
1241
- debug20 14, val, result
1321
+ debug 20
1242
1322
  }
1243
1323
  | fcall brace_block
1244
1324
  {
@@ -1256,9 +1336,10 @@ rule
1256
1336
  iter.insert 1, call # FIX
1257
1337
  result = iter
1258
1338
  }
1259
- | tLAMBDA lambda
1339
+ | lambda
1260
1340
  {
1261
- result = val[1] # TODO: fix lineno
1341
+ expr, = val
1342
+ result = expr
1262
1343
  }
1263
1344
  | k_if expr_value then compstmt if_tail k_end
1264
1345
  {
@@ -1290,6 +1371,12 @@ rule
1290
1371
  (_, line), _, body, _ = val
1291
1372
  result = new_case nil, body, line
1292
1373
  }
1374
+ | k_case expr_value opt_terms p_case_body k_end
1375
+ {
1376
+ (_, line), expr, _, body, _ = val
1377
+
1378
+ result = new_case expr, body, line
1379
+ }
1293
1380
  | k_for for_var kIN expr_value_do compstmt k_end
1294
1381
  {
1295
1382
  _, var, _, iter, body, _ = val
@@ -1301,7 +1388,6 @@ rule
1301
1388
  }
1302
1389
  cpath superclass
1303
1390
  {
1304
- self.comments.push self.lexer.comments
1305
1391
  if (self.in_def || self.in_single > 0) then
1306
1392
  yyerror "class definition in method body"
1307
1393
  end
@@ -1311,7 +1397,7 @@ rule
1311
1397
  {
1312
1398
  result = new_class val
1313
1399
  self.env.unextend
1314
- self.lexer.comments # we don't care about comments in the body
1400
+ self.lexer.ignore_body_comments
1315
1401
  }
1316
1402
  | k_class tLSHFT
1317
1403
  {
@@ -1332,7 +1418,7 @@ rule
1332
1418
  {
1333
1419
  result = new_sclass val
1334
1420
  self.env.unextend
1335
- self.lexer.comments # we don't care about comments in the body
1421
+ self.lexer.ignore_body_comments
1336
1422
  }
1337
1423
  | k_module
1338
1424
  {
@@ -1340,7 +1426,6 @@ rule
1340
1426
  }
1341
1427
  cpath
1342
1428
  {
1343
- self.comments.push self.lexer.comments
1344
1429
  yyerror "module definition in method body" if
1345
1430
  self.in_def or self.in_single > 0
1346
1431
 
@@ -1350,7 +1435,7 @@ rule
1350
1435
  {
1351
1436
  result = new_module val
1352
1437
  self.env.unextend
1353
- self.lexer.comments # we don't care about comments in the body
1438
+ self.lexer.ignore_body_comments
1354
1439
  }
1355
1440
  | k_def fname
1356
1441
  {
@@ -1360,21 +1445,17 @@ rule
1360
1445
  self.env.extend
1361
1446
  lexer.cmdarg.push false
1362
1447
  lexer.cond.push false
1363
-
1364
- self.comments.push self.lexer.comments
1365
1448
  }
1366
- f_arglist bodystmt { result = lexer.lineno } k_end
1449
+ f_arglist bodystmt k_end
1367
1450
  {
1368
- in_def = val[2]
1369
-
1370
- result = new_defn val
1451
+ result, in_def = new_defn val
1371
1452
 
1372
1453
  lexer.cond.pop # group = local_pop
1373
1454
  lexer.cmdarg.pop
1374
1455
  self.env.unextend
1375
1456
  self.in_def = in_def
1376
1457
 
1377
- self.lexer.comments # we don't care about comments in the body
1458
+ self.lexer.ignore_body_comments
1378
1459
  }
1379
1460
  | k_def singleton dot_or_colon
1380
1461
  {
@@ -1382,7 +1463,7 @@ rule
1382
1463
  }
1383
1464
  fname
1384
1465
  {
1385
- result = [self.in_def, lexer.lineno]
1466
+ result = self.in_def
1386
1467
 
1387
1468
  self.in_single += 1 # TODO: remove?
1388
1469
 
@@ -1392,13 +1473,18 @@ rule
1392
1473
  lexer.cond.push false
1393
1474
 
1394
1475
  lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1395
- self.comments.push self.lexer.comments
1396
1476
  }
1397
1477
  f_arglist bodystmt k_end
1398
1478
  {
1399
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1400
1479
 
1401
- result = new_defs val
1480
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1481
+ # =>
1482
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1483
+
1484
+ val.delete_at 3
1485
+ val.delete_at 2
1486
+
1487
+ result, in_def = new_defs val
1402
1488
 
1403
1489
  lexer.cond.pop # group = local_pop
1404
1490
  lexer.cmdarg.pop
@@ -1409,7 +1495,7 @@ rule
1409
1495
 
1410
1496
  # TODO: restore cur_arg ? what's cur_arg?
1411
1497
 
1412
- self.lexer.comments # we don't care about comments in the body
1498
+ self.lexer.ignore_body_comments
1413
1499
  }
1414
1500
  | kBREAK
1415
1501
  {
@@ -1446,8 +1532,17 @@ rule
1446
1532
  k_case: kCASE
1447
1533
  k_for: kFOR
1448
1534
  k_class: kCLASS
1535
+ {
1536
+ self.comments.push self.lexer.comments
1537
+ }
1449
1538
  k_module: kMODULE
1539
+ {
1540
+ self.comments.push self.lexer.comments
1541
+ }
1450
1542
  k_def: kDEF
1543
+ {
1544
+ self.comments.push self.lexer.comments
1545
+ }
1451
1546
  k_do: kDO
1452
1547
  k_do_block: kDO_BLOCK
1453
1548
  k_rescue: kRESCUE
@@ -1508,51 +1603,42 @@ rule
1508
1603
 
1509
1604
  result = block_var args
1510
1605
  }
1511
- | f_marg_list tCOMMA tSTAR f_norm_arg
1606
+ | f_marg_list tCOMMA f_rest_marg
1512
1607
  {
1513
- args, _, _, splat = val
1608
+ args, _, rest = val
1514
1609
 
1515
- result = block_var args, "*#{splat}".to_sym
1610
+ result = block_var args, rest
1516
1611
  }
1517
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1612
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1518
1613
  {
1519
- args, _, _, splat, _, args2 = val
1614
+ lhs, _, splat, _, rhs = val
1520
1615
 
1521
- result = block_var args, "*#{splat}".to_sym, args2
1616
+ result = block_var lhs, splat, rhs
1522
1617
  }
1523
- | f_marg_list tCOMMA tSTAR
1618
+ | f_rest_marg
1524
1619
  {
1525
- args, _, _ = val
1620
+ rest, = val
1526
1621
 
1527
- result = block_var args, :*
1622
+ result = block_var rest
1528
1623
  }
1529
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1624
+ | f_rest_marg tCOMMA f_marg_list
1530
1625
  {
1531
- args, _, _, _, args2 = val
1626
+ splat, _, rest = val
1532
1627
 
1533
- result = block_var args, :*, args2
1628
+ result = block_var splat, rest
1534
1629
  }
1535
- | tSTAR f_norm_arg
1536
- {
1537
- _, splat = val
1538
1630
 
1539
- result = block_var :"*#{splat}"
1540
- }
1541
- | tSTAR f_norm_arg tCOMMA f_marg_list
1631
+ f_rest_marg: tSTAR f_norm_arg
1542
1632
  {
1543
- _, splat, _, args = val
1633
+ _, (id, line) = val
1544
1634
 
1545
- result = block_var :"*#{splat}", args
1635
+ result = args ["*#{id}".to_sym]
1636
+ result.line line
1546
1637
  }
1547
1638
  | tSTAR
1548
1639
  {
1549
- result = block_var :*
1550
- }
1551
- | tSTAR tCOMMA f_marg_list
1552
- {
1553
- _, _, args = val
1554
-
1555
- result = block_var :*, args
1640
+ result = args [:*]
1641
+ result.line lexer.lineno # FIX: tSTAR -> line
1556
1642
  }
1557
1643
 
1558
1644
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1567,10 +1653,14 @@ rule
1567
1653
  {
1568
1654
  result = call_args val
1569
1655
  }
1656
+ | f_no_kwarg opt_f_block_arg
1657
+ {
1658
+ result = args val
1659
+ }
1570
1660
  | f_block_arg
1571
1661
  {
1572
- line = lexer.lineno
1573
- result = call_args val # TODO: push line down
1662
+ (id, line), = val
1663
+ result = call_args [id]
1574
1664
  result.line line
1575
1665
  }
1576
1666
 
@@ -1679,13 +1769,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1679
1769
 
1680
1770
  bvar: tIDENTIFIER
1681
1771
  {
1682
- id, = val
1683
- line = lexer.lineno
1684
- result = s(:shadow, id.to_sym).line line
1772
+ result = wrap :shadow, val[0]
1685
1773
  }
1686
1774
  | f_bad_arg
1687
1775
 
1688
- lambda: {
1776
+ lambda: tLAMBDA
1777
+ {
1689
1778
  self.env.extend :dynamic
1690
1779
  result = [lexer.lineno, lexer.lpar_beg]
1691
1780
  lexer.paren_nest += 1
@@ -1697,14 +1786,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1697
1786
  }
1698
1787
  lambda_body
1699
1788
  {
1700
- (line, lpar), args, _cmdarg, body = val
1789
+ _, (line, lpar), args, _cmdarg, body = val
1701
1790
  lexer.lpar_beg = lpar
1702
1791
 
1703
1792
  lexer.cmdarg.pop
1704
1793
 
1705
1794
  call = s(:lambda).line line
1706
1795
  result = new_iter call, args, body
1707
- result.line = line
1796
+ result.line line
1708
1797
  self.env.unextend # TODO: dynapush & dynapop
1709
1798
  }
1710
1799
 
@@ -1739,23 +1828,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1739
1828
  ## if (nd_type($1) == NODE_YIELD) {
1740
1829
  ## compile_error(PARSER_ARG "block given to yield");
1741
1830
 
1742
- syntax_error "Both block arg and actual block given." if
1743
- val[0].block_pass?
1831
+ cmd, blk = val
1744
1832
 
1745
- val = invert_block_call val if inverted? val
1833
+ syntax_error "Both block arg and actual block given." if
1834
+ cmd.block_pass?
1746
1835
 
1747
- cmd, blk = val
1836
+ if inverted? val then
1837
+ val = invert_block_call val
1838
+ cmd, blk = val
1839
+ end
1748
1840
 
1749
1841
  result = blk
1750
1842
  result.insert 1, cmd
1751
1843
  }
1752
1844
  | block_call call_op2 operation2 opt_paren_args
1753
1845
  {
1754
- result = new_call val[0], val[2].to_sym, val[3]
1846
+ lhs, _, (id, _line), args = val
1847
+
1848
+ result = new_call lhs, id.to_sym, args
1755
1849
  }
1756
1850
  | block_call call_op2 operation2 opt_paren_args brace_block
1757
1851
  {
1758
- iter1, _, name, args, iter2 = val
1852
+ iter1, _, (name, _line), args, iter2 = val
1759
1853
 
1760
1854
  call = new_call iter1, name.to_sym, args
1761
1855
  iter2.insert 1, call
@@ -1764,7 +1858,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1764
1858
  }
1765
1859
  | block_call call_op2 operation2 command_args do_block
1766
1860
  {
1767
- iter1, _, name, args, iter2 = val
1861
+ iter1, _, (name, _line), args, iter2 = val
1768
1862
 
1769
1863
  call = new_call iter1, name.to_sym, args
1770
1864
  iter2.insert 1, call
@@ -1772,28 +1866,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1772
1866
  result = iter2
1773
1867
  }
1774
1868
 
1775
- method_call: fcall
1869
+ method_call: fcall paren_args
1776
1870
  {
1777
- result = self.lexer.lineno
1778
- }
1779
- paren_args
1780
- {
1781
- call, lineno, args = val
1871
+ call, args = val
1782
1872
 
1783
1873
  result = call.concat args.sexp_body if args
1784
- result.line lineno
1785
1874
  }
1786
1875
  | primary_value call_op operation2 opt_paren_args
1787
1876
  {
1788
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1877
+ recv, call_op, (op, _line), args = val
1878
+
1879
+ result = new_call recv, op.to_sym, args, call_op
1789
1880
  }
1790
1881
  | primary_value tCOLON2 operation2 paren_args
1791
1882
  {
1792
- result = new_call val[0], val[2].to_sym, val[3]
1883
+ recv, _, (op, _line), args = val
1884
+
1885
+ result = new_call recv, op.to_sym, args
1793
1886
  }
1794
1887
  | primary_value tCOLON2 operation3
1795
1888
  {
1796
- result = new_call val[0], val[2].to_sym
1889
+ lhs, _, (id, _line) = val
1890
+
1891
+ result = new_call lhs, id.to_sym
1797
1892
  }
1798
1893
  | primary_value call_op paren_args
1799
1894
  {
@@ -1826,7 +1921,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1826
1921
  _, line, body, _ = val
1827
1922
 
1828
1923
  result = body
1829
- result.line = line
1924
+ result.line line
1830
1925
 
1831
1926
  self.env.unextend
1832
1927
  }
@@ -1840,7 +1935,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1840
1935
  _, line, body, _ = val
1841
1936
 
1842
1937
  result = body
1843
- result.line = line
1938
+ result.line line
1844
1939
 
1845
1940
  self.env.unextend
1846
1941
  }
@@ -1869,18 +1964,549 @@ opt_block_args_tail: tCOMMA block_args_tail
1869
1964
  self.env.unextend
1870
1965
  }
1871
1966
 
1967
+ case_args: arg_value
1968
+ {
1969
+ arg, = val
1970
+
1971
+ result = s(:array, arg).line arg.line
1972
+ }
1973
+ | tSTAR arg_value
1974
+ {
1975
+ _, arg = val
1976
+
1977
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1978
+ }
1979
+ | case_args tCOMMA arg_value
1980
+ {
1981
+ args, _, id = val
1982
+
1983
+ result = self.list_append args, id
1984
+ }
1985
+ | case_args tCOMMA tSTAR arg_value
1986
+ {
1987
+ args, _, _, id = val
1988
+
1989
+ result = self.list_append args, s(:splat, id).line(id.line)
1990
+ }
1991
+
1872
1992
  case_body: k_when
1873
1993
  {
1874
1994
  result = self.lexer.lineno
1875
1995
  }
1876
- args then compstmt cases
1996
+ case_args then compstmt cases
1877
1997
  {
1878
1998
  result = new_when(val[2], val[4])
1879
- result.line = val[1]
1999
+ result.line val[1]
1880
2000
  result << val[5] if val[5]
1881
2001
  }
1882
2002
 
1883
2003
  cases: opt_else | case_body
2004
+ ######################################################################
2005
+
2006
+ p_case_body: kIN
2007
+ {
2008
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2009
+ self.lexer.command_start = false
2010
+ result = self.in_kwarg
2011
+ self.in_kwarg = true
2012
+ push_pvtbl
2013
+ push_pktbl
2014
+ }
2015
+ p_top_expr then
2016
+ {
2017
+ pop_pktbl
2018
+ pop_pvtbl
2019
+ old_kwargs = _values[-3]
2020
+ self.in_kwarg = old_kwargs
2021
+ }
2022
+ compstmt
2023
+ p_cases
2024
+ {
2025
+ (_, line), _, pat, _, _, body, cases = val
2026
+
2027
+ result = new_in pat, body, cases, line
2028
+ }
2029
+
2030
+ p_cases: opt_else
2031
+ | p_case_body
2032
+
2033
+ p_top_expr: p_top_expr_body
2034
+ | p_top_expr_body kIF_MOD expr_value
2035
+ {
2036
+ body, _, cond = val
2037
+ body = remove_begin body
2038
+
2039
+ result = s(:if, cond, body, nil).line body.line
2040
+ }
2041
+ | p_top_expr_body kUNLESS_MOD expr_value
2042
+ {
2043
+ body, _, cond = val
2044
+ body = remove_begin body
2045
+
2046
+ result = s(:if, cond, nil, body).line body.line
2047
+ }
2048
+
2049
+ p_top_expr_body: p_expr
2050
+ | p_expr tCOMMA
2051
+ {
2052
+ expr, _ = val
2053
+
2054
+ tail = new_array_pattern_tail nil, true, nil, nil
2055
+ result = new_array_pattern nil, expr, tail, expr.line
2056
+ }
2057
+ | p_expr tCOMMA p_args
2058
+ {
2059
+ expr, _, args = val
2060
+
2061
+ result = new_array_pattern nil, expr, args, expr.line
2062
+ }
2063
+ | p_args_tail
2064
+ {
2065
+ args, = val
2066
+ result = new_array_pattern nil, nil, args, args.line
2067
+ }
2068
+ | p_kwargs
2069
+ {
2070
+ kwargs, = val
2071
+ result = new_hash_pattern nil, kwargs, kwargs.line
2072
+ }
2073
+
2074
+ p_expr: p_as
2075
+
2076
+ p_as: p_expr tASSOC p_variable
2077
+ {
2078
+ # NODE *n = NEW_LIST($1, &@$);
2079
+ # n = list_append(p, n, $3);
2080
+ # $$ = new_hash(p, n, &@$);
2081
+
2082
+ expr, _, var = val
2083
+
2084
+ id = var.last
2085
+
2086
+ self.env[id] = :lvar # HACK: need to extend env
2087
+ lhs = s(:lasgn, id).line var.line
2088
+
2089
+ result = new_assign lhs, expr
2090
+ }
2091
+ | p_alt
2092
+
2093
+ p_alt: p_alt tPIPE p_expr_basic
2094
+ {
2095
+ lhs, _, rhs = val
2096
+
2097
+ result = s(:or, lhs, rhs).line lhs.line
2098
+ }
2099
+ | p_expr_basic
2100
+
2101
+ p_lparen: tLPAREN2 { push_pktbl }
2102
+ p_lbracket: tLBRACK2 { push_pktbl }
2103
+
2104
+ p_expr_basic: p_value
2105
+ | p_const p_lparen p_args tRPAREN
2106
+ {
2107
+ lhs, _, args, _ = val
2108
+
2109
+ pop_pktbl
2110
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2111
+ }
2112
+ | p_const p_lparen p_kwargs tRPAREN
2113
+ {
2114
+ lhs, _, kwargs, _ = val
2115
+
2116
+ pop_pktbl
2117
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2118
+ }
2119
+ | p_const tLPAREN2 tRPAREN
2120
+ {
2121
+ const, _, _ = val
2122
+
2123
+ tail = new_array_pattern_tail nil, nil, nil, nil
2124
+ result = new_array_pattern const, nil, tail, const.line
2125
+ }
2126
+ | p_const p_lbracket p_args rbracket
2127
+ {
2128
+ const, _, pre_arg, _ = val
2129
+
2130
+ pop_pktbl
2131
+ result = new_array_pattern const, nil, pre_arg, const.line
2132
+ }
2133
+ | p_const p_lbracket p_kwargs rbracket
2134
+ {
2135
+ const, _, kwargs, _ = val
2136
+
2137
+ result = new_hash_pattern const, kwargs, const.line
2138
+ }
2139
+ | p_const tLBRACK2 rbracket
2140
+ {
2141
+ const, _, _ = val
2142
+
2143
+ tail = new_array_pattern_tail nil, nil, nil, nil
2144
+ result = new_array_pattern const, nil, tail, const.line
2145
+ }
2146
+ | tLBRACK { push_pktbl } p_args rbracket
2147
+ {
2148
+ _, _, pat, _ = val
2149
+
2150
+ pop_pktbl
2151
+ result = new_array_pattern nil, nil, pat, pat.line
2152
+ }
2153
+ | tLBRACK rbracket
2154
+ {
2155
+ (_, line), _ = val
2156
+
2157
+ result = s(:array_pat).line line
2158
+ }
2159
+ | tLBRACE
2160
+ {
2161
+ push_pktbl
2162
+ result = self.in_kwarg
2163
+ self.in_kwarg = false
2164
+ }
2165
+ p_kwargs rbrace
2166
+ {
2167
+ _, in_kwarg, kwargs, _ = val
2168
+
2169
+ pop_pktbl
2170
+ self.in_kwarg = in_kwarg
2171
+
2172
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2173
+ }
2174
+ | tLBRACE rbrace
2175
+ {
2176
+ (_, line), _ = val
2177
+
2178
+ tail = new_hash_pattern_tail nil, nil, line
2179
+ result = new_hash_pattern nil, tail, line
2180
+ }
2181
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2182
+ {
2183
+ _, _, expr, _ = val
2184
+
2185
+ pop_pktbl
2186
+ result = expr
2187
+ }
2188
+
2189
+ p_args: p_expr
2190
+ {
2191
+ expr, = val
2192
+
2193
+ ary = s(:array_TAIL, expr).line expr.line
2194
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2195
+ }
2196
+ | p_args_head
2197
+ {
2198
+ head, = val
2199
+
2200
+ result = new_array_pattern_tail head, true, nil, nil
2201
+ }
2202
+ | p_args_head p_arg
2203
+ {
2204
+ head, tail = val
2205
+
2206
+ both = array_pat_concat head, tail
2207
+
2208
+ result = new_array_pattern_tail both, nil, nil, nil
2209
+ result.line head.line
2210
+ }
2211
+ | p_args_head tSTAR tIDENTIFIER
2212
+ {
2213
+ head, _, (id, _line) = val
2214
+
2215
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2216
+ result.line head.line
2217
+ }
2218
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2219
+ {
2220
+ head, _, (id, _line), _, post = val
2221
+
2222
+ result = new_array_pattern_tail head, true, id.to_sym, post
2223
+ result.line head.line
2224
+ }
2225
+ | p_args_head tSTAR
2226
+ {
2227
+ expr, _ = val
2228
+
2229
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2230
+ }
2231
+ | p_args_head tSTAR tCOMMA p_args_post
2232
+ {
2233
+ head, _, _, post = val
2234
+
2235
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2236
+ }
2237
+ | p_args_tail
2238
+
2239
+ p_args_head: p_arg tCOMMA
2240
+ {
2241
+ arg, _ = val
2242
+ result = arg
2243
+ }
2244
+ | p_args_head p_arg tCOMMA
2245
+ {
2246
+ head, tail, _ = val
2247
+
2248
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2249
+ result.line head.line
2250
+ }
2251
+
2252
+ p_args_tail: tSTAR tIDENTIFIER
2253
+ {
2254
+ _, (id, line) = val
2255
+
2256
+ result = new_array_pattern_tail nil, true, id.to_sym, nil
2257
+ result.line line
2258
+ }
2259
+ | tSTAR tIDENTIFIER tCOMMA p_args_post
2260
+ {
2261
+ _, (id, line), _, rhs = val
2262
+
2263
+ result = new_array_pattern_tail nil, true, id.to_sym, rhs
2264
+ result.line line
2265
+ }
2266
+ | tSTAR
2267
+ {
2268
+ (_, line), = val
2269
+
2270
+ result = new_array_pattern_tail nil, true, nil, nil
2271
+ result.line line
2272
+ }
2273
+ | tSTAR tCOMMA p_args_post
2274
+ {
2275
+ (_, line), _, args = val
2276
+
2277
+ result = new_array_pattern_tail nil, true, nil, args
2278
+ result.line line
2279
+ }
2280
+
2281
+ p_args_post: p_arg
2282
+ | p_args_post tCOMMA p_arg
2283
+ {
2284
+ lhs, _, rhs = val
2285
+
2286
+ result = array_pat_concat lhs, rhs
2287
+ }
2288
+
2289
+ p_arg: p_expr
2290
+ {
2291
+ expr, = val
2292
+ expr = s(:array_TAIL, expr).line expr.line unless
2293
+ expr.sexp_type == :array_TAIL
2294
+ result = expr
2295
+ }
2296
+
2297
+ p_kwargs: p_kwarg tCOMMA p_kwrest
2298
+ {
2299
+ kw_arg, _, rest = val
2300
+ # TODO? new_unique_key_hash(p, $1, &@$)
2301
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2302
+ }
2303
+ | p_kwarg
2304
+ {
2305
+ kwarg, = val
2306
+ # TODO? new_unique_key_hash(p, $1, &@$)
2307
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2308
+ }
2309
+ | p_kwarg tCOMMA
2310
+ {
2311
+ kwarg, _ = val
2312
+ # TODO? new_unique_key_hash(p, $1, &@$)
2313
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2314
+ }
2315
+ | p_kwrest
2316
+ {
2317
+ rest, = val
2318
+
2319
+ result = new_hash_pattern_tail nil, rest, rest.line
2320
+ }
2321
+ | p_kwarg tCOMMA p_kwnorest
2322
+ {
2323
+ kwarg, _, norest = val
2324
+
2325
+ # TODO? new_unique_key_hash(p, $1, &@$)
2326
+ result = new_hash_pattern_tail kwarg, norest, kwarg.line
2327
+ }
2328
+ | p_kwnorest
2329
+ {
2330
+ norest, = val
2331
+
2332
+ result = new_hash_pattern_tail nil, norest, norest.line
2333
+ }
2334
+
2335
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2336
+ | p_kwarg tCOMMA p_kw
2337
+ {
2338
+ kwarg, _, kw = val
2339
+ kwarg.concat kw.sexp_body
2340
+ result = kwarg
2341
+ }
2342
+
2343
+ p_kw: p_kw_label p_expr
2344
+ {
2345
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2346
+ lhs, rhs = val
2347
+
2348
+ result = s(:PAIR, lhs, rhs).line lhs.line
2349
+ }
2350
+ | p_kw_label
2351
+ {
2352
+ lhs, = val
2353
+
2354
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2355
+
2356
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2357
+ # yyerror1(&@1, "key must be valid as local variables");
2358
+ # }
2359
+
2360
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2361
+ # assignable(p, $1, 0, &@$));
2362
+
2363
+
2364
+ case lhs.sexp_type
2365
+ when :lit then
2366
+ assignable [lhs.value, lhs.line]
2367
+ else
2368
+ # TODO or done?
2369
+ debug 666
2370
+ end
2371
+
2372
+ # TODO PAIR -> LIST ?
2373
+ result = s(:PAIR, lhs, nil).line lhs.line
2374
+ }
2375
+
2376
+ p_kw_label: tLABEL
2377
+ {
2378
+ result = wrap :lit, val[0]
2379
+ }
2380
+
2381
+ p_kwrest: kwrest_mark tIDENTIFIER
2382
+ {
2383
+ _, (id, line) = val
2384
+
2385
+ name = id.to_sym
2386
+ self.assignable [name, line]
2387
+ result = s(:kwrest, :"**#{name}").line line
2388
+ }
2389
+ | kwrest_mark
2390
+ {
2391
+ (_, line), = val
2392
+
2393
+ result = s(:kwrest, :"**").line line
2394
+ }
2395
+
2396
+ p_kwnorest: kwrest_mark kNIL
2397
+ {
2398
+ (_, line), _ = val
2399
+
2400
+ # TODO: or s(:norest)? s(:**nil)?
2401
+ result = s(:kwrest, :"**nil").line line
2402
+ }
2403
+
2404
+ p_value: p_primitive
2405
+ | p_primitive tDOT2 p_primitive
2406
+ {
2407
+ lhs, _, rhs = val
2408
+
2409
+ lhs = value_expr lhs
2410
+ rhs = value_expr rhs
2411
+
2412
+ result = s(:dot2, lhs, rhs).line lhs.line
2413
+ }
2414
+ | p_primitive tDOT3 p_primitive
2415
+ {
2416
+ lhs, _, rhs = val
2417
+
2418
+ lhs = value_expr lhs
2419
+ rhs = value_expr rhs
2420
+
2421
+ result = s(:dot3, lhs, rhs).line lhs.line
2422
+ }
2423
+ | p_primitive tDOT2
2424
+ {
2425
+ v1, _ = val
2426
+
2427
+ result = s(:dot2, v1, nil).line v1.line
2428
+ }
2429
+ | p_primitive tDOT3
2430
+ {
2431
+ v1, _ = val
2432
+
2433
+ result = s(:dot3, v1, nil).line v1.line
2434
+ }
2435
+ | p_variable
2436
+ | p_var_ref
2437
+ | p_const
2438
+ | tBDOT2 p_primitive
2439
+ {
2440
+ _, v1 = val
2441
+
2442
+ result = s(:dot2, nil, v1).line v1.line
2443
+ }
2444
+ | tBDOT3 p_primitive
2445
+ {
2446
+ _, v1 = val
2447
+
2448
+ result = s(:dot3, nil, v1).line v1.line
2449
+ }
2450
+
2451
+ p_primitive: literal
2452
+ | strings
2453
+ | xstring
2454
+ | regexp
2455
+ | words
2456
+ {
2457
+ result = ary_to_pat val[0]
2458
+ }
2459
+ | qwords
2460
+ {
2461
+ result = ary_to_pat val[0]
2462
+ }
2463
+ | symbols
2464
+ {
2465
+ result = ary_to_pat val[0]
2466
+ }
2467
+ | qsymbols
2468
+ {
2469
+ result = ary_to_pat val[0]
2470
+ }
2471
+ | keyword_variable
2472
+ {
2473
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2474
+ var, = val
2475
+
2476
+ result = var
2477
+ }
2478
+ | lambda
2479
+
2480
+ p_variable: tIDENTIFIER
2481
+ {
2482
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2483
+ # TODO: assignable(p, $1, 0, &@$);
2484
+ result = wrap :lasgn, val[0]
2485
+ }
2486
+
2487
+ p_var_ref: tCARET tIDENTIFIER
2488
+ {
2489
+ # TODO: check id against env for lvar or dvar
2490
+ result = wrap :lvar, val[1]
2491
+ }
2492
+
2493
+ p_const: tCOLON3 cname
2494
+ {
2495
+ result = wrap :colon3, val[1]
2496
+ }
2497
+ | p_const tCOLON2 cname
2498
+ {
2499
+ lhs, _, (id, _line) = val
2500
+
2501
+ l = lhs.line
2502
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2503
+ }
2504
+ | tCONSTANT
2505
+ {
2506
+ # TODO $$ = gettable(p, $1, &@$);
2507
+ result = wrap :const, val[0]
2508
+ }
2509
+ ######################################################################
1884
2510
 
1885
2511
  opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1886
2512
  {
@@ -1922,17 +2548,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1922
2548
 
1923
2549
  literal: numeric
1924
2550
  {
1925
- line = lexer.lineno
1926
- result = s(:lit, val[0])
1927
- result.line = line
2551
+ (lit, line), = val
2552
+ result = s(:lit, lit).line line
1928
2553
  }
1929
2554
  | symbol
1930
- {
1931
- line = lexer.lineno
1932
- result = s(:lit, val[0])
1933
- result.line = line
1934
- }
1935
- | dsym
1936
2555
 
1937
2556
  strings: string
1938
2557
  {
@@ -1943,7 +2562,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1943
2562
 
1944
2563
  string: tCHAR
1945
2564
  {
1946
- debug20 23, val, result
2565
+ debug 37
1947
2566
  }
1948
2567
  | string1
1949
2568
  | string string1
@@ -1953,11 +2572,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1953
2572
 
1954
2573
  string1: tSTRING_BEG string_contents tSTRING_END
1955
2574
  {
1956
- _, str, (_, func) = val
2575
+ (_, line), str, (_, func) = val
1957
2576
 
1958
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2577
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1959
2578
 
1960
- result = str
2579
+ result = str.line line
1961
2580
  }
1962
2581
  | tSTRING
1963
2582
  {
@@ -1977,11 +2596,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1977
2596
 
1978
2597
  words: tWORDS_BEG tSPACE tSTRING_END
1979
2598
  {
1980
- result = s(:array).line lexer.lineno
2599
+ (_, line), _, _ = val
2600
+
2601
+ result = s(:array).line line
1981
2602
  }
1982
2603
  | tWORDS_BEG word_list tSTRING_END
1983
2604
  {
1984
- result = val[1]
2605
+ (_, line), list, _ = val
2606
+
2607
+ result = list.line line
1985
2608
  }
1986
2609
 
1987
2610
  word_list: none
@@ -2001,18 +2624,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2001
2624
 
2002
2625
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2003
2626
  {
2004
- result = s(:array).line lexer.lineno
2627
+ (_, line), _, _ = val
2628
+
2629
+ result = s(:array).line line
2005
2630
  }
2006
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2631
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2007
2632
  {
2008
- _, line, list, _, = val
2009
- list.line = line
2633
+ (_, line), list, _, = val
2634
+ list.line line
2010
2635
  result = list
2011
2636
  }
2012
2637
 
2013
2638
  symbol_list: none
2014
2639
  {
2015
- result = new_symbol_list.line lexer.lineno
2640
+ result = new_symbol_list
2016
2641
  }
2017
2642
  | symbol_list word tSPACE
2018
2643
  {
@@ -2022,20 +2647,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2022
2647
 
2023
2648
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2024
2649
  {
2025
- result = s(:array).line lexer.lineno
2650
+ (_, line), _, _ = val
2651
+
2652
+ result = s(:array).line line
2026
2653
  }
2027
2654
  | tQWORDS_BEG qword_list tSTRING_END
2028
2655
  {
2029
- result = val[1]
2656
+ (_, line), list, _ = val
2657
+
2658
+ result = list.line line
2030
2659
  }
2031
2660
 
2032
2661
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2033
2662
  {
2034
- result = s(:array).line lexer.lineno # FIX
2663
+ (_, line), _, _ = val
2664
+
2665
+ result = s(:array).line line
2035
2666
  }
2036
2667
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2037
2668
  {
2038
- result = val[1]
2669
+ (_, line), list, _ = val
2670
+
2671
+ result = list.line line
2039
2672
  }
2040
2673
 
2041
2674
  qword_list: none
@@ -2058,7 +2691,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2058
2691
 
2059
2692
  string_contents: none
2060
2693
  {
2061
- result = s(:str, "").line lexer.lineno
2694
+ line = prev_value_to_lineno _values.last
2695
+ result = s(:str, +"").line line
2062
2696
  }
2063
2697
  | string_contents string_content
2064
2698
  {
@@ -2133,8 +2767,8 @@ regexp_contents: none
2133
2767
  lexer.brace_nest = brace_nest
2134
2768
  lexer.string_nest = string_nest
2135
2769
 
2136
- lexer.cmdarg.pop
2137
2770
  lexer.cond.pop
2771
+ lexer.cmdarg.pop
2138
2772
 
2139
2773
  lexer.lex_state = oldlex_state
2140
2774
 
@@ -2149,29 +2783,42 @@ regexp_contents: none
2149
2783
  when nil then
2150
2784
  result = s(:evstr).line line
2151
2785
  else
2152
- debug20 25
2786
+ debug 38
2153
2787
  raise "unknown string body: #{stmt.inspect}"
2154
2788
  end
2155
2789
  }
2156
2790
 
2157
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2158
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2159
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2791
+ string_dvar: tGVAR
2792
+ {
2793
+ result = wrap :gvar, val[0]
2794
+ }
2795
+ | tIVAR
2796
+ {
2797
+ result = wrap :ivar, val[0]
2798
+ }
2799
+ | tCVAR
2800
+ {
2801
+ result = wrap :cvar, val[0]
2802
+ }
2160
2803
  | backref
2161
2804
 
2162
- symbol: tSYMBEG sym
2805
+ symbol: ssym
2806
+ | dsym
2807
+
2808
+ ssym: tSYMBEG sym
2163
2809
  {
2164
2810
  lexer.lex_state = EXPR_END
2165
- result = val[1].to_sym
2811
+ result = wrap :lit, val[1]
2166
2812
  }
2167
2813
  | tSYMBOL
2168
2814
  {
2169
- result = val[0].to_sym
2815
+ lexer.lex_state = EXPR_END
2816
+ result = wrap :lit, val[0]
2170
2817
  }
2171
2818
 
2172
2819
  sym: fname | tIVAR | tGVAR | tCVAR
2173
2820
 
2174
- dsym: tSYMBEG xstring_contents tSTRING_END
2821
+ dsym: tSYMBEG string_contents tSTRING_END
2175
2822
  {
2176
2823
  _, result, _ = val
2177
2824
 
@@ -2187,14 +2834,15 @@ regexp_contents: none
2187
2834
  when :evstr then
2188
2835
  result = s(:dsym, "", result).line result.line
2189
2836
  else
2190
- debug20 26, val, result
2837
+ debug 39
2191
2838
  end
2192
2839
  }
2193
2840
 
2194
2841
  numeric: simple_numeric
2195
- | tUMINUS_NUM simple_numeric
2842
+ | tUMINUS_NUM simple_numeric =tLOWEST
2196
2843
  {
2197
- result = -val[1] # TODO: pt_testcase
2844
+ _, (num, line) = val
2845
+ result = [-num, line]
2198
2846
  }
2199
2847
 
2200
2848
  simple_numeric: tINTEGER
@@ -2227,8 +2875,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2227
2875
 
2228
2876
  var_ref: user_variable
2229
2877
  {
2230
- var = val[0]
2878
+ raise "NO: #{val.inspect}" if Sexp === val.first
2879
+ (var, line), = val
2231
2880
  result = Sexp === var ? var : self.gettable(var)
2881
+ result.line line
2232
2882
  }
2233
2883
  | keyword_variable
2234
2884
  {
@@ -2243,11 +2893,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2243
2893
  | keyword_variable
2244
2894
  {
2245
2895
  result = self.assignable val[0]
2246
- debug20 29, val, result
2896
+ debug 40
2247
2897
  }
2248
2898
 
2249
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2250
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2899
+ backref: tNTH_REF
2900
+ {
2901
+ (ref, line), = val
2902
+ result = s(:nth_ref, ref).line line
2903
+ }
2904
+ | tBACK_REF
2905
+ {
2906
+ (ref, line), = val
2907
+ result = s(:back_ref, ref).line line
2908
+ }
2251
2909
 
2252
2910
  superclass: tLT
2253
2911
  {
@@ -2265,9 +2923,15 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2923
 
2266
2924
  f_arglist: tLPAREN2 f_args rparen
2267
2925
  {
2268
- result = val[1]
2269
- self.lexer.lex_state = EXPR_BEG
2270
- self.lexer.command_start = true
2926
+ result = end_args val
2927
+ }
2928
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
2929
+ {
2930
+ result = end_args val
2931
+ }
2932
+ | tLPAREN2 args_forward rparen
2933
+ {
2934
+ result = end_args val
2271
2935
  }
2272
2936
  | {
2273
2937
  result = self.in_kwarg
@@ -2276,12 +2940,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2276
2940
  }
2277
2941
  f_args term
2278
2942
  {
2279
- kwarg, args, _ = val
2280
-
2281
- self.in_kwarg = kwarg
2282
- result = args
2283
- lexer.lex_state = EXPR_BEG
2284
- lexer.command_start = true
2943
+ result = end_args val
2285
2944
  }
2286
2945
 
2287
2946
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2296,6 +2955,10 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2296
2955
  {
2297
2956
  result = args val
2298
2957
  }
2958
+ | f_no_kwarg opt_f_block_arg
2959
+ {
2960
+ result = args val
2961
+ }
2299
2962
  | f_block_arg
2300
2963
 
2301
2964
  opt_args_tail: tCOMMA args_tail
@@ -2366,6 +3029,12 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2366
3029
  |
2367
3030
  {
2368
3031
  result = args val
3032
+ # result.line lexer.lineno
3033
+ }
3034
+
3035
+ args_forward: tBDOT3
3036
+ {
3037
+ result = s(:forward_args).line lexer.lineno
2369
3038
  }
2370
3039
 
2371
3040
  f_bad_arg: tCONSTANT
@@ -2388,10 +3057,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2388
3057
  f_norm_arg: f_bad_arg
2389
3058
  | tIDENTIFIER
2390
3059
  {
2391
- identifier = val[0].to_sym
3060
+ (id, line), = val
3061
+ identifier = id.to_sym
2392
3062
  self.env[identifier] = :lvar
2393
3063
 
2394
- result = identifier
3064
+ result = [identifier, line]
2395
3065
  }
2396
3066
 
2397
3067
  f_arg_asgn: f_norm_arg
@@ -2399,22 +3069,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2399
3069
  f_arg_item: f_arg_asgn
2400
3070
  | tLPAREN f_margs rparen
2401
3071
  {
2402
- result = val[1]
3072
+ _, margs, _ = val
3073
+
3074
+ result = margs
2403
3075
  }
2404
3076
 
2405
3077
  f_arg: f_arg_item
2406
3078
  {
2407
- arg, = val
2408
-
2409
- case arg
2410
- when Symbol then
2411
- result = s(:args, arg).line lexer.lineno
2412
- when Sexp then
2413
- result = arg
2414
- else
2415
- debug20 32
2416
- raise "Unknown f_arg type: #{val.inspect}"
2417
- end
3079
+ result = new_arg val
2418
3080
  }
2419
3081
  | f_arg tCOMMA f_arg_item
2420
3082
  {
@@ -2426,7 +3088,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2426
3088
  result = s(:args, list).line list.line
2427
3089
  end
2428
3090
 
2429
- result << item
3091
+ result << (Sexp === item ? item : item.first)
2430
3092
  }
2431
3093
 
2432
3094
  f_label: tLABEL
@@ -2487,26 +3149,37 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2487
3149
  kwrest_mark: tPOW
2488
3150
  | tDSTAR
2489
3151
 
3152
+ f_no_kwarg: kwrest_mark kNIL
3153
+ {
3154
+ result = :"**nil"
3155
+ }
3156
+
2490
3157
  f_kwrest: kwrest_mark tIDENTIFIER
2491
3158
  {
2492
- name = val[1].to_sym
2493
- self.assignable name
2494
- result = :"**#{name}"
3159
+ _, (id, line) = val
3160
+
3161
+ name = id.to_sym
3162
+ self.assignable [name, line]
3163
+ result = [:"**#{name}", line]
2495
3164
  }
2496
3165
  | kwrest_mark
2497
3166
  {
2498
- result = :"**"
3167
+ id = :"**"
3168
+ self.env[id] = :lvar # TODO: needed?!?
3169
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2499
3170
  }
2500
3171
 
2501
3172
  f_opt: f_arg_asgn tEQL arg_value
2502
3173
  {
2503
- result = self.assignable val[0], val[2]
3174
+ lhs, _, rhs = val
3175
+ result = self.assignable lhs, rhs
2504
3176
  # TODO: detect duplicate names
2505
3177
  }
2506
3178
 
2507
3179
  f_block_opt: f_arg_asgn tEQL primary_value
2508
3180
  {
2509
- result = self.assignable val[0], val[2]
3181
+ lhs, _, rhs = val
3182
+ result = self.assignable lhs, rhs
2510
3183
  }
2511
3184
 
2512
3185
  f_block_optarg: f_block_opt
@@ -2536,30 +3209,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2536
3209
  f_rest_arg: restarg_mark tIDENTIFIER
2537
3210
  {
2538
3211
  # TODO: differs from parse.y - needs tests
2539
- name = val[1].to_sym
2540
- self.assignable name
2541
- result = :"*#{name}"
3212
+ _, (id, line) = val
3213
+ name = id.to_sym
3214
+ self.assignable [name, line]
3215
+ result = [:"*#{name}", line]
2542
3216
  }
2543
3217
  | restarg_mark
2544
3218
  {
2545
3219
  name = :"*"
2546
3220
  self.env[name] = :lvar
2547
- result = name
3221
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2548
3222
  }
2549
3223
 
2550
3224
  blkarg_mark: tAMPER2 | tAMPER
2551
3225
 
2552
3226
  f_block_arg: blkarg_mark tIDENTIFIER
2553
3227
  {
2554
- identifier = val[1].to_sym
3228
+ _, (id, line) = val
3229
+ identifier = id.to_sym
2555
3230
 
2556
3231
  self.env[identifier] = :lvar
2557
- result = "&#{identifier}".to_sym
3232
+ result = ["&#{identifier}".to_sym, line]
2558
3233
  }
2559
3234
 
2560
3235
  opt_f_block_arg: tCOMMA f_block_arg
2561
3236
  {
2562
- result = val[1]
3237
+ _, arg = val
3238
+ result = arg
2563
3239
  }
2564
3240
  |
2565
3241
  {
@@ -2601,16 +3277,18 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2601
3277
  }
2602
3278
  | tLABEL arg_value
2603
3279
  {
2604
- (label, line), arg = val
3280
+ label, arg = val
2605
3281
 
2606
- lit = s(:lit, label.to_sym).line line
2607
- result = s(:array, lit, arg).line line
3282
+ lit = wrap :lit, label
3283
+ result = s(:array, lit, arg).line lit.line
2608
3284
  }
2609
3285
  | tSTRING_BEG string_contents tLABEL_END arg_value
2610
3286
  {
2611
- _, sym, _, value = val
3287
+ (_, line), sym, _, value = val
3288
+
2612
3289
  sym.sexp_type = :dsym
2613
- result = s(:array, sym, value).line sym.line
3290
+
3291
+ result = s(:array, sym, value).line line
2614
3292
  }
2615
3293
  | tDSTAR arg_value
2616
3294
  {
@@ -2633,6 +3311,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2633
3311
  opt_nl: | tNL
2634
3312
  rparen: opt_nl tRPAREN
2635
3313
  rbracket: opt_nl tRBRACK
3314
+ rbrace: opt_nl tRCURLY
2636
3315
  trailer: | tNL | tCOMMA
2637
3316
 
2638
3317
  term: tSEMI { yyerrok }