ruby_parser 3.13.0 → 3.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,18 +790,18 @@ 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 tPLUS arg
@@ -748,7 +830,9 @@ rule
748
830
  }
749
831
  | tUMINUS_NUM simple_numeric tPOW arg
750
832
  {
751
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
833
+ lit = s(:lit, val[1]).line lexer.lineno
834
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
835
+
752
836
  }
753
837
  | tUPLUS arg
754
838
  {
@@ -789,15 +873,19 @@ rule
789
873
  }
790
874
  | arg tMATCH arg
791
875
  {
792
- result = new_match val[0], val[2]
876
+ lhs, _, rhs = val
877
+ result = new_match lhs, rhs
793
878
  }
794
879
  | arg tNMATCH arg
795
880
  {
796
- result = s(:not, new_match(val[0], val[2]))
881
+ lhs, _, rhs = val
882
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
797
883
  }
798
884
  | tBANG arg
799
885
  {
800
- result = new_call val[1], :"!"
886
+ _, arg = val
887
+ result = new_call arg, :"!"
888
+ result.line arg.line
801
889
  }
802
890
  | tTILDE arg
803
891
  {
@@ -825,11 +913,13 @@ rule
825
913
  }
826
914
  | kDEFINED opt_nl arg
827
915
  {
828
- result = s(:defined, val[2])
916
+ (_, line), _, arg = val
917
+ result = s(:defined, arg).line line
829
918
  }
830
919
  | arg tEH arg opt_nl tCOLON arg
831
920
  {
832
- result = s(:if, val[0], val[2], val[5])
921
+ c, _, t, _, _, f = val
922
+ result = s(:if, c, t, f).line c.line
833
923
  }
834
924
  | primary
835
925
 
@@ -872,28 +962,25 @@ rule
872
962
  arg_rhs: arg =tOP_ASGN
873
963
  | arg kRESCUE_MOD arg
874
964
  {
875
- body, _, resbody = val
965
+ body, (_, line), resbody = val
876
966
  body = value_expr body
877
967
  resbody = remove_begin resbody
878
- result = new_rescue(body, new_resbody(s(:array), resbody))
968
+
969
+ ary = s(:array).line line
970
+ result = new_rescue(body, new_resbody(ary, resbody))
879
971
  }
880
972
 
881
973
  paren_args: tLPAREN2 opt_call_args rparen
882
974
  {
883
- result = val[1]
975
+ _, args, _ = val
976
+ result = args
884
977
  }
885
978
 
886
979
  opt_paren_args: none
887
980
  | paren_args
888
981
 
889
982
  opt_call_args: none
890
- {
891
- result = val[0]
892
- }
893
983
  | call_args
894
- {
895
- result = val[0]
896
- }
897
984
  | args tCOMMA
898
985
  {
899
986
  result = args val
@@ -915,17 +1002,14 @@ rule
915
1002
  | args opt_block_arg
916
1003
  {
917
1004
  result = call_args val
918
- result = self.arg_blk_pass val[0], val[1]
919
1005
  }
920
1006
  | assocs opt_block_arg
921
1007
  {
922
- result = call_args [array_to_hash(val[0])]
923
- result = self.arg_blk_pass result, val[1]
1008
+ result = call_args [array_to_hash(val[0]), val[1]]
924
1009
  }
925
1010
  | args tCOMMA assocs opt_block_arg
926
1011
  {
927
- result = call_args [val[0], array_to_hash(val[2])]
928
- result = self.arg_blk_pass result, val[3]
1012
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
929
1013
  }
930
1014
  | block_arg
931
1015
  {
@@ -933,17 +1017,45 @@ rule
933
1017
  }
934
1018
 
935
1019
  command_args: {
936
- result = lexer.cmdarg.store true
1020
+ # parse26.y line 2200
1021
+
1022
+ # If call_args starts with a open paren '(' or
1023
+ # '[', look-ahead reading of the letters calls
1024
+ # CMDARG_PUSH(0), but the push must be done
1025
+ # after CMDARG_PUSH(1). So this code makes them
1026
+ # consistent by first cancelling the premature
1027
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1028
+ # finally redoing CMDARG_PUSH(0).
1029
+
1030
+ result = yychar = self.last_token_type.first
1031
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1032
+ lexer.cmdarg.pop if lookahead
1033
+ lexer.cmdarg.push true
1034
+ lexer.cmdarg.push false if lookahead
937
1035
  }
938
1036
  call_args
939
1037
  {
940
- lexer.cmdarg.restore val[0]
941
- result = val[1]
1038
+ yychar, args = val
1039
+
1040
+ # call_args can be followed by tLBRACE_ARG (that
1041
+ # does CMDARG_PUSH(0) in the lexer) but the push
1042
+ # must be done after CMDARG_POP() in the parser.
1043
+ # So this code does CMDARG_POP() to pop 0 pushed
1044
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1045
+ # by command_args, and CMDARG_PUSH(0) to restore
1046
+ # back the flag set by tLBRACE_ARG.
1047
+
1048
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1049
+ lexer.cmdarg.pop if lookahead
1050
+ lexer.cmdarg.pop
1051
+ lexer.cmdarg.push false if lookahead
1052
+ result = args
942
1053
  }
943
1054
 
944
1055
  block_arg: tAMPER arg_value
945
1056
  {
946
- result = s(:block_pass, val[1])
1057
+ _, arg = val
1058
+ result = s(:block_pass, arg).line arg.line
947
1059
  }
948
1060
 
949
1061
  opt_block_arg: tCOMMA block_arg
@@ -954,19 +1066,27 @@ rule
954
1066
 
955
1067
  args: arg_value
956
1068
  {
957
- result = s(:array, val[0])
1069
+ arg, = val
1070
+ lineno = arg.line || lexer.lineno # HACK
1071
+
1072
+ result = s(:array, arg).line lineno
958
1073
  }
959
1074
  | tSTAR arg_value
960
1075
  {
961
- result = s(:array, s(:splat, val[1]))
1076
+ _, arg = val
1077
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
962
1078
  }
963
1079
  | args tCOMMA arg_value
964
1080
  {
965
- result = self.list_append val[0], val[2]
1081
+ args, _, id = val
1082
+ result = self.list_append args, id
966
1083
  }
967
1084
  | args tCOMMA tSTAR arg_value
968
1085
  {
969
- result = self.list_append val[0], s(:splat, val[3])
1086
+ # TODO: the line number from tSTAR has been dropped
1087
+ args, _, _, id = val
1088
+ line = lexer.lineno
1089
+ result = self.list_append args, s(:splat, id).line(line)
970
1090
  }
971
1091
 
972
1092
  mrhs_arg: mrhs
@@ -984,11 +1104,14 @@ rule
984
1104
  }
985
1105
  | args tCOMMA tSTAR arg_value
986
1106
  {
987
- result = self.arg_concat val[0], val[3]
1107
+ # TODO: make all tXXXX terminals include lexer.lineno
1108
+ arg, _, _, splat = val
1109
+ result = self.arg_concat arg, splat
988
1110
  }
989
1111
  | tSTAR arg_value
990
1112
  {
991
- result = s(:splat, val[1])
1113
+ _, arg = val
1114
+ result = s(:splat, arg).line arg.line
992
1115
  }
993
1116
 
994
1117
  primary: literal
@@ -1003,65 +1126,65 @@ rule
1003
1126
  | backref
1004
1127
  | tFID
1005
1128
  {
1006
- result = new_call nil, val[0].to_sym
1129
+ msg, = val
1130
+ result = new_call nil, msg.to_sym
1007
1131
  }
1008
1132
  | k_begin
1009
1133
  {
1134
+ lexer.cmdarg.push false
1010
1135
  result = self.lexer.lineno
1011
- # TODO:
1012
- # $<val>1 = cmdarg_stack;
1013
- # CMDARG_SET(0);
1014
1136
  }
1015
1137
  bodystmt k_end
1016
1138
  {
1017
- # TODO: CMDARG_SET($<val>1);
1018
- unless val[2] then
1019
- result = s(:nil)
1020
- else
1021
- result = s(:begin, val[2])
1022
- end
1023
-
1024
- result.line = val[1]
1139
+ lexer.cmdarg.pop
1140
+ result = new_begin val
1025
1141
  }
1026
- | tLPAREN_ARG rparen
1142
+ | tLPAREN_ARG
1027
1143
  {
1028
- # TODO: lex_state = :expr_endarg in between
1029
- debug20 13, val, result
1144
+ lexer.lex_state = EXPR_ENDARG
1145
+ result = lexer.lineno
1030
1146
  }
1031
- | tLPAREN_ARG
1147
+ rparen
1032
1148
  {
1033
- result = lexer.cmdarg.store false
1034
- # result = self.lexer.cmdarg.stack.dup
1035
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1149
+ _, line, _ = val
1150
+ result = s(:begin).line line
1036
1151
  }
1152
+ | tLPAREN_ARG
1037
1153
  stmt
1038
1154
  {
1039
- lexer.lex_state = :expr_endarg
1155
+ lexer.lex_state = EXPR_ENDARG
1040
1156
  }
1041
1157
  rparen
1042
1158
  {
1043
- _, cmdarg, stmt, _, _, = val
1044
- warning "(...) interpreted as grouped expression"
1045
- lexer.cmdarg.restore cmdarg
1159
+ _, stmt, _, _, = val
1160
+ # warning "(...) interpreted as grouped expression"
1046
1161
  result = stmt
1047
1162
  }
1048
1163
  | tLPAREN compstmt tRPAREN
1049
1164
  {
1050
- result = val[1] || s(:nil)
1165
+ _, stmt, _ = val
1166
+ result = stmt
1167
+ result ||= s(:nil).line lexer.lineno
1051
1168
  result.paren = true
1052
1169
  }
1053
1170
  | primary_value tCOLON2 tCONSTANT
1054
1171
  {
1055
- result = s(:colon2, val[0], val[2].to_sym)
1172
+ expr, _, id = val
1173
+
1174
+ result = s(:colon2, expr, id.to_sym).line expr.line
1056
1175
  }
1057
1176
  | tCOLON3 tCONSTANT
1058
1177
  {
1059
- result = s(:colon3, val[1].to_sym)
1178
+ _, id = val
1179
+
1180
+ result = s(:colon3, id.to_sym).line lexer.lineno
1060
1181
  }
1061
- | tLBRACK aref_args tRBRACK
1182
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1062
1183
  {
1063
- result = val[1] || s(:array)
1184
+ _, line, args, _ = val
1185
+ result = args || s(:array)
1064
1186
  result.sexp_type = :array # aref_args is :args
1187
+ result.line line
1065
1188
  }
1066
1189
  | tLBRACE
1067
1190
  {
@@ -1073,7 +1196,8 @@ rule
1073
1196
  }
1074
1197
  | k_return
1075
1198
  {
1076
- result = s(:return)
1199
+ (_, line), = val
1200
+ result = s(:return).line line
1077
1201
  }
1078
1202
  | kYIELD tLPAREN2 call_args rparen
1079
1203
  {
@@ -1089,11 +1213,14 @@ rule
1089
1213
  }
1090
1214
  | kDEFINED opt_nl tLPAREN2 expr rparen
1091
1215
  {
1092
- result = s(:defined, val[3])
1216
+ (_, line), _, _, arg, _ = val
1217
+
1218
+ result = s(:defined, arg).line line
1093
1219
  }
1094
1220
  | kNOT tLPAREN2 expr rparen
1095
1221
  {
1096
- result = s(:call, val[2], :"!")
1222
+ _, _, lhs, _ = val
1223
+ result = new_call lhs, :"!"
1097
1224
  }
1098
1225
  | kNOT tLPAREN2 rparen
1099
1226
  {
@@ -1101,11 +1228,11 @@ rule
1101
1228
  }
1102
1229
  | fcall brace_block
1103
1230
  {
1104
- oper, iter = val[0], val[1]
1105
- call = oper # FIX
1231
+ call, iter = val
1232
+
1106
1233
  iter.insert 1, call
1107
1234
  result = iter
1108
- call.line = iter.line
1235
+ # FIX: probably not: call.line = iter.line
1109
1236
  }
1110
1237
  | method_call
1111
1238
  | method_call brace_block
@@ -1213,66 +1340,82 @@ rule
1213
1340
  }
1214
1341
  | k_def fname
1215
1342
  {
1216
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1343
+ result = self.in_def
1217
1344
 
1218
- self.comments.push self.lexer.comments
1219
- self.in_def = true
1345
+ self.in_def = true # group = local_push
1220
1346
  self.env.extend
1221
- # TODO: local->cmdargs = cmdarg_stack;
1222
- # TODO: port local_push_gen and local_pop_gen
1223
- lexer.cmdarg.stack.replace [false]
1347
+ lexer.cmdarg.push false
1348
+ lexer.cond.push false
1349
+
1350
+ self.comments.push self.lexer.comments
1224
1351
  }
1225
- f_arglist bodystmt k_end
1352
+ f_arglist bodystmt { result = lexer.lineno } k_end
1226
1353
  {
1227
- in_def, cmdarg = val[2]
1354
+ in_def = val[2]
1228
1355
 
1229
1356
  result = new_defn val
1230
1357
 
1231
- lexer.cmdarg.stack.replace cmdarg
1358
+ lexer.cond.pop # group = local_pop
1359
+ lexer.cmdarg.pop
1232
1360
  self.env.unextend
1233
1361
  self.in_def = in_def
1362
+
1234
1363
  self.lexer.comments # we don't care about comments in the body
1235
1364
  }
1236
1365
  | k_def singleton dot_or_colon
1237
1366
  {
1238
- self.comments.push self.lexer.comments
1239
- lexer.lex_state = :expr_fname
1367
+ lexer.lex_state = EXPR_FNAME
1240
1368
  }
1241
1369
  fname
1242
1370
  {
1243
- self.in_single += 1
1371
+ result = [self.in_def, lexer.lineno]
1372
+
1373
+ self.in_single += 1 # TODO: remove?
1374
+
1375
+ self.in_def = true # local_push
1244
1376
  self.env.extend
1245
- lexer.lex_state = :expr_endfn # force for args
1246
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1247
- lexer.cmdarg.stack.replace [false]
1377
+ lexer.cmdarg.push false
1378
+ lexer.cond.push false
1379
+
1380
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1381
+ self.comments.push self.lexer.comments
1248
1382
  }
1249
1383
  f_arglist bodystmt k_end
1250
1384
  {
1251
- line, cmdarg = val[5]
1252
- result = new_defs val
1253
- result[3].line line
1385
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1254
1386
 
1255
- lexer.cmdarg.stack.replace cmdarg
1387
+ result = new_defs val
1256
1388
 
1389
+ lexer.cond.pop # group = local_pop
1390
+ lexer.cmdarg.pop
1257
1391
  self.env.unextend
1392
+ self.in_def = in_def
1393
+
1258
1394
  self.in_single -= 1
1395
+
1396
+ # TODO: restore cur_arg ? what's cur_arg?
1397
+
1259
1398
  self.lexer.comments # we don't care about comments in the body
1260
1399
  }
1261
1400
  | kBREAK
1262
1401
  {
1263
- result = s(:break)
1402
+ (_, line), = val
1403
+ result = s(:break).line line
1264
1404
  }
1265
1405
  | kNEXT
1266
1406
  {
1267
- result = s(:next)
1407
+ (_, line), = val
1408
+ result = s(:next).line line
1268
1409
  }
1269
1410
  | kREDO
1270
1411
  {
1271
- result = s(:redo)
1412
+ (_, line), = val
1413
+ result = s(:redo).line line
1272
1414
  }
1273
1415
  | kRETRY
1274
1416
  {
1275
- result = s(:retry)
1417
+ (_, line), = val
1418
+ result = s(:retry).line line
1276
1419
  }
1277
1420
 
1278
1421
  primary_value: primary
@@ -1311,7 +1454,9 @@ rule
1311
1454
  if_tail: opt_else
1312
1455
  | k_elsif expr_value then compstmt if_tail
1313
1456
  {
1314
- result = s(:if, val[1], val[3], val[4])
1457
+ (_, line), c, _, t, rest = val
1458
+
1459
+ result = s(:if, c, t, rest).line line
1315
1460
  }
1316
1461
 
1317
1462
  opt_else: none
@@ -1334,7 +1479,9 @@ rule
1334
1479
 
1335
1480
  f_marg_list: f_marg
1336
1481
  {
1337
- result = s(:array, val[0])
1482
+ sym, = val
1483
+
1484
+ result = s(:array, sym).line lexer.lineno
1338
1485
  }
1339
1486
  | f_marg_list tCOMMA f_marg
1340
1487
  {
@@ -1408,7 +1555,9 @@ rule
1408
1555
  }
1409
1556
  | f_block_arg
1410
1557
  {
1411
- result = call_args val
1558
+ line = lexer.lineno
1559
+ result = call_args val # TODO: push line down
1560
+ result.line line
1412
1561
  }
1413
1562
 
1414
1563
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1439,7 +1588,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1439
1588
  }
1440
1589
  | f_arg tCOMMA
1441
1590
  {
1442
- result = args val
1591
+ result = args(val) << nil
1443
1592
  }
1444
1593
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1445
1594
  {
@@ -1491,7 +1640,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1491
1640
  }
1492
1641
  | tOROP
1493
1642
  {
1494
- result = s(:args)
1643
+ result = s(:args).line lexer.lineno
1495
1644
  }
1496
1645
  | tPIPE block_param opt_bv_decl tPIPE
1497
1646
  {
@@ -1516,34 +1665,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1516
1665
 
1517
1666
  bvar: tIDENTIFIER
1518
1667
  {
1519
- result = s(:shadow, val[0].to_sym)
1668
+ id, = val
1669
+ line = lexer.lineno
1670
+ result = s(:shadow, id.to_sym).line line
1520
1671
  }
1521
1672
  | f_bad_arg
1522
1673
 
1523
1674
  lambda: {
1524
1675
  self.env.extend :dynamic
1525
- result = self.lexer.lineno
1526
-
1527
- result = lexer.lpar_beg
1676
+ result = [lexer.lineno, lexer.lpar_beg]
1528
1677
  lexer.paren_nest += 1
1529
1678
  lexer.lpar_beg = lexer.paren_nest
1530
1679
  }
1531
1680
  f_larglist
1532
1681
  {
1533
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1682
+ lexer.cmdarg.push false
1534
1683
  }
1535
1684
  lambda_body
1536
1685
  {
1537
- lpar, args, (cmdarg, lineno), body = val
1686
+ (line, lpar), args, _cmdarg, body = val
1538
1687
  lexer.lpar_beg = lpar
1539
1688
 
1540
- lexer.cmdarg.restore cmdarg
1541
- lexer.cmdarg.lexpop
1689
+ lexer.cmdarg.pop
1542
1690
 
1543
- call = new_call nil, :lambda
1691
+ call = s(:lambda).line line
1544
1692
  result = new_iter call, args, body
1545
- result.line = lineno
1546
- self.env.unextend
1693
+ result.line = line
1694
+ self.env.unextend # TODO: dynapush & dynapop
1547
1695
  }
1548
1696
 
1549
1697
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1567,8 +1715,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1567
1715
 
1568
1716
  do_block: k_do_block do_body kEND
1569
1717
  {
1570
- # TODO: maybe fix lineno to kDO's lineno?
1571
- result = val[1]
1718
+ (_, line), iter, _ = val
1719
+ result = iter.line line
1572
1720
  }
1573
1721
 
1574
1722
  block_call: command do_block
@@ -1582,8 +1730,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1582
1730
 
1583
1731
  val = invert_block_call val if inverted? val
1584
1732
 
1585
- result = val[1]
1586
- result.insert 1, val[0]
1733
+ cmd, blk = val
1734
+
1735
+ result = blk
1736
+ result.insert 1, cmd
1587
1737
  }
1588
1738
  | block_call call_op2 operation2 opt_paren_args
1589
1739
  {
@@ -1614,8 +1764,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1614
1764
  }
1615
1765
  paren_args
1616
1766
  {
1617
- args = self.call_args val[2..-1]
1618
- result = val[0].concat args.sexp_body
1767
+ call, lineno, args = val
1768
+
1769
+ result = call.concat args.sexp_body if args
1770
+ result.line lineno
1619
1771
  }
1620
1772
  | primary_value call_op operation2 opt_paren_args
1621
1773
  {
@@ -1643,7 +1795,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1643
1795
  }
1644
1796
  | kSUPER
1645
1797
  {
1646
- result = s(:zsuper)
1798
+ result = s(:zsuper).line lexer.lineno
1647
1799
  }
1648
1800
  | primary_value tLBRACK2 opt_call_args rbracket
1649
1801
  {
@@ -1692,15 +1844,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1692
1844
  }
1693
1845
 
1694
1846
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1695
- { result = lexer.cmdarg.store(false) }
1847
+ { lexer.cmdarg.push false }
1696
1848
  opt_block_param
1697
1849
  bodystmt
1698
1850
  {
1699
- line, cmdarg, param, cmpstmt = val
1851
+ line, _cmdarg, param, cmpstmt = val
1700
1852
 
1701
1853
  result = new_do_body param, cmpstmt, line
1854
+ lexer.cmdarg.pop
1702
1855
  self.env.unextend
1703
- lexer.cmdarg.restore cmdarg
1704
1856
  }
1705
1857
 
1706
1858
  case_body: k_when
@@ -1721,7 +1873,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1721
1873
  (_, line), klasses, var, _, body, rest = val
1722
1874
 
1723
1875
  klasses ||= s(:array)
1724
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1876
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1725
1877
  klasses.line line
1726
1878
 
1727
1879
  result = new_resbody(klasses, body)
@@ -1734,7 +1886,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1734
1886
 
1735
1887
  exc_list: arg_value
1736
1888
  {
1737
- result = s(:array, val[0])
1889
+ arg, = val
1890
+ result = s(:array, arg).line arg.line
1738
1891
  }
1739
1892
  | mrhs
1740
1893
  | none
@@ -1747,26 +1900,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1747
1900
 
1748
1901
  opt_ensure: k_ensure compstmt
1749
1902
  {
1750
- _, body = val
1903
+ (_, line), body = val
1751
1904
 
1752
- result = body || s(:nil)
1905
+ result = body || s(:nil).line(line)
1753
1906
  }
1754
1907
  | none
1755
1908
 
1756
1909
  literal: numeric
1757
1910
  {
1911
+ line = lexer.lineno
1758
1912
  result = s(:lit, val[0])
1913
+ result.line = line
1759
1914
  }
1760
1915
  | symbol
1761
1916
  {
1917
+ line = lexer.lineno
1762
1918
  result = s(:lit, val[0])
1919
+ result.line = line
1763
1920
  }
1764
1921
  | dsym
1765
1922
 
1766
1923
  strings: string
1767
1924
  {
1768
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1769
- result = val[0]
1925
+ str, = val
1926
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1927
+ result = str
1770
1928
  }
1771
1929
 
1772
1930
  string: tCHAR
@@ -1781,7 +1939,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1781
1939
 
1782
1940
  string1: tSTRING_BEG string_contents tSTRING_END
1783
1941
  {
1784
- result = val[1]
1942
+ _, str, (_, func) = val
1943
+
1944
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1945
+
1946
+ result = str
1785
1947
  }
1786
1948
  | tSTRING
1787
1949
  {
@@ -1790,7 +1952,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1790
1952
 
1791
1953
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1792
1954
  {
1793
- result = new_xstring val[1]
1955
+ result = new_xstring val
1956
+ # TODO: dedent?!?! SERIOUSLY?!?
1794
1957
  }
1795
1958
 
1796
1959
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1800,7 +1963,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1800
1963
 
1801
1964
  words: tWORDS_BEG tSPACE tSTRING_END
1802
1965
  {
1803
- result = s(:array)
1966
+ result = s(:array).line lexer.lineno
1804
1967
  }
1805
1968
  | tWORDS_BEG word_list tSTRING_END
1806
1969
  {
@@ -1824,25 +1987,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1824
1987
 
1825
1988
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1826
1989
  {
1827
- result = s(:array)
1990
+ result = s(:array).line lexer.lineno
1828
1991
  }
1829
- | tSYMBOLS_BEG symbol_list tSTRING_END
1992
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1830
1993
  {
1831
- result = val[1]
1994
+ _, line, list, _, = val
1995
+ list.line = line
1996
+ result = list
1832
1997
  }
1833
1998
 
1834
1999
  symbol_list: none
1835
2000
  {
1836
- result = new_symbol_list
2001
+ result = new_symbol_list.line lexer.lineno
1837
2002
  }
1838
2003
  | symbol_list word tSPACE
1839
2004
  {
1840
- result = val[0].dup << new_symbol_list_entry(val)
2005
+ list, * = val
2006
+ result = list.dup << new_symbol_list_entry(val)
1841
2007
  }
1842
2008
 
1843
2009
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1844
2010
  {
1845
- result = s(:array)
2011
+ result = s(:array).line lexer.lineno
1846
2012
  }
1847
2013
  | tQWORDS_BEG qword_list tSTRING_END
1848
2014
  {
@@ -1851,7 +2017,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1851
2017
 
1852
2018
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1853
2019
  {
1854
- result = s(:array)
2020
+ result = s(:array).line lexer.lineno # FIX
1855
2021
  }
1856
2022
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1857
2023
  {
@@ -1878,11 +2044,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1878
2044
 
1879
2045
  string_contents: none
1880
2046
  {
1881
- result = s(:str, "")
2047
+ result = s(:str, "").line lexer.lineno
1882
2048
  }
1883
2049
  | string_contents string_content
1884
2050
  {
1885
- result = literal_concat(val[0], val[1])
2051
+ v1, v2 = val
2052
+ result = literal_concat v1, v2
1886
2053
  }
1887
2054
 
1888
2055
  xstring_contents: none
@@ -1891,7 +2058,8 @@ xstring_contents: none
1891
2058
  }
1892
2059
  | xstring_contents string_content
1893
2060
  {
1894
- result = literal_concat(val[0], val[1])
2061
+ v1, v2 = val
2062
+ result = literal_concat v1, v2
1895
2063
  }
1896
2064
 
1897
2065
  regexp_contents: none
@@ -1900,7 +2068,8 @@ regexp_contents: none
1900
2068
  }
1901
2069
  | regexp_contents string_content
1902
2070
  {
1903
- result = literal_concat(val[0], val[1])
2071
+ v1, v2 = val
2072
+ result = literal_concat v1, v2
1904
2073
  }
1905
2074
 
1906
2075
  string_content: tSTRING_CONTENT
@@ -1912,42 +2081,46 @@ regexp_contents: none
1912
2081
  result = lexer.lex_strterm
1913
2082
 
1914
2083
  lexer.lex_strterm = nil
1915
- lexer.lex_state = :expr_beg
2084
+ lexer.lex_state = EXPR_BEG
1916
2085
  }
1917
2086
  string_dvar
1918
2087
  {
1919
- lexer.lex_strterm = val[1]
1920
- result = s(:evstr, val[2])
2088
+ _, strterm, str = val
2089
+ lexer.lex_strterm = strterm
2090
+ result = s(:evstr, str).line str.line
1921
2091
  }
1922
2092
  | tSTRING_DBEG
1923
2093
  {
1924
2094
  result = [lexer.lex_strterm,
1925
2095
  lexer.brace_nest,
1926
2096
  lexer.string_nest, # TODO: remove
1927
- lexer.cond.store,
1928
- lexer.cmdarg.store,
1929
2097
  lexer.lex_state,
2098
+ lexer.lineno,
1930
2099
  ]
1931
2100
 
2101
+ lexer.cmdarg.push false
2102
+ lexer.cond.push false
2103
+
1932
2104
  lexer.lex_strterm = nil
1933
2105
  lexer.brace_nest = 0
1934
2106
  lexer.string_nest = 0
1935
2107
 
1936
- lexer.lex_state = :expr_beg
2108
+ lexer.lex_state = EXPR_BEG
1937
2109
  }
1938
2110
  compstmt
1939
2111
  tSTRING_DEND
1940
2112
  {
1941
2113
  _, memo, stmt, _ = val
1942
2114
 
1943
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2115
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2116
+ # TODO: heredoc_indent
1944
2117
 
1945
2118
  lexer.lex_strterm = lex_strterm
1946
2119
  lexer.brace_nest = brace_nest
1947
2120
  lexer.string_nest = string_nest
1948
2121
 
1949
- lexer.cond.restore oldcond
1950
- lexer.cmdarg.restore oldcmdarg
2122
+ lexer.cmdarg.pop
2123
+ lexer.cond.pop
1951
2124
 
1952
2125
  lexer.lex_state = oldlex_state
1953
2126
 
@@ -1957,24 +2130,24 @@ regexp_contents: none
1957
2130
  when :str, :dstr, :evstr then
1958
2131
  result = stmt
1959
2132
  else
1960
- result = s(:evstr, stmt)
2133
+ result = s(:evstr, stmt).line line
1961
2134
  end
1962
2135
  when nil then
1963
- result = s(:evstr)
2136
+ result = s(:evstr).line line
1964
2137
  else
1965
2138
  debug20 25
1966
2139
  raise "unknown string body: #{stmt.inspect}"
1967
2140
  end
1968
2141
  }
1969
2142
 
1970
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1971
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1972
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2143
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2144
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2145
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
1973
2146
  | backref
1974
2147
 
1975
2148
  symbol: tSYMBEG sym
1976
2149
  {
1977
- lexer.lex_state = :expr_end
2150
+ lexer.lex_state = EXPR_END
1978
2151
  result = val[1].to_sym
1979
2152
  }
1980
2153
  | tSYMBOL
@@ -1986,18 +2159,19 @@ regexp_contents: none
1986
2159
 
1987
2160
  dsym: tSYMBEG xstring_contents tSTRING_END
1988
2161
  {
1989
- lexer.lex_state = :expr_end
1990
- result = val[1]
2162
+ _, result, _ = val
2163
+
2164
+ lexer.lex_state = EXPR_END
1991
2165
 
1992
- result ||= s(:str, "")
2166
+ result ||= s(:str, "").line lexer.lineno
1993
2167
 
1994
2168
  case result.sexp_type
1995
2169
  when :dstr then
1996
2170
  result.sexp_type = :dsym
1997
2171
  when :str then
1998
- result = s(:lit, result.last.to_sym)
2172
+ result = s(:lit, result.last.to_sym).line result.line
1999
2173
  when :evstr then
2000
- result = s(:dsym, "", result)
2174
+ result = s(:dsym, "", result).line result.line
2001
2175
  else
2002
2176
  debug20 26, val, result
2003
2177
  end
@@ -2020,19 +2194,20 @@ regexp_contents: none
2020
2194
  | tCONSTANT
2021
2195
  | tCVAR
2022
2196
 
2023
- keyword_variable: kNIL { result = s(:nil) }
2024
- | kSELF { result = s(:self) }
2025
- | kTRUE { result = s(:true) }
2026
- | kFALSE { result = s(:false) }
2027
- | k__FILE__ { result = s(:str, self.file) }
2028
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2197
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2198
+ | kSELF { result = s(:self).line lexer.lineno }
2199
+ | kTRUE { result = s(:true).line lexer.lineno }
2200
+ | kFALSE { result = s(:false).line lexer.lineno }
2201
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2202
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2029
2203
  | k__ENCODING__
2030
2204
  {
2205
+ l = lexer.lineno
2031
2206
  result =
2032
2207
  if defined? Encoding then
2033
- s(:colon2, s(:const, :Encoding), :UTF_8)
2208
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2034
2209
  else
2035
- s(:str, "Unsupported!")
2210
+ s(:str, "Unsupported!").line l
2036
2211
  end
2037
2212
  }
2038
2213
 
@@ -2057,12 +2232,12 @@ keyword_variable: kNIL { result = s(:nil) }
2057
2232
  debug20 29, val, result
2058
2233
  }
2059
2234
 
2060
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2061
- | tBACK_REF { result = s(:back_ref, val[0]) }
2235
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2236
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2062
2237
 
2063
2238
  superclass: tLT
2064
2239
  {
2065
- lexer.lex_state = :expr_beg
2240
+ lexer.lex_state = EXPR_BEG
2066
2241
  lexer.command_start = true
2067
2242
  }
2068
2243
  expr_value term
@@ -2077,13 +2252,13 @@ keyword_variable: kNIL { result = s(:nil) }
2077
2252
  f_arglist: tLPAREN2 f_args rparen
2078
2253
  {
2079
2254
  result = val[1]
2080
- self.lexer.lex_state = :expr_beg
2255
+ self.lexer.lex_state = EXPR_BEG
2081
2256
  self.lexer.command_start = true
2082
2257
  }
2083
2258
  | {
2084
2259
  result = self.in_kwarg
2085
2260
  self.in_kwarg = true
2086
- # TODO: self.lexer.lex_state |= :expr_label
2261
+ self.lexer.lex_state |= EXPR_LABEL
2087
2262
  }
2088
2263
  f_args term
2089
2264
  {
@@ -2091,7 +2266,7 @@ keyword_variable: kNIL { result = s(:nil) }
2091
2266
 
2092
2267
  self.in_kwarg = kwarg
2093
2268
  result = args
2094
- lexer.lex_state = :expr_beg
2269
+ lexer.lex_state = EXPR_BEG
2095
2270
  lexer.command_start = true
2096
2271
  }
2097
2272
 
@@ -2215,12 +2390,13 @@ keyword_variable: kNIL { result = s(:nil) }
2215
2390
 
2216
2391
  f_arg: f_arg_item
2217
2392
  {
2218
- case val[0]
2393
+ arg, = val
2394
+
2395
+ case arg
2219
2396
  when Symbol then
2220
- result = s(:args)
2221
- result << val[0]
2397
+ result = s(:args, arg).line lexer.lineno
2222
2398
  when Sexp then
2223
- result = val[0]
2399
+ result = arg
2224
2400
  else
2225
2401
  debug20 32
2226
2402
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2233,7 +2409,7 @@ keyword_variable: kNIL { result = s(:nil) }
2233
2409
  if list.sexp_type == :args then
2234
2410
  result = list
2235
2411
  else
2236
- result = s(:args, list)
2412
+ result = s(:args, list).line list.line
2237
2413
  end
2238
2414
 
2239
2415
  result << item
@@ -2243,38 +2419,42 @@ keyword_variable: kNIL { result = s(:nil) }
2243
2419
 
2244
2420
  f_kw: f_label arg_value
2245
2421
  {
2246
- # TODO: call_args
2247
- label, _ = val[0] # TODO: fix lineno?
2422
+ # TODO: new_kw_arg
2423
+ (label, line), arg = val
2424
+
2248
2425
  identifier = label.to_sym
2249
2426
  self.env[identifier] = :lvar
2250
2427
 
2251
- result = s(:array, s(:kwarg, identifier, val[1]))
2428
+ kwarg = s(:kwarg, identifier, arg).line line
2429
+ result = s(:array, kwarg).line line
2252
2430
  }
2253
2431
  | f_label
2254
2432
  {
2255
- label, _ = val[0] # TODO: fix lineno?
2256
- identifier = label.to_sym
2257
- self.env[identifier] = :lvar
2433
+ (label, line), = val
2258
2434
 
2259
- result = s(:array, s(:kwarg, identifier))
2435
+ id = label.to_sym
2436
+ self.env[id] = :lvar
2437
+
2438
+ result = s(:array, s(:kwarg, id).line(line)).line line
2260
2439
  }
2261
2440
 
2262
2441
  f_block_kw: f_label primary_value
2263
2442
  {
2264
- # TODO: call_args
2265
- label, _ = val[0] # TODO: fix lineno?
2266
- identifier = label.to_sym
2267
- self.env[identifier] = :lvar
2443
+ # TODO: new_kw_arg
2444
+ (label, line), expr = val
2445
+ id = label.to_sym
2446
+ self.env[id] = :lvar
2268
2447
 
2269
- result = s(:array, s(:kwarg, identifier, val[1]))
2448
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2270
2449
  }
2271
2450
  | f_label
2272
2451
  {
2273
- label, _ = val[0] # TODO: fix lineno?
2274
- identifier = label.to_sym
2275
- self.env[identifier] = :lvar
2452
+ # TODO: new_kw_arg
2453
+ (label, line), = val
2454
+ id = label.to_sym
2455
+ self.env[id] = :lvar
2276
2456
 
2277
- result = s(:array, s(:kwarg, identifier))
2457
+ result = s(:array, s(:kwarg, id).line(line)).line line
2278
2458
  }
2279
2459
 
2280
2460
  f_block_kwarg: f_block_kw
@@ -2317,17 +2497,20 @@ keyword_variable: kNIL { result = s(:nil) }
2317
2497
 
2318
2498
  f_block_optarg: f_block_opt
2319
2499
  {
2320
- result = s(:block, val[0])
2500
+ optblk, = val
2501
+ result = s(:block, optblk).line optblk.line
2321
2502
  }
2322
2503
  | f_block_optarg tCOMMA f_block_opt
2323
2504
  {
2324
- result = val[0]
2325
- result << val[2]
2505
+ optarg, _, optblk = val
2506
+ result = optarg
2507
+ result << optblk
2326
2508
  }
2327
2509
 
2328
2510
  f_optarg: f_opt
2329
2511
  {
2330
- result = s(:block, val[0])
2512
+ opt, = val
2513
+ result = s(:block, opt).line opt.line
2331
2514
  }
2332
2515
  | f_optarg tCOMMA f_opt
2333
2516
  {
@@ -2372,7 +2555,7 @@ keyword_variable: kNIL { result = s(:nil) }
2372
2555
  singleton: var_ref
2373
2556
  | tLPAREN2
2374
2557
  {
2375
- lexer.lex_state = :expr_beg
2558
+ lexer.lex_state = EXPR_BEG
2376
2559
  }
2377
2560
  expr rparen
2378
2561
  {
@@ -2381,14 +2564,11 @@ keyword_variable: kNIL { result = s(:nil) }
2381
2564
  result.sexp_type == :lit
2382
2565
  }
2383
2566
 
2384
- assoc_list: none # [!nil]
2567
+ assoc_list: none
2385
2568
  {
2386
- result = s(:array)
2387
- }
2388
- | assocs trailer # [!nil]
2389
- {
2390
- result = val[0]
2569
+ result = s(:array).line lexer.lineno
2391
2570
  }
2571
+ | assocs trailer
2392
2572
 
2393
2573
  assocs: assoc
2394
2574
  | assocs tCOMMA assoc
@@ -2402,22 +2582,27 @@ keyword_variable: kNIL { result = s(:nil) }
2402
2582
 
2403
2583
  assoc: arg_value tASSOC arg_value
2404
2584
  {
2405
- result = s(:array, val[0], val[2])
2585
+ v1, _, v2 = val
2586
+ result = s(:array, v1, v2).line v1.line
2406
2587
  }
2407
2588
  | tLABEL arg_value
2408
2589
  {
2409
- (label, _), arg = val
2410
- result = s(:array, s(:lit, label.to_sym), arg)
2590
+ (label, line), arg = val
2591
+
2592
+ lit = s(:lit, label.to_sym).line line
2593
+ result = s(:array, lit, arg).line line
2411
2594
  }
2412
2595
  | tSTRING_BEG string_contents tLABEL_END arg_value
2413
2596
  {
2414
2597
  _, sym, _, value = val
2415
2598
  sym.sexp_type = :dsym
2416
- result = s(:array, sym, value)
2599
+ result = s(:array, sym, value).line sym.line
2417
2600
  }
2418
2601
  | tDSTAR arg_value
2419
2602
  {
2420
- result = s(:array, s(:kwsplat, val[1]))
2603
+ _, arg = val
2604
+ line = arg.line
2605
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2421
2606
  }
2422
2607
 
2423
2608
  operation: tIDENTIFIER | tCONSTANT | tFID
@@ -2449,6 +2634,7 @@ end
2449
2634
 
2450
2635
  require "ruby_lexer"
2451
2636
  require "ruby_parser_extras"
2637
+ include RubyLexer::State::Values
2452
2638
 
2453
2639
  # :stopdoc:
2454
2640