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.
@@ -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