ruby_parser 3.13.0 → 3.15.0

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