ruby_parser 3.17.0 → 3.18.0

Sign up to get free protection for your applications and to get access to all the features.
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 }