ruby_parser 3.13.0 → 3.15.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -23,35 +23,35 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
23
23
  tLABEL_END
24
24
  tLONELY
25
25
 
26
- prechigh
27
- right tBANG tTILDE tUPLUS
28
- right tPOW
29
- right tUMINUS_NUM tUMINUS
30
- left tSTAR2 tDIVIDE tPERCENT
31
- left tPLUS tMINUS
32
- left tLSHFT tRSHFT
33
- left tAMPER2
34
- left tPIPE tCARET
35
- left tGT tGEQ tLT tLEQ
36
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
37
- left tANDOP
38
- left tOROP
39
- nonassoc tDOT2 tDOT3
40
- right tEH tCOLON
41
- left kRESCUE_MOD
42
- right tEQL tOP_ASGN
43
- nonassoc kDEFINED
44
- right kNOT
45
- left kOR kAND
46
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
47
- nonassoc tLBRACE_ARG
48
- nonassoc tLOWEST
49
26
  preclow
27
+ nonassoc tLOWEST
28
+ nonassoc tLBRACE_ARG
29
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
30
+ left kOR kAND
31
+ right kNOT
32
+ nonassoc kDEFINED
33
+ right tEQL tOP_ASGN
34
+ left kRESCUE_MOD
35
+ right tEH tCOLON
36
+ nonassoc tDOT2 tDOT3
37
+ left tOROP
38
+ left tANDOP
39
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
40
+ left tGT tGEQ tLT tLEQ
41
+ left tPIPE tCARET
42
+ left tAMPER2
43
+ left tLSHFT tRSHFT
44
+ left tPLUS tMINUS
45
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
46
+ right tUMINUS_NUM tUMINUS
47
+ right tPOW
48
+ right tBANG tTILDE tUPLUS
49
+ prechigh
50
50
 
51
51
  rule
52
52
 
53
53
  program: {
54
- self.lexer.lex_state = :expr_beg
54
+ self.lexer.lex_state = EXPR_BEG
55
55
  }
56
56
  top_compstmt
57
57
  {
@@ -60,7 +60,8 @@ rule
60
60
 
61
61
  top_compstmt: top_stmts opt_terms
62
62
  {
63
- result = val[0]
63
+ stmt, _ = val
64
+ result = stmt
64
65
  }
65
66
 
66
67
  top_stmts: none
@@ -72,14 +73,6 @@ rule
72
73
  | error top_stmt
73
74
 
74
75
  top_stmt: stmt
75
- {
76
- result = val[0]
77
-
78
- # TODO: remove once I have more confidence this is fixed
79
- # result.each_of_type :call_args do |s|
80
- # debug20 666, s, result
81
- # end
82
- }
83
76
  | klBEGIN
84
77
  {
85
78
  if (self.in_def || self.in_single > 0) then
@@ -90,14 +83,19 @@ rule
90
83
  }
91
84
  begin_block
92
85
  {
93
- _, _, block = val
94
- result = block
86
+ (_, lineno), _, iter = val
87
+ iter.line lineno
88
+
89
+ (_, preexe,) = iter
90
+ preexe.line lineno
91
+
92
+ result = iter
95
93
  }
96
94
 
97
- begin_block: tLCURLY top_compstmt tRCURLY
95
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
98
96
  {
99
- _, stmt, _ = val
100
- result = new_iter s(:preexe), 0, stmt
97
+ _, line, stmt, _ = val
98
+ result = new_iter s(:preexe).line(line), 0, stmt
101
99
  }
102
100
 
103
101
  bodystmt: compstmt opt_rescue k_else
@@ -139,34 +137,27 @@ rule
139
137
  stmt_or_begin: stmt
140
138
  | klBEGIN
141
139
  {
142
- if (self.in_def || self.in_single > 0) then
143
- debug20 1
144
- yyerror "BEGIN in method"
145
- end
146
- self.env.extend
147
- }
148
- begin_block
149
- {
150
- _, _, stmt = val
151
- result = stmt
140
+ yyerror "BEGIN is permitted only at toplevel"
152
141
  }
153
142
 
154
143
  stmt: kALIAS fitem
155
144
  {
156
- lexer.lex_state = :expr_fname
157
- result = self.lexer.lineno
145
+ lexer.lex_state = EXPR_FNAME
158
146
  }
159
147
  fitem
160
148
  {
161
- result = s(:alias, val[1], val[3]).line(val[2])
149
+ (_, line), lhs, _, rhs = val
150
+ result = s(:alias, lhs, rhs).line(line).line line
162
151
  }
163
152
  | kALIAS tGVAR tGVAR
164
153
  {
165
- result = s(:valias, val[1].to_sym, val[2].to_sym)
154
+ (_, line), lhs, rhs = val
155
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
166
156
  }
167
157
  | kALIAS tGVAR tBACK_REF
168
158
  {
169
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
159
+ (_, line), lhs, rhs = val
160
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
170
161
  }
171
162
  | kALIAS tGVAR tNTH_REF
172
163
  {
@@ -178,32 +169,41 @@ rule
178
169
  }
179
170
  | stmt kIF_MOD expr_value
180
171
  {
181
- result = new_if val[2], val[0], nil
172
+ t, _, c = val
173
+ result = new_if c, t, nil
182
174
  }
183
175
  | stmt kUNLESS_MOD expr_value
184
176
  {
185
- result = new_if val[2], nil, val[0]
177
+ f, _, c = val
178
+ result = new_if c, nil, f
186
179
  }
187
180
  | stmt kWHILE_MOD expr_value
188
181
  {
189
- result = new_while val[0], val[2], true
182
+ e, _, c = val
183
+ result = new_while e, c, true
190
184
  }
191
185
  | stmt kUNTIL_MOD expr_value
192
186
  {
193
- result = new_until val[0], val[2], true
187
+ e, _, c = val
188
+ result = new_until e, c, true
194
189
  }
195
190
  | stmt kRESCUE_MOD stmt
196
191
  {
197
192
  body, _, resbody = val
198
- result = new_rescue body, new_resbody(s(:array), resbody)
193
+
194
+ resbody = new_resbody s(:array).line(resbody.line), resbody
195
+ result = new_rescue body, resbody
199
196
  }
200
197
  | klEND tLCURLY compstmt tRCURLY
201
198
  {
199
+ (_, line), _, stmt, _ = val
200
+
202
201
  if (self.in_def || self.in_single > 0) then
203
202
  debug20 3
204
203
  yyerror "END in method; use at_exit"
205
204
  end
206
- result = new_iter s(:postexe), 0, val[2]
205
+
206
+ result = new_iter s(:postexe).line(line), 0, stmt
207
207
  }
208
208
  | command_asgn
209
209
  | mlhs tEQL command_call
@@ -212,7 +212,8 @@ rule
212
212
  }
213
213
  | lhs tEQL mrhs
214
214
  {
215
- result = new_assign val[0], s(:svalue, val[2])
215
+ lhs, _, rhs = val
216
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
216
217
  }
217
218
  | mlhs tEQL mrhs_arg
218
219
  {
@@ -234,11 +235,12 @@ rule
234
235
  }
235
236
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
236
237
  {
237
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
238
+ result = new_op_asgn1 val
238
239
  }
239
240
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
240
241
  {
241
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
242
+ prim, _, id, opasgn, rhs = val
243
+ result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
242
244
  if val[1] == '&.'
243
245
  result.sexp_type = :safe_op_asgn
244
246
  end
@@ -254,13 +256,15 @@ rule
254
256
  }
255
257
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
256
258
  {
257
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
258
- debug20 4, val, result
259
+ lhs1, _, lhs2, op, rhs = val
260
+
261
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
259
262
  }
260
263
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
261
264
  {
262
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
263
- debug20 5, val, result
265
+ lhs1, _, lhs2, op, rhs = val
266
+
267
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
264
268
  }
265
269
  | backref tOP_ASGN command_rhs
266
270
  {
@@ -274,28 +278,37 @@ rule
274
278
  }
275
279
  | command_call kRESCUE_MOD stmt
276
280
  {
277
- expr, _, resbody = val
281
+ expr, (_, line), resbody = val
282
+
278
283
  expr = value_expr expr
279
- result = new_rescue(expr, new_resbody(s(:array), resbody))
284
+ ary = s(:array).line line
285
+ result = new_rescue(expr, new_resbody(ary, resbody))
280
286
  }
281
287
  | command_asgn
282
288
 
283
289
  expr: command_call
284
290
  | expr kAND expr
285
291
  {
286
- result = logical_op :and, val[0], val[2]
292
+ lhs, _, rhs = val
293
+ result = logical_op :and, lhs, rhs
287
294
  }
288
295
  | expr kOR expr
289
296
  {
290
- result = logical_op :or, val[0], val[2]
297
+ lhs, _, rhs = val
298
+ result = logical_op :or, lhs, rhs
291
299
  }
292
300
  | kNOT opt_nl expr
293
301
  {
294
- result = s(:call, val[2], :"!")
302
+ (_, line), _, expr = val
303
+ result = new_call(expr, :"!").line line
304
+ # REFACTOR: call_uni_op
295
305
  }
296
306
  | tBANG command_call
297
307
  {
298
- result = s(:call, val[1], :"!")
308
+ _, cmd = val
309
+ result = new_call(cmd, :"!").line cmd.line
310
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
+ # REFACTOR: call_uni_op -- see parse26.y
299
312
  }
300
313
  | arg
301
314
 
@@ -322,7 +335,8 @@ rule
322
335
  block_command: block_call
323
336
  | block_call call_op2 operation2 command_args
324
337
  {
325
- result = new_call val[0], val[2].to_sym, val[3]
338
+ blk, _, msg, args = val
339
+ result = new_call(blk, msg.to_sym, args).line blk.line
326
340
  }
327
341
 
328
342
  cmd_brace_block: tLBRACE_ARG
@@ -342,26 +356,32 @@ rule
342
356
 
343
357
  fcall: operation
344
358
  {
345
- result = new_call nil, val[0].to_sym
359
+ msg, = val
360
+ result = new_call(nil, msg.to_sym).line lexer.lineno
346
361
  }
347
362
 
348
363
  command: fcall command_args =tLOWEST
349
364
  {
350
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
365
+ call, args = val
366
+ result = call.concat args.sexp_body
351
367
  }
352
368
  | fcall command_args cmd_brace_block
353
369
  {
354
- result = val[0].concat val[1].sexp_body
355
- if val[2] then
356
- block_dup_check result, val[2]
370
+ call, args, block = val
357
371
 
358
- result, operation = val[2], result
372
+ result = call.concat args.sexp_body
373
+
374
+ if block then
375
+ block_dup_check result, block
376
+
377
+ result, operation = block, result
359
378
  result.insert 1, operation
360
379
  end
361
380
  }
362
381
  | primary_value call_op operation2 command_args =tLOWEST
363
382
  {
364
- result = new_call val[0], val[2].to_sym, val[3], val[1]
383
+ lhs, callop, op, args = val
384
+ result = new_call lhs, op.to_sym, args, callop
365
385
  }
366
386
  | primary_value call_op operation2 command_args cmd_brace_block
367
387
  {
@@ -393,7 +413,9 @@ rule
393
413
  }
394
414
  | kYIELD command_args
395
415
  {
396
- result = new_yield val[1]
416
+ (_, line), args = val
417
+ result = new_yield args
418
+ result.line line # TODO: push to new_yield
397
419
  }
398
420
  | k_return call_args
399
421
  {
@@ -402,8 +424,8 @@ rule
402
424
  }
403
425
  | kBREAK call_args
404
426
  {
405
- line = val[0].last
406
- result = s(:break, ret_args(val[1])).line(line)
427
+ (_, line), args = val
428
+ result = s(:break, ret_args(args)).line line
407
429
  }
408
430
  | kNEXT call_args
409
431
  {
@@ -420,56 +442,79 @@ rule
420
442
  mlhs_inner: mlhs_basic
421
443
  | tLPAREN mlhs_inner rparen
422
444
  {
423
- result = s(:masgn, s(:array, val[1]))
445
+ _, arg, _ = val
446
+ l = arg.line
447
+
448
+ result = s(:masgn, s(:array, arg).line(l)).line l
424
449
  }
425
450
 
426
451
  mlhs_basic: mlhs_head
427
452
  {
428
- result = s(:masgn, val[0])
453
+ head, = val
454
+ result = s(:masgn, head).line head.line
429
455
  }
430
456
  | mlhs_head mlhs_item
431
457
  {
432
- result = s(:masgn, val[0] << val[1].compact)
458
+ lhs, rhs = val
459
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
433
460
  }
434
461
  | mlhs_head tSTAR mlhs_node
435
462
  {
436
- result = s(:masgn, val[0] << s(:splat, val[2]))
463
+ head, _, tail = val
464
+ head << s(:splat, tail).line(tail.line)
465
+ result = s(:masgn, head).line head.line
437
466
  }
438
467
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
439
468
  {
440
469
  ary1, _, splat, _, ary2 = val
441
470
 
442
- result = list_append ary1, s(:splat, splat)
471
+ result = list_append ary1, s(:splat, splat).line(splat.line)
443
472
  result.concat ary2.sexp_body
444
- result = s(:masgn, result)
473
+ result = s(:masgn, result).line result.line
445
474
  }
446
475
  | mlhs_head tSTAR
447
476
  {
448
- result = s(:masgn, val[0] << s(:splat))
477
+ head, _ = val
478
+ l = head.line
479
+ result = s(:masgn, head << s(:splat).line(l)).line l
449
480
  }
450
481
  | mlhs_head tSTAR tCOMMA mlhs_post
451
482
  {
452
- ary = list_append val[0], s(:splat)
453
- ary.concat val[3].sexp_body
454
- result = s(:masgn, ary)
483
+ head, _, _, post = val
484
+ ary = list_append head, s(:splat).line(head.line)
485
+ ary.concat post.sexp_body
486
+ result = s(:masgn, ary).line ary.line
455
487
  }
456
488
  | tSTAR mlhs_node
457
489
  {
458
- result = s(:masgn, s(:array, s(:splat, val[1])))
490
+ _, node = val
491
+ l = node.line
492
+ splat = s(:splat, node).line l
493
+ ary = s(:array, splat).line l
494
+ result = s(:masgn, ary).line l
459
495
  }
460
496
  | tSTAR mlhs_node tCOMMA mlhs_post
461
497
  {
462
- ary = s(:array, s(:splat, val[1]))
463
- ary.concat val[3].sexp_body
464
- result = s(:masgn, ary)
498
+ _, node, _, post = val
499
+
500
+ splat = s(:splat, node).line node.line
501
+ ary = s(:array, splat).line splat.line
502
+ ary.concat post.sexp_body
503
+ result = s(:masgn, ary).line ary.line
465
504
  }
466
505
  | tSTAR
467
506
  {
468
- result = s(:masgn, s(:array, s(:splat)))
507
+ l = lexer.lineno
508
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
469
509
  }
470
510
  | tSTAR tCOMMA mlhs_post
471
511
  {
472
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
512
+ _, _, post = val
513
+ l = post.line
514
+
515
+ splat = s(:splat).line l
516
+ ary = s(:array, splat, *post.sexp_body).line l
517
+ result = s(:masgn, ary).line l
473
518
  }
474
519
 
475
520
  mlhs_item: mlhs_node
@@ -480,7 +525,8 @@ rule
480
525
 
481
526
  mlhs_head: mlhs_item tCOMMA
482
527
  {
483
- result = s(:array, val[0])
528
+ lhs, _ = val
529
+ result = s(:array, lhs).line lhs.line
484
530
  }
485
531
  | mlhs_head mlhs_item tCOMMA
486
532
  {
@@ -489,7 +535,8 @@ rule
489
535
 
490
536
  mlhs_post: mlhs_item
491
537
  {
492
- result = s(:array, val[0])
538
+ item, = val
539
+ result = s(:array, item).line item.line
493
540
  }
494
541
  | mlhs_post tCOMMA mlhs_item
495
542
  {
@@ -514,7 +561,8 @@ rule
514
561
  }
515
562
  | primary_value tCOLON2 tIDENTIFIER
516
563
  {
517
- result = s(:attrasgn, val[0], :"#{val[2]}=")
564
+ recv, _, id = val
565
+ result = new_attrasgn recv, id
518
566
  }
519
567
  | primary_value call_op tCONSTANT
520
568
  {
@@ -527,7 +575,10 @@ rule
527
575
  yyerror "dynamic constant assignment"
528
576
  end
529
577
 
530
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
578
+ expr, _, id = val
579
+ l = expr.line
580
+
581
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
531
582
  }
532
583
  | tCOLON3 tCONSTANT
533
584
  {
@@ -536,7 +587,10 @@ rule
536
587
  yyerror "dynamic constant assignment"
537
588
  end
538
589
 
539
- result = s(:const, nil, s(:colon3, val[1].to_sym))
590
+ _, id = val
591
+ l = lexer.lineno
592
+
593
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
540
594
  }
541
595
  | backref
542
596
  {
@@ -545,24 +599,31 @@ rule
545
599
 
546
600
  lhs: user_variable
547
601
  {
602
+ line = lexer.lineno
548
603
  result = self.assignable val[0]
604
+ result.line = line
549
605
  }
550
606
  | keyword_variable
551
607
  {
608
+ line = lexer.lineno
552
609
  result = self.assignable val[0]
610
+ result.line = line
553
611
  debug20 9, val, result
554
612
  }
555
613
  | primary_value tLBRACK2 opt_call_args rbracket
556
614
  {
557
- result = self.aryset val[0], val[2]
615
+ lhs, _, args, _ = val
616
+ result = self.aryset lhs, args
558
617
  }
559
618
  | primary_value call_op tIDENTIFIER # REFACTOR
560
619
  {
561
- result = new_attrasgn val[0], val[2], val[1]
620
+ lhs, op, id = val
621
+ result = new_attrasgn lhs, id, op
562
622
  }
563
623
  | primary_value tCOLON2 tIDENTIFIER
564
624
  {
565
- result = s(:attrasgn, val[0], :"#{val[2]}=")
625
+ lhs, _, id = val
626
+ result = new_attrasgn lhs, id
566
627
  }
567
628
  | primary_value call_op tCONSTANT # REFACTOR?
568
629
  {
@@ -570,21 +631,27 @@ rule
570
631
  }
571
632
  | primary_value tCOLON2 tCONSTANT
572
633
  {
634
+ expr, _, id = val
635
+
573
636
  if (self.in_def || self.in_single > 0) then
574
637
  debug20 10
575
638
  yyerror "dynamic constant assignment"
576
639
  end
577
640
 
578
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
641
+ l = expr.line
642
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
579
643
  }
580
644
  | tCOLON3 tCONSTANT
581
645
  {
646
+ _, id = val
647
+
582
648
  if (self.in_def || self.in_single > 0) then
583
649
  debug20 11
584
650
  yyerror "dynamic constant assignment"
585
651
  end
586
652
 
587
- result = s(:const, s(:colon3, val[1].to_sym))
653
+ l = lexer.lineno
654
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
588
655
  }
589
656
  | backref
590
657
  {
@@ -599,7 +666,8 @@ rule
599
666
 
600
667
  cpath: tCOLON3 cname
601
668
  {
602
- result = s(:colon3, val[1].to_sym)
669
+ _, name = val
670
+ result = s(:colon3, name.to_sym).line lexer.lineno
603
671
  }
604
672
  | cname
605
673
  {
@@ -607,20 +675,23 @@ rule
607
675
  }
608
676
  | primary_value tCOLON2 cname
609
677
  {
610
- result = s(:colon2, val[0], val[2].to_sym)
678
+ pval, _, name = val
679
+
680
+ result = s(:colon2, pval, name.to_sym)
681
+ result.line pval.line
611
682
  }
612
683
 
613
684
  fname: tIDENTIFIER | tCONSTANT | tFID
614
685
  | op
615
686
  {
616
- lexer.lex_state = :expr_end
687
+ lexer.lex_state = EXPR_END
617
688
  result = val[0]
618
689
  }
619
690
 
620
691
  | reswords
621
692
  {
622
693
  (sym, _line), = val
623
- lexer.lex_state = :expr_end
694
+ lexer.lex_state = EXPR_END
624
695
  result = sym
625
696
  }
626
697
 
@@ -628,7 +699,8 @@ rule
628
699
 
629
700
  fitem: fsym
630
701
  {
631
- result = s(:lit, val[0].to_sym)
702
+ id, = val
703
+ result = s(:lit, id.to_sym).line lexer.lineno
632
704
  }
633
705
  | dsym
634
706
 
@@ -639,7 +711,7 @@ rule
639
711
  |
640
712
  undef_list tCOMMA
641
713
  {
642
- lexer.lex_state = :expr_fname
714
+ lexer.lex_state = EXPR_FNAME
643
715
  }
644
716
  fitem
645
717
  {
@@ -651,6 +723,7 @@ rule
651
723
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
652
724
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
653
725
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
+ # TODO: tUBANG dead?
654
727
  | tUBANG
655
728
 
656
729
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
@@ -673,8 +746,7 @@ rule
673
746
  }
674
747
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
675
748
  {
676
- val[2].sexp_type = :arglist if val[2]
677
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
749
+ result = new_op_asgn1 val
678
750
  }
679
751
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
680
752
  {
@@ -686,17 +758,27 @@ rule
686
758
  }
687
759
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
688
760
  {
689
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
761
+ lhs, _, id, op, rhs = val
762
+
763
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
690
764
  }
691
765
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
692
766
  {
693
- # TODO: assignment
694
- raise "not yet: %p" % [val]
767
+ lhs1, _, lhs2, op, rhs = val
768
+
769
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
+ result = new_const_op_asgn [lhs, op, rhs]
695
771
  }
696
- | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
772
+ | tCOLON3 tCONSTANT
697
773
  {
698
- # TODO: assignment
699
- raise "not yet: %p" % [val]
774
+ result = self.lexer.lineno
775
+ }
776
+ tOP_ASGN arg_rhs
777
+ {
778
+ _, lhs, line, op, rhs = val
779
+
780
+ lhs = s(:colon3, lhs.to_sym).line line
781
+ result = new_const_op_asgn [lhs, op, rhs]
700
782
  }
701
783
  | backref tOP_ASGN arg_rhs
702
784
  {
@@ -708,31 +790,33 @@ rule
708
790
  {
709
791
  v1, v2 = val[0], val[2]
710
792
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
711
- result = s(:lit, (v1.last)..(v2.last))
793
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
712
794
  else
713
- result = s(:dot2, v1, v2)
795
+ result = s(:dot2, v1, v2).line v1.line
714
796
  end
715
797
  }
716
798
  | arg tDOT3 arg
717
799
  {
718
800
  v1, v2 = val[0], val[2]
719
801
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
720
- result = s(:lit, (v1.last)...(v2.last))
802
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
721
803
  else
722
- result = s(:dot3, v1, v2)
804
+ result = s(:dot3, v1, v2).line v1.line
723
805
  end
724
806
  }
725
807
  | arg tDOT2
726
808
  {
727
- v1, v2 = val[0], nil
809
+ v1, _ = val
810
+ v2 = nil
728
811
 
729
- result = s(:dot2, v1, v2)
812
+ result = s(:dot2, v1, v2).line v1.line
730
813
  }
731
814
  | arg tDOT3
732
815
  {
733
- v1, v2 = val[0], nil
816
+ v1, _ = val
817
+ v2 = nil
734
818
 
735
- result = s(:dot3, v1, v2)
819
+ result = s(:dot3, v1, v2).line v1.line
736
820
  }
737
821
  | arg tPLUS arg
738
822
  {
@@ -760,7 +844,9 @@ rule
760
844
  }
761
845
  | tUMINUS_NUM simple_numeric tPOW arg
762
846
  {
763
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
847
+ lit = s(:lit, val[1]).line lexer.lineno
848
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
849
+
764
850
  }
765
851
  | tUPLUS arg
766
852
  {
@@ -801,15 +887,19 @@ rule
801
887
  }
802
888
  | arg tMATCH arg
803
889
  {
804
- result = new_match val[0], val[2]
890
+ lhs, _, rhs = val
891
+ result = new_match lhs, rhs
805
892
  }
806
893
  | arg tNMATCH arg
807
894
  {
808
- result = s(:not, new_match(val[0], val[2]))
895
+ lhs, _, rhs = val
896
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
809
897
  }
810
898
  | tBANG arg
811
899
  {
812
- result = new_call val[1], :"!"
900
+ _, arg = val
901
+ result = new_call arg, :"!"
902
+ result.line arg.line
813
903
  }
814
904
  | tTILDE arg
815
905
  {
@@ -837,11 +927,13 @@ rule
837
927
  }
838
928
  | kDEFINED opt_nl arg
839
929
  {
840
- result = s(:defined, val[2])
930
+ (_, line), _, arg = val
931
+ result = s(:defined, arg).line line
841
932
  }
842
933
  | arg tEH arg opt_nl tCOLON arg
843
934
  {
844
- result = s(:if, val[0], val[2], val[5])
935
+ c, _, t, _, _, f = val
936
+ result = s(:if, c, t, f).line c.line
845
937
  }
846
938
  | primary
847
939
 
@@ -884,28 +976,25 @@ rule
884
976
  arg_rhs: arg =tOP_ASGN
885
977
  | arg kRESCUE_MOD arg
886
978
  {
887
- body, _, resbody = val
979
+ body, (_, line), resbody = val
888
980
  body = value_expr body
889
981
  resbody = remove_begin resbody
890
- result = new_rescue(body, new_resbody(s(:array), resbody))
982
+
983
+ ary = s(:array).line line
984
+ result = new_rescue(body, new_resbody(ary, resbody))
891
985
  }
892
986
 
893
987
  paren_args: tLPAREN2 opt_call_args rparen
894
988
  {
895
- result = val[1]
989
+ _, args, _ = val
990
+ result = args
896
991
  }
897
992
 
898
993
  opt_paren_args: none
899
994
  | paren_args
900
995
 
901
996
  opt_call_args: none
902
- {
903
- result = val[0]
904
- }
905
997
  | call_args
906
- {
907
- result = val[0]
908
- }
909
998
  | args tCOMMA
910
999
  {
911
1000
  result = args val
@@ -927,17 +1016,14 @@ rule
927
1016
  | args opt_block_arg
928
1017
  {
929
1018
  result = call_args val
930
- result = self.arg_blk_pass val[0], val[1]
931
1019
  }
932
1020
  | assocs opt_block_arg
933
1021
  {
934
- result = call_args [array_to_hash(val[0])]
935
- result = self.arg_blk_pass result, val[1]
1022
+ result = call_args [array_to_hash(val[0]), val[1]]
936
1023
  }
937
1024
  | args tCOMMA assocs opt_block_arg
938
1025
  {
939
- result = call_args [val[0], array_to_hash(val[2])]
940
- result = self.arg_blk_pass result, val[3]
1026
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
941
1027
  }
942
1028
  | block_arg
943
1029
  {
@@ -945,17 +1031,45 @@ rule
945
1031
  }
946
1032
 
947
1033
  command_args: {
948
- result = lexer.cmdarg.store true
1034
+ # parse26.y line 2200
1035
+
1036
+ # If call_args starts with a open paren '(' or
1037
+ # '[', look-ahead reading of the letters calls
1038
+ # CMDARG_PUSH(0), but the push must be done
1039
+ # after CMDARG_PUSH(1). So this code makes them
1040
+ # consistent by first cancelling the premature
1041
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1042
+ # finally redoing CMDARG_PUSH(0).
1043
+
1044
+ result = yychar = self.last_token_type.first
1045
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1046
+ lexer.cmdarg.pop if lookahead
1047
+ lexer.cmdarg.push true
1048
+ lexer.cmdarg.push false if lookahead
949
1049
  }
950
1050
  call_args
951
1051
  {
952
- lexer.cmdarg.restore val[0]
953
- result = val[1]
1052
+ yychar, args = val
1053
+
1054
+ # call_args can be followed by tLBRACE_ARG (that
1055
+ # does CMDARG_PUSH(0) in the lexer) but the push
1056
+ # must be done after CMDARG_POP() in the parser.
1057
+ # So this code does CMDARG_POP() to pop 0 pushed
1058
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1059
+ # by command_args, and CMDARG_PUSH(0) to restore
1060
+ # back the flag set by tLBRACE_ARG.
1061
+
1062
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1063
+ lexer.cmdarg.pop if lookahead
1064
+ lexer.cmdarg.pop
1065
+ lexer.cmdarg.push false if lookahead
1066
+ result = args
954
1067
  }
955
1068
 
956
1069
  block_arg: tAMPER arg_value
957
1070
  {
958
- result = s(:block_pass, val[1])
1071
+ _, arg = val
1072
+ result = s(:block_pass, arg).line arg.line
959
1073
  }
960
1074
 
961
1075
  opt_block_arg: tCOMMA block_arg
@@ -966,19 +1080,27 @@ rule
966
1080
 
967
1081
  args: arg_value
968
1082
  {
969
- result = s(:array, val[0])
1083
+ arg, = val
1084
+ lineno = arg.line || lexer.lineno # HACK
1085
+
1086
+ result = s(:array, arg).line lineno
970
1087
  }
971
1088
  | tSTAR arg_value
972
1089
  {
973
- result = s(:array, s(:splat, val[1]))
1090
+ _, arg = val
1091
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
974
1092
  }
975
1093
  | args tCOMMA arg_value
976
1094
  {
977
- result = self.list_append val[0], val[2]
1095
+ args, _, id = val
1096
+ result = self.list_append args, id
978
1097
  }
979
1098
  | args tCOMMA tSTAR arg_value
980
1099
  {
981
- result = self.list_append val[0], s(:splat, val[3])
1100
+ # TODO: the line number from tSTAR has been dropped
1101
+ args, _, _, id = val
1102
+ line = lexer.lineno
1103
+ result = self.list_append args, s(:splat, id).line(line)
982
1104
  }
983
1105
 
984
1106
  mrhs_arg: mrhs
@@ -996,11 +1118,14 @@ rule
996
1118
  }
997
1119
  | args tCOMMA tSTAR arg_value
998
1120
  {
999
- result = self.arg_concat val[0], val[3]
1121
+ # TODO: make all tXXXX terminals include lexer.lineno
1122
+ arg, _, _, splat = val
1123
+ result = self.arg_concat arg, splat
1000
1124
  }
1001
1125
  | tSTAR arg_value
1002
1126
  {
1003
- result = s(:splat, val[1])
1127
+ _, arg = val
1128
+ result = s(:splat, arg).line arg.line
1004
1129
  }
1005
1130
 
1006
1131
  primary: literal
@@ -1015,65 +1140,65 @@ rule
1015
1140
  | backref
1016
1141
  | tFID
1017
1142
  {
1018
- result = new_call nil, val[0].to_sym
1143
+ msg, = val
1144
+ result = new_call nil, msg.to_sym
1019
1145
  }
1020
1146
  | k_begin
1021
1147
  {
1148
+ lexer.cmdarg.push false
1022
1149
  result = self.lexer.lineno
1023
- # TODO:
1024
- # $<val>1 = cmdarg_stack;
1025
- # CMDARG_SET(0);
1026
1150
  }
1027
1151
  bodystmt k_end
1028
1152
  {
1029
- # TODO: CMDARG_SET($<val>1);
1030
- unless val[2] then
1031
- result = s(:nil)
1032
- else
1033
- result = s(:begin, val[2])
1034
- end
1035
-
1036
- result.line = val[1]
1153
+ lexer.cmdarg.pop
1154
+ result = new_begin val
1037
1155
  }
1038
- | tLPAREN_ARG rparen
1156
+ | tLPAREN_ARG
1039
1157
  {
1040
- # TODO: lex_state = :expr_endarg in between
1041
- debug20 13, val, result
1158
+ lexer.lex_state = EXPR_ENDARG
1159
+ result = lexer.lineno
1042
1160
  }
1043
- | tLPAREN_ARG
1161
+ rparen
1044
1162
  {
1045
- result = lexer.cmdarg.store false
1046
- # result = self.lexer.cmdarg.stack.dup
1047
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1163
+ _, line, _ = val
1164
+ result = s(:begin).line line
1048
1165
  }
1166
+ | tLPAREN_ARG
1049
1167
  stmt
1050
1168
  {
1051
- lexer.lex_state = :expr_endarg
1169
+ lexer.lex_state = EXPR_ENDARG
1052
1170
  }
1053
1171
  rparen
1054
1172
  {
1055
- _, cmdarg, stmt, _, _, = val
1056
- warning "(...) interpreted as grouped expression"
1057
- lexer.cmdarg.restore cmdarg
1173
+ _, stmt, _, _, = val
1174
+ # warning "(...) interpreted as grouped expression"
1058
1175
  result = stmt
1059
1176
  }
1060
1177
  | tLPAREN compstmt tRPAREN
1061
1178
  {
1062
- result = val[1] || s(:nil)
1179
+ _, stmt, _ = val
1180
+ result = stmt
1181
+ result ||= s(:nil).line lexer.lineno
1063
1182
  result.paren = true
1064
1183
  }
1065
1184
  | primary_value tCOLON2 tCONSTANT
1066
1185
  {
1067
- result = s(:colon2, val[0], val[2].to_sym)
1186
+ expr, _, id = val
1187
+
1188
+ result = s(:colon2, expr, id.to_sym).line expr.line
1068
1189
  }
1069
1190
  | tCOLON3 tCONSTANT
1070
1191
  {
1071
- result = s(:colon3, val[1].to_sym)
1192
+ _, id = val
1193
+
1194
+ result = s(:colon3, id.to_sym).line lexer.lineno
1072
1195
  }
1073
- | tLBRACK aref_args tRBRACK
1196
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1074
1197
  {
1075
- result = val[1] || s(:array)
1198
+ _, line, args, _ = val
1199
+ result = args || s(:array)
1076
1200
  result.sexp_type = :array # aref_args is :args
1201
+ result.line line
1077
1202
  }
1078
1203
  | tLBRACE
1079
1204
  {
@@ -1085,7 +1210,8 @@ rule
1085
1210
  }
1086
1211
  | k_return
1087
1212
  {
1088
- result = s(:return)
1213
+ (_, line), = val
1214
+ result = s(:return).line line
1089
1215
  }
1090
1216
  | kYIELD tLPAREN2 call_args rparen
1091
1217
  {
@@ -1101,11 +1227,14 @@ rule
1101
1227
  }
1102
1228
  | kDEFINED opt_nl tLPAREN2 expr rparen
1103
1229
  {
1104
- result = s(:defined, val[3])
1230
+ (_, line), _, _, arg, _ = val
1231
+
1232
+ result = s(:defined, arg).line line
1105
1233
  }
1106
1234
  | kNOT tLPAREN2 expr rparen
1107
1235
  {
1108
- result = s(:call, val[2], :"!")
1236
+ _, _, lhs, _ = val
1237
+ result = new_call lhs, :"!"
1109
1238
  }
1110
1239
  | kNOT tLPAREN2 rparen
1111
1240
  {
@@ -1113,11 +1242,11 @@ rule
1113
1242
  }
1114
1243
  | fcall brace_block
1115
1244
  {
1116
- oper, iter = val[0], val[1]
1117
- call = oper # FIX
1245
+ call, iter = val
1246
+
1118
1247
  iter.insert 1, call
1119
1248
  result = iter
1120
- call.line = iter.line
1249
+ # FIX: probably not: call.line = iter.line
1121
1250
  }
1122
1251
  | method_call
1123
1252
  | method_call brace_block
@@ -1225,66 +1354,82 @@ rule
1225
1354
  }
1226
1355
  | k_def fname
1227
1356
  {
1228
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1357
+ result = self.in_def
1229
1358
 
1230
- self.comments.push self.lexer.comments
1231
- self.in_def = true
1359
+ self.in_def = true # group = local_push
1232
1360
  self.env.extend
1233
- # TODO: local->cmdargs = cmdarg_stack;
1234
- # TODO: port local_push_gen and local_pop_gen
1235
- lexer.cmdarg.stack.replace [false]
1361
+ lexer.cmdarg.push false
1362
+ lexer.cond.push false
1363
+
1364
+ self.comments.push self.lexer.comments
1236
1365
  }
1237
- f_arglist bodystmt k_end
1366
+ f_arglist bodystmt { result = lexer.lineno } k_end
1238
1367
  {
1239
- in_def, cmdarg = val[2]
1368
+ in_def = val[2]
1240
1369
 
1241
1370
  result = new_defn val
1242
1371
 
1243
- lexer.cmdarg.stack.replace cmdarg
1372
+ lexer.cond.pop # group = local_pop
1373
+ lexer.cmdarg.pop
1244
1374
  self.env.unextend
1245
1375
  self.in_def = in_def
1376
+
1246
1377
  self.lexer.comments # we don't care about comments in the body
1247
1378
  }
1248
1379
  | k_def singleton dot_or_colon
1249
1380
  {
1250
- self.comments.push self.lexer.comments
1251
- lexer.lex_state = :expr_fname
1381
+ lexer.lex_state = EXPR_FNAME
1252
1382
  }
1253
1383
  fname
1254
1384
  {
1255
- self.in_single += 1
1385
+ result = [self.in_def, lexer.lineno]
1386
+
1387
+ self.in_single += 1 # TODO: remove?
1388
+
1389
+ self.in_def = true # local_push
1256
1390
  self.env.extend
1257
- lexer.lex_state = :expr_endfn # force for args
1258
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1259
- lexer.cmdarg.stack.replace [false]
1391
+ lexer.cmdarg.push false
1392
+ lexer.cond.push false
1393
+
1394
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1395
+ self.comments.push self.lexer.comments
1260
1396
  }
1261
1397
  f_arglist bodystmt k_end
1262
1398
  {
1263
- line, cmdarg = val[5]
1264
- result = new_defs val
1265
- result[3].line line
1399
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1266
1400
 
1267
- lexer.cmdarg.stack.replace cmdarg
1401
+ result = new_defs val
1268
1402
 
1403
+ lexer.cond.pop # group = local_pop
1404
+ lexer.cmdarg.pop
1269
1405
  self.env.unextend
1406
+ self.in_def = in_def
1407
+
1270
1408
  self.in_single -= 1
1409
+
1410
+ # TODO: restore cur_arg ? what's cur_arg?
1411
+
1271
1412
  self.lexer.comments # we don't care about comments in the body
1272
1413
  }
1273
1414
  | kBREAK
1274
1415
  {
1275
- result = s(:break)
1416
+ (_, line), = val
1417
+ result = s(:break).line line
1276
1418
  }
1277
1419
  | kNEXT
1278
1420
  {
1279
- result = s(:next)
1421
+ (_, line), = val
1422
+ result = s(:next).line line
1280
1423
  }
1281
1424
  | kREDO
1282
1425
  {
1283
- result = s(:redo)
1426
+ (_, line), = val
1427
+ result = s(:redo).line line
1284
1428
  }
1285
1429
  | kRETRY
1286
1430
  {
1287
- result = s(:retry)
1431
+ (_, line), = val
1432
+ result = s(:retry).line line
1288
1433
  }
1289
1434
 
1290
1435
  primary_value: primary
@@ -1323,7 +1468,9 @@ rule
1323
1468
  if_tail: opt_else
1324
1469
  | k_elsif expr_value then compstmt if_tail
1325
1470
  {
1326
- result = s(:if, val[1], val[3], val[4])
1471
+ (_, line), c, _, t, rest = val
1472
+
1473
+ result = s(:if, c, t, rest).line line
1327
1474
  }
1328
1475
 
1329
1476
  opt_else: none
@@ -1346,7 +1493,9 @@ rule
1346
1493
 
1347
1494
  f_marg_list: f_marg
1348
1495
  {
1349
- result = s(:array, val[0])
1496
+ sym, = val
1497
+
1498
+ result = s(:array, sym).line lexer.lineno
1350
1499
  }
1351
1500
  | f_marg_list tCOMMA f_marg
1352
1501
  {
@@ -1420,7 +1569,9 @@ rule
1420
1569
  }
1421
1570
  | f_block_arg
1422
1571
  {
1423
- result = call_args val
1572
+ line = lexer.lineno
1573
+ result = call_args val # TODO: push line down
1574
+ result.line line
1424
1575
  }
1425
1576
 
1426
1577
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1451,7 +1602,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1451
1602
  }
1452
1603
  | f_arg tCOMMA
1453
1604
  {
1454
- result = args val
1605
+ result = args(val) << nil
1455
1606
  }
1456
1607
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1457
1608
  {
@@ -1503,7 +1654,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1503
1654
  }
1504
1655
  | tOROP
1505
1656
  {
1506
- result = s(:args)
1657
+ result = s(:args).line lexer.lineno
1507
1658
  }
1508
1659
  | tPIPE block_param opt_bv_decl tPIPE
1509
1660
  {
@@ -1528,34 +1679,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1528
1679
 
1529
1680
  bvar: tIDENTIFIER
1530
1681
  {
1531
- result = s(:shadow, val[0].to_sym)
1682
+ id, = val
1683
+ line = lexer.lineno
1684
+ result = s(:shadow, id.to_sym).line line
1532
1685
  }
1533
1686
  | f_bad_arg
1534
1687
 
1535
1688
  lambda: {
1536
1689
  self.env.extend :dynamic
1537
- result = self.lexer.lineno
1538
-
1539
- result = lexer.lpar_beg
1690
+ result = [lexer.lineno, lexer.lpar_beg]
1540
1691
  lexer.paren_nest += 1
1541
1692
  lexer.lpar_beg = lexer.paren_nest
1542
1693
  }
1543
1694
  f_larglist
1544
1695
  {
1545
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1696
+ lexer.cmdarg.push false
1546
1697
  }
1547
1698
  lambda_body
1548
1699
  {
1549
- lpar, args, (cmdarg, lineno), body = val
1700
+ (line, lpar), args, _cmdarg, body = val
1550
1701
  lexer.lpar_beg = lpar
1551
1702
 
1552
- lexer.cmdarg.restore cmdarg
1553
- lexer.cmdarg.lexpop
1703
+ lexer.cmdarg.pop
1554
1704
 
1555
- call = new_call nil, :lambda
1705
+ call = s(:lambda).line line
1556
1706
  result = new_iter call, args, body
1557
- result.line = lineno
1558
- self.env.unextend
1707
+ result.line = line
1708
+ self.env.unextend # TODO: dynapush & dynapop
1559
1709
  }
1560
1710
 
1561
1711
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1579,8 +1729,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1579
1729
 
1580
1730
  do_block: k_do_block do_body kEND
1581
1731
  {
1582
- # TODO: maybe fix lineno to kDO's lineno?
1583
- result = val[1]
1732
+ (_, line), iter, _ = val
1733
+ result = iter.line line
1584
1734
  }
1585
1735
 
1586
1736
  block_call: command do_block
@@ -1594,8 +1744,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1594
1744
 
1595
1745
  val = invert_block_call val if inverted? val
1596
1746
 
1597
- result = val[1]
1598
- result.insert 1, val[0]
1747
+ cmd, blk = val
1748
+
1749
+ result = blk
1750
+ result.insert 1, cmd
1599
1751
  }
1600
1752
  | block_call call_op2 operation2 opt_paren_args
1601
1753
  {
@@ -1626,8 +1778,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1626
1778
  }
1627
1779
  paren_args
1628
1780
  {
1629
- args = self.call_args val[2..-1]
1630
- result = val[0].concat args.sexp_body
1781
+ call, lineno, args = val
1782
+
1783
+ result = call.concat args.sexp_body if args
1784
+ result.line lineno
1631
1785
  }
1632
1786
  | primary_value call_op operation2 opt_paren_args
1633
1787
  {
@@ -1655,7 +1809,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1655
1809
  }
1656
1810
  | kSUPER
1657
1811
  {
1658
- result = s(:zsuper)
1812
+ result = s(:zsuper).line lexer.lineno
1659
1813
  }
1660
1814
  | primary_value tLBRACK2 opt_call_args rbracket
1661
1815
  {
@@ -1704,15 +1858,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1704
1858
  }
1705
1859
 
1706
1860
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1707
- { result = lexer.cmdarg.store(false) }
1861
+ { lexer.cmdarg.push false }
1708
1862
  opt_block_param
1709
1863
  bodystmt
1710
1864
  {
1711
- line, cmdarg, param, cmpstmt = val
1865
+ line, _cmdarg, param, cmpstmt = val
1712
1866
 
1713
1867
  result = new_do_body param, cmpstmt, line
1868
+ lexer.cmdarg.pop
1714
1869
  self.env.unextend
1715
- lexer.cmdarg.restore cmdarg
1716
1870
  }
1717
1871
 
1718
1872
  case_body: k_when
@@ -1733,7 +1887,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1733
1887
  (_, line), klasses, var, _, body, rest = val
1734
1888
 
1735
1889
  klasses ||= s(:array)
1736
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1890
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1737
1891
  klasses.line line
1738
1892
 
1739
1893
  result = new_resbody(klasses, body)
@@ -1746,7 +1900,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1746
1900
 
1747
1901
  exc_list: arg_value
1748
1902
  {
1749
- result = s(:array, val[0])
1903
+ arg, = val
1904
+ result = s(:array, arg).line arg.line
1750
1905
  }
1751
1906
  | mrhs
1752
1907
  | none
@@ -1759,26 +1914,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1759
1914
 
1760
1915
  opt_ensure: k_ensure compstmt
1761
1916
  {
1762
- _, body = val
1917
+ (_, line), body = val
1763
1918
 
1764
- result = body || s(:nil)
1919
+ result = body || s(:nil).line(line)
1765
1920
  }
1766
1921
  | none
1767
1922
 
1768
1923
  literal: numeric
1769
1924
  {
1925
+ line = lexer.lineno
1770
1926
  result = s(:lit, val[0])
1927
+ result.line = line
1771
1928
  }
1772
1929
  | symbol
1773
1930
  {
1931
+ line = lexer.lineno
1774
1932
  result = s(:lit, val[0])
1933
+ result.line = line
1775
1934
  }
1776
1935
  | dsym
1777
1936
 
1778
1937
  strings: string
1779
1938
  {
1780
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1781
- result = val[0]
1939
+ str, = val
1940
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1941
+ result = str
1782
1942
  }
1783
1943
 
1784
1944
  string: tCHAR
@@ -1793,7 +1953,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1793
1953
 
1794
1954
  string1: tSTRING_BEG string_contents tSTRING_END
1795
1955
  {
1796
- result = val[1]
1956
+ _, str, (_, func) = val
1957
+
1958
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1959
+
1960
+ result = str
1797
1961
  }
1798
1962
  | tSTRING
1799
1963
  {
@@ -1802,7 +1966,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1966
 
1803
1967
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1804
1968
  {
1805
- result = new_xstring val[1]
1969
+ result = new_xstring val
1970
+ # TODO: dedent?!?! SERIOUSLY?!?
1806
1971
  }
1807
1972
 
1808
1973
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1812,7 +1977,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1812
1977
 
1813
1978
  words: tWORDS_BEG tSPACE tSTRING_END
1814
1979
  {
1815
- result = s(:array)
1980
+ result = s(:array).line lexer.lineno
1816
1981
  }
1817
1982
  | tWORDS_BEG word_list tSTRING_END
1818
1983
  {
@@ -1836,25 +2001,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1836
2001
 
1837
2002
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1838
2003
  {
1839
- result = s(:array)
2004
+ result = s(:array).line lexer.lineno
1840
2005
  }
1841
- | tSYMBOLS_BEG symbol_list tSTRING_END
2006
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1842
2007
  {
1843
- result = val[1]
2008
+ _, line, list, _, = val
2009
+ list.line = line
2010
+ result = list
1844
2011
  }
1845
2012
 
1846
2013
  symbol_list: none
1847
2014
  {
1848
- result = new_symbol_list
2015
+ result = new_symbol_list.line lexer.lineno
1849
2016
  }
1850
2017
  | symbol_list word tSPACE
1851
2018
  {
1852
- result = val[0].dup << new_symbol_list_entry(val)
2019
+ list, * = val
2020
+ result = list.dup << new_symbol_list_entry(val)
1853
2021
  }
1854
2022
 
1855
2023
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1856
2024
  {
1857
- result = s(:array)
2025
+ result = s(:array).line lexer.lineno
1858
2026
  }
1859
2027
  | tQWORDS_BEG qword_list tSTRING_END
1860
2028
  {
@@ -1863,7 +2031,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1863
2031
 
1864
2032
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1865
2033
  {
1866
- result = s(:array)
2034
+ result = s(:array).line lexer.lineno # FIX
1867
2035
  }
1868
2036
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1869
2037
  {
@@ -1890,11 +2058,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1890
2058
 
1891
2059
  string_contents: none
1892
2060
  {
1893
- result = s(:str, "")
2061
+ result = s(:str, "").line lexer.lineno
1894
2062
  }
1895
2063
  | string_contents string_content
1896
2064
  {
1897
- result = literal_concat(val[0], val[1])
2065
+ v1, v2 = val
2066
+ result = literal_concat v1, v2
1898
2067
  }
1899
2068
 
1900
2069
  xstring_contents: none
@@ -1903,7 +2072,8 @@ xstring_contents: none
1903
2072
  }
1904
2073
  | xstring_contents string_content
1905
2074
  {
1906
- result = literal_concat(val[0], val[1])
2075
+ v1, v2 = val
2076
+ result = literal_concat v1, v2
1907
2077
  }
1908
2078
 
1909
2079
  regexp_contents: none
@@ -1912,7 +2082,8 @@ regexp_contents: none
1912
2082
  }
1913
2083
  | regexp_contents string_content
1914
2084
  {
1915
- result = literal_concat(val[0], val[1])
2085
+ v1, v2 = val
2086
+ result = literal_concat v1, v2
1916
2087
  }
1917
2088
 
1918
2089
  string_content: tSTRING_CONTENT
@@ -1924,42 +2095,46 @@ regexp_contents: none
1924
2095
  result = lexer.lex_strterm
1925
2096
 
1926
2097
  lexer.lex_strterm = nil
1927
- lexer.lex_state = :expr_beg
2098
+ lexer.lex_state = EXPR_BEG
1928
2099
  }
1929
2100
  string_dvar
1930
2101
  {
1931
- lexer.lex_strterm = val[1]
1932
- result = s(:evstr, val[2])
2102
+ _, strterm, str = val
2103
+ lexer.lex_strterm = strterm
2104
+ result = s(:evstr, str).line str.line
1933
2105
  }
1934
2106
  | tSTRING_DBEG
1935
2107
  {
1936
2108
  result = [lexer.lex_strterm,
1937
2109
  lexer.brace_nest,
1938
2110
  lexer.string_nest, # TODO: remove
1939
- lexer.cond.store,
1940
- lexer.cmdarg.store,
1941
2111
  lexer.lex_state,
2112
+ lexer.lineno,
1942
2113
  ]
1943
2114
 
2115
+ lexer.cmdarg.push false
2116
+ lexer.cond.push false
2117
+
1944
2118
  lexer.lex_strterm = nil
1945
2119
  lexer.brace_nest = 0
1946
2120
  lexer.string_nest = 0
1947
2121
 
1948
- lexer.lex_state = :expr_beg
2122
+ lexer.lex_state = EXPR_BEG
1949
2123
  }
1950
2124
  compstmt
1951
2125
  tSTRING_DEND
1952
2126
  {
1953
2127
  _, memo, stmt, _ = val
1954
2128
 
1955
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2129
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2130
+ # TODO: heredoc_indent
1956
2131
 
1957
2132
  lexer.lex_strterm = lex_strterm
1958
2133
  lexer.brace_nest = brace_nest
1959
2134
  lexer.string_nest = string_nest
1960
2135
 
1961
- lexer.cond.restore oldcond
1962
- lexer.cmdarg.restore oldcmdarg
2136
+ lexer.cmdarg.pop
2137
+ lexer.cond.pop
1963
2138
 
1964
2139
  lexer.lex_state = oldlex_state
1965
2140
 
@@ -1969,24 +2144,24 @@ regexp_contents: none
1969
2144
  when :str, :dstr, :evstr then
1970
2145
  result = stmt
1971
2146
  else
1972
- result = s(:evstr, stmt)
2147
+ result = s(:evstr, stmt).line line
1973
2148
  end
1974
2149
  when nil then
1975
- result = s(:evstr)
2150
+ result = s(:evstr).line line
1976
2151
  else
1977
2152
  debug20 25
1978
2153
  raise "unknown string body: #{stmt.inspect}"
1979
2154
  end
1980
2155
  }
1981
2156
 
1982
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1983
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1984
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2157
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2158
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2159
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
1985
2160
  | backref
1986
2161
 
1987
2162
  symbol: tSYMBEG sym
1988
2163
  {
1989
- lexer.lex_state = :expr_end
2164
+ lexer.lex_state = EXPR_END
1990
2165
  result = val[1].to_sym
1991
2166
  }
1992
2167
  | tSYMBOL
@@ -1998,18 +2173,19 @@ regexp_contents: none
1998
2173
 
1999
2174
  dsym: tSYMBEG xstring_contents tSTRING_END
2000
2175
  {
2001
- lexer.lex_state = :expr_end
2002
- result = val[1]
2176
+ _, result, _ = val
2177
+
2178
+ lexer.lex_state = EXPR_END
2003
2179
 
2004
- result ||= s(:str, "")
2180
+ result ||= s(:str, "").line lexer.lineno
2005
2181
 
2006
2182
  case result.sexp_type
2007
2183
  when :dstr then
2008
2184
  result.sexp_type = :dsym
2009
2185
  when :str then
2010
- result = s(:lit, result.last.to_sym)
2186
+ result = s(:lit, result.last.to_sym).line result.line
2011
2187
  when :evstr then
2012
- result = s(:dsym, "", result)
2188
+ result = s(:dsym, "", result).line result.line
2013
2189
  else
2014
2190
  debug20 26, val, result
2015
2191
  end
@@ -2032,19 +2208,20 @@ regexp_contents: none
2032
2208
  | tCONSTANT
2033
2209
  | tCVAR
2034
2210
 
2035
- keyword_variable: kNIL { result = s(:nil) }
2036
- | kSELF { result = s(:self) }
2037
- | kTRUE { result = s(:true) }
2038
- | kFALSE { result = s(:false) }
2039
- | k__FILE__ { result = s(:str, self.file) }
2040
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2211
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2212
+ | kSELF { result = s(:self).line lexer.lineno }
2213
+ | kTRUE { result = s(:true).line lexer.lineno }
2214
+ | kFALSE { result = s(:false).line lexer.lineno }
2215
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2216
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2041
2217
  | k__ENCODING__
2042
2218
  {
2219
+ l = lexer.lineno
2043
2220
  result =
2044
2221
  if defined? Encoding then
2045
- s(:colon2, s(:const, :Encoding), :UTF_8)
2222
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2046
2223
  else
2047
- s(:str, "Unsupported!")
2224
+ s(:str, "Unsupported!").line l
2048
2225
  end
2049
2226
  }
2050
2227
 
@@ -2069,12 +2246,12 @@ keyword_variable: kNIL { result = s(:nil) }
2069
2246
  debug20 29, val, result
2070
2247
  }
2071
2248
 
2072
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2073
- | tBACK_REF { result = s(:back_ref, val[0]) }
2249
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2250
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2074
2251
 
2075
2252
  superclass: tLT
2076
2253
  {
2077
- lexer.lex_state = :expr_beg
2254
+ lexer.lex_state = EXPR_BEG
2078
2255
  lexer.command_start = true
2079
2256
  }
2080
2257
  expr_value term
@@ -2089,13 +2266,13 @@ keyword_variable: kNIL { result = s(:nil) }
2089
2266
  f_arglist: tLPAREN2 f_args rparen
2090
2267
  {
2091
2268
  result = val[1]
2092
- self.lexer.lex_state = :expr_beg
2269
+ self.lexer.lex_state = EXPR_BEG
2093
2270
  self.lexer.command_start = true
2094
2271
  }
2095
2272
  | {
2096
2273
  result = self.in_kwarg
2097
2274
  self.in_kwarg = true
2098
- # TODO: self.lexer.lex_state |= :expr_label
2275
+ self.lexer.lex_state |= EXPR_LABEL
2099
2276
  }
2100
2277
  f_args term
2101
2278
  {
@@ -2103,7 +2280,7 @@ keyword_variable: kNIL { result = s(:nil) }
2103
2280
 
2104
2281
  self.in_kwarg = kwarg
2105
2282
  result = args
2106
- lexer.lex_state = :expr_beg
2283
+ lexer.lex_state = EXPR_BEG
2107
2284
  lexer.command_start = true
2108
2285
  }
2109
2286
 
@@ -2227,12 +2404,13 @@ keyword_variable: kNIL { result = s(:nil) }
2227
2404
 
2228
2405
  f_arg: f_arg_item
2229
2406
  {
2230
- case val[0]
2407
+ arg, = val
2408
+
2409
+ case arg
2231
2410
  when Symbol then
2232
- result = s(:args)
2233
- result << val[0]
2411
+ result = s(:args, arg).line lexer.lineno
2234
2412
  when Sexp then
2235
- result = val[0]
2413
+ result = arg
2236
2414
  else
2237
2415
  debug20 32
2238
2416
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2245,7 +2423,7 @@ keyword_variable: kNIL { result = s(:nil) }
2245
2423
  if list.sexp_type == :args then
2246
2424
  result = list
2247
2425
  else
2248
- result = s(:args, list)
2426
+ result = s(:args, list).line list.line
2249
2427
  end
2250
2428
 
2251
2429
  result << item
@@ -2255,38 +2433,42 @@ keyword_variable: kNIL { result = s(:nil) }
2255
2433
 
2256
2434
  f_kw: f_label arg_value
2257
2435
  {
2258
- # TODO: call_args
2259
- label, _ = val[0] # TODO: fix lineno?
2436
+ # TODO: new_kw_arg
2437
+ (label, line), arg = val
2438
+
2260
2439
  identifier = label.to_sym
2261
2440
  self.env[identifier] = :lvar
2262
2441
 
2263
- result = s(:array, s(:kwarg, identifier, val[1]))
2442
+ kwarg = s(:kwarg, identifier, arg).line line
2443
+ result = s(:array, kwarg).line line
2264
2444
  }
2265
2445
  | f_label
2266
2446
  {
2267
- label, _ = val[0] # TODO: fix lineno?
2268
- identifier = label.to_sym
2269
- self.env[identifier] = :lvar
2447
+ (label, line), = val
2270
2448
 
2271
- result = s(:array, s(:kwarg, identifier))
2449
+ id = label.to_sym
2450
+ self.env[id] = :lvar
2451
+
2452
+ result = s(:array, s(:kwarg, id).line(line)).line line
2272
2453
  }
2273
2454
 
2274
2455
  f_block_kw: f_label primary_value
2275
2456
  {
2276
- # TODO: call_args
2277
- label, _ = val[0] # TODO: fix lineno?
2278
- identifier = label.to_sym
2279
- self.env[identifier] = :lvar
2457
+ # TODO: new_kw_arg
2458
+ (label, line), expr = val
2459
+ id = label.to_sym
2460
+ self.env[id] = :lvar
2280
2461
 
2281
- result = s(:array, s(:kwarg, identifier, val[1]))
2462
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2282
2463
  }
2283
2464
  | f_label
2284
2465
  {
2285
- label, _ = val[0] # TODO: fix lineno?
2286
- identifier = label.to_sym
2287
- self.env[identifier] = :lvar
2466
+ # TODO: new_kw_arg
2467
+ (label, line), = val
2468
+ id = label.to_sym
2469
+ self.env[id] = :lvar
2288
2470
 
2289
- result = s(:array, s(:kwarg, identifier))
2471
+ result = s(:array, s(:kwarg, id).line(line)).line line
2290
2472
  }
2291
2473
 
2292
2474
  f_block_kwarg: f_block_kw
@@ -2329,17 +2511,20 @@ keyword_variable: kNIL { result = s(:nil) }
2329
2511
 
2330
2512
  f_block_optarg: f_block_opt
2331
2513
  {
2332
- result = s(:block, val[0])
2514
+ optblk, = val
2515
+ result = s(:block, optblk).line optblk.line
2333
2516
  }
2334
2517
  | f_block_optarg tCOMMA f_block_opt
2335
2518
  {
2336
- result = val[0]
2337
- result << val[2]
2519
+ optarg, _, optblk = val
2520
+ result = optarg
2521
+ result << optblk
2338
2522
  }
2339
2523
 
2340
2524
  f_optarg: f_opt
2341
2525
  {
2342
- result = s(:block, val[0])
2526
+ opt, = val
2527
+ result = s(:block, opt).line opt.line
2343
2528
  }
2344
2529
  | f_optarg tCOMMA f_opt
2345
2530
  {
@@ -2384,7 +2569,7 @@ keyword_variable: kNIL { result = s(:nil) }
2384
2569
  singleton: var_ref
2385
2570
  | tLPAREN2
2386
2571
  {
2387
- lexer.lex_state = :expr_beg
2572
+ lexer.lex_state = EXPR_BEG
2388
2573
  }
2389
2574
  expr rparen
2390
2575
  {
@@ -2393,14 +2578,11 @@ keyword_variable: kNIL { result = s(:nil) }
2393
2578
  result.sexp_type == :lit
2394
2579
  }
2395
2580
 
2396
- assoc_list: none # [!nil]
2581
+ assoc_list: none
2397
2582
  {
2398
- result = s(:array)
2399
- }
2400
- | assocs trailer # [!nil]
2401
- {
2402
- result = val[0]
2583
+ result = s(:array).line lexer.lineno
2403
2584
  }
2585
+ | assocs trailer
2404
2586
 
2405
2587
  assocs: assoc
2406
2588
  | assocs tCOMMA assoc
@@ -2414,22 +2596,27 @@ keyword_variable: kNIL { result = s(:nil) }
2414
2596
 
2415
2597
  assoc: arg_value tASSOC arg_value
2416
2598
  {
2417
- result = s(:array, val[0], val[2])
2599
+ v1, _, v2 = val
2600
+ result = s(:array, v1, v2).line v1.line
2418
2601
  }
2419
2602
  | tLABEL arg_value
2420
2603
  {
2421
- (label, _), arg = val
2422
- result = s(:array, s(:lit, label.to_sym), arg)
2604
+ (label, line), arg = val
2605
+
2606
+ lit = s(:lit, label.to_sym).line line
2607
+ result = s(:array, lit, arg).line line
2423
2608
  }
2424
2609
  | tSTRING_BEG string_contents tLABEL_END arg_value
2425
2610
  {
2426
2611
  _, sym, _, value = val
2427
2612
  sym.sexp_type = :dsym
2428
- result = s(:array, sym, value)
2613
+ result = s(:array, sym, value).line sym.line
2429
2614
  }
2430
2615
  | tDSTAR arg_value
2431
2616
  {
2432
- result = s(:array, s(:kwsplat, val[1]))
2617
+ _, arg = val
2618
+ line = arg.line
2619
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2433
2620
  }
2434
2621
 
2435
2622
  operation: tIDENTIFIER | tCONSTANT | tFID
@@ -2461,6 +2648,7 @@ end
2461
2648
 
2462
2649
  require "ruby_lexer"
2463
2650
  require "ruby_parser_extras"
2651
+ include RubyLexer::State::Values
2464
2652
 
2465
2653
  # :stopdoc:
2466
2654