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