ruby_parser 3.13.0 → 3.15.0

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