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.
@@ -21,35 +21,35 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
21
21
  tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
22
22
  tRATIONAL tIMAGINARY
23
23
 
24
- prechigh
25
- right tBANG tTILDE tUPLUS
26
- right tPOW
27
- right tUMINUS_NUM tUMINUS
28
- left tSTAR2 tDIVIDE tPERCENT
29
- left tPLUS tMINUS
30
- left tLSHFT tRSHFT
31
- left tAMPER2
32
- left tPIPE tCARET
33
- left tGT tGEQ tLT tLEQ
34
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
35
- left tANDOP
36
- left tOROP
37
- nonassoc tDOT2 tDOT3
38
- right tEH tCOLON
39
- left kRESCUE_MOD
40
- right tEQL tOP_ASGN
41
- nonassoc kDEFINED
42
- right kNOT
43
- left kOR kAND
44
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
45
- nonassoc tLBRACE_ARG
46
- nonassoc tLOWEST
47
24
  preclow
25
+ nonassoc tLOWEST
26
+ nonassoc tLBRACE_ARG
27
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
28
+ left kOR kAND
29
+ right kNOT
30
+ nonassoc kDEFINED
31
+ right tEQL tOP_ASGN
32
+ left kRESCUE_MOD
33
+ right tEH tCOLON
34
+ nonassoc tDOT2 tDOT3
35
+ left tOROP
36
+ left tANDOP
37
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
38
+ left tGT tGEQ tLT tLEQ
39
+ left tPIPE tCARET
40
+ left tAMPER2
41
+ left tLSHFT tRSHFT
42
+ left tPLUS tMINUS
43
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
44
+ right tUMINUS_NUM tUMINUS
45
+ right tPOW
46
+ right tBANG tTILDE tUPLUS
47
+ prechigh
48
48
 
49
49
  rule
50
50
 
51
51
  program: {
52
- self.lexer.lex_state = :expr_beg
52
+ self.lexer.lex_state = EXPR_BEG
53
53
  }
54
54
  top_compstmt
55
55
  {
@@ -58,7 +58,8 @@ rule
58
58
 
59
59
  top_compstmt: top_stmts opt_terms
60
60
  {
61
- result = val[0]
61
+ stmt, _ = val
62
+ result = stmt
62
63
  }
63
64
 
64
65
  top_stmts: none
@@ -70,14 +71,6 @@ rule
70
71
  | error top_stmt
71
72
 
72
73
  top_stmt: stmt
73
- {
74
- result = val[0]
75
-
76
- # TODO: remove once I have more confidence this is fixed
77
- # result.each_of_type :call_args do |s|
78
- # debug20 666, s, result
79
- # end
80
- }
81
74
  | klBEGIN
82
75
  {
83
76
  if (self.in_def || self.in_single > 0) then
@@ -88,14 +81,19 @@ rule
88
81
  }
89
82
  begin_block
90
83
  {
91
- _, _, block = val
92
- result = block
84
+ (_, lineno), _, iter = val
85
+ iter.line lineno
86
+
87
+ (_, preexe,) = iter
88
+ preexe.line lineno
89
+
90
+ result = iter
93
91
  }
94
92
 
95
- begin_block: tLCURLY top_compstmt tRCURLY
93
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
96
94
  {
97
- _, stmt, _ = val
98
- result = new_iter s(:preexe), 0, stmt
95
+ _, line, stmt, _ = val
96
+ result = new_iter s(:preexe).line(line), 0, stmt
99
97
  }
100
98
 
101
99
  bodystmt: compstmt opt_rescue k_else
@@ -137,34 +135,27 @@ rule
137
135
  stmt_or_begin: stmt
138
136
  | klBEGIN
139
137
  {
140
- if (self.in_def || self.in_single > 0) then
141
- debug20 1
142
- yyerror "BEGIN in method"
143
- end
144
- self.env.extend
145
- }
146
- begin_block
147
- {
148
- _, _, stmt = val
149
- result = stmt
138
+ yyerror "BEGIN is permitted only at toplevel"
150
139
  }
151
140
 
152
141
  stmt: kALIAS fitem
153
142
  {
154
- lexer.lex_state = :expr_fname
155
- result = self.lexer.lineno
143
+ lexer.lex_state = EXPR_FNAME
156
144
  }
157
145
  fitem
158
146
  {
159
- result = s(:alias, val[1], val[3]).line(val[2])
147
+ (_, line), lhs, _, rhs = val
148
+ result = s(:alias, lhs, rhs).line(line).line line
160
149
  }
161
150
  | kALIAS tGVAR tGVAR
162
151
  {
163
- result = s(:valias, val[1].to_sym, val[2].to_sym)
152
+ (_, line), lhs, rhs = val
153
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
164
154
  }
165
155
  | kALIAS tGVAR tBACK_REF
166
156
  {
167
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
157
+ (_, line), lhs, rhs = val
158
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
168
159
  }
169
160
  | kALIAS tGVAR tNTH_REF
170
161
  {
@@ -176,32 +167,41 @@ rule
176
167
  }
177
168
  | stmt kIF_MOD expr_value
178
169
  {
179
- result = new_if val[2], val[0], nil
170
+ t, _, c = val
171
+ result = new_if c, t, nil
180
172
  }
181
173
  | stmt kUNLESS_MOD expr_value
182
174
  {
183
- result = new_if val[2], nil, val[0]
175
+ f, _, c = val
176
+ result = new_if c, nil, f
184
177
  }
185
178
  | stmt kWHILE_MOD expr_value
186
179
  {
187
- result = new_while val[0], val[2], true
180
+ e, _, c = val
181
+ result = new_while e, c, true
188
182
  }
189
183
  | stmt kUNTIL_MOD expr_value
190
184
  {
191
- result = new_until val[0], val[2], true
185
+ e, _, c = val
186
+ result = new_until e, c, true
192
187
  }
193
188
  | stmt kRESCUE_MOD stmt
194
189
  {
195
190
  body, _, resbody = val
196
- result = new_rescue body, new_resbody(s(:array), resbody)
191
+
192
+ resbody = new_resbody s(:array).line(resbody.line), resbody
193
+ result = new_rescue body, resbody
197
194
  }
198
195
  | klEND tLCURLY compstmt tRCURLY
199
196
  {
197
+ (_, line), _, stmt, _ = val
198
+
200
199
  if (self.in_def || self.in_single > 0) then
201
200
  debug20 3
202
201
  yyerror "END in method; use at_exit"
203
202
  end
204
- result = new_iter s(:postexe), 0, val[2]
203
+
204
+ result = new_iter s(:postexe).line(line), 0, stmt
205
205
  }
206
206
  | command_asgn
207
207
  | mlhs tEQL command_call
@@ -210,7 +210,8 @@ rule
210
210
  }
211
211
  | lhs tEQL mrhs
212
212
  {
213
- result = new_assign val[0], s(:svalue, val[2])
213
+ lhs, _, rhs = val
214
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
214
215
  }
215
216
  | mlhs tEQL mrhs_arg
216
217
  {
@@ -232,11 +233,12 @@ rule
232
233
  }
233
234
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
234
235
  {
235
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
236
+ result = new_op_asgn1 val
236
237
  }
237
238
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
238
239
  {
239
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
240
+ prim, _, id, opasgn, rhs = val
241
+ result = s(:op_asgn, prim, rhs, id.to_sym, opasgn.to_sym)
240
242
  if val[1] == '&.'
241
243
  result.sexp_type = :safe_op_asgn
242
244
  end
@@ -252,13 +254,15 @@ rule
252
254
  }
253
255
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
254
256
  {
255
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
256
- debug20 4, val, result
257
+ lhs1, _, lhs2, op, rhs = val
258
+
259
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
257
260
  }
258
261
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
259
262
  {
260
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
261
- debug20 5, val, result
263
+ lhs1, _, lhs2, op, rhs = val
264
+
265
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, op.to_sym)
262
266
  }
263
267
  | backref tOP_ASGN command_rhs
264
268
  {
@@ -270,30 +274,31 @@ rule
270
274
  expr, = val
271
275
  result = value_expr expr
272
276
  }
273
- | command_call kRESCUE_MOD stmt
274
- {
275
- expr, _, resbody = val
276
- expr = value_expr expr
277
- result = new_rescue(expr, new_resbody(s(:array), resbody))
278
- }
279
277
  | command_asgn
280
278
 
281
279
  expr: command_call
282
280
  | expr kAND expr
283
281
  {
284
- result = logical_op :and, val[0], val[2]
282
+ lhs, _, rhs = val
283
+ result = logical_op :and, lhs, rhs
285
284
  }
286
285
  | expr kOR expr
287
286
  {
288
- result = logical_op :or, val[0], val[2]
287
+ lhs, _, rhs = val
288
+ result = logical_op :or, lhs, rhs
289
289
  }
290
290
  | kNOT opt_nl expr
291
291
  {
292
- result = s(:call, val[2], :"!")
292
+ (_, line), _, expr = val
293
+ result = new_call(expr, :"!").line line
294
+ # REFACTOR: call_uni_op
293
295
  }
294
296
  | tBANG command_call
295
297
  {
296
- result = s(:call, val[1], :"!")
298
+ _, cmd = val
299
+ result = new_call(cmd, :"!").line cmd.line
300
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
301
+ # REFACTOR: call_uni_op -- see parse26.y
297
302
  }
298
303
  | arg
299
304
 
@@ -320,7 +325,8 @@ rule
320
325
  block_command: block_call
321
326
  | block_call call_op2 operation2 command_args
322
327
  {
323
- result = new_call val[0], val[2].to_sym, val[3]
328
+ blk, _, msg, args = val
329
+ result = new_call(blk, msg.to_sym, args).line blk.line
324
330
  }
325
331
 
326
332
  cmd_brace_block: tLBRACE_ARG
@@ -340,26 +346,32 @@ rule
340
346
 
341
347
  fcall: operation
342
348
  {
343
- result = new_call nil, val[0].to_sym
349
+ msg, = val
350
+ result = new_call(nil, msg.to_sym).line lexer.lineno
344
351
  }
345
352
 
346
353
  command: fcall command_args =tLOWEST
347
354
  {
348
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
355
+ call, args = val
356
+ result = call.concat args.sexp_body
349
357
  }
350
358
  | fcall command_args cmd_brace_block
351
359
  {
352
- result = val[0].concat val[1].sexp_body
353
- if val[2] then
354
- block_dup_check result, val[2]
360
+ call, args, block = val
361
+
362
+ result = call.concat args.sexp_body
363
+
364
+ if block then
365
+ block_dup_check result, block
355
366
 
356
- result, operation = val[2], result
367
+ result, operation = block, result
357
368
  result.insert 1, operation
358
369
  end
359
370
  }
360
371
  | primary_value call_op operation2 command_args =tLOWEST
361
372
  {
362
- result = new_call val[0], val[2].to_sym, val[3], val[1]
373
+ lhs, callop, op, args = val
374
+ result = new_call lhs, op.to_sym, args, callop
363
375
  }
364
376
  | primary_value call_op operation2 command_args cmd_brace_block
365
377
  {
@@ -391,7 +403,9 @@ rule
391
403
  }
392
404
  | kYIELD command_args
393
405
  {
394
- result = new_yield val[1]
406
+ (_, line), args = val
407
+ result = new_yield args
408
+ result.line line # TODO: push to new_yield
395
409
  }
396
410
  | k_return call_args
397
411
  {
@@ -400,8 +414,8 @@ rule
400
414
  }
401
415
  | kBREAK call_args
402
416
  {
403
- line = val[0].last
404
- result = s(:break, ret_args(val[1])).line(line)
417
+ (_, line), args = val
418
+ result = s(:break, ret_args(args)).line line
405
419
  }
406
420
  | kNEXT call_args
407
421
  {
@@ -418,56 +432,79 @@ rule
418
432
  mlhs_inner: mlhs_basic
419
433
  | tLPAREN mlhs_inner rparen
420
434
  {
421
- result = s(:masgn, s(:array, val[1]))
435
+ _, arg, _ = val
436
+ l = arg.line
437
+
438
+ result = s(:masgn, s(:array, arg).line(l)).line l
422
439
  }
423
440
 
424
441
  mlhs_basic: mlhs_head
425
442
  {
426
- result = s(:masgn, val[0])
443
+ head, = val
444
+ result = s(:masgn, head).line head.line
427
445
  }
428
446
  | mlhs_head mlhs_item
429
447
  {
430
- result = s(:masgn, val[0] << val[1].compact)
448
+ lhs, rhs = val
449
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
431
450
  }
432
451
  | mlhs_head tSTAR mlhs_node
433
452
  {
434
- result = s(:masgn, val[0] << s(:splat, val[2]))
453
+ head, _, tail = val
454
+ head << s(:splat, tail).line(tail.line)
455
+ result = s(:masgn, head).line head.line
435
456
  }
436
457
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
437
458
  {
438
459
  ary1, _, splat, _, ary2 = val
439
460
 
440
- result = list_append ary1, s(:splat, splat)
461
+ result = list_append ary1, s(:splat, splat).line(splat.line)
441
462
  result.concat ary2.sexp_body
442
- result = s(:masgn, result)
463
+ result = s(:masgn, result).line result.line
443
464
  }
444
465
  | mlhs_head tSTAR
445
466
  {
446
- result = s(:masgn, val[0] << s(:splat))
467
+ head, _ = val
468
+ l = head.line
469
+ result = s(:masgn, head << s(:splat).line(l)).line l
447
470
  }
448
471
  | mlhs_head tSTAR tCOMMA mlhs_post
449
472
  {
450
- ary = list_append val[0], s(:splat)
451
- ary.concat val[3].sexp_body
452
- result = s(:masgn, ary)
473
+ head, _, _, post = val
474
+ ary = list_append head, s(:splat).line(head.line)
475
+ ary.concat post.sexp_body
476
+ result = s(:masgn, ary).line ary.line
453
477
  }
454
478
  | tSTAR mlhs_node
455
479
  {
456
- result = s(:masgn, s(:array, s(:splat, val[1])))
480
+ _, node = val
481
+ l = node.line
482
+ splat = s(:splat, node).line l
483
+ ary = s(:array, splat).line l
484
+ result = s(:masgn, ary).line l
457
485
  }
458
486
  | tSTAR mlhs_node tCOMMA mlhs_post
459
487
  {
460
- ary = s(:array, s(:splat, val[1]))
461
- ary.concat val[3].sexp_body
462
- result = s(:masgn, ary)
488
+ _, node, _, post = val
489
+
490
+ splat = s(:splat, node).line node.line
491
+ ary = s(:array, splat).line splat.line
492
+ ary.concat post.sexp_body
493
+ result = s(:masgn, ary).line ary.line
463
494
  }
464
495
  | tSTAR
465
496
  {
466
- result = s(:masgn, s(:array, s(:splat)))
497
+ l = lexer.lineno
498
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
467
499
  }
468
500
  | tSTAR tCOMMA mlhs_post
469
501
  {
470
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
502
+ _, _, post = val
503
+ l = post.line
504
+
505
+ splat = s(:splat).line l
506
+ ary = s(:array, splat, *post.sexp_body).line l
507
+ result = s(:masgn, ary).line l
471
508
  }
472
509
 
473
510
  mlhs_item: mlhs_node
@@ -478,7 +515,8 @@ rule
478
515
 
479
516
  mlhs_head: mlhs_item tCOMMA
480
517
  {
481
- result = s(:array, val[0])
518
+ lhs, _ = val
519
+ result = s(:array, lhs).line lhs.line
482
520
  }
483
521
  | mlhs_head mlhs_item tCOMMA
484
522
  {
@@ -487,7 +525,8 @@ rule
487
525
 
488
526
  mlhs_post: mlhs_item
489
527
  {
490
- result = s(:array, val[0])
528
+ item, = val
529
+ result = s(:array, item).line item.line
491
530
  }
492
531
  | mlhs_post tCOMMA mlhs_item
493
532
  {
@@ -512,7 +551,8 @@ rule
512
551
  }
513
552
  | primary_value tCOLON2 tIDENTIFIER
514
553
  {
515
- result = s(:attrasgn, val[0], :"#{val[2]}=")
554
+ recv, _, id = val
555
+ result = new_attrasgn recv, id
516
556
  }
517
557
  | primary_value call_op tCONSTANT
518
558
  {
@@ -525,7 +565,10 @@ rule
525
565
  yyerror "dynamic constant assignment"
526
566
  end
527
567
 
528
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
568
+ expr, _, id = val
569
+ l = expr.line
570
+
571
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
529
572
  }
530
573
  | tCOLON3 tCONSTANT
531
574
  {
@@ -534,7 +577,10 @@ rule
534
577
  yyerror "dynamic constant assignment"
535
578
  end
536
579
 
537
- result = s(:const, nil, s(:colon3, val[1].to_sym))
580
+ _, id = val
581
+ l = lexer.lineno
582
+
583
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
538
584
  }
539
585
  | backref
540
586
  {
@@ -543,24 +589,31 @@ rule
543
589
 
544
590
  lhs: user_variable
545
591
  {
592
+ line = lexer.lineno
546
593
  result = self.assignable val[0]
594
+ result.line = line
547
595
  }
548
596
  | keyword_variable
549
597
  {
598
+ line = lexer.lineno
550
599
  result = self.assignable val[0]
600
+ result.line = line
551
601
  debug20 9, val, result
552
602
  }
553
603
  | primary_value tLBRACK2 opt_call_args rbracket
554
604
  {
555
- result = self.aryset val[0], val[2]
605
+ lhs, _, args, _ = val
606
+ result = self.aryset lhs, args
556
607
  }
557
608
  | primary_value call_op tIDENTIFIER # REFACTOR
558
609
  {
559
- result = new_attrasgn val[0], val[2], val[1]
610
+ lhs, op, id = val
611
+ result = new_attrasgn lhs, id, op
560
612
  }
561
613
  | primary_value tCOLON2 tIDENTIFIER
562
614
  {
563
- result = s(:attrasgn, val[0], :"#{val[2]}=")
615
+ lhs, _, id = val
616
+ result = new_attrasgn lhs, id
564
617
  }
565
618
  | primary_value call_op tCONSTANT # REFACTOR?
566
619
  {
@@ -568,21 +621,27 @@ rule
568
621
  }
569
622
  | primary_value tCOLON2 tCONSTANT
570
623
  {
624
+ expr, _, id = val
625
+
571
626
  if (self.in_def || self.in_single > 0) then
572
627
  debug20 10
573
628
  yyerror "dynamic constant assignment"
574
629
  end
575
630
 
576
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
631
+ l = expr.line
632
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
577
633
  }
578
634
  | tCOLON3 tCONSTANT
579
635
  {
636
+ _, id = val
637
+
580
638
  if (self.in_def || self.in_single > 0) then
581
639
  debug20 11
582
640
  yyerror "dynamic constant assignment"
583
641
  end
584
642
 
585
- result = s(:const, s(:colon3, val[1].to_sym))
643
+ l = lexer.lineno
644
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
586
645
  }
587
646
  | backref
588
647
  {
@@ -597,7 +656,8 @@ rule
597
656
 
598
657
  cpath: tCOLON3 cname
599
658
  {
600
- result = s(:colon3, val[1].to_sym)
659
+ _, name = val
660
+ result = s(:colon3, name.to_sym).line lexer.lineno
601
661
  }
602
662
  | cname
603
663
  {
@@ -605,20 +665,23 @@ rule
605
665
  }
606
666
  | primary_value tCOLON2 cname
607
667
  {
608
- result = s(:colon2, val[0], val[2].to_sym)
668
+ pval, _, name = val
669
+
670
+ result = s(:colon2, pval, name.to_sym)
671
+ result.line pval.line
609
672
  }
610
673
 
611
674
  fname: tIDENTIFIER | tCONSTANT | tFID
612
675
  | op
613
676
  {
614
- lexer.lex_state = :expr_end
677
+ lexer.lex_state = EXPR_END
615
678
  result = val[0]
616
679
  }
617
680
 
618
681
  | reswords
619
682
  {
620
683
  (sym, _line), = val
621
- lexer.lex_state = :expr_end
684
+ lexer.lex_state = EXPR_END
622
685
  result = sym
623
686
  }
624
687
 
@@ -626,7 +689,8 @@ rule
626
689
 
627
690
  fitem: fsym
628
691
  {
629
- result = s(:lit, val[0].to_sym)
692
+ id, = val
693
+ result = s(:lit, id.to_sym).line lexer.lineno
630
694
  }
631
695
  | dsym
632
696
 
@@ -637,7 +701,7 @@ rule
637
701
  |
638
702
  undef_list tCOMMA
639
703
  {
640
- lexer.lex_state = :expr_fname
704
+ lexer.lex_state = EXPR_FNAME
641
705
  }
642
706
  fitem
643
707
  {
@@ -649,6 +713,7 @@ rule
649
713
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
650
714
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
651
715
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
716
+ # TODO: tUBANG dead?
652
717
  | tUBANG
653
718
 
654
719
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
@@ -671,8 +736,7 @@ rule
671
736
  }
672
737
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
673
738
  {
674
- val[2].sexp_type = :arglist if val[2]
675
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
739
+ result = new_op_asgn1 val
676
740
  }
677
741
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
678
742
  {
@@ -684,17 +748,27 @@ rule
684
748
  }
685
749
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
686
750
  {
687
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
751
+ lhs, _, id, op, rhs = val
752
+
753
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
688
754
  }
689
755
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
690
756
  {
691
- # TODO: assignment
692
- raise "not yet: %p" % [val]
757
+ lhs1, _, lhs2, op, rhs = val
758
+
759
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
760
+ result = new_const_op_asgn [lhs, op, rhs]
761
+ }
762
+ | tCOLON3 tCONSTANT
763
+ {
764
+ result = self.lexer.lineno
693
765
  }
694
- | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
766
+ tOP_ASGN arg_rhs
695
767
  {
696
- # TODO: assignment
697
- raise "not yet: %p" % [val]
768
+ _, lhs, line, op, rhs = val
769
+
770
+ lhs = s(:colon3, lhs.to_sym).line line
771
+ result = new_const_op_asgn [lhs, op, rhs]
698
772
  }
699
773
  | backref tOP_ASGN arg_rhs
700
774
  {
@@ -706,18 +780,18 @@ rule
706
780
  {
707
781
  v1, v2 = val[0], val[2]
708
782
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
709
- result = s(:lit, (v1.last)..(v2.last))
783
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
710
784
  else
711
- result = s(:dot2, v1, v2)
785
+ result = s(:dot2, v1, v2).line v1.line
712
786
  end
713
787
  }
714
788
  | arg tDOT3 arg
715
789
  {
716
790
  v1, v2 = val[0], val[2]
717
791
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
718
- result = s(:lit, (v1.last)...(v2.last))
792
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
719
793
  else
720
- result = s(:dot3, v1, v2)
794
+ result = s(:dot3, v1, v2).line v1.line
721
795
  end
722
796
  }
723
797
  | arg tPLUS arg
@@ -746,7 +820,9 @@ rule
746
820
  }
747
821
  | tUMINUS_NUM simple_numeric tPOW arg
748
822
  {
749
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
823
+ lit = s(:lit, val[1]).line lexer.lineno
824
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
825
+
750
826
  }
751
827
  | tUPLUS arg
752
828
  {
@@ -787,15 +863,19 @@ rule
787
863
  }
788
864
  | arg tMATCH arg
789
865
  {
790
- result = new_match val[0], val[2]
866
+ lhs, _, rhs = val
867
+ result = new_match lhs, rhs
791
868
  }
792
869
  | arg tNMATCH arg
793
870
  {
794
- result = s(:not, new_match(val[0], val[2]))
871
+ lhs, _, rhs = val
872
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
795
873
  }
796
874
  | tBANG arg
797
875
  {
798
- result = new_call val[1], :"!"
876
+ _, arg = val
877
+ result = new_call arg, :"!"
878
+ result.line arg.line
799
879
  }
800
880
  | tTILDE arg
801
881
  {
@@ -823,11 +903,13 @@ rule
823
903
  }
824
904
  | kDEFINED opt_nl arg
825
905
  {
826
- result = s(:defined, val[2])
906
+ (_, line), _, arg = val
907
+ result = s(:defined, arg).line line
827
908
  }
828
909
  | arg tEH arg opt_nl tCOLON arg
829
910
  {
830
- result = s(:if, val[0], val[2], val[5])
911
+ c, _, t, _, _, f = val
912
+ result = s(:if, c, t, f).line c.line
831
913
  }
832
914
  | primary
833
915
 
@@ -870,28 +952,25 @@ rule
870
952
  arg_rhs: arg =tOP_ASGN
871
953
  | arg kRESCUE_MOD arg
872
954
  {
873
- body, _, resbody = val
955
+ body, (_, line), resbody = val
874
956
  body = value_expr body
875
957
  resbody = remove_begin resbody
876
- result = new_rescue(body, new_resbody(s(:array), resbody))
958
+
959
+ ary = s(:array).line line
960
+ result = new_rescue(body, new_resbody(ary, resbody))
877
961
  }
878
962
 
879
963
  paren_args: tLPAREN2 opt_call_args rparen
880
964
  {
881
- result = val[1]
965
+ _, args, _ = val
966
+ result = args
882
967
  }
883
968
 
884
969
  opt_paren_args: none
885
970
  | paren_args
886
971
 
887
972
  opt_call_args: none
888
- {
889
- result = val[0]
890
- }
891
973
  | call_args
892
- {
893
- result = val[0]
894
- }
895
974
  | args tCOMMA
896
975
  {
897
976
  result = args val
@@ -913,17 +992,14 @@ rule
913
992
  | args opt_block_arg
914
993
  {
915
994
  result = call_args val
916
- result = self.arg_blk_pass val[0], val[1]
917
995
  }
918
996
  | assocs opt_block_arg
919
997
  {
920
- result = call_args [array_to_hash(val[0])]
921
- result = self.arg_blk_pass result, val[1]
998
+ result = call_args [array_to_hash(val[0]), val[1]]
922
999
  }
923
1000
  | args tCOMMA assocs opt_block_arg
924
1001
  {
925
- result = call_args [val[0], array_to_hash(val[2])]
926
- result = self.arg_blk_pass result, val[3]
1002
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
927
1003
  }
928
1004
  | block_arg
929
1005
  {
@@ -931,17 +1007,45 @@ rule
931
1007
  }
932
1008
 
933
1009
  command_args: {
934
- result = lexer.cmdarg.store true
1010
+ # parse26.y line 2200
1011
+
1012
+ # If call_args starts with a open paren '(' or
1013
+ # '[', look-ahead reading of the letters calls
1014
+ # CMDARG_PUSH(0), but the push must be done
1015
+ # after CMDARG_PUSH(1). So this code makes them
1016
+ # consistent by first cancelling the premature
1017
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1018
+ # finally redoing CMDARG_PUSH(0).
1019
+
1020
+ result = yychar = self.last_token_type.first
1021
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1022
+ lexer.cmdarg.pop if lookahead
1023
+ lexer.cmdarg.push true
1024
+ lexer.cmdarg.push false if lookahead
935
1025
  }
936
1026
  call_args
937
1027
  {
938
- lexer.cmdarg.restore val[0]
939
- result = val[1]
1028
+ yychar, args = val
1029
+
1030
+ # call_args can be followed by tLBRACE_ARG (that
1031
+ # does CMDARG_PUSH(0) in the lexer) but the push
1032
+ # must be done after CMDARG_POP() in the parser.
1033
+ # So this code does CMDARG_POP() to pop 0 pushed
1034
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1035
+ # by command_args, and CMDARG_PUSH(0) to restore
1036
+ # back the flag set by tLBRACE_ARG.
1037
+
1038
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1039
+ lexer.cmdarg.pop if lookahead
1040
+ lexer.cmdarg.pop
1041
+ lexer.cmdarg.push false if lookahead
1042
+ result = args
940
1043
  }
941
1044
 
942
1045
  block_arg: tAMPER arg_value
943
1046
  {
944
- result = s(:block_pass, val[1])
1047
+ _, arg = val
1048
+ result = s(:block_pass, arg).line arg.line
945
1049
  }
946
1050
 
947
1051
  opt_block_arg: tCOMMA block_arg
@@ -952,19 +1056,27 @@ rule
952
1056
 
953
1057
  args: arg_value
954
1058
  {
955
- result = s(:array, val[0])
1059
+ arg, = val
1060
+ lineno = arg.line || lexer.lineno # HACK
1061
+
1062
+ result = s(:array, arg).line lineno
956
1063
  }
957
1064
  | tSTAR arg_value
958
1065
  {
959
- result = s(:array, s(:splat, val[1]))
1066
+ _, arg = val
1067
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
960
1068
  }
961
1069
  | args tCOMMA arg_value
962
1070
  {
963
- result = self.list_append val[0], val[2]
1071
+ args, _, id = val
1072
+ result = self.list_append args, id
964
1073
  }
965
1074
  | args tCOMMA tSTAR arg_value
966
1075
  {
967
- result = self.list_append val[0], s(:splat, val[3])
1076
+ # TODO: the line number from tSTAR has been dropped
1077
+ args, _, _, id = val
1078
+ line = lexer.lineno
1079
+ result = self.list_append args, s(:splat, id).line(line)
968
1080
  }
969
1081
 
970
1082
  mrhs_arg: mrhs
@@ -982,11 +1094,14 @@ rule
982
1094
  }
983
1095
  | args tCOMMA tSTAR arg_value
984
1096
  {
985
- result = self.arg_concat val[0], val[3]
1097
+ # TODO: make all tXXXX terminals include lexer.lineno
1098
+ arg, _, _, splat = val
1099
+ result = self.arg_concat arg, splat
986
1100
  }
987
1101
  | tSTAR arg_value
988
1102
  {
989
- result = s(:splat, val[1])
1103
+ _, arg = val
1104
+ result = s(:splat, arg).line arg.line
990
1105
  }
991
1106
 
992
1107
  primary: literal
@@ -1001,65 +1116,65 @@ rule
1001
1116
  | backref
1002
1117
  | tFID
1003
1118
  {
1004
- result = new_call nil, val[0].to_sym
1119
+ msg, = val
1120
+ result = new_call nil, msg.to_sym
1005
1121
  }
1006
1122
  | k_begin
1007
1123
  {
1124
+ lexer.cmdarg.push false
1008
1125
  result = self.lexer.lineno
1009
- # TODO:
1010
- # $<val>1 = cmdarg_stack;
1011
- # CMDARG_SET(0);
1012
1126
  }
1013
1127
  bodystmt k_end
1014
1128
  {
1015
- # TODO: CMDARG_SET($<val>1);
1016
- unless val[2] then
1017
- result = s(:nil)
1018
- else
1019
- result = s(:begin, val[2])
1020
- end
1021
-
1022
- result.line = val[1]
1129
+ lexer.cmdarg.pop
1130
+ result = new_begin val
1023
1131
  }
1024
- | tLPAREN_ARG rparen
1132
+ | tLPAREN_ARG
1025
1133
  {
1026
- # TODO: lex_state = :expr_endarg in between
1027
- debug20 13, val, result
1134
+ lexer.lex_state = EXPR_ENDARG
1135
+ result = lexer.lineno
1028
1136
  }
1029
- | tLPAREN_ARG
1137
+ rparen
1030
1138
  {
1031
- result = lexer.cmdarg.store false
1032
- # result = self.lexer.cmdarg.stack.dup
1033
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1139
+ _, line, _ = val
1140
+ result = s(:begin).line line
1034
1141
  }
1142
+ | tLPAREN_ARG
1035
1143
  stmt
1036
1144
  {
1037
- lexer.lex_state = :expr_endarg
1145
+ lexer.lex_state = EXPR_ENDARG
1038
1146
  }
1039
1147
  rparen
1040
1148
  {
1041
- _, cmdarg, stmt, _, _, = val
1042
- warning "(...) interpreted as grouped expression"
1043
- lexer.cmdarg.restore cmdarg
1149
+ _, stmt, _, _, = val
1150
+ # warning "(...) interpreted as grouped expression"
1044
1151
  result = stmt
1045
1152
  }
1046
1153
  | tLPAREN compstmt tRPAREN
1047
1154
  {
1048
- result = val[1] || s(:nil)
1155
+ _, stmt, _ = val
1156
+ result = stmt
1157
+ result ||= s(:nil).line lexer.lineno
1049
1158
  result.paren = true
1050
1159
  }
1051
1160
  | primary_value tCOLON2 tCONSTANT
1052
1161
  {
1053
- result = s(:colon2, val[0], val[2].to_sym)
1162
+ expr, _, id = val
1163
+
1164
+ result = s(:colon2, expr, id.to_sym).line expr.line
1054
1165
  }
1055
1166
  | tCOLON3 tCONSTANT
1056
1167
  {
1057
- result = s(:colon3, val[1].to_sym)
1168
+ _, id = val
1169
+
1170
+ result = s(:colon3, id.to_sym).line lexer.lineno
1058
1171
  }
1059
- | tLBRACK aref_args tRBRACK
1172
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1060
1173
  {
1061
- result = val[1] || s(:array)
1174
+ _, line, args, _ = val
1175
+ result = args || s(:array)
1062
1176
  result.sexp_type = :array # aref_args is :args
1177
+ result.line line
1063
1178
  }
1064
1179
  | tLBRACE
1065
1180
  {
@@ -1071,7 +1186,8 @@ rule
1071
1186
  }
1072
1187
  | k_return
1073
1188
  {
1074
- result = s(:return)
1189
+ (_, line), = val
1190
+ result = s(:return).line line
1075
1191
  }
1076
1192
  | kYIELD tLPAREN2 call_args rparen
1077
1193
  {
@@ -1087,11 +1203,14 @@ rule
1087
1203
  }
1088
1204
  | kDEFINED opt_nl tLPAREN2 expr rparen
1089
1205
  {
1090
- result = s(:defined, val[3])
1206
+ (_, line), _, _, arg, _ = val
1207
+
1208
+ result = s(:defined, arg).line line
1091
1209
  }
1092
1210
  | kNOT tLPAREN2 expr rparen
1093
1211
  {
1094
- result = s(:call, val[2], :"!")
1212
+ _, _, lhs, _ = val
1213
+ result = new_call lhs, :"!"
1095
1214
  }
1096
1215
  | kNOT tLPAREN2 rparen
1097
1216
  {
@@ -1099,11 +1218,11 @@ rule
1099
1218
  }
1100
1219
  | fcall brace_block
1101
1220
  {
1102
- oper, iter = val[0], val[1]
1103
- call = oper # FIX
1221
+ call, iter = val
1222
+
1104
1223
  iter.insert 1, call
1105
1224
  result = iter
1106
- call.line = iter.line
1225
+ # FIX: probably not: call.line = iter.line
1107
1226
  }
1108
1227
  | method_call
1109
1228
  | method_call brace_block
@@ -1211,66 +1330,82 @@ rule
1211
1330
  }
1212
1331
  | k_def fname
1213
1332
  {
1214
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1333
+ result = self.in_def
1215
1334
 
1216
- self.comments.push self.lexer.comments
1217
- self.in_def = true
1335
+ self.in_def = true # group = local_push
1218
1336
  self.env.extend
1219
- # TODO: local->cmdargs = cmdarg_stack;
1220
- # TODO: port local_push_gen and local_pop_gen
1221
- lexer.cmdarg.stack.replace [false]
1337
+ lexer.cmdarg.push false
1338
+ lexer.cond.push false
1339
+
1340
+ self.comments.push self.lexer.comments
1222
1341
  }
1223
- f_arglist bodystmt k_end
1342
+ f_arglist bodystmt { result = lexer.lineno } k_end
1224
1343
  {
1225
- in_def, cmdarg = val[2]
1344
+ in_def = val[2]
1226
1345
 
1227
1346
  result = new_defn val
1228
1347
 
1229
- lexer.cmdarg.stack.replace cmdarg
1348
+ lexer.cond.pop # group = local_pop
1349
+ lexer.cmdarg.pop
1230
1350
  self.env.unextend
1231
1351
  self.in_def = in_def
1352
+
1232
1353
  self.lexer.comments # we don't care about comments in the body
1233
1354
  }
1234
1355
  | k_def singleton dot_or_colon
1235
1356
  {
1236
- self.comments.push self.lexer.comments
1237
- lexer.lex_state = :expr_fname
1357
+ lexer.lex_state = EXPR_FNAME
1238
1358
  }
1239
1359
  fname
1240
1360
  {
1241
- self.in_single += 1
1361
+ result = [self.in_def, lexer.lineno]
1362
+
1363
+ self.in_single += 1 # TODO: remove?
1364
+
1365
+ self.in_def = true # local_push
1242
1366
  self.env.extend
1243
- lexer.lex_state = :expr_endfn # force for args
1244
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1245
- lexer.cmdarg.stack.replace [false]
1367
+ lexer.cmdarg.push false
1368
+ lexer.cond.push false
1369
+
1370
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1371
+ self.comments.push self.lexer.comments
1246
1372
  }
1247
1373
  f_arglist bodystmt k_end
1248
1374
  {
1249
- line, cmdarg = val[5]
1250
- result = new_defs val
1251
- result[3].line line
1375
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1252
1376
 
1253
- lexer.cmdarg.stack.replace cmdarg
1377
+ result = new_defs val
1254
1378
 
1379
+ lexer.cond.pop # group = local_pop
1380
+ lexer.cmdarg.pop
1255
1381
  self.env.unextend
1382
+ self.in_def = in_def
1383
+
1256
1384
  self.in_single -= 1
1385
+
1386
+ # TODO: restore cur_arg ? what's cur_arg?
1387
+
1257
1388
  self.lexer.comments # we don't care about comments in the body
1258
1389
  }
1259
1390
  | kBREAK
1260
1391
  {
1261
- result = s(:break)
1392
+ (_, line), = val
1393
+ result = s(:break).line line
1262
1394
  }
1263
1395
  | kNEXT
1264
1396
  {
1265
- result = s(:next)
1397
+ (_, line), = val
1398
+ result = s(:next).line line
1266
1399
  }
1267
1400
  | kREDO
1268
1401
  {
1269
- result = s(:redo)
1402
+ (_, line), = val
1403
+ result = s(:redo).line line
1270
1404
  }
1271
1405
  | kRETRY
1272
1406
  {
1273
- result = s(:retry)
1407
+ (_, line), = val
1408
+ result = s(:retry).line line
1274
1409
  }
1275
1410
 
1276
1411
  primary_value: primary
@@ -1309,7 +1444,9 @@ rule
1309
1444
  if_tail: opt_else
1310
1445
  | k_elsif expr_value then compstmt if_tail
1311
1446
  {
1312
- result = s(:if, val[1], val[3], val[4])
1447
+ (_, line), c, _, t, rest = val
1448
+
1449
+ result = s(:if, c, t, rest).line line
1313
1450
  }
1314
1451
 
1315
1452
  opt_else: none
@@ -1332,7 +1469,9 @@ rule
1332
1469
 
1333
1470
  f_marg_list: f_marg
1334
1471
  {
1335
- result = s(:array, val[0])
1472
+ sym, = val
1473
+
1474
+ result = s(:array, sym).line lexer.lineno
1336
1475
  }
1337
1476
  | f_marg_list tCOMMA f_marg
1338
1477
  {
@@ -1406,7 +1545,9 @@ rule
1406
1545
  }
1407
1546
  | f_block_arg
1408
1547
  {
1409
- result = call_args val
1548
+ line = lexer.lineno
1549
+ result = call_args val # TODO: push line down
1550
+ result.line line
1410
1551
  }
1411
1552
 
1412
1553
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1437,7 +1578,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1437
1578
  }
1438
1579
  | f_arg tCOMMA
1439
1580
  {
1440
- result = args val
1581
+ result = args(val) << nil
1441
1582
  }
1442
1583
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1443
1584
  {
@@ -1489,7 +1630,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1489
1630
  }
1490
1631
  | tOROP
1491
1632
  {
1492
- result = s(:args)
1633
+ result = s(:args).line lexer.lineno
1493
1634
  }
1494
1635
  | tPIPE block_param opt_bv_decl tPIPE
1495
1636
  {
@@ -1514,34 +1655,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1514
1655
 
1515
1656
  bvar: tIDENTIFIER
1516
1657
  {
1517
- result = s(:shadow, val[0].to_sym)
1658
+ id, = val
1659
+ line = lexer.lineno
1660
+ result = s(:shadow, id.to_sym).line line
1518
1661
  }
1519
1662
  | f_bad_arg
1520
1663
 
1521
1664
  lambda: {
1522
1665
  self.env.extend :dynamic
1523
- result = self.lexer.lineno
1524
-
1525
- result = lexer.lpar_beg
1666
+ result = [lexer.lineno, lexer.lpar_beg]
1526
1667
  lexer.paren_nest += 1
1527
1668
  lexer.lpar_beg = lexer.paren_nest
1528
1669
  }
1529
1670
  f_larglist
1530
1671
  {
1531
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1672
+ lexer.cmdarg.push false
1532
1673
  }
1533
1674
  lambda_body
1534
1675
  {
1535
- lpar, args, (cmdarg, lineno), body = val
1676
+ (line, lpar), args, _cmdarg, body = val
1536
1677
  lexer.lpar_beg = lpar
1537
1678
 
1538
- lexer.cmdarg.restore cmdarg
1539
- lexer.cmdarg.lexpop
1679
+ lexer.cmdarg.pop
1540
1680
 
1541
- call = new_call nil, :lambda
1681
+ call = s(:lambda).line line
1542
1682
  result = new_iter call, args, body
1543
- result.line = lineno
1544
- self.env.unextend
1683
+ result.line = line
1684
+ self.env.unextend # TODO: dynapush & dynapop
1545
1685
  }
1546
1686
 
1547
1687
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1565,8 +1705,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1565
1705
 
1566
1706
  do_block: k_do_block do_body kEND
1567
1707
  {
1568
- # TODO: maybe fix lineno to kDO's lineno?
1569
- result = val[1]
1708
+ (_, line), iter, _ = val
1709
+ result = iter.line line
1570
1710
  }
1571
1711
 
1572
1712
  block_call: command do_block
@@ -1580,8 +1720,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1580
1720
 
1581
1721
  val = invert_block_call val if inverted? val
1582
1722
 
1583
- result = val[1]
1584
- result.insert 1, val[0]
1723
+ cmd, blk = val
1724
+
1725
+ result = blk
1726
+ result.insert 1, cmd
1585
1727
  }
1586
1728
  | block_call call_op2 operation2 opt_paren_args
1587
1729
  {
@@ -1612,8 +1754,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1612
1754
  }
1613
1755
  paren_args
1614
1756
  {
1615
- args = self.call_args val[2..-1]
1616
- result = val[0].concat args.sexp_body
1757
+ call, lineno, args = val
1758
+
1759
+ result = call.concat args.sexp_body if args
1760
+ result.line lineno
1617
1761
  }
1618
1762
  | primary_value call_op operation2 opt_paren_args
1619
1763
  {
@@ -1641,7 +1785,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1641
1785
  }
1642
1786
  | kSUPER
1643
1787
  {
1644
- result = s(:zsuper)
1788
+ result = s(:zsuper).line lexer.lineno
1645
1789
  }
1646
1790
  | primary_value tLBRACK2 opt_call_args rbracket
1647
1791
  {
@@ -1690,15 +1834,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1690
1834
  }
1691
1835
 
1692
1836
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1693
- { result = lexer.cmdarg.store(false) }
1837
+ { lexer.cmdarg.push false }
1694
1838
  opt_block_param
1695
1839
  compstmt
1696
1840
  {
1697
- line, cmdarg, param, cmpstmt = val
1841
+ line, _cmdarg, param, cmpstmt = val
1698
1842
 
1699
1843
  result = new_do_body param, cmpstmt, line
1844
+ lexer.cmdarg.pop
1700
1845
  self.env.unextend
1701
- lexer.cmdarg.restore cmdarg
1702
1846
  }
1703
1847
 
1704
1848
  case_body: k_when
@@ -1719,7 +1863,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1719
1863
  (_, line), klasses, var, _, body, rest = val
1720
1864
 
1721
1865
  klasses ||= s(:array)
1722
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1866
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1723
1867
  klasses.line line
1724
1868
 
1725
1869
  result = new_resbody(klasses, body)
@@ -1732,7 +1876,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1732
1876
 
1733
1877
  exc_list: arg_value
1734
1878
  {
1735
- result = s(:array, val[0])
1879
+ arg, = val
1880
+ result = s(:array, arg).line arg.line
1736
1881
  }
1737
1882
  | mrhs
1738
1883
  | none
@@ -1745,26 +1890,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1745
1890
 
1746
1891
  opt_ensure: k_ensure compstmt
1747
1892
  {
1748
- _, body = val
1893
+ (_, line), body = val
1749
1894
 
1750
- result = body || s(:nil)
1895
+ result = body || s(:nil).line(line)
1751
1896
  }
1752
1897
  | none
1753
1898
 
1754
1899
  literal: numeric
1755
1900
  {
1901
+ line = lexer.lineno
1756
1902
  result = s(:lit, val[0])
1903
+ result.line = line
1757
1904
  }
1758
1905
  | symbol
1759
1906
  {
1907
+ line = lexer.lineno
1760
1908
  result = s(:lit, val[0])
1909
+ result.line = line
1761
1910
  }
1762
1911
  | dsym
1763
1912
 
1764
1913
  strings: string
1765
1914
  {
1766
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1767
- result = val[0]
1915
+ str, = val
1916
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1917
+ result = str
1768
1918
  }
1769
1919
 
1770
1920
  string: tCHAR
@@ -1779,7 +1929,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1779
1929
 
1780
1930
  string1: tSTRING_BEG string_contents tSTRING_END
1781
1931
  {
1782
- result = val[1]
1932
+ _, str, (_, func) = val
1933
+
1934
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1935
+
1936
+ result = str
1783
1937
  }
1784
1938
  | tSTRING
1785
1939
  {
@@ -1788,7 +1942,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1788
1942
 
1789
1943
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1790
1944
  {
1791
- result = new_xstring val[1]
1945
+ result = new_xstring val
1946
+ # TODO: dedent?!?! SERIOUSLY?!?
1792
1947
  }
1793
1948
 
1794
1949
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1798,7 +1953,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1798
1953
 
1799
1954
  words: tWORDS_BEG tSPACE tSTRING_END
1800
1955
  {
1801
- result = s(:array)
1956
+ result = s(:array).line lexer.lineno
1802
1957
  }
1803
1958
  | tWORDS_BEG word_list tSTRING_END
1804
1959
  {
@@ -1822,25 +1977,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1822
1977
 
1823
1978
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1824
1979
  {
1825
- result = s(:array)
1980
+ result = s(:array).line lexer.lineno
1826
1981
  }
1827
- | tSYMBOLS_BEG symbol_list tSTRING_END
1982
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1828
1983
  {
1829
- result = val[1]
1984
+ _, line, list, _, = val
1985
+ list.line = line
1986
+ result = list
1830
1987
  }
1831
1988
 
1832
1989
  symbol_list: none
1833
1990
  {
1834
- result = new_symbol_list
1991
+ result = new_symbol_list.line lexer.lineno
1835
1992
  }
1836
1993
  | symbol_list word tSPACE
1837
1994
  {
1838
- result = val[0].dup << new_symbol_list_entry(val)
1995
+ list, * = val
1996
+ result = list.dup << new_symbol_list_entry(val)
1839
1997
  }
1840
1998
 
1841
1999
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1842
2000
  {
1843
- result = s(:array)
2001
+ result = s(:array).line lexer.lineno
1844
2002
  }
1845
2003
  | tQWORDS_BEG qword_list tSTRING_END
1846
2004
  {
@@ -1849,7 +2007,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1849
2007
 
1850
2008
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1851
2009
  {
1852
- result = s(:array)
2010
+ result = s(:array).line lexer.lineno # FIX
1853
2011
  }
1854
2012
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1855
2013
  {
@@ -1876,11 +2034,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1876
2034
 
1877
2035
  string_contents: none
1878
2036
  {
1879
- result = s(:str, "")
2037
+ result = s(:str, "").line lexer.lineno
1880
2038
  }
1881
2039
  | string_contents string_content
1882
2040
  {
1883
- result = literal_concat(val[0], val[1])
2041
+ v1, v2 = val
2042
+ result = literal_concat v1, v2
1884
2043
  }
1885
2044
 
1886
2045
  xstring_contents: none
@@ -1889,7 +2048,8 @@ xstring_contents: none
1889
2048
  }
1890
2049
  | xstring_contents string_content
1891
2050
  {
1892
- result = literal_concat(val[0], val[1])
2051
+ v1, v2 = val
2052
+ result = literal_concat v1, v2
1893
2053
  }
1894
2054
 
1895
2055
  regexp_contents: none
@@ -1898,7 +2058,8 @@ regexp_contents: none
1898
2058
  }
1899
2059
  | regexp_contents string_content
1900
2060
  {
1901
- result = literal_concat(val[0], val[1])
2061
+ v1, v2 = val
2062
+ result = literal_concat v1, v2
1902
2063
  }
1903
2064
 
1904
2065
  string_content: tSTRING_CONTENT
@@ -1910,42 +2071,46 @@ regexp_contents: none
1910
2071
  result = lexer.lex_strterm
1911
2072
 
1912
2073
  lexer.lex_strterm = nil
1913
- lexer.lex_state = :expr_beg
2074
+ lexer.lex_state = EXPR_BEG
1914
2075
  }
1915
2076
  string_dvar
1916
2077
  {
1917
- lexer.lex_strterm = val[1]
1918
- result = s(:evstr, val[2])
2078
+ _, strterm, str = val
2079
+ lexer.lex_strterm = strterm
2080
+ result = s(:evstr, str).line str.line
1919
2081
  }
1920
2082
  | tSTRING_DBEG
1921
2083
  {
1922
2084
  result = [lexer.lex_strterm,
1923
2085
  lexer.brace_nest,
1924
2086
  lexer.string_nest, # TODO: remove
1925
- lexer.cond.store,
1926
- lexer.cmdarg.store,
1927
2087
  lexer.lex_state,
2088
+ lexer.lineno,
1928
2089
  ]
1929
2090
 
2091
+ lexer.cmdarg.push false
2092
+ lexer.cond.push false
2093
+
1930
2094
  lexer.lex_strterm = nil
1931
2095
  lexer.brace_nest = 0
1932
2096
  lexer.string_nest = 0
1933
2097
 
1934
- lexer.lex_state = :expr_beg
2098
+ lexer.lex_state = EXPR_BEG
1935
2099
  }
1936
2100
  compstmt
1937
2101
  tSTRING_DEND
1938
2102
  {
1939
2103
  _, memo, stmt, _ = val
1940
2104
 
1941
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2105
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2106
+ # TODO: heredoc_indent
1942
2107
 
1943
2108
  lexer.lex_strterm = lex_strterm
1944
2109
  lexer.brace_nest = brace_nest
1945
2110
  lexer.string_nest = string_nest
1946
2111
 
1947
- lexer.cond.restore oldcond
1948
- lexer.cmdarg.restore oldcmdarg
2112
+ lexer.cmdarg.pop
2113
+ lexer.cond.pop
1949
2114
 
1950
2115
  lexer.lex_state = oldlex_state
1951
2116
 
@@ -1955,24 +2120,24 @@ regexp_contents: none
1955
2120
  when :str, :dstr, :evstr then
1956
2121
  result = stmt
1957
2122
  else
1958
- result = s(:evstr, stmt)
2123
+ result = s(:evstr, stmt).line line
1959
2124
  end
1960
2125
  when nil then
1961
- result = s(:evstr)
2126
+ result = s(:evstr).line line
1962
2127
  else
1963
2128
  debug20 25
1964
2129
  raise "unknown string body: #{stmt.inspect}"
1965
2130
  end
1966
2131
  }
1967
2132
 
1968
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1969
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1970
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2133
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2134
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2135
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
1971
2136
  | backref
1972
2137
 
1973
2138
  symbol: tSYMBEG sym
1974
2139
  {
1975
- lexer.lex_state = :expr_end
2140
+ lexer.lex_state = EXPR_END
1976
2141
  result = val[1].to_sym
1977
2142
  }
1978
2143
  | tSYMBOL
@@ -1984,18 +2149,19 @@ regexp_contents: none
1984
2149
 
1985
2150
  dsym: tSYMBEG xstring_contents tSTRING_END
1986
2151
  {
1987
- lexer.lex_state = :expr_end
1988
- result = val[1]
2152
+ _, result, _ = val
2153
+
2154
+ lexer.lex_state = EXPR_END
1989
2155
 
1990
- result ||= s(:str, "")
2156
+ result ||= s(:str, "").line lexer.lineno
1991
2157
 
1992
2158
  case result.sexp_type
1993
2159
  when :dstr then
1994
2160
  result.sexp_type = :dsym
1995
2161
  when :str then
1996
- result = s(:lit, result.last.to_sym)
2162
+ result = s(:lit, result.last.to_sym).line result.line
1997
2163
  when :evstr then
1998
- result = s(:dsym, "", result)
2164
+ result = s(:dsym, "", result).line result.line
1999
2165
  else
2000
2166
  debug20 26, val, result
2001
2167
  end
@@ -2018,19 +2184,20 @@ regexp_contents: none
2018
2184
  | tCONSTANT
2019
2185
  | tCVAR
2020
2186
 
2021
- keyword_variable: kNIL { result = s(:nil) }
2022
- | kSELF { result = s(:self) }
2023
- | kTRUE { result = s(:true) }
2024
- | kFALSE { result = s(:false) }
2025
- | k__FILE__ { result = s(:str, self.file) }
2026
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2187
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2188
+ | kSELF { result = s(:self).line lexer.lineno }
2189
+ | kTRUE { result = s(:true).line lexer.lineno }
2190
+ | kFALSE { result = s(:false).line lexer.lineno }
2191
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2192
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2027
2193
  | k__ENCODING__
2028
2194
  {
2195
+ l = lexer.lineno
2029
2196
  result =
2030
2197
  if defined? Encoding then
2031
- s(:colon2, s(:const, :Encoding), :UTF_8)
2198
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2032
2199
  else
2033
- s(:str, "Unsupported!")
2200
+ s(:str, "Unsupported!").line l
2034
2201
  end
2035
2202
  }
2036
2203
 
@@ -2055,12 +2222,12 @@ keyword_variable: kNIL { result = s(:nil) }
2055
2222
  debug20 29, val, result
2056
2223
  }
2057
2224
 
2058
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2059
- | tBACK_REF { result = s(:back_ref, val[0]) }
2225
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2226
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2060
2227
 
2061
2228
  superclass: tLT
2062
2229
  {
2063
- lexer.lex_state = :expr_beg
2230
+ lexer.lex_state = EXPR_BEG
2064
2231
  lexer.command_start = true
2065
2232
  }
2066
2233
  expr_value term
@@ -2075,13 +2242,13 @@ keyword_variable: kNIL { result = s(:nil) }
2075
2242
  f_arglist: tLPAREN2 f_args rparen
2076
2243
  {
2077
2244
  result = val[1]
2078
- self.lexer.lex_state = :expr_beg
2245
+ self.lexer.lex_state = EXPR_BEG
2079
2246
  self.lexer.command_start = true
2080
2247
  }
2081
2248
  | {
2082
2249
  result = self.in_kwarg
2083
2250
  self.in_kwarg = true
2084
- # TODO: self.lexer.lex_state |= :expr_label
2251
+ self.lexer.lex_state |= EXPR_LABEL
2085
2252
  }
2086
2253
  f_args term
2087
2254
  {
@@ -2089,7 +2256,7 @@ keyword_variable: kNIL { result = s(:nil) }
2089
2256
 
2090
2257
  self.in_kwarg = kwarg
2091
2258
  result = args
2092
- lexer.lex_state = :expr_beg
2259
+ lexer.lex_state = EXPR_BEG
2093
2260
  lexer.command_start = true
2094
2261
  }
2095
2262
 
@@ -2211,12 +2378,13 @@ keyword_variable: kNIL { result = s(:nil) }
2211
2378
 
2212
2379
  f_arg: f_arg_item
2213
2380
  {
2214
- case val[0]
2381
+ arg, = val
2382
+
2383
+ case arg
2215
2384
  when Symbol then
2216
- result = s(:args)
2217
- result << val[0]
2385
+ result = s(:args, arg).line lexer.lineno
2218
2386
  when Sexp then
2219
- result = val[0]
2387
+ result = arg
2220
2388
  else
2221
2389
  debug20 32
2222
2390
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2229,7 +2397,7 @@ keyword_variable: kNIL { result = s(:nil) }
2229
2397
  if list.sexp_type == :args then
2230
2398
  result = list
2231
2399
  else
2232
- result = s(:args, list)
2400
+ result = s(:args, list).line list.line
2233
2401
  end
2234
2402
 
2235
2403
  result << item
@@ -2239,38 +2407,42 @@ keyword_variable: kNIL { result = s(:nil) }
2239
2407
 
2240
2408
  f_kw: f_label arg_value
2241
2409
  {
2242
- # TODO: call_args
2243
- label, _ = val[0] # TODO: fix lineno?
2410
+ # TODO: new_kw_arg
2411
+ (label, line), arg = val
2412
+
2244
2413
  identifier = label.to_sym
2245
2414
  self.env[identifier] = :lvar
2246
2415
 
2247
- result = s(:array, s(:kwarg, identifier, val[1]))
2416
+ kwarg = s(:kwarg, identifier, arg).line line
2417
+ result = s(:array, kwarg).line line
2248
2418
  }
2249
2419
  | f_label
2250
2420
  {
2251
- label, _ = val[0] # TODO: fix lineno?
2252
- identifier = label.to_sym
2253
- self.env[identifier] = :lvar
2421
+ (label, line), = val
2422
+
2423
+ id = label.to_sym
2424
+ self.env[id] = :lvar
2254
2425
 
2255
- result = s(:array, s(:kwarg, identifier))
2426
+ result = s(:array, s(:kwarg, id).line(line)).line line
2256
2427
  }
2257
2428
 
2258
2429
  f_block_kw: f_label primary_value
2259
2430
  {
2260
- # TODO: call_args
2261
- label, _ = val[0] # TODO: fix lineno?
2262
- identifier = label.to_sym
2263
- self.env[identifier] = :lvar
2431
+ # TODO: new_kw_arg
2432
+ (label, line), expr = val
2433
+ id = label.to_sym
2434
+ self.env[id] = :lvar
2264
2435
 
2265
- result = s(:array, s(:kwarg, identifier, val[1]))
2436
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2266
2437
  }
2267
2438
  | f_label
2268
2439
  {
2269
- label, _ = val[0] # TODO: fix lineno?
2270
- identifier = label.to_sym
2271
- self.env[identifier] = :lvar
2440
+ # TODO: new_kw_arg
2441
+ (label, line), = val
2442
+ id = label.to_sym
2443
+ self.env[id] = :lvar
2272
2444
 
2273
- result = s(:array, s(:kwarg, identifier))
2445
+ result = s(:array, s(:kwarg, id).line(line)).line line
2274
2446
  }
2275
2447
 
2276
2448
  f_block_kwarg: f_block_kw
@@ -2313,17 +2485,20 @@ keyword_variable: kNIL { result = s(:nil) }
2313
2485
 
2314
2486
  f_block_optarg: f_block_opt
2315
2487
  {
2316
- result = s(:block, val[0])
2488
+ optblk, = val
2489
+ result = s(:block, optblk).line optblk.line
2317
2490
  }
2318
2491
  | f_block_optarg tCOMMA f_block_opt
2319
2492
  {
2320
- result = val[0]
2321
- result << val[2]
2493
+ optarg, _, optblk = val
2494
+ result = optarg
2495
+ result << optblk
2322
2496
  }
2323
2497
 
2324
2498
  f_optarg: f_opt
2325
2499
  {
2326
- result = s(:block, val[0])
2500
+ opt, = val
2501
+ result = s(:block, opt).line opt.line
2327
2502
  }
2328
2503
  | f_optarg tCOMMA f_opt
2329
2504
  {
@@ -2368,7 +2543,7 @@ keyword_variable: kNIL { result = s(:nil) }
2368
2543
  singleton: var_ref
2369
2544
  | tLPAREN2
2370
2545
  {
2371
- lexer.lex_state = :expr_beg
2546
+ lexer.lex_state = EXPR_BEG
2372
2547
  }
2373
2548
  expr rparen
2374
2549
  {
@@ -2377,14 +2552,11 @@ keyword_variable: kNIL { result = s(:nil) }
2377
2552
  result.sexp_type == :lit
2378
2553
  }
2379
2554
 
2380
- assoc_list: none # [!nil]
2381
- {
2382
- result = s(:array)
2383
- }
2384
- | assocs trailer # [!nil]
2555
+ assoc_list: none
2385
2556
  {
2386
- result = val[0]
2557
+ result = s(:array).line lexer.lineno
2387
2558
  }
2559
+ | assocs trailer
2388
2560
 
2389
2561
  assocs: assoc
2390
2562
  | assocs tCOMMA assoc
@@ -2398,16 +2570,21 @@ keyword_variable: kNIL { result = s(:nil) }
2398
2570
 
2399
2571
  assoc: arg_value tASSOC arg_value
2400
2572
  {
2401
- result = s(:array, val[0], val[2])
2573
+ v1, _, v2 = val
2574
+ result = s(:array, v1, v2).line v1.line
2402
2575
  }
2403
2576
  | tLABEL arg_value
2404
2577
  {
2405
- (label, _), arg = val
2406
- result = s(:array, s(:lit, label.to_sym), arg)
2578
+ (label, line), arg = val
2579
+
2580
+ lit = s(:lit, label.to_sym).line line
2581
+ result = s(:array, lit, arg).line line
2407
2582
  }
2408
2583
  | tDSTAR arg_value
2409
2584
  {
2410
- result = s(:array, s(:kwsplat, val[1]))
2585
+ _, arg = val
2586
+ line = arg.line
2587
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2411
2588
  }
2412
2589
 
2413
2590
  operation: tIDENTIFIER | tCONSTANT | tFID
@@ -2438,6 +2615,7 @@ end
2438
2615
 
2439
2616
  require "ruby_lexer"
2440
2617
  require "ruby_parser_extras"
2618
+ include RubyLexer::State::Values
2441
2619
 
2442
2620
  # :stopdoc:
2443
2621