ruby_parser 3.13.0 → 3.15.0

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