ruby_parser 3.17.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/ruby30_parser.y CHANGED
@@ -18,11 +18,11 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
- tLONELY
25
- tBDOT2 tBDOT3
24
+ tLONELY
25
+ tBDOT2 tBDOT3
26
26
 
27
27
  preclow
28
28
  nonassoc tLOWEST
@@ -80,7 +80,7 @@ rule
80
80
  | klBEGIN
81
81
  {
82
82
  if (self.in_def || self.in_single > 0) then
83
- debug20 1
83
+ debug 11
84
84
  yyerror "BEGIN in method"
85
85
  end
86
86
  self.env.extend
@@ -135,7 +135,7 @@ rule
135
135
  | error stmt
136
136
  {
137
137
  result = val[1]
138
- debug20 2, val, result
138
+ debug 12
139
139
  }
140
140
 
141
141
  stmt_or_begin: stmt
@@ -143,6 +143,10 @@ rule
143
143
  {
144
144
  yyerror "BEGIN is permitted only at toplevel"
145
145
  }
146
+ begin_block
147
+ {
148
+ result = val[2] # wtf?
149
+ }
146
150
 
147
151
  stmt: kALIAS fitem
148
152
  {
@@ -155,12 +159,12 @@ rule
155
159
  }
156
160
  | kALIAS tGVAR tGVAR
157
161
  {
158
- (_, line), lhs, rhs = val
162
+ (_, line), (lhs, _), (rhs, _) = val
159
163
  result = s(:valias, lhs.to_sym, rhs.to_sym).line line
160
164
  }
161
165
  | kALIAS tGVAR tBACK_REF
162
166
  {
163
- (_, line), lhs, rhs = val
167
+ (_, line), (lhs, _), (rhs, _) = val
164
168
  result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
165
169
  }
166
170
  | kALIAS tGVAR tNTH_REF
@@ -203,7 +207,7 @@ rule
203
207
  (_, line), _, stmt, _ = val
204
208
 
205
209
  if (self.in_def || self.in_single > 0) then
206
- debug20 3
210
+ debug 13
207
211
  yyerror "END in method; use at_exit"
208
212
  end
209
213
 
@@ -219,6 +223,15 @@ rule
219
223
  lhs, _, rhs = val
220
224
  result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
221
225
  }
226
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
227
+ {
228
+ # unwraps s(:to_ary, rhs)
229
+ lhs, _, (_, rhs), _, resbody = val
230
+
231
+ resbody = new_resbody s(:array).line(resbody.line), resbody
232
+
233
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
234
+ }
222
235
  | mlhs tEQL mrhs_arg
223
236
  {
224
237
  result = new_masgn val[0], val[2]
@@ -243,32 +256,31 @@ rule
243
256
  }
244
257
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
245
258
  {
246
- prim, _, id, opasgn, rhs = val
247
- result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
248
- if val[1] == '&.'
249
- result.sexp_type = :safe_op_asgn
250
- end
251
- result.line = val[0].line
259
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
260
+
261
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
262
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
263
+ result.line prim.line
252
264
  }
253
265
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
254
266
  {
255
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
256
- if val[1] == '&.'
257
- result.sexp_type = :safe_op_asgn
258
- end
259
- result.line = val[0].line
267
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
268
+
269
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
270
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
271
+ result.line prim.line
260
272
  }
261
273
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
262
274
  {
263
- lhs1, _, lhs2, op, rhs = val
275
+ lhs1, _, (lhs2, line), (id, _), rhs = val
264
276
 
265
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
277
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
266
278
  }
267
279
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
268
280
  {
269
- lhs1, _, lhs2, op, rhs = val
281
+ lhs1, _, (lhs2, line), (id, _), rhs = val
270
282
 
271
- result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
283
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
272
284
  }
273
285
  | backref tOP_ASGN command_rhs
274
286
  {
@@ -314,7 +326,86 @@ rule
314
326
  # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
315
327
  # REFACTOR: call_uni_op -- see parse26.y
316
328
  }
329
+ | arg tASSOC
330
+ {
331
+ # value_expr($1);
332
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
333
+ self.lexer.command_start = false
334
+ result = self.in_kwarg
335
+ self.in_kwarg = true
336
+ self.env.extend
337
+ }
338
+ p_expr
339
+ {
340
+ lhs, _, in_kwarg, rhs = val
341
+
342
+ self.env.unextend
343
+ self.in_kwarg = in_kwarg
344
+
345
+ rhs = new_in rhs, nil, nil, rhs.line
346
+ result = new_case lhs, rhs, rhs.line
347
+ }
317
348
  | arg
349
+ kIN
350
+ {
351
+ # TODO? value_expr($1);
352
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
353
+ self.lexer.command_start = false
354
+ result = self.in_kwarg
355
+ self.in_kwarg = true
356
+ self.env.extend
357
+ }
358
+ p_expr
359
+ {
360
+ self.env.unextend
361
+
362
+ expr, _, old_kwarg, pat = val
363
+
364
+ expr = value_expr expr
365
+
366
+ self.in_kwarg = old_kwarg
367
+ pat_in = new_in pat, nil, nil, expr.line
368
+ result = new_case expr, pat_in, expr.line
369
+ }
370
+ | arg =tLBRACE_ARG
371
+
372
+ def_name: fname
373
+ {
374
+ # TODO: numparam_name(p, fname);
375
+
376
+ (id, line), = val
377
+ old_in_def = self.in_def
378
+
379
+ self.in_def = true # group = local_push
380
+ self.env.extend
381
+ lexer.cmdarg.push false
382
+ lexer.cond.push false
383
+
384
+ result = [id.to_sym, line, old_in_def]
385
+ }
386
+ defn_head: k_def def_name
387
+ {
388
+ _, name = val
389
+ result = name
390
+ }
391
+ defs_head: k_def singleton dot_or_colon
392
+ {
393
+ lexer.lex_state = EXPR_FNAME
394
+ }
395
+ def_name
396
+ {
397
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
398
+ self.in_single += 1 # TODO: remove?
399
+
400
+ # self.in_def = true # local_push
401
+ # self.env.extend
402
+ # lexer.cmdarg.push false
403
+ # lexer.cond.push false
404
+
405
+ _, recv, _, _, name = val
406
+
407
+ result = [recv, name]
408
+ }
318
409
 
319
410
  expr_value: expr
320
411
  {
@@ -339,7 +430,7 @@ rule
339
430
  block_command: block_call
340
431
  | block_call call_op2 operation2 command_args
341
432
  {
342
- blk, _, msg, args = val
433
+ blk, _, (msg, _line), args = val
343
434
  result = new_call(blk, msg.to_sym, args).line blk.line
344
435
  }
345
436
 
@@ -353,15 +444,15 @@ rule
353
444
  _, line, body, _ = val
354
445
 
355
446
  result = body
356
- result.line = line
447
+ result.line line
357
448
 
358
449
  # self.env.unextend
359
450
  }
360
451
 
361
452
  fcall: operation
362
453
  {
363
- msg, = val
364
- result = new_call(nil, msg.to_sym).line lexer.lineno
454
+ (msg, line), = val
455
+ result = new_call(nil, msg.to_sym).line line
365
456
  }
366
457
 
367
458
  command: fcall command_args =tLOWEST
@@ -384,12 +475,14 @@ rule
384
475
  }
385
476
  | primary_value call_op operation2 command_args =tLOWEST
386
477
  {
387
- lhs, callop, op, args = val
478
+ lhs, callop, (op, _), args = val
479
+
388
480
  result = new_call lhs, op.to_sym, args, callop
481
+ result.line lhs.line
389
482
  }
390
483
  | primary_value call_op operation2 command_args cmd_brace_block
391
484
  {
392
- recv, _, msg, args, block = val
485
+ recv, _, (msg, _line), args, block = val
393
486
  call = new_call recv, msg.to_sym, args, val[1]
394
487
 
395
488
  block_dup_check call, block
@@ -399,11 +492,14 @@ rule
399
492
  }
400
493
  | primary_value tCOLON2 operation2 command_args =tLOWEST
401
494
  {
402
- result = new_call val[0], val[2].to_sym, val[3]
495
+ lhs, _, (id, line), args = val
496
+
497
+ result = new_call lhs, id.to_sym, args
498
+ result.line line
403
499
  }
404
500
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
405
501
  {
406
- recv, _, msg, args, block = val
502
+ recv, _, (msg, _line), args, block = val
407
503
  call = new_call recv, msg.to_sym, args
408
504
 
409
505
  block_dup_check call, block
@@ -561,25 +657,29 @@ rule
561
657
  }
562
658
  | primary_value call_op tIDENTIFIER
563
659
  {
564
- result = new_attrasgn val[0], val[2], val[1]
660
+ lhs, call_op, (id, _line) = val
661
+
662
+ result = new_attrasgn lhs, id, call_op
565
663
  }
566
664
  | primary_value tCOLON2 tIDENTIFIER
567
665
  {
568
- recv, _, id = val
666
+ recv, _, (id, _line) = val
569
667
  result = new_attrasgn recv, id
570
668
  }
571
669
  | primary_value call_op tCONSTANT
572
670
  {
573
- result = new_attrasgn val[0], val[2], val[1]
671
+ lhs, call_op, (id, _line) = val
672
+
673
+ result = new_attrasgn lhs, id, call_op
574
674
  }
575
675
  | primary_value tCOLON2 tCONSTANT
576
676
  {
577
677
  if (self.in_def || self.in_single > 0) then
578
- debug20 7
678
+ debug 14
579
679
  yyerror "dynamic constant assignment"
580
680
  end
581
681
 
582
- expr, _, id = val
682
+ expr, _, (id, _line) = val
583
683
  l = expr.line
584
684
 
585
685
  result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
@@ -587,58 +687,65 @@ rule
587
687
  | tCOLON3 tCONSTANT
588
688
  {
589
689
  if (self.in_def || self.in_single > 0) then
590
- debug20 8
690
+ debug 15
591
691
  yyerror "dynamic constant assignment"
592
692
  end
593
693
 
594
- _, id = val
595
- l = lexer.lineno
694
+ _, (id, l) = val
596
695
 
597
696
  result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
598
697
  }
599
698
  | backref
600
699
  {
601
- self.backref_assign_error val[0]
700
+ ref, = val
701
+
702
+ self.backref_assign_error ref
602
703
  }
603
704
 
604
705
  lhs: user_variable
605
706
  {
606
- line = lexer.lineno
607
- result = self.assignable val[0]
608
- result.line = line
707
+ var, = val
708
+
709
+ result = self.assignable var
609
710
  }
610
711
  | keyword_variable
611
712
  {
612
- line = lexer.lineno
613
- result = self.assignable val[0]
614
- result.line = line
615
- debug20 9, val, result
713
+ var, = val
714
+
715
+ result = self.assignable var
716
+
717
+ debug 16
616
718
  }
617
719
  | primary_value tLBRACK2 opt_call_args rbracket
618
720
  {
619
721
  lhs, _, args, _ = val
722
+
620
723
  result = self.aryset lhs, args
621
724
  }
622
725
  | primary_value call_op tIDENTIFIER # REFACTOR
623
726
  {
624
- lhs, op, id = val
727
+ lhs, op, (id, _line) = val
728
+
625
729
  result = new_attrasgn lhs, id, op
626
730
  }
627
731
  | primary_value tCOLON2 tIDENTIFIER
628
732
  {
629
- lhs, _, id = val
733
+ lhs, _, (id, _line) = val
734
+
630
735
  result = new_attrasgn lhs, id
631
736
  }
632
737
  | primary_value call_op tCONSTANT # REFACTOR?
633
738
  {
634
- result = new_attrasgn val[0], val[2], val[1]
739
+ lhs, call_op, (id, _line) = val
740
+
741
+ result = new_attrasgn lhs, id, call_op
635
742
  }
636
743
  | primary_value tCOLON2 tCONSTANT
637
744
  {
638
- expr, _, id = val
745
+ expr, _, (id, _line) = val
639
746
 
640
747
  if (self.in_def || self.in_single > 0) then
641
- debug20 10
748
+ debug 17
642
749
  yyerror "dynamic constant assignment"
643
750
  end
644
751
 
@@ -647,14 +754,13 @@ rule
647
754
  }
648
755
  | tCOLON3 tCONSTANT
649
756
  {
650
- _, id = val
757
+ _, (id, l) = val
651
758
 
652
759
  if (self.in_def || self.in_single > 0) then
653
- debug20 11
760
+ debug 18
654
761
  yyerror "dynamic constant assignment"
655
762
  end
656
763
 
657
- l = lexer.lineno
658
764
  result = s(:const, s(:colon3, id.to_sym).line(l)).line l
659
765
  }
660
766
  | backref
@@ -670,16 +776,17 @@ rule
670
776
 
671
777
  cpath: tCOLON3 cname
672
778
  {
673
- _, name = val
674
- result = s(:colon3, name.to_sym).line lexer.lineno
779
+ _, (name, line) = val
780
+ result = s(:colon3, name.to_sym).line line
675
781
  }
676
782
  | cname
677
783
  {
678
- result = val[0].to_sym
784
+ (id, line), = val
785
+ result = [id.to_sym, line] # TODO: sexp?
679
786
  }
680
787
  | primary_value tCOLON2 cname
681
788
  {
682
- pval, _, name = val
789
+ pval, _, (name, _line) = val
683
790
 
684
791
  result = s(:colon2, pval, name.to_sym)
685
792
  result.line pval.line
@@ -689,24 +796,17 @@ rule
689
796
  | op
690
797
  {
691
798
  lexer.lex_state = EXPR_END
692
- result = val[0]
693
799
  }
694
800
 
695
801
  | reswords
696
- {
697
- (sym, _line), = val
698
- lexer.lex_state = EXPR_END
699
- result = sym
700
- }
701
-
702
- fsym: fname | symbol
703
802
 
704
- fitem: fsym
803
+ fitem: fname
705
804
  {
706
- id, = val
707
- result = s(:lit, id.to_sym).line lexer.lineno
805
+ (id, line), = val
806
+
807
+ result = s(:lit, id.to_sym).line line
708
808
  }
709
- | dsym
809
+ | symbol
710
810
 
711
811
  undef_list: fitem
712
812
  {
@@ -727,8 +827,6 @@ rule
727
827
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
728
828
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
729
829
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
730
- # TODO: tUBANG dead?
731
- | tUBANG
732
830
 
733
831
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
734
832
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -762,24 +860,20 @@ rule
762
860
  }
763
861
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
764
862
  {
765
- lhs, _, id, op, rhs = val
863
+ lhs, _, (id, _line), (op, _), rhs = val
766
864
 
767
865
  result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
768
866
  }
769
867
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
770
868
  {
771
- lhs1, _, lhs2, op, rhs = val
869
+ lhs1, _, (lhs2, _line), op, rhs = val
772
870
 
773
871
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
774
872
  result = new_const_op_asgn [lhs, op, rhs]
775
873
  }
776
- | tCOLON3 tCONSTANT
777
- {
778
- result = self.lexer.lineno
779
- }
780
- tOP_ASGN arg_rhs
874
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
781
875
  {
782
- _, lhs, line, op, rhs = val
876
+ _, (lhs, line), op, rhs = val
783
877
 
784
878
  lhs = s(:colon3, lhs.to_sym).line line
785
879
  result = new_const_op_asgn [lhs, op, rhs]
@@ -793,7 +887,7 @@ rule
793
887
  | arg tDOT2 arg
794
888
  {
795
889
  v1, v2 = val[0], val[2]
796
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
890
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
797
891
  result = s(:lit, (v1.last)..(v2.last)).line v1.line
798
892
  else
799
893
  result = s(:dot2, v1, v2).line v1.line
@@ -802,7 +896,7 @@ rule
802
896
  | arg tDOT3 arg
803
897
  {
804
898
  v1, v2 = val[0], val[2]
805
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
899
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
806
900
  result = s(:lit, (v1.last)...(v2.last)).line v1.line
807
901
  else
808
902
  result = s(:dot3, v1, v2).line v1.line
@@ -864,8 +958,9 @@ rule
864
958
  }
865
959
  | tUMINUS_NUM simple_numeric tPOW arg
866
960
  {
867
- lit = s(:lit, val[1]).line lexer.lineno
868
- result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
961
+ _, (num, line), _, arg = val
962
+ lit = s(:lit, num).line line
963
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
869
964
 
870
965
  }
871
966
  | tUPLUS arg
@@ -955,6 +1050,49 @@ rule
955
1050
  c, _, t, _, _, f = val
956
1051
  result = s(:if, c, t, f).line c.line
957
1052
  }
1053
+ | defn_head f_opt_paren_args tEQL arg
1054
+ {
1055
+ (name, line, in_def), args, _, body = val
1056
+
1057
+ result = s(:defn, name, args, body).line line
1058
+
1059
+ local_pop in_def
1060
+ endless_method_name result
1061
+ }
1062
+ | defn_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1063
+ {
1064
+ (name, line, in_def), args, _, body, _, resbody = val
1065
+
1066
+ result = s(:defn, name, args,
1067
+ new_rescue(body,
1068
+ new_resbody(s(:array).line(line),
1069
+ resbody))).line line
1070
+
1071
+ local_pop in_def
1072
+ endless_method_name result
1073
+ }
1074
+ | defs_head f_opt_paren_args tEQL arg
1075
+ {
1076
+ (recv, (name, line, in_def)), args, _, body = val
1077
+
1078
+ result = s(:defs, recv, name, args, body).line(line)
1079
+
1080
+ self.in_single -= 1
1081
+ local_pop in_def
1082
+ endless_method_name result
1083
+ }
1084
+ | defs_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1085
+ {
1086
+ (recv, (name, line, in_def)), args, _, body, _, resbody = val
1087
+
1088
+ result = s(:defs, recv, name, args,
1089
+ new_rescue(body,
1090
+ new_resbody(s(:array).line(line),
1091
+ resbody))).line line
1092
+
1093
+ local_pop in_def
1094
+ endless_method_name result
1095
+ }
958
1096
  | primary
959
1097
 
960
1098
  relop: tGT
@@ -964,12 +1102,12 @@ rule
964
1102
 
965
1103
  rel_expr: arg relop arg =tGT
966
1104
  {
967
- lhs, op, rhs = val
1105
+ lhs, (op, _), rhs = val
968
1106
  result = new_call lhs, op.to_sym, argl(rhs)
969
1107
  }
970
1108
  | rel_expr relop arg =tGT
971
1109
  {
972
- lhs, op, rhs = val
1110
+ lhs, (op, _), rhs = val
973
1111
  warn "comparison '%s' after comparison", op
974
1112
  result = new_call lhs, op.to_sym, argl(rhs)
975
1113
  }
@@ -1178,8 +1316,9 @@ rule
1178
1316
  | backref
1179
1317
  | tFID
1180
1318
  {
1181
- msg, = val
1319
+ (msg, line), = val
1182
1320
  result = new_call nil, msg.to_sym
1321
+ result.line line
1183
1322
  }
1184
1323
  | k_begin
1185
1324
  {
@@ -1221,15 +1360,15 @@ rule
1221
1360
  }
1222
1361
  | primary_value tCOLON2 tCONSTANT
1223
1362
  {
1224
- expr, _, id = val
1363
+ expr, _, (id, _line) = val
1225
1364
 
1226
1365
  result = s(:colon2, expr, id.to_sym).line expr.line
1227
1366
  }
1228
1367
  | tCOLON3 tCONSTANT
1229
1368
  {
1230
- _, id = val
1369
+ _, (id, line) = val
1231
1370
 
1232
- result = s(:colon3, id.to_sym).line lexer.lineno
1371
+ result = s(:colon3, id.to_sym).line line
1233
1372
  }
1234
1373
  | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1235
1374
  {
@@ -1276,7 +1415,7 @@ rule
1276
1415
  }
1277
1416
  | kNOT tLPAREN2 rparen
1278
1417
  {
1279
- debug20 14, val, result
1418
+ debug 19
1280
1419
  }
1281
1420
  | fcall brace_block
1282
1421
  {
@@ -1294,9 +1433,10 @@ rule
1294
1433
  iter.insert 1, call # FIX
1295
1434
  result = iter
1296
1435
  }
1297
- | tLAMBDA lambda
1436
+ | lambda
1298
1437
  {
1299
- result = val[1] # TODO: fix lineno
1438
+ expr, = val
1439
+ result = expr
1300
1440
  }
1301
1441
  | k_if expr_value then compstmt if_tail k_end
1302
1442
  {
@@ -1328,6 +1468,12 @@ rule
1328
1468
  (_, line), _, body, _ = val
1329
1469
  result = new_case nil, body, line
1330
1470
  }
1471
+ | k_case expr_value opt_terms p_case_body k_end
1472
+ {
1473
+ (_, line), expr, _, body, _ = val
1474
+
1475
+ result = new_case expr, body, line
1476
+ }
1331
1477
  | k_for for_var kIN expr_value_do compstmt k_end
1332
1478
  {
1333
1479
  _, var, _, iter, body, _ = val
@@ -1339,7 +1485,6 @@ rule
1339
1485
  }
1340
1486
  cpath superclass
1341
1487
  {
1342
- self.comments.push self.lexer.comments
1343
1488
  if (self.in_def || self.in_single > 0) then
1344
1489
  yyerror "class definition in method body"
1345
1490
  end
@@ -1349,7 +1494,7 @@ rule
1349
1494
  {
1350
1495
  result = new_class val
1351
1496
  self.env.unextend
1352
- self.lexer.comments # we don't care about comments in the body
1497
+ self.lexer.ignore_body_comments
1353
1498
  }
1354
1499
  | k_class tLSHFT
1355
1500
  {
@@ -1370,7 +1515,7 @@ rule
1370
1515
  {
1371
1516
  result = new_sclass val
1372
1517
  self.env.unextend
1373
- self.lexer.comments # we don't care about comments in the body
1518
+ self.lexer.ignore_body_comments
1374
1519
  }
1375
1520
  | k_module
1376
1521
  {
@@ -1378,7 +1523,6 @@ rule
1378
1523
  }
1379
1524
  cpath
1380
1525
  {
1381
- self.comments.push self.lexer.comments
1382
1526
  yyerror "module definition in method body" if
1383
1527
  self.in_def or self.in_single > 0
1384
1528
 
@@ -1388,55 +1532,40 @@ rule
1388
1532
  {
1389
1533
  result = new_module val
1390
1534
  self.env.unextend
1391
- self.lexer.comments # we don't care about comments in the body
1392
- }
1393
- | k_def fname
1394
- {
1395
- result = self.in_def
1396
-
1397
- self.in_def = true # group = local_push
1398
- self.env.extend
1399
- lexer.cmdarg.push false
1400
- lexer.cond.push false
1401
-
1402
- self.comments.push self.lexer.comments
1535
+ self.lexer.ignore_body_comments
1403
1536
  }
1404
- f_arglist bodystmt { result = lexer.lineno } k_end
1537
+ | defn_head f_arglist bodystmt k_end
1405
1538
  {
1406
- in_def = val[2]
1539
+ # [ [:f, 1, false], s(:args)...]
1540
+ # =>
1541
+ # [[:k_def, 666], [:f, 1], false, s(:args)...]
1542
+ val.insert 1, val.first.pop
1543
+ val.insert 0, [:k_def, 666]
1407
1544
 
1408
- result = new_defn val
1545
+ result, in_def = new_defn val
1409
1546
 
1410
1547
  lexer.cond.pop # group = local_pop
1411
1548
  lexer.cmdarg.pop
1412
1549
  self.env.unextend
1413
1550
  self.in_def = in_def
1414
1551
 
1415
- self.lexer.comments # we don't care about comments in the body
1552
+ self.lexer.ignore_body_comments
1416
1553
  }
1417
- | k_def singleton dot_or_colon
1554
+ | defs_head f_arglist bodystmt k_end
1418
1555
  {
1419
- lexer.lex_state = EXPR_FNAME
1420
- }
1421
- fname
1422
- {
1423
- result = [self.in_def, lexer.lineno]
1424
-
1425
- self.in_single += 1 # TODO: remove?
1426
-
1427
- self.in_def = true # local_push
1428
- self.env.extend
1429
- lexer.cmdarg.push false
1430
- lexer.cond.push false
1556
+ # [ [recv, [:name, 1, false]], s(:args...]
1557
+ # =>
1558
+ # [ recv, [:name, 1, false], s(:args...]
1559
+ # =>
1560
+ # [ recv, [:name, 1], false, s(:args...]
1561
+ # =>
1562
+ # [ :k_def, recv, [:name, 1], false, s(:args...]
1431
1563
 
1432
- lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1433
- self.comments.push self.lexer.comments
1434
- }
1435
- f_arglist bodystmt k_end
1436
- {
1437
- _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1564
+ val.prepend(*val.shift)
1565
+ val.insert 2, val[1].pop
1566
+ val.insert 0, [:k_def, 666]
1438
1567
 
1439
- result = new_defs val
1568
+ result, in_def = new_defs val
1440
1569
 
1441
1570
  lexer.cond.pop # group = local_pop
1442
1571
  lexer.cmdarg.pop
@@ -1447,7 +1576,7 @@ rule
1447
1576
 
1448
1577
  # TODO: restore cur_arg ? what's cur_arg?
1449
1578
 
1450
- self.lexer.comments # we don't care about comments in the body
1579
+ self.lexer.ignore_body_comments
1451
1580
  }
1452
1581
  | kBREAK
1453
1582
  {
@@ -1484,8 +1613,17 @@ rule
1484
1613
  k_case: kCASE
1485
1614
  k_for: kFOR
1486
1615
  k_class: kCLASS
1616
+ {
1617
+ self.comments.push self.lexer.comments
1618
+ }
1487
1619
  k_module: kMODULE
1620
+ {
1621
+ self.comments.push self.lexer.comments
1622
+ }
1488
1623
  k_def: kDEF
1624
+ {
1625
+ self.comments.push self.lexer.comments
1626
+ }
1489
1627
  k_do: kDO
1490
1628
  k_do_block: kDO_BLOCK
1491
1629
  k_rescue: kRESCUE
@@ -1546,52 +1684,46 @@ rule
1546
1684
 
1547
1685
  result = block_var args
1548
1686
  }
1549
- | f_marg_list tCOMMA tSTAR f_norm_arg
1687
+ | f_marg_list tCOMMA f_rest_marg
1550
1688
  {
1551
- args, _, _, splat = val
1689
+ args, _, rest = val
1552
1690
 
1553
- result = block_var args, "*#{splat}".to_sym
1691
+ result = block_var args, rest
1554
1692
  }
1555
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1693
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1556
1694
  {
1557
- args, _, _, splat, _, args2 = val
1695
+ lhs, _, splat, _, rhs = val
1558
1696
 
1559
- result = block_var args, "*#{splat}".to_sym, args2
1697
+ result = block_var lhs, splat, rhs
1560
1698
  }
1561
- | f_marg_list tCOMMA tSTAR
1699
+ | f_rest_marg
1562
1700
  {
1563
- args, _, _ = val
1701
+ rest, = val
1564
1702
 
1565
- result = block_var args, :*
1703
+ result = block_var rest
1566
1704
  }
1567
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1705
+ | f_rest_marg tCOMMA f_marg_list
1568
1706
  {
1569
- args, _, _, _, args2 = val
1707
+ splat, _, rest = val
1570
1708
 
1571
- result = block_var args, :*, args2
1709
+ result = block_var splat, rest
1572
1710
  }
1573
- | tSTAR f_norm_arg
1574
- {
1575
- _, splat = val
1576
1711
 
1577
- result = block_var :"*#{splat}"
1578
- }
1579
- | tSTAR f_norm_arg tCOMMA f_marg_list
1712
+ f_rest_marg: tSTAR f_norm_arg
1580
1713
  {
1581
- _, splat, _, args = val
1714
+ _, (id, line) = val
1582
1715
 
1583
- result = block_var :"*#{splat}", args
1716
+ result = args ["*#{id}".to_sym]
1717
+ result.line line
1584
1718
  }
1585
1719
  | tSTAR
1586
1720
  {
1587
- result = block_var :*
1721
+ result = args [:*]
1722
+ result.line lexer.lineno # FIX: tSTAR -> line
1588
1723
  }
1589
- | tSTAR tCOMMA f_marg_list
1590
- {
1591
- _, _, args = val
1592
1724
 
1593
- result = block_var :*, args
1594
- }
1725
+ f_any_kwrest: f_kwrest
1726
+ | f_no_kwarg
1595
1727
 
1596
1728
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1597
1729
  {
@@ -1601,14 +1733,14 @@ rule
1601
1733
  {
1602
1734
  result = call_args val
1603
1735
  }
1604
- | f_kwrest opt_f_block_arg
1736
+ | f_any_kwrest opt_f_block_arg
1605
1737
  {
1606
1738
  result = call_args val
1607
1739
  }
1608
1740
  | f_block_arg
1609
1741
  {
1610
- line = lexer.lineno
1611
- result = call_args val # TODO: push line down
1742
+ (id, line), = val
1743
+ result = call_args [id]
1612
1744
  result.line line
1613
1745
  }
1614
1746
 
@@ -1618,6 +1750,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1618
1750
  }
1619
1751
  | none
1620
1752
 
1753
+ excessed_comma: tCOMMA
1754
+ {
1755
+ result = s(:WTF_COMMA!)
1756
+ }
1757
+
1621
1758
  block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1622
1759
  {
1623
1760
  result = args val
@@ -1638,9 +1775,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1638
1775
  {
1639
1776
  result = args val
1640
1777
  }
1641
- | f_arg tCOMMA
1778
+ | f_arg excessed_comma
1642
1779
  {
1643
- result = args(val) << nil
1780
+ arg, _ = val
1781
+ result = arg << nil
1644
1782
  }
1645
1783
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1646
1784
  {
@@ -1717,13 +1855,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1717
1855
 
1718
1856
  bvar: tIDENTIFIER
1719
1857
  {
1720
- id, = val
1721
- line = lexer.lineno
1858
+ (id, line), = val
1722
1859
  result = s(:shadow, id.to_sym).line line
1723
1860
  }
1724
1861
  | f_bad_arg
1725
1862
 
1726
- lambda: {
1863
+ lambda: tLAMBDA
1864
+ {
1727
1865
  self.env.extend :dynamic
1728
1866
  result = [lexer.lineno, lexer.lpar_beg]
1729
1867
  lexer.paren_nest += 1
@@ -1735,14 +1873,14 @@ opt_block_args_tail: tCOMMA block_args_tail
1735
1873
  }
1736
1874
  lambda_body
1737
1875
  {
1738
- (line, lpar), args, _cmdarg, body = val
1876
+ _, (line, lpar), args, _cmdarg, body = val
1739
1877
  lexer.lpar_beg = lpar
1740
1878
 
1741
1879
  lexer.cmdarg.pop
1742
1880
 
1743
1881
  call = s(:lambda).line line
1744
1882
  result = new_iter call, args, body
1745
- result.line = line
1883
+ result.line line
1746
1884
  self.env.unextend # TODO: dynapush & dynapop
1747
1885
  }
1748
1886
 
@@ -1777,23 +1915,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1777
1915
  ## if (nd_type($1) == NODE_YIELD) {
1778
1916
  ## compile_error(PARSER_ARG "block given to yield");
1779
1917
 
1780
- syntax_error "Both block arg and actual block given." if
1781
- val[0].block_pass?
1918
+ cmd, blk = val
1782
1919
 
1783
- val = invert_block_call val if inverted? val
1920
+ syntax_error "Both block arg and actual block given." if
1921
+ cmd.block_pass?
1784
1922
 
1785
- cmd, blk = val
1923
+ if inverted? val then
1924
+ val = invert_block_call val
1925
+ cmd, blk = val
1926
+ end
1786
1927
 
1787
1928
  result = blk
1788
1929
  result.insert 1, cmd
1789
1930
  }
1790
1931
  | block_call call_op2 operation2 opt_paren_args
1791
1932
  {
1792
- result = new_call val[0], val[2].to_sym, val[3]
1933
+ lhs, _, (id, _line), args = val
1934
+
1935
+ result = new_call lhs, id.to_sym, args
1793
1936
  }
1794
1937
  | block_call call_op2 operation2 opt_paren_args brace_block
1795
1938
  {
1796
- iter1, _, name, args, iter2 = val
1939
+ iter1, _, (name, _line), args, iter2 = val
1797
1940
 
1798
1941
  call = new_call iter1, name.to_sym, args
1799
1942
  iter2.insert 1, call
@@ -1802,7 +1945,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1945
  }
1803
1946
  | block_call call_op2 operation2 command_args do_block
1804
1947
  {
1805
- iter1, _, name, args, iter2 = val
1948
+ iter1, _, (name, _line), args, iter2 = val
1806
1949
 
1807
1950
  call = new_call iter1, name.to_sym, args
1808
1951
  iter2.insert 1, call
@@ -1810,28 +1953,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1810
1953
  result = iter2
1811
1954
  }
1812
1955
 
1813
- method_call: fcall
1956
+ method_call: fcall paren_args
1814
1957
  {
1815
- result = self.lexer.lineno
1816
- }
1817
- paren_args
1818
- {
1819
- call, lineno, args = val
1958
+ call, args = val
1820
1959
 
1821
1960
  result = call.concat args.sexp_body if args
1822
- result.line lineno
1823
1961
  }
1824
1962
  | primary_value call_op operation2 opt_paren_args
1825
1963
  {
1826
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1964
+ recv, call_op, (op, _line), args = val
1965
+
1966
+ result = new_call recv, op.to_sym, args, call_op
1827
1967
  }
1828
1968
  | primary_value tCOLON2 operation2 paren_args
1829
1969
  {
1830
- result = new_call val[0], val[2].to_sym, val[3]
1970
+ recv, _, (op, _line), args = val
1971
+
1972
+ result = new_call recv, op.to_sym, args
1831
1973
  }
1832
1974
  | primary_value tCOLON2 operation3
1833
1975
  {
1834
- result = new_call val[0], val[2].to_sym
1976
+ lhs, _, (id, _line) = val
1977
+
1978
+ result = new_call lhs, id.to_sym
1835
1979
  }
1836
1980
  | primary_value call_op paren_args
1837
1981
  {
@@ -1864,7 +2008,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1864
2008
  _, line, body, _ = val
1865
2009
 
1866
2010
  result = body
1867
- result.line = line
2011
+ result.line line
1868
2012
 
1869
2013
  self.env.unextend
1870
2014
  }
@@ -1878,7 +2022,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1878
2022
  _, line, body, _ = val
1879
2023
 
1880
2024
  result = body
1881
- result.line = line
2025
+ result.line line
1882
2026
 
1883
2027
  self.env.unextend
1884
2028
  }
@@ -1907,99 +2051,640 @@ opt_block_args_tail: tCOMMA block_args_tail
1907
2051
  self.env.unextend
1908
2052
  }
1909
2053
 
2054
+ case_args: arg_value
2055
+ {
2056
+ arg, = val
2057
+
2058
+ result = s(:array, arg).line arg.line
2059
+ }
2060
+ | tSTAR arg_value
2061
+ {
2062
+ _, arg = val
2063
+
2064
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2065
+ }
2066
+ | case_args tCOMMA arg_value
2067
+ {
2068
+ args, _, id = val
2069
+
2070
+ result = self.list_append args, id
2071
+ }
2072
+ | case_args tCOMMA tSTAR arg_value
2073
+ {
2074
+ args, _, _, id = val
2075
+
2076
+ result = self.list_append args, s(:splat, id).line(id.line)
2077
+ }
2078
+
1910
2079
  case_body: k_when
1911
2080
  {
1912
2081
  result = self.lexer.lineno
1913
2082
  }
1914
- args then compstmt cases
2083
+ case_args then compstmt cases
1915
2084
  {
1916
2085
  result = new_when(val[2], val[4])
1917
- result.line = val[1]
2086
+ result.line val[1]
1918
2087
  result << val[5] if val[5]
1919
2088
  }
1920
2089
 
1921
2090
  cases: opt_else | case_body
2091
+ ######################################################################
1922
2092
 
1923
- opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2093
+ p_case_body: kIN
1924
2094
  {
1925
- (_, line), klasses, var, _, body, rest = val
1926
-
1927
- klasses ||= s(:array)
1928
- klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1929
- klasses.line line
1930
-
1931
- result = new_resbody(klasses, body)
1932
- result << rest if rest # UGH, rewritten above
2095
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2096
+ self.lexer.command_start = false
2097
+ result = self.in_kwarg
2098
+ self.in_kwarg = true
2099
+ push_pvtbl
2100
+ push_pktbl
1933
2101
  }
1934
- |
2102
+ p_top_expr then
1935
2103
  {
1936
- result = nil
2104
+ pop_pktbl
2105
+ pop_pvtbl
2106
+ old_kwargs = _values[-3]
2107
+ self.in_kwarg = old_kwargs
1937
2108
  }
1938
-
1939
- exc_list: arg_value
2109
+ compstmt
2110
+ p_cases
1940
2111
  {
1941
- arg, = val
1942
- result = s(:array, arg).line arg.line
2112
+ (_, line), _, pat, _, _, body, cases = val
2113
+
2114
+ result = new_in pat, body, cases, line
1943
2115
  }
1944
- | mrhs
1945
- | none
1946
2116
 
1947
- exc_var: tASSOC lhs
2117
+ p_cases: opt_else
2118
+ | p_case_body
2119
+
2120
+ p_top_expr: p_top_expr_body
2121
+ | p_top_expr_body kIF_MOD expr_value
1948
2122
  {
1949
- result = val[1]
1950
- }
1951
- | none
2123
+ body, _, cond = val
2124
+ body = remove_begin body
1952
2125
 
1953
- opt_ensure: k_ensure compstmt
2126
+ result = s(:if, cond, body, nil).line body.line
2127
+ }
2128
+ | p_top_expr_body kUNLESS_MOD expr_value
1954
2129
  {
1955
- (_, line), body = val
2130
+ body, _, cond = val
2131
+ body = remove_begin body
1956
2132
 
1957
- result = body || s(:nil).line(line)
2133
+ result = s(:if, cond, nil, body).line body.line
1958
2134
  }
1959
- | none
1960
2135
 
1961
- literal: numeric
2136
+ p_top_expr_body: p_expr
2137
+ | p_expr tCOMMA
1962
2138
  {
1963
- line = lexer.lineno
1964
- result = s(:lit, val[0])
1965
- result.line = line
2139
+ expr, _ = val
2140
+
2141
+ tail = new_array_pattern_tail nil, true, nil, nil
2142
+ result = new_array_pattern nil, expr, tail, expr.line
1966
2143
  }
1967
- | symbol
2144
+ | p_expr tCOMMA p_args
1968
2145
  {
1969
- line = lexer.lineno
1970
- result = s(:lit, val[0])
1971
- result.line = line
1972
- }
1973
- | dsym
2146
+ expr, _, args = val
1974
2147
 
1975
- strings: string
1976
- {
1977
- str, = val
1978
- str = s(:dstr, str.value) if str.sexp_type == :evstr
1979
- result = str
2148
+ result = new_array_pattern nil, expr, args, expr.line
1980
2149
  }
2150
+ | p_find
2151
+ {
2152
+ find, = val
1981
2153
 
1982
- string: tCHAR
2154
+ result = new_find_pattern nil, find
2155
+ }
2156
+ | p_args_tail
1983
2157
  {
1984
- debug20 23, val, result
2158
+ args, = val
2159
+ result = new_array_pattern nil, nil, args, args.line
1985
2160
  }
1986
- | string1
1987
- | string string1
2161
+ | p_kwargs
1988
2162
  {
1989
- result = self.literal_concat val[0], val[1]
2163
+ kwargs, = val
2164
+ result = new_hash_pattern nil, kwargs, kwargs.line
1990
2165
  }
1991
2166
 
1992
- string1: tSTRING_BEG string_contents tSTRING_END
2167
+ p_expr: p_as
2168
+
2169
+ p_as: p_expr tASSOC p_variable
1993
2170
  {
1994
- _, str, (_, func) = val
2171
+ # NODE *n = NEW_LIST($1, &@$);
2172
+ # n = list_append(p, n, $3);
2173
+ # $$ = new_hash(p, n, &@$);
1995
2174
 
1996
- str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
2175
+ expr, _, var = val
1997
2176
 
1998
- result = str
2177
+ id = var.last
2178
+
2179
+ self.env[id] = :lvar # HACK: need to extend env
2180
+ lhs = s(:lasgn, id).line var.line
2181
+
2182
+ result = new_assign lhs, expr
1999
2183
  }
2000
- | tSTRING
2184
+ | p_alt
2185
+
2186
+ p_alt: p_alt tPIPE p_expr_basic
2001
2187
  {
2002
- result = new_string val
2188
+ lhs, _, rhs = val
2189
+
2190
+ result = s(:or, lhs, rhs).line lhs.line
2191
+ }
2192
+ | p_expr_basic
2193
+
2194
+ p_lparen: tLPAREN2 { push_pktbl }
2195
+ p_lbracket: tLBRACK2 { push_pktbl }
2196
+
2197
+ p_expr_basic: p_value
2198
+ | p_const p_lparen p_args tRPAREN
2199
+ {
2200
+ lhs, _, args, _ = val
2201
+
2202
+ pop_pktbl
2203
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2204
+ }
2205
+ | p_const p_lparen p_find tRPAREN
2206
+ {
2207
+ const, _, find, _ = val
2208
+
2209
+ pop_pktbl
2210
+ result = new_find_pattern(const, find).line const.line
2211
+ }
2212
+ | p_const p_lparen p_kwargs tRPAREN
2213
+ {
2214
+ lhs, _, kwargs, _ = val
2215
+
2216
+ pop_pktbl
2217
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2218
+ }
2219
+ | p_const tLPAREN2 tRPAREN
2220
+ {
2221
+ const, _, _ = val
2222
+
2223
+ tail = new_array_pattern_tail nil, nil, nil, nil
2224
+ result = new_array_pattern const, nil, tail, const.line
2225
+ }
2226
+ | p_const p_lbracket p_args rbracket
2227
+ {
2228
+ const, _, pre_arg, _ = val
2229
+
2230
+ pop_pktbl
2231
+ result = new_array_pattern const, nil, pre_arg, const.line
2232
+ }
2233
+ | p_const p_lbracket p_find rbracket
2234
+ {
2235
+ const, _, find, _ = val
2236
+
2237
+ pop_pktbl
2238
+ result = new_find_pattern(const, find).line const.line
2239
+ }
2240
+ | p_const p_lbracket p_kwargs rbracket
2241
+ {
2242
+ const, _, kwargs, _ = val
2243
+
2244
+ result = new_hash_pattern const, kwargs, const.line
2245
+ }
2246
+ | p_const tLBRACK2 rbracket
2247
+ {
2248
+ const, _, _ = val
2249
+
2250
+ tail = new_array_pattern_tail nil, nil, nil, nil
2251
+ result = new_array_pattern const, nil, tail, const.line
2252
+ }
2253
+ | tLBRACK p_args rbracket
2254
+ {
2255
+ _, pat, _ = val
2256
+
2257
+ result = new_array_pattern nil, nil, pat, pat.line
2258
+ }
2259
+ | tLBRACK p_find rbracket
2260
+ {
2261
+ _, find, _ = val
2262
+
2263
+ result = new_find_pattern nil, find
2264
+ }
2265
+ | tLBRACK rbracket
2266
+ {
2267
+ (_, line), _ = val
2268
+
2269
+ result = s(:array_pat).line line
2270
+ }
2271
+ | tLBRACE
2272
+ {
2273
+ push_pktbl
2274
+ result = self.in_kwarg
2275
+ self.in_kwarg = false
2276
+ }
2277
+ p_kwargs rbrace
2278
+ {
2279
+ _, in_kwarg, kwargs, _ = val
2280
+
2281
+ pop_pktbl
2282
+ self.in_kwarg = in_kwarg
2283
+
2284
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2285
+ }
2286
+ | tLBRACE rbrace
2287
+ {
2288
+ (_, line), _ = val
2289
+
2290
+ tail = new_hash_pattern_tail nil, nil, line
2291
+ result = new_hash_pattern nil, tail, line
2292
+ }
2293
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2294
+ {
2295
+ _, _, expr, _ = val
2296
+
2297
+ pop_pktbl
2298
+ result = expr
2299
+ }
2300
+
2301
+ p_args: p_expr
2302
+ {
2303
+ expr, = val
2304
+
2305
+ ary = s(:array_TAIL, expr).line expr.line
2306
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2307
+ }
2308
+ | p_args_head
2309
+ {
2310
+ head, = val
2311
+
2312
+ result = new_array_pattern_tail head, true, nil, nil
2313
+ }
2314
+ | p_args_head p_arg
2315
+ {
2316
+ head, tail = val
2317
+
2318
+ both = array_pat_concat head, tail
2319
+
2320
+ result = new_array_pattern_tail both, nil, nil, nil
2321
+ result.line head.line
2322
+ }
2323
+ | p_args_head tSTAR tIDENTIFIER
2324
+ {
2325
+ head, _, (id, _line) = val
2326
+
2327
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2328
+ result.line head.line
2329
+ }
2330
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2331
+ {
2332
+ head, _, (id, _line), _, post = val
2333
+
2334
+ result = new_array_pattern_tail head, true, id.to_sym, post
2335
+ result.line head.line
2336
+ }
2337
+ | p_args_head tSTAR
2338
+ {
2339
+ expr, _ = val
2340
+
2341
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2342
+ }
2343
+ | p_args_head tSTAR tCOMMA p_args_post
2344
+ {
2345
+ head, _, _, post = val
2346
+
2347
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2348
+ }
2349
+ | p_args_tail
2350
+
2351
+ p_args_head: p_arg tCOMMA
2352
+ {
2353
+ arg, _ = val
2354
+ result = arg
2355
+ }
2356
+ | p_args_head p_arg tCOMMA
2357
+ {
2358
+ head, tail, _ = val
2359
+
2360
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2361
+ result.line head.line
2362
+ }
2363
+
2364
+ p_args_tail: p_rest
2365
+ {
2366
+ (id, line), = val
2367
+
2368
+ result = new_array_pattern_tail nil, true, id, nil
2369
+ result.line line
2370
+ }
2371
+ | p_rest tCOMMA p_args_post
2372
+ {
2373
+ (id, line), _, rhs = val
2374
+
2375
+ result = new_array_pattern_tail nil, true, id, rhs
2376
+ result.line line
2377
+ }
2378
+
2379
+ p_find: p_rest tCOMMA p_args_post tCOMMA p_rest
2380
+ {
2381
+ lhs, _, mid, _, rhs = val
2382
+
2383
+ result = new_find_pattern_tail lhs, mid, rhs
2384
+ }
2385
+
2386
+ p_rest: tSTAR tIDENTIFIER
2387
+ {
2388
+ _, (id, line) = val
2389
+
2390
+ result = [id.to_sym, line]
2391
+ }
2392
+ | tSTAR
2393
+ {
2394
+ (_id, line), = val
2395
+
2396
+ result = [nil, line]
2397
+ }
2398
+
2399
+ p_args_post: p_arg
2400
+ | p_args_post tCOMMA p_arg
2401
+ {
2402
+ lhs, _, rhs = val
2403
+
2404
+ result = array_pat_concat lhs, rhs
2405
+ }
2406
+
2407
+ p_arg: p_expr
2408
+ {
2409
+ expr, = val
2410
+ expr = s(:array_TAIL, expr).line expr.line unless
2411
+ expr.sexp_type == :array_TAIL
2412
+ result = expr
2413
+ }
2414
+
2415
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2416
+ {
2417
+ kw_arg, _, rest = val
2418
+ # TODO? new_unique_key_hash(p, $1, &@$)
2419
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2420
+ }
2421
+ | p_kwarg
2422
+ {
2423
+ kwarg, = val
2424
+ # TODO? new_unique_key_hash(p, $1, &@$)
2425
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2426
+ }
2427
+ | p_kwarg tCOMMA
2428
+ {
2429
+ kwarg, _ = val
2430
+ # TODO? new_unique_key_hash(p, $1, &@$)
2431
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2432
+ }
2433
+ | p_any_kwrest
2434
+ {
2435
+ rest, = val
2436
+
2437
+ result = new_hash_pattern_tail nil, rest, rest.line
2438
+ }
2439
+
2440
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2441
+ | p_kwarg tCOMMA p_kw
2442
+ {
2443
+ kwarg, _, kw = val
2444
+ kwarg.concat kw.sexp_body
2445
+ result = kwarg
2446
+ }
2447
+
2448
+ p_kw: p_kw_label p_expr
2449
+ {
2450
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2451
+ lhs, rhs = val
2452
+
2453
+ result = s(:PAIR, lhs, rhs).line lhs.line
2454
+ }
2455
+ | p_kw_label
2456
+ {
2457
+ lhs, = val
2458
+
2459
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2460
+
2461
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2462
+ # yyerror1(&@1, "key must be valid as local variables");
2463
+ # }
2464
+
2465
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2466
+ # assignable(p, $1, 0, &@$));
2467
+
2468
+ case lhs.sexp_type
2469
+ when :lit then
2470
+ assignable [lhs.value, lhs.line]
2471
+ else
2472
+ # TODO or done?
2473
+ debug 666
2474
+ end
2475
+
2476
+ # TODO PAIR -> LIST ?
2477
+ result = s(:PAIR, lhs, nil).line lhs.line
2478
+ }
2479
+
2480
+ p_kw_label: tLABEL
2481
+ {
2482
+ (id, line), = val
2483
+
2484
+ result = s(:lit, id.to_sym).line line
2485
+ }
2486
+
2487
+ p_kwrest: kwrest_mark tIDENTIFIER
2488
+ {
2489
+ _, (id, line) = val
2490
+
2491
+ name = id.to_sym
2492
+ self.assignable [name, line]
2493
+ result = s(:kwrest, :"**#{name}").line line
2494
+ }
2495
+ | kwrest_mark
2496
+ {
2497
+ (_, line), = val
2498
+
2499
+ result = s(:kwrest, :"**").line line
2500
+ }
2501
+
2502
+ p_kwnorest: kwrest_mark kNIL
2503
+ {
2504
+ (_, line), _ = val
2505
+
2506
+ # TODO: or s(:norest)? s(:**nil)?
2507
+ result = s(:kwrest, :"**nil").line line
2508
+ }
2509
+
2510
+ p_any_kwrest: p_kwrest
2511
+ | p_kwnorest
2512
+
2513
+ p_value: p_primitive
2514
+ | p_primitive tDOT2 p_primitive
2515
+ {
2516
+ lhs, _, rhs = val
2517
+
2518
+ lhs = value_expr lhs
2519
+ rhs = value_expr rhs
2520
+
2521
+ result = s(:dot2, lhs, rhs).line lhs.line
2522
+ }
2523
+ | p_primitive tDOT3 p_primitive
2524
+ {
2525
+ lhs, _, rhs = val
2526
+
2527
+ lhs = value_expr lhs
2528
+ rhs = value_expr rhs
2529
+
2530
+ result = s(:dot3, lhs, rhs).line lhs.line
2531
+ }
2532
+ | p_primitive tDOT2
2533
+ {
2534
+ v1, _ = val
2535
+
2536
+ result = s(:dot2, v1, nil).line v1.line
2537
+ }
2538
+ | p_primitive tDOT3
2539
+ {
2540
+ v1, _ = val
2541
+
2542
+ result = s(:dot3, v1, nil).line v1.line
2543
+ }
2544
+ | p_variable
2545
+ | p_var_ref
2546
+ | p_const
2547
+ | tBDOT2 p_primitive
2548
+ {
2549
+ _, v1 = val
2550
+
2551
+ result = s(:dot2, nil, v1).line v1.line
2552
+ }
2553
+ | tBDOT3 p_primitive
2554
+ {
2555
+ _, v1 = val
2556
+
2557
+ result = s(:dot3, nil, v1).line v1.line
2558
+ }
2559
+
2560
+ p_primitive: literal
2561
+ | strings
2562
+ | xstring
2563
+ | regexp
2564
+ | words
2565
+ | qwords
2566
+ | symbols
2567
+ | qsymbols
2568
+ | keyword_variable
2569
+ {
2570
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2571
+ var, = val
2572
+
2573
+ result = var
2574
+ }
2575
+ | lambda
2576
+
2577
+ p_variable: tIDENTIFIER
2578
+ {
2579
+ (id, line), = val
2580
+
2581
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2582
+ # TODO: assignable(p, $1, 0, &@$);
2583
+ result = s(:lvar, id.to_sym).line line
2584
+ }
2585
+
2586
+ p_var_ref: tCARET tIDENTIFIER
2587
+ {
2588
+ _, (id, line) = val
2589
+
2590
+ # TODO: check id against env for lvar or dvar
2591
+
2592
+ result = s(:lvar, id.to_sym).line line
2593
+ }
2594
+
2595
+ p_const: tCOLON3 cname
2596
+ {
2597
+ _, (id, line) = val
2598
+ result = s(:colon3, id.to_sym).line line
2599
+ }
2600
+ | p_const tCOLON2 cname
2601
+ {
2602
+ lhs, _, (id, _line) = val
2603
+
2604
+ l = lhs.line
2605
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2606
+ }
2607
+ | tCONSTANT
2608
+ {
2609
+ # TODO $$ = gettable(p, $1, &@$);
2610
+ (id, line), = val
2611
+ result = s(:const, id.to_sym).line line
2612
+ }
2613
+ ######################################################################
2614
+
2615
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
2616
+ {
2617
+ (_, line), klasses, var, _, body, rest = val
2618
+
2619
+ klasses ||= s(:array)
2620
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
2621
+ klasses.line line
2622
+
2623
+ result = new_resbody(klasses, body)
2624
+ result << rest if rest # UGH, rewritten above
2625
+ }
2626
+ |
2627
+ {
2628
+ result = nil
2629
+ }
2630
+
2631
+ exc_list: arg_value
2632
+ {
2633
+ arg, = val
2634
+ result = s(:array, arg).line arg.line
2635
+ }
2636
+ | mrhs
2637
+ | none
2638
+
2639
+ exc_var: tASSOC lhs
2640
+ {
2641
+ result = val[1]
2642
+ }
2643
+ | none
2644
+
2645
+ opt_ensure: k_ensure compstmt
2646
+ {
2647
+ (_, line), body = val
2648
+
2649
+ result = body || s(:nil).line(line)
2650
+ }
2651
+ | none
2652
+
2653
+ literal: numeric
2654
+ {
2655
+ (lit, line), = val
2656
+ result = s(:lit, lit).line line
2657
+ }
2658
+ | symbol
2659
+
2660
+ strings: string
2661
+ {
2662
+ str, = val
2663
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2664
+ result = str
2665
+ }
2666
+
2667
+ string: tCHAR
2668
+ {
2669
+ debug 36
2670
+ }
2671
+ | string1
2672
+ | string string1
2673
+ {
2674
+ result = self.literal_concat val[0], val[1]
2675
+ }
2676
+
2677
+ string1: tSTRING_BEG string_contents tSTRING_END
2678
+ {
2679
+ (_, line), str, (_, func) = val
2680
+
2681
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2682
+
2683
+ result = str.line line
2684
+ }
2685
+ | tSTRING
2686
+ {
2687
+ result = new_string val
2003
2688
  }
2004
2689
 
2005
2690
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
@@ -2015,11 +2700,15 @@ opt_block_args_tail: tCOMMA block_args_tail
2015
2700
 
2016
2701
  words: tWORDS_BEG tSPACE tSTRING_END
2017
2702
  {
2018
- result = s(:array).line lexer.lineno
2703
+ (_, line), _, _ = val
2704
+
2705
+ result = s(:array).line line
2019
2706
  }
2020
2707
  | tWORDS_BEG word_list tSTRING_END
2021
2708
  {
2022
- result = val[1]
2709
+ (_, line), list, _ = val
2710
+
2711
+ result = list.line line
2023
2712
  }
2024
2713
 
2025
2714
  word_list: none
@@ -2039,18 +2728,20 @@ opt_block_args_tail: tCOMMA block_args_tail
2039
2728
 
2040
2729
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
2041
2730
  {
2042
- result = s(:array).line lexer.lineno
2731
+ (_, line), _, _ = val
2732
+
2733
+ result = s(:array).line line
2043
2734
  }
2044
- | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
2735
+ | tSYMBOLS_BEG symbol_list tSTRING_END
2045
2736
  {
2046
- _, line, list, _, = val
2047
- list.line = line
2737
+ (_, line), list, _, = val
2738
+ list.line line
2048
2739
  result = list
2049
2740
  }
2050
2741
 
2051
2742
  symbol_list: none
2052
2743
  {
2053
- result = new_symbol_list.line lexer.lineno
2744
+ result = new_symbol_list
2054
2745
  }
2055
2746
  | symbol_list word tSPACE
2056
2747
  {
@@ -2060,20 +2751,28 @@ opt_block_args_tail: tCOMMA block_args_tail
2060
2751
 
2061
2752
  qwords: tQWORDS_BEG tSPACE tSTRING_END
2062
2753
  {
2063
- result = s(:array).line lexer.lineno
2754
+ (_, line), _, _ = val
2755
+
2756
+ result = s(:array).line line
2064
2757
  }
2065
2758
  | tQWORDS_BEG qword_list tSTRING_END
2066
2759
  {
2067
- result = val[1]
2760
+ (_, line), list, _ = val
2761
+
2762
+ result = list.line line
2068
2763
  }
2069
2764
 
2070
2765
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
2071
2766
  {
2072
- result = s(:array).line lexer.lineno # FIX
2767
+ (_, line), _, _ = val
2768
+
2769
+ result = s(:array).line line
2073
2770
  }
2074
2771
  | tQSYMBOLS_BEG qsym_list tSTRING_END
2075
2772
  {
2076
- result = val[1]
2773
+ (_, line), list, _ = val
2774
+
2775
+ result = list.line line
2077
2776
  }
2078
2777
 
2079
2778
  qword_list: none
@@ -2096,7 +2795,8 @@ opt_block_args_tail: tCOMMA block_args_tail
2096
2795
 
2097
2796
  string_contents: none
2098
2797
  {
2099
- result = s(:str, "").line lexer.lineno
2798
+ line = prev_value_to_lineno _values.last
2799
+ result = s(:str, +"").line line
2100
2800
  }
2101
2801
  | string_contents string_content
2102
2802
  {
@@ -2171,8 +2871,8 @@ regexp_contents: none
2171
2871
  lexer.brace_nest = brace_nest
2172
2872
  lexer.string_nest = string_nest
2173
2873
 
2174
- lexer.cmdarg.pop
2175
2874
  lexer.cond.pop
2875
+ lexer.cmdarg.pop
2176
2876
 
2177
2877
  lexer.lex_state = oldlex_state
2178
2878
 
@@ -2187,29 +2887,49 @@ regexp_contents: none
2187
2887
  when nil then
2188
2888
  result = s(:evstr).line line
2189
2889
  else
2190
- debug20 25
2890
+ debug 37
2191
2891
  raise "unknown string body: #{stmt.inspect}"
2192
2892
  end
2193
2893
  }
2194
2894
 
2195
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2196
- | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2197
- | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
2895
+ string_dvar: tGVAR
2896
+ {
2897
+ (id, line), = val
2898
+ result = s(:gvar, id.to_sym).line line
2899
+ }
2900
+ | tIVAR
2901
+ {
2902
+ (id, line), = val
2903
+ result = s(:ivar, id.to_sym).line line
2904
+ }
2905
+ | tCVAR
2906
+ {
2907
+ (id, line), = val
2908
+ result = s(:cvar, id.to_sym).line line
2909
+ }
2198
2910
  | backref
2199
2911
 
2200
- symbol: tSYMBEG sym
2912
+ symbol: ssym
2913
+ | dsym
2914
+
2915
+ ssym: tSYMBEG sym
2201
2916
  {
2917
+ _, (id, line) = val
2918
+
2202
2919
  lexer.lex_state = EXPR_END
2203
- result = val[1].to_sym
2920
+ result = s(:lit, id.to_sym).line line
2204
2921
  }
2205
2922
  | tSYMBOL
2206
2923
  {
2207
- result = val[0].to_sym
2924
+ (id, line), = val
2925
+
2926
+ lexer.lex_state = EXPR_END
2927
+ result = s(:lit, id.to_sym).line line
2208
2928
  }
2209
2929
 
2210
2930
  sym: fname | tIVAR | tGVAR | tCVAR
2211
2931
 
2212
- dsym: tSYMBEG xstring_contents tSTRING_END
2932
+ dsym: tSYMBEG string_contents tSTRING_END
2213
2933
  {
2214
2934
  _, result, _ = val
2215
2935
 
@@ -2225,14 +2945,15 @@ regexp_contents: none
2225
2945
  when :evstr then
2226
2946
  result = s(:dsym, "", result).line result.line
2227
2947
  else
2228
- debug20 26, val, result
2948
+ debug 38
2229
2949
  end
2230
2950
  }
2231
2951
 
2232
2952
  numeric: simple_numeric
2233
- | tUMINUS_NUM simple_numeric
2953
+ | tUMINUS_NUM simple_numeric =tLOWEST
2234
2954
  {
2235
- result = -val[1] # TODO: pt_testcase
2955
+ _, (num, line) = val
2956
+ result = [-num, line]
2236
2957
  }
2237
2958
 
2238
2959
  simple_numeric: tINTEGER
@@ -2265,8 +2986,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2265
2986
 
2266
2987
  var_ref: user_variable
2267
2988
  {
2268
- var = val[0]
2989
+ raise "NO: #{val.inspect}" if Sexp === val.first
2990
+ (var, line), = val
2269
2991
  result = Sexp === var ? var : self.gettable(var)
2992
+
2993
+ result.line line
2270
2994
  }
2271
2995
  | keyword_variable
2272
2996
  {
@@ -2281,11 +3005,19 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2281
3005
  | keyword_variable
2282
3006
  {
2283
3007
  result = self.assignable val[0]
2284
- debug20 29, val, result
3008
+ debug 39
2285
3009
  }
2286
3010
 
2287
- backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2288
- | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
3011
+ backref: tNTH_REF
3012
+ {
3013
+ (ref, line), = val
3014
+ result = s(:nth_ref, ref).line line
3015
+ }
3016
+ | tBACK_REF
3017
+ {
3018
+ (ref, line), = val
3019
+ result = s(:back_ref, ref).line line
3020
+ }
2289
3021
 
2290
3022
  superclass: tLT
2291
3023
  {
@@ -2301,26 +3033,23 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2301
3033
  result = nil
2302
3034
  }
2303
3035
 
2304
- f_arglist: tLPAREN2 f_args rparen
3036
+ f_opt_paren_args: f_paren_args
3037
+ | none
3038
+
3039
+ f_paren_args: tLPAREN2 f_args rparen
2305
3040
  {
2306
- result = val[1]
2307
- self.lexer.lex_state = EXPR_BEG
2308
- self.lexer.command_start = true
3041
+ result = end_args val
2309
3042
  }
2310
3043
  | tLPAREN2 f_arg tCOMMA args_forward rparen
2311
3044
  {
2312
- result = args val
2313
-
2314
- self.lexer.lex_state = EXPR_BEG
2315
- self.lexer.command_start = true
3045
+ result = end_args val
2316
3046
  }
2317
3047
  | tLPAREN2 args_forward rparen
2318
3048
  {
2319
- result = args val
2320
-
2321
- self.lexer.lex_state = EXPR_BEG
2322
- self.lexer.command_start = true
3049
+ result = end_args val
2323
3050
  }
3051
+
3052
+ f_arglist: f_paren_args
2324
3053
  | {
2325
3054
  result = self.in_kwarg
2326
3055
  self.in_kwarg = true
@@ -2328,12 +3057,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2328
3057
  }
2329
3058
  f_args term
2330
3059
  {
2331
- kwarg, args, _ = val
2332
-
2333
- self.in_kwarg = kwarg
2334
- result = args
2335
- lexer.lex_state = EXPR_BEG
2336
- lexer.command_start = true
3060
+ result = end_args val
2337
3061
  }
2338
3062
 
2339
3063
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2344,7 +3068,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2344
3068
  {
2345
3069
  result = args val
2346
3070
  }
2347
- | f_kwrest opt_f_block_arg
3071
+ | f_any_kwrest opt_f_block_arg
2348
3072
  {
2349
3073
  result = args val
2350
3074
  }
@@ -2418,6 +3142,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2418
3142
  |
2419
3143
  {
2420
3144
  result = args val
3145
+ # result.line lexer.lineno
2421
3146
  }
2422
3147
 
2423
3148
  args_forward: tBDOT3
@@ -2445,10 +3170,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2445
3170
  f_norm_arg: f_bad_arg
2446
3171
  | tIDENTIFIER
2447
3172
  {
2448
- identifier = val[0].to_sym
3173
+ (id, line), = val
3174
+ identifier = id.to_sym
2449
3175
  self.env[identifier] = :lvar
2450
3176
 
2451
- result = identifier
3177
+ result = [identifier, line]
2452
3178
  }
2453
3179
 
2454
3180
  f_arg_asgn: f_norm_arg
@@ -2456,22 +3182,14 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2456
3182
  f_arg_item: f_arg_asgn
2457
3183
  | tLPAREN f_margs rparen
2458
3184
  {
2459
- result = val[1]
3185
+ _, margs, _ = val
3186
+
3187
+ result = margs
2460
3188
  }
2461
3189
 
2462
3190
  f_arg: f_arg_item
2463
3191
  {
2464
- arg, = val
2465
-
2466
- case arg
2467
- when Symbol then
2468
- result = s(:args, arg).line lexer.lineno
2469
- when Sexp then
2470
- result = arg
2471
- else
2472
- debug20 32
2473
- raise "Unknown f_arg type: #{val.inspect}"
2474
- end
3192
+ result = new_arg val
2475
3193
  }
2476
3194
  | f_arg tCOMMA f_arg_item
2477
3195
  {
@@ -2483,7 +3201,7 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2483
3201
  result = s(:args, list).line list.line
2484
3202
  end
2485
3203
 
2486
- result << item
3204
+ result << (Sexp === item ? item : item.first)
2487
3205
  }
2488
3206
 
2489
3207
  f_label: tLABEL
@@ -2544,27 +3262,38 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2544
3262
  kwrest_mark: tPOW
2545
3263
  | tDSTAR
2546
3264
 
3265
+ f_no_kwarg: kwrest_mark kNIL
3266
+ {
3267
+ (_, line), _ = val
3268
+ result = [:"**nil", line]
3269
+ }
3270
+
2547
3271
  f_kwrest: kwrest_mark tIDENTIFIER
2548
3272
  {
2549
- name = val[1].to_sym
2550
- self.assignable name
2551
- result = :"**#{name}"
3273
+ _, (id, line) = val
3274
+
3275
+ name = id.to_sym
3276
+ self.assignable [name, line]
3277
+ result = [:"**#{name}", line]
2552
3278
  }
2553
3279
  | kwrest_mark
2554
3280
  {
2555
- result = :"**"
2556
- self.env[result] = :lvar
3281
+ id = :"**"
3282
+ self.env[id] = :lvar # TODO: needed?!?
3283
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2557
3284
  }
2558
3285
 
2559
3286
  f_opt: f_arg_asgn tEQL arg_value
2560
3287
  {
2561
- result = self.assignable val[0], val[2]
3288
+ lhs, _, rhs = val
3289
+ result = self.assignable lhs, rhs
2562
3290
  # TODO: detect duplicate names
2563
3291
  }
2564
3292
 
2565
3293
  f_block_opt: f_arg_asgn tEQL primary_value
2566
3294
  {
2567
- result = self.assignable val[0], val[2]
3295
+ lhs, _, rhs = val
3296
+ result = self.assignable lhs, rhs
2568
3297
  }
2569
3298
 
2570
3299
  f_block_optarg: f_block_opt
@@ -2594,30 +3323,33 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2594
3323
  f_rest_arg: restarg_mark tIDENTIFIER
2595
3324
  {
2596
3325
  # TODO: differs from parse.y - needs tests
2597
- name = val[1].to_sym
2598
- self.assignable name
2599
- result = :"*#{name}"
3326
+ _, (id, line) = val
3327
+ name = id.to_sym
3328
+ self.assignable [name, line]
3329
+ result = [:"*#{name}", line]
2600
3330
  }
2601
3331
  | restarg_mark
2602
3332
  {
2603
3333
  name = :"*"
2604
3334
  self.env[name] = :lvar
2605
- result = name
3335
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2606
3336
  }
2607
3337
 
2608
3338
  blkarg_mark: tAMPER2 | tAMPER
2609
3339
 
2610
3340
  f_block_arg: blkarg_mark tIDENTIFIER
2611
3341
  {
2612
- identifier = val[1].to_sym
3342
+ _, (id, line) = val
3343
+ identifier = id.to_sym
2613
3344
 
2614
3345
  self.env[identifier] = :lvar
2615
- result = "&#{identifier}".to_sym
3346
+ result = ["&#{identifier}".to_sym, line]
2616
3347
  }
2617
3348
 
2618
3349
  opt_f_block_arg: tCOMMA f_block_arg
2619
3350
  {
2620
- result = val[1]
3351
+ _, arg = val
3352
+ result = arg
2621
3353
  }
2622
3354
  |
2623
3355
  {
@@ -2666,9 +3398,11 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2666
3398
  }
2667
3399
  | tSTRING_BEG string_contents tLABEL_END arg_value
2668
3400
  {
2669
- _, sym, _, value = val
3401
+ (_, line), sym, _, value = val
3402
+
2670
3403
  sym.sexp_type = :dsym
2671
- result = s(:array, sym, value).line sym.line
3404
+
3405
+ result = s(:array, sym, value).line line
2672
3406
  }
2673
3407
  | tDSTAR arg_value
2674
3408
  {
@@ -2690,7 +3424,21 @@ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2690
3424
  opt_terms: | terms
2691
3425
  opt_nl: | tNL
2692
3426
  rparen: opt_nl tRPAREN
3427
+ # TODO:
3428
+ # {
3429
+ # _, close = val
3430
+ # result = [close, lexer.lineno]
3431
+ # }
2693
3432
  rbracket: opt_nl tRBRACK
3433
+ {
3434
+ _, close = val
3435
+ result = [close, lexer.lineno]
3436
+ }
3437
+ rbrace: opt_nl tRCURLY
3438
+ {
3439
+ _, close = val
3440
+ result = [close, lexer.lineno]
3441
+ }
2694
3442
  trailer: | tNL | tCOMMA
2695
3443
 
2696
3444
  term: tSEMI { yyerrok }