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
  {
@@ -274,28 +278,37 @@ rule
274
278
  }
275
279
  | command_call kRESCUE_MOD stmt
276
280
  {
277
- expr, _, resbody = val
281
+ expr, (_, line), resbody = val
282
+
278
283
  expr = value_expr expr
279
- result = new_rescue(expr, new_resbody(s(:array), resbody))
284
+ ary = s(:array).line line
285
+ result = new_rescue(expr, new_resbody(ary, resbody))
280
286
  }
281
287
  | command_asgn
282
288
 
283
289
  expr: command_call
284
290
  | expr kAND expr
285
291
  {
286
- result = logical_op :and, val[0], val[2]
292
+ lhs, _, rhs = val
293
+ result = logical_op :and, lhs, rhs
287
294
  }
288
295
  | expr kOR expr
289
296
  {
290
- result = logical_op :or, val[0], val[2]
297
+ lhs, _, rhs = val
298
+ result = logical_op :or, lhs, rhs
291
299
  }
292
300
  | kNOT opt_nl expr
293
301
  {
294
- result = s(:call, val[2], :"!")
302
+ (_, line), _, expr = val
303
+ result = new_call(expr, :"!").line line
304
+ # REFACTOR: call_uni_op
295
305
  }
296
306
  | tBANG command_call
297
307
  {
298
- result = s(:call, val[1], :"!")
308
+ _, cmd = val
309
+ result = new_call(cmd, :"!").line cmd.line
310
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
311
+ # REFACTOR: call_uni_op -- see parse26.y
299
312
  }
300
313
  | arg
301
314
 
@@ -322,7 +335,8 @@ rule
322
335
  block_command: block_call
323
336
  | block_call call_op2 operation2 command_args
324
337
  {
325
- result = new_call val[0], val[2].to_sym, val[3]
338
+ blk, _, msg, args = val
339
+ result = new_call(blk, msg.to_sym, args).line blk.line
326
340
  }
327
341
 
328
342
  cmd_brace_block: tLBRACE_ARG
@@ -342,26 +356,32 @@ rule
342
356
 
343
357
  fcall: operation
344
358
  {
345
- result = new_call nil, val[0].to_sym
359
+ msg, = val
360
+ result = new_call(nil, msg.to_sym).line lexer.lineno
346
361
  }
347
362
 
348
363
  command: fcall command_args =tLOWEST
349
364
  {
350
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
365
+ call, args = val
366
+ result = call.concat args.sexp_body
351
367
  }
352
368
  | fcall command_args cmd_brace_block
353
369
  {
354
- result = val[0].concat val[1].sexp_body
355
- if val[2] then
356
- block_dup_check result, val[2]
370
+ call, args, block = val
357
371
 
358
- result, operation = val[2], result
372
+ result = call.concat args.sexp_body
373
+
374
+ if block then
375
+ block_dup_check result, block
376
+
377
+ result, operation = block, result
359
378
  result.insert 1, operation
360
379
  end
361
380
  }
362
381
  | primary_value call_op operation2 command_args =tLOWEST
363
382
  {
364
- result = new_call val[0], val[2].to_sym, val[3], val[1]
383
+ lhs, callop, op, args = val
384
+ result = new_call lhs, op.to_sym, args, callop
365
385
  }
366
386
  | primary_value call_op operation2 command_args cmd_brace_block
367
387
  {
@@ -393,7 +413,9 @@ rule
393
413
  }
394
414
  | kYIELD command_args
395
415
  {
396
- result = new_yield val[1]
416
+ (_, line), args = val
417
+ result = new_yield args
418
+ result.line line # TODO: push to new_yield
397
419
  }
398
420
  | k_return call_args
399
421
  {
@@ -402,8 +424,8 @@ rule
402
424
  }
403
425
  | kBREAK call_args
404
426
  {
405
- line = val[0].last
406
- result = s(:break, ret_args(val[1])).line(line)
427
+ (_, line), args = val
428
+ result = s(:break, ret_args(args)).line line
407
429
  }
408
430
  | kNEXT call_args
409
431
  {
@@ -420,56 +442,79 @@ rule
420
442
  mlhs_inner: mlhs_basic
421
443
  | tLPAREN mlhs_inner rparen
422
444
  {
423
- result = s(:masgn, s(:array, val[1]))
445
+ _, arg, _ = val
446
+ l = arg.line
447
+
448
+ result = s(:masgn, s(:array, arg).line(l)).line l
424
449
  }
425
450
 
426
451
  mlhs_basic: mlhs_head
427
452
  {
428
- result = s(:masgn, val[0])
453
+ head, = val
454
+ result = s(:masgn, head).line head.line
429
455
  }
430
456
  | mlhs_head mlhs_item
431
457
  {
432
- result = s(:masgn, val[0] << val[1].compact)
458
+ lhs, rhs = val
459
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
433
460
  }
434
461
  | mlhs_head tSTAR mlhs_node
435
462
  {
436
- result = s(:masgn, val[0] << s(:splat, val[2]))
463
+ head, _, tail = val
464
+ head << s(:splat, tail).line(tail.line)
465
+ result = s(:masgn, head).line head.line
437
466
  }
438
467
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
439
468
  {
440
469
  ary1, _, splat, _, ary2 = val
441
470
 
442
- result = list_append ary1, s(:splat, splat)
471
+ result = list_append ary1, s(:splat, splat).line(splat.line)
443
472
  result.concat ary2.sexp_body
444
- result = s(:masgn, result)
473
+ result = s(:masgn, result).line result.line
445
474
  }
446
475
  | mlhs_head tSTAR
447
476
  {
448
- result = s(:masgn, val[0] << s(:splat))
477
+ head, _ = val
478
+ l = head.line
479
+ result = s(:masgn, head << s(:splat).line(l)).line l
449
480
  }
450
481
  | mlhs_head tSTAR tCOMMA mlhs_post
451
482
  {
452
- ary = list_append val[0], s(:splat)
453
- ary.concat val[3].sexp_body
454
- result = s(:masgn, ary)
483
+ head, _, _, post = val
484
+ ary = list_append head, s(:splat).line(head.line)
485
+ ary.concat post.sexp_body
486
+ result = s(:masgn, ary).line ary.line
455
487
  }
456
488
  | tSTAR mlhs_node
457
489
  {
458
- result = s(:masgn, s(:array, s(:splat, val[1])))
490
+ _, node = val
491
+ l = node.line
492
+ splat = s(:splat, node).line l
493
+ ary = s(:array, splat).line l
494
+ result = s(:masgn, ary).line l
459
495
  }
460
496
  | tSTAR mlhs_node tCOMMA mlhs_post
461
497
  {
462
- ary = s(:array, s(:splat, val[1]))
463
- ary.concat val[3].sexp_body
464
- result = s(:masgn, ary)
498
+ _, node, _, post = val
499
+
500
+ splat = s(:splat, node).line node.line
501
+ ary = s(:array, splat).line splat.line
502
+ ary.concat post.sexp_body
503
+ result = s(:masgn, ary).line ary.line
465
504
  }
466
505
  | tSTAR
467
506
  {
468
- result = s(:masgn, s(:array, s(:splat)))
507
+ l = lexer.lineno
508
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
469
509
  }
470
510
  | tSTAR tCOMMA mlhs_post
471
511
  {
472
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
512
+ _, _, post = val
513
+ l = post.line
514
+
515
+ splat = s(:splat).line l
516
+ ary = s(:array, splat, *post.sexp_body).line l
517
+ result = s(:masgn, ary).line l
473
518
  }
474
519
 
475
520
  mlhs_item: mlhs_node
@@ -480,7 +525,8 @@ rule
480
525
 
481
526
  mlhs_head: mlhs_item tCOMMA
482
527
  {
483
- result = s(:array, val[0])
528
+ lhs, _ = val
529
+ result = s(:array, lhs).line lhs.line
484
530
  }
485
531
  | mlhs_head mlhs_item tCOMMA
486
532
  {
@@ -489,7 +535,8 @@ rule
489
535
 
490
536
  mlhs_post: mlhs_item
491
537
  {
492
- result = s(:array, val[0])
538
+ item, = val
539
+ result = s(:array, item).line item.line
493
540
  }
494
541
  | mlhs_post tCOMMA mlhs_item
495
542
  {
@@ -514,7 +561,8 @@ rule
514
561
  }
515
562
  | primary_value tCOLON2 tIDENTIFIER
516
563
  {
517
- result = s(:attrasgn, val[0], :"#{val[2]}=")
564
+ recv, _, id = val
565
+ result = new_attrasgn recv, id
518
566
  }
519
567
  | primary_value call_op tCONSTANT
520
568
  {
@@ -527,7 +575,10 @@ rule
527
575
  yyerror "dynamic constant assignment"
528
576
  end
529
577
 
530
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
578
+ expr, _, id = val
579
+ l = expr.line
580
+
581
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
531
582
  }
532
583
  | tCOLON3 tCONSTANT
533
584
  {
@@ -536,7 +587,10 @@ rule
536
587
  yyerror "dynamic constant assignment"
537
588
  end
538
589
 
539
- result = s(:const, nil, s(:colon3, val[1].to_sym))
590
+ _, id = val
591
+ l = lexer.lineno
592
+
593
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
540
594
  }
541
595
  | backref
542
596
  {
@@ -545,24 +599,31 @@ rule
545
599
 
546
600
  lhs: user_variable
547
601
  {
602
+ line = lexer.lineno
548
603
  result = self.assignable val[0]
604
+ result.line = line
549
605
  }
550
606
  | keyword_variable
551
607
  {
608
+ line = lexer.lineno
552
609
  result = self.assignable val[0]
610
+ result.line = line
553
611
  debug20 9, val, result
554
612
  }
555
613
  | primary_value tLBRACK2 opt_call_args rbracket
556
614
  {
557
- result = self.aryset val[0], val[2]
615
+ lhs, _, args, _ = val
616
+ result = self.aryset lhs, args
558
617
  }
559
618
  | primary_value call_op tIDENTIFIER # REFACTOR
560
619
  {
561
- result = new_attrasgn val[0], val[2], val[1]
620
+ lhs, op, id = val
621
+ result = new_attrasgn lhs, id, op
562
622
  }
563
623
  | primary_value tCOLON2 tIDENTIFIER
564
624
  {
565
- result = s(:attrasgn, val[0], :"#{val[2]}=")
625
+ lhs, _, id = val
626
+ result = new_attrasgn lhs, id
566
627
  }
567
628
  | primary_value call_op tCONSTANT # REFACTOR?
568
629
  {
@@ -570,21 +631,27 @@ rule
570
631
  }
571
632
  | primary_value tCOLON2 tCONSTANT
572
633
  {
634
+ expr, _, id = val
635
+
573
636
  if (self.in_def || self.in_single > 0) then
574
637
  debug20 10
575
638
  yyerror "dynamic constant assignment"
576
639
  end
577
640
 
578
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
641
+ l = expr.line
642
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
579
643
  }
580
644
  | tCOLON3 tCONSTANT
581
645
  {
646
+ _, id = val
647
+
582
648
  if (self.in_def || self.in_single > 0) then
583
649
  debug20 11
584
650
  yyerror "dynamic constant assignment"
585
651
  end
586
652
 
587
- result = s(:const, s(:colon3, val[1].to_sym))
653
+ l = lexer.lineno
654
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
588
655
  }
589
656
  | backref
590
657
  {
@@ -599,7 +666,8 @@ rule
599
666
 
600
667
  cpath: tCOLON3 cname
601
668
  {
602
- result = s(:colon3, val[1].to_sym)
669
+ _, name = val
670
+ result = s(:colon3, name.to_sym).line lexer.lineno
603
671
  }
604
672
  | cname
605
673
  {
@@ -607,20 +675,23 @@ rule
607
675
  }
608
676
  | primary_value tCOLON2 cname
609
677
  {
610
- result = s(:colon2, val[0], val[2].to_sym)
678
+ pval, _, name = val
679
+
680
+ result = s(:colon2, pval, name.to_sym)
681
+ result.line pval.line
611
682
  }
612
683
 
613
684
  fname: tIDENTIFIER | tCONSTANT | tFID
614
685
  | op
615
686
  {
616
- lexer.lex_state = :expr_end
687
+ lexer.lex_state = EXPR_END
617
688
  result = val[0]
618
689
  }
619
690
 
620
691
  | reswords
621
692
  {
622
693
  (sym, _line), = val
623
- lexer.lex_state = :expr_end
694
+ lexer.lex_state = EXPR_END
624
695
  result = sym
625
696
  }
626
697
 
@@ -628,7 +699,8 @@ rule
628
699
 
629
700
  fitem: fsym
630
701
  {
631
- result = s(:lit, val[0].to_sym)
702
+ id, = val
703
+ result = s(:lit, id.to_sym).line lexer.lineno
632
704
  }
633
705
  | dsym
634
706
 
@@ -639,7 +711,7 @@ rule
639
711
  |
640
712
  undef_list tCOMMA
641
713
  {
642
- lexer.lex_state = :expr_fname
714
+ lexer.lex_state = EXPR_FNAME
643
715
  }
644
716
  fitem
645
717
  {
@@ -651,6 +723,7 @@ rule
651
723
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
652
724
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
653
725
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
726
+ # TODO: tUBANG dead?
654
727
  | tUBANG
655
728
 
656
729
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
@@ -673,8 +746,7 @@ rule
673
746
  }
674
747
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
675
748
  {
676
- val[2].sexp_type = :arglist if val[2]
677
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
749
+ result = new_op_asgn1 val
678
750
  }
679
751
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
680
752
  {
@@ -686,17 +758,27 @@ rule
686
758
  }
687
759
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
688
760
  {
689
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
761
+ lhs, _, id, op, rhs = val
762
+
763
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
690
764
  }
691
765
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
692
766
  {
693
- # TODO: assignment
694
- raise "not yet: %p" % [val]
767
+ lhs1, _, lhs2, op, rhs = val
768
+
769
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
770
+ result = new_const_op_asgn [lhs, op, rhs]
695
771
  }
696
- | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
772
+ | tCOLON3 tCONSTANT
697
773
  {
698
- # TODO: assignment
699
- raise "not yet: %p" % [val]
774
+ result = self.lexer.lineno
775
+ }
776
+ tOP_ASGN arg_rhs
777
+ {
778
+ _, lhs, line, op, rhs = val
779
+
780
+ lhs = s(:colon3, lhs.to_sym).line line
781
+ result = new_const_op_asgn [lhs, op, rhs]
700
782
  }
701
783
  | backref tOP_ASGN arg_rhs
702
784
  {
@@ -708,31 +790,33 @@ rule
708
790
  {
709
791
  v1, v2 = val[0], val[2]
710
792
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
711
- result = s(:lit, (v1.last)..(v2.last))
793
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
712
794
  else
713
- result = s(:dot2, v1, v2)
795
+ result = s(:dot2, v1, v2).line v1.line
714
796
  end
715
797
  }
716
798
  | arg tDOT3 arg
717
799
  {
718
800
  v1, v2 = val[0], val[2]
719
801
  if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
720
- result = s(:lit, (v1.last)...(v2.last))
802
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
721
803
  else
722
- result = s(:dot3, v1, v2)
804
+ result = s(:dot3, v1, v2).line v1.line
723
805
  end
724
806
  }
725
807
  | arg tDOT2
726
808
  {
727
- v1, v2 = val[0], nil
809
+ v1, _ = val
810
+ v2 = nil
728
811
 
729
- result = s(:dot2, v1, v2)
812
+ result = s(:dot2, v1, v2).line v1.line
730
813
  }
731
814
  | arg tDOT3
732
815
  {
733
- v1, v2 = val[0], nil
816
+ v1, _ = val
817
+ v2 = nil
734
818
 
735
- result = s(:dot3, v1, v2)
819
+ result = s(:dot3, v1, v2).line v1.line
736
820
  }
737
821
  | arg tPLUS arg
738
822
  {
@@ -760,7 +844,9 @@ rule
760
844
  }
761
845
  | tUMINUS_NUM simple_numeric tPOW arg
762
846
  {
763
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
847
+ lit = s(:lit, val[1]).line lexer.lineno
848
+ result = new_call(new_call(lit, :"**", argl(val[3])), :"-@")
849
+
764
850
  }
765
851
  | tUPLUS arg
766
852
  {
@@ -801,15 +887,19 @@ rule
801
887
  }
802
888
  | arg tMATCH arg
803
889
  {
804
- result = new_match val[0], val[2]
890
+ lhs, _, rhs = val
891
+ result = new_match lhs, rhs
805
892
  }
806
893
  | arg tNMATCH arg
807
894
  {
808
- result = s(:not, new_match(val[0], val[2]))
895
+ lhs, _, rhs = val
896
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
809
897
  }
810
898
  | tBANG arg
811
899
  {
812
- result = new_call val[1], :"!"
900
+ _, arg = val
901
+ result = new_call arg, :"!"
902
+ result.line arg.line
813
903
  }
814
904
  | tTILDE arg
815
905
  {
@@ -837,11 +927,13 @@ rule
837
927
  }
838
928
  | kDEFINED opt_nl arg
839
929
  {
840
- result = s(:defined, val[2])
930
+ (_, line), _, arg = val
931
+ result = s(:defined, arg).line line
841
932
  }
842
933
  | arg tEH arg opt_nl tCOLON arg
843
934
  {
844
- result = s(:if, val[0], val[2], val[5])
935
+ c, _, t, _, _, f = val
936
+ result = s(:if, c, t, f).line c.line
845
937
  }
846
938
  | primary
847
939
 
@@ -884,28 +976,25 @@ rule
884
976
  arg_rhs: arg =tOP_ASGN
885
977
  | arg kRESCUE_MOD arg
886
978
  {
887
- body, _, resbody = val
979
+ body, (_, line), resbody = val
888
980
  body = value_expr body
889
981
  resbody = remove_begin resbody
890
- result = new_rescue(body, new_resbody(s(:array), resbody))
982
+
983
+ ary = s(:array).line line
984
+ result = new_rescue(body, new_resbody(ary, resbody))
891
985
  }
892
986
 
893
987
  paren_args: tLPAREN2 opt_call_args rparen
894
988
  {
895
- result = val[1]
989
+ _, args, _ = val
990
+ result = args
896
991
  }
897
992
 
898
993
  opt_paren_args: none
899
994
  | paren_args
900
995
 
901
996
  opt_call_args: none
902
- {
903
- result = val[0]
904
- }
905
997
  | call_args
906
- {
907
- result = val[0]
908
- }
909
998
  | args tCOMMA
910
999
  {
911
1000
  result = args val
@@ -927,17 +1016,14 @@ rule
927
1016
  | args opt_block_arg
928
1017
  {
929
1018
  result = call_args val
930
- result = self.arg_blk_pass val[0], val[1]
931
1019
  }
932
1020
  | assocs opt_block_arg
933
1021
  {
934
- result = call_args [array_to_hash(val[0])]
935
- result = self.arg_blk_pass result, val[1]
1022
+ result = call_args [array_to_hash(val[0]), val[1]]
936
1023
  }
937
1024
  | args tCOMMA assocs opt_block_arg
938
1025
  {
939
- result = call_args [val[0], array_to_hash(val[2])]
940
- result = self.arg_blk_pass result, val[3]
1026
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
941
1027
  }
942
1028
  | block_arg
943
1029
  {
@@ -945,17 +1031,45 @@ rule
945
1031
  }
946
1032
 
947
1033
  command_args: {
948
- result = lexer.cmdarg.store true
1034
+ # parse26.y line 2200
1035
+
1036
+ # If call_args starts with a open paren '(' or
1037
+ # '[', look-ahead reading of the letters calls
1038
+ # CMDARG_PUSH(0), but the push must be done
1039
+ # after CMDARG_PUSH(1). So this code makes them
1040
+ # consistent by first cancelling the premature
1041
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1042
+ # finally redoing CMDARG_PUSH(0).
1043
+
1044
+ result = yychar = self.last_token_type.first
1045
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1046
+ lexer.cmdarg.pop if lookahead
1047
+ lexer.cmdarg.push true
1048
+ lexer.cmdarg.push false if lookahead
949
1049
  }
950
1050
  call_args
951
1051
  {
952
- lexer.cmdarg.restore val[0]
953
- result = val[1]
1052
+ yychar, args = val
1053
+
1054
+ # call_args can be followed by tLBRACE_ARG (that
1055
+ # does CMDARG_PUSH(0) in the lexer) but the push
1056
+ # must be done after CMDARG_POP() in the parser.
1057
+ # So this code does CMDARG_POP() to pop 0 pushed
1058
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1059
+ # by command_args, and CMDARG_PUSH(0) to restore
1060
+ # back the flag set by tLBRACE_ARG.
1061
+
1062
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1063
+ lexer.cmdarg.pop if lookahead
1064
+ lexer.cmdarg.pop
1065
+ lexer.cmdarg.push false if lookahead
1066
+ result = args
954
1067
  }
955
1068
 
956
1069
  block_arg: tAMPER arg_value
957
1070
  {
958
- result = s(:block_pass, val[1])
1071
+ _, arg = val
1072
+ result = s(:block_pass, arg).line arg.line
959
1073
  }
960
1074
 
961
1075
  opt_block_arg: tCOMMA block_arg
@@ -966,19 +1080,27 @@ rule
966
1080
 
967
1081
  args: arg_value
968
1082
  {
969
- result = s(:array, val[0])
1083
+ arg, = val
1084
+ lineno = arg.line || lexer.lineno # HACK
1085
+
1086
+ result = s(:array, arg).line lineno
970
1087
  }
971
1088
  | tSTAR arg_value
972
1089
  {
973
- result = s(:array, s(:splat, val[1]))
1090
+ _, arg = val
1091
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
974
1092
  }
975
1093
  | args tCOMMA arg_value
976
1094
  {
977
- result = self.list_append val[0], val[2]
1095
+ args, _, id = val
1096
+ result = self.list_append args, id
978
1097
  }
979
1098
  | args tCOMMA tSTAR arg_value
980
1099
  {
981
- result = self.list_append val[0], s(:splat, val[3])
1100
+ # TODO: the line number from tSTAR has been dropped
1101
+ args, _, _, id = val
1102
+ line = lexer.lineno
1103
+ result = self.list_append args, s(:splat, id).line(line)
982
1104
  }
983
1105
 
984
1106
  mrhs_arg: mrhs
@@ -996,11 +1118,14 @@ rule
996
1118
  }
997
1119
  | args tCOMMA tSTAR arg_value
998
1120
  {
999
- result = self.arg_concat val[0], val[3]
1121
+ # TODO: make all tXXXX terminals include lexer.lineno
1122
+ arg, _, _, splat = val
1123
+ result = self.arg_concat arg, splat
1000
1124
  }
1001
1125
  | tSTAR arg_value
1002
1126
  {
1003
- result = s(:splat, val[1])
1127
+ _, arg = val
1128
+ result = s(:splat, arg).line arg.line
1004
1129
  }
1005
1130
 
1006
1131
  primary: literal
@@ -1015,65 +1140,65 @@ rule
1015
1140
  | backref
1016
1141
  | tFID
1017
1142
  {
1018
- result = new_call nil, val[0].to_sym
1143
+ msg, = val
1144
+ result = new_call nil, msg.to_sym
1019
1145
  }
1020
1146
  | k_begin
1021
1147
  {
1148
+ lexer.cmdarg.push false
1022
1149
  result = self.lexer.lineno
1023
- # TODO:
1024
- # $<val>1 = cmdarg_stack;
1025
- # CMDARG_SET(0);
1026
1150
  }
1027
1151
  bodystmt k_end
1028
1152
  {
1029
- # TODO: CMDARG_SET($<val>1);
1030
- unless val[2] then
1031
- result = s(:nil)
1032
- else
1033
- result = s(:begin, val[2])
1034
- end
1035
-
1036
- result.line = val[1]
1153
+ lexer.cmdarg.pop
1154
+ result = new_begin val
1037
1155
  }
1038
- | tLPAREN_ARG rparen
1156
+ | tLPAREN_ARG
1039
1157
  {
1040
- # TODO: lex_state = :expr_endarg in between
1041
- debug20 13, val, result
1158
+ lexer.lex_state = EXPR_ENDARG
1159
+ result = lexer.lineno
1042
1160
  }
1043
- | tLPAREN_ARG
1161
+ rparen
1044
1162
  {
1045
- result = lexer.cmdarg.store false
1046
- # result = self.lexer.cmdarg.stack.dup
1047
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1163
+ _, line, _ = val
1164
+ result = s(:begin).line line
1048
1165
  }
1166
+ | tLPAREN_ARG
1049
1167
  stmt
1050
1168
  {
1051
- lexer.lex_state = :expr_endarg
1169
+ lexer.lex_state = EXPR_ENDARG
1052
1170
  }
1053
1171
  rparen
1054
1172
  {
1055
- _, cmdarg, stmt, _, _, = val
1056
- warning "(...) interpreted as grouped expression"
1057
- lexer.cmdarg.restore cmdarg
1173
+ _, stmt, _, _, = val
1174
+ # warning "(...) interpreted as grouped expression"
1058
1175
  result = stmt
1059
1176
  }
1060
1177
  | tLPAREN compstmt tRPAREN
1061
1178
  {
1062
- result = val[1] || s(:nil)
1179
+ _, stmt, _ = val
1180
+ result = stmt
1181
+ result ||= s(:nil).line lexer.lineno
1063
1182
  result.paren = true
1064
1183
  }
1065
1184
  | primary_value tCOLON2 tCONSTANT
1066
1185
  {
1067
- result = s(:colon2, val[0], val[2].to_sym)
1186
+ expr, _, id = val
1187
+
1188
+ result = s(:colon2, expr, id.to_sym).line expr.line
1068
1189
  }
1069
1190
  | tCOLON3 tCONSTANT
1070
1191
  {
1071
- result = s(:colon3, val[1].to_sym)
1192
+ _, id = val
1193
+
1194
+ result = s(:colon3, id.to_sym).line lexer.lineno
1072
1195
  }
1073
- | tLBRACK aref_args tRBRACK
1196
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
1074
1197
  {
1075
- result = val[1] || s(:array)
1198
+ _, line, args, _ = val
1199
+ result = args || s(:array)
1076
1200
  result.sexp_type = :array # aref_args is :args
1201
+ result.line line
1077
1202
  }
1078
1203
  | tLBRACE
1079
1204
  {
@@ -1085,7 +1210,8 @@ rule
1085
1210
  }
1086
1211
  | k_return
1087
1212
  {
1088
- result = s(:return)
1213
+ (_, line), = val
1214
+ result = s(:return).line line
1089
1215
  }
1090
1216
  | kYIELD tLPAREN2 call_args rparen
1091
1217
  {
@@ -1101,11 +1227,14 @@ rule
1101
1227
  }
1102
1228
  | kDEFINED opt_nl tLPAREN2 expr rparen
1103
1229
  {
1104
- result = s(:defined, val[3])
1230
+ (_, line), _, _, arg, _ = val
1231
+
1232
+ result = s(:defined, arg).line line
1105
1233
  }
1106
1234
  | kNOT tLPAREN2 expr rparen
1107
1235
  {
1108
- result = s(:call, val[2], :"!")
1236
+ _, _, lhs, _ = val
1237
+ result = new_call lhs, :"!"
1109
1238
  }
1110
1239
  | kNOT tLPAREN2 rparen
1111
1240
  {
@@ -1113,11 +1242,11 @@ rule
1113
1242
  }
1114
1243
  | fcall brace_block
1115
1244
  {
1116
- oper, iter = val[0], val[1]
1117
- call = oper # FIX
1245
+ call, iter = val
1246
+
1118
1247
  iter.insert 1, call
1119
1248
  result = iter
1120
- call.line = iter.line
1249
+ # FIX: probably not: call.line = iter.line
1121
1250
  }
1122
1251
  | method_call
1123
1252
  | method_call brace_block
@@ -1225,66 +1354,82 @@ rule
1225
1354
  }
1226
1355
  | k_def fname
1227
1356
  {
1228
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1357
+ result = self.in_def
1229
1358
 
1230
- self.comments.push self.lexer.comments
1231
- self.in_def = true
1359
+ self.in_def = true # group = local_push
1232
1360
  self.env.extend
1233
- # TODO: local->cmdargs = cmdarg_stack;
1234
- # TODO: port local_push_gen and local_pop_gen
1235
- lexer.cmdarg.stack.replace [false]
1361
+ lexer.cmdarg.push false
1362
+ lexer.cond.push false
1363
+
1364
+ self.comments.push self.lexer.comments
1236
1365
  }
1237
- f_arglist bodystmt k_end
1366
+ f_arglist bodystmt { result = lexer.lineno } k_end
1238
1367
  {
1239
- in_def, cmdarg = val[2]
1368
+ in_def = val[2]
1240
1369
 
1241
1370
  result = new_defn val
1242
1371
 
1243
- lexer.cmdarg.stack.replace cmdarg
1372
+ lexer.cond.pop # group = local_pop
1373
+ lexer.cmdarg.pop
1244
1374
  self.env.unextend
1245
1375
  self.in_def = in_def
1376
+
1246
1377
  self.lexer.comments # we don't care about comments in the body
1247
1378
  }
1248
1379
  | k_def singleton dot_or_colon
1249
1380
  {
1250
- self.comments.push self.lexer.comments
1251
- lexer.lex_state = :expr_fname
1381
+ lexer.lex_state = EXPR_FNAME
1252
1382
  }
1253
1383
  fname
1254
1384
  {
1255
- self.in_single += 1
1385
+ result = [self.in_def, lexer.lineno]
1386
+
1387
+ self.in_single += 1 # TODO: remove?
1388
+
1389
+ self.in_def = true # local_push
1256
1390
  self.env.extend
1257
- lexer.lex_state = :expr_endfn # force for args
1258
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1259
- lexer.cmdarg.stack.replace [false]
1391
+ lexer.cmdarg.push false
1392
+ lexer.cond.push false
1393
+
1394
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1395
+ self.comments.push self.lexer.comments
1260
1396
  }
1261
1397
  f_arglist bodystmt k_end
1262
1398
  {
1263
- line, cmdarg = val[5]
1264
- result = new_defs val
1265
- result[3].line line
1399
+ _, _recv, _, _, _name, (in_def, _lineno), _args, _body, _ = val
1266
1400
 
1267
- lexer.cmdarg.stack.replace cmdarg
1401
+ result = new_defs val
1268
1402
 
1403
+ lexer.cond.pop # group = local_pop
1404
+ lexer.cmdarg.pop
1269
1405
  self.env.unextend
1406
+ self.in_def = in_def
1407
+
1270
1408
  self.in_single -= 1
1409
+
1410
+ # TODO: restore cur_arg ? what's cur_arg?
1411
+
1271
1412
  self.lexer.comments # we don't care about comments in the body
1272
1413
  }
1273
1414
  | kBREAK
1274
1415
  {
1275
- result = s(:break)
1416
+ (_, line), = val
1417
+ result = s(:break).line line
1276
1418
  }
1277
1419
  | kNEXT
1278
1420
  {
1279
- result = s(:next)
1421
+ (_, line), = val
1422
+ result = s(:next).line line
1280
1423
  }
1281
1424
  | kREDO
1282
1425
  {
1283
- result = s(:redo)
1426
+ (_, line), = val
1427
+ result = s(:redo).line line
1284
1428
  }
1285
1429
  | kRETRY
1286
1430
  {
1287
- result = s(:retry)
1431
+ (_, line), = val
1432
+ result = s(:retry).line line
1288
1433
  }
1289
1434
 
1290
1435
  primary_value: primary
@@ -1323,7 +1468,9 @@ rule
1323
1468
  if_tail: opt_else
1324
1469
  | k_elsif expr_value then compstmt if_tail
1325
1470
  {
1326
- result = s(:if, val[1], val[3], val[4])
1471
+ (_, line), c, _, t, rest = val
1472
+
1473
+ result = s(:if, c, t, rest).line line
1327
1474
  }
1328
1475
 
1329
1476
  opt_else: none
@@ -1346,7 +1493,9 @@ rule
1346
1493
 
1347
1494
  f_marg_list: f_marg
1348
1495
  {
1349
- result = s(:array, val[0])
1496
+ sym, = val
1497
+
1498
+ result = s(:array, sym).line lexer.lineno
1350
1499
  }
1351
1500
  | f_marg_list tCOMMA f_marg
1352
1501
  {
@@ -1420,7 +1569,9 @@ rule
1420
1569
  }
1421
1570
  | f_block_arg
1422
1571
  {
1423
- result = call_args val
1572
+ line = lexer.lineno
1573
+ result = call_args val # TODO: push line down
1574
+ result.line line
1424
1575
  }
1425
1576
 
1426
1577
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1451,7 +1602,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1451
1602
  }
1452
1603
  | f_arg tCOMMA
1453
1604
  {
1454
- result = args val
1605
+ result = args(val) << nil
1455
1606
  }
1456
1607
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1457
1608
  {
@@ -1503,7 +1654,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1503
1654
  }
1504
1655
  | tOROP
1505
1656
  {
1506
- result = s(:args)
1657
+ result = s(:args).line lexer.lineno
1507
1658
  }
1508
1659
  | tPIPE block_param opt_bv_decl tPIPE
1509
1660
  {
@@ -1528,34 +1679,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1528
1679
 
1529
1680
  bvar: tIDENTIFIER
1530
1681
  {
1531
- result = s(:shadow, val[0].to_sym)
1682
+ id, = val
1683
+ line = lexer.lineno
1684
+ result = s(:shadow, id.to_sym).line line
1532
1685
  }
1533
1686
  | f_bad_arg
1534
1687
 
1535
1688
  lambda: {
1536
1689
  self.env.extend :dynamic
1537
- result = self.lexer.lineno
1538
-
1539
- result = lexer.lpar_beg
1690
+ result = [lexer.lineno, lexer.lpar_beg]
1540
1691
  lexer.paren_nest += 1
1541
1692
  lexer.lpar_beg = lexer.paren_nest
1542
1693
  }
1543
1694
  f_larglist
1544
1695
  {
1545
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1696
+ lexer.cmdarg.push false
1546
1697
  }
1547
1698
  lambda_body
1548
1699
  {
1549
- lpar, args, (cmdarg, lineno), body = val
1700
+ (line, lpar), args, _cmdarg, body = val
1550
1701
  lexer.lpar_beg = lpar
1551
1702
 
1552
- lexer.cmdarg.restore cmdarg
1553
- lexer.cmdarg.lexpop
1703
+ lexer.cmdarg.pop
1554
1704
 
1555
- call = new_call nil, :lambda
1705
+ call = s(:lambda).line line
1556
1706
  result = new_iter call, args, body
1557
- result.line = lineno
1558
- self.env.unextend
1707
+ result.line = line
1708
+ self.env.unextend # TODO: dynapush & dynapop
1559
1709
  }
1560
1710
 
1561
1711
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1579,8 +1729,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1579
1729
 
1580
1730
  do_block: k_do_block do_body kEND
1581
1731
  {
1582
- # TODO: maybe fix lineno to kDO's lineno?
1583
- result = val[1]
1732
+ (_, line), iter, _ = val
1733
+ result = iter.line line
1584
1734
  }
1585
1735
 
1586
1736
  block_call: command do_block
@@ -1594,8 +1744,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1594
1744
 
1595
1745
  val = invert_block_call val if inverted? val
1596
1746
 
1597
- result = val[1]
1598
- result.insert 1, val[0]
1747
+ cmd, blk = val
1748
+
1749
+ result = blk
1750
+ result.insert 1, cmd
1599
1751
  }
1600
1752
  | block_call call_op2 operation2 opt_paren_args
1601
1753
  {
@@ -1626,8 +1778,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1626
1778
  }
1627
1779
  paren_args
1628
1780
  {
1629
- args = self.call_args val[2..-1]
1630
- result = val[0].concat args.sexp_body
1781
+ call, lineno, args = val
1782
+
1783
+ result = call.concat args.sexp_body if args
1784
+ result.line lineno
1631
1785
  }
1632
1786
  | primary_value call_op operation2 opt_paren_args
1633
1787
  {
@@ -1655,7 +1809,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1655
1809
  }
1656
1810
  | kSUPER
1657
1811
  {
1658
- result = s(:zsuper)
1812
+ result = s(:zsuper).line lexer.lineno
1659
1813
  }
1660
1814
  | primary_value tLBRACK2 opt_call_args rbracket
1661
1815
  {
@@ -1704,15 +1858,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1704
1858
  }
1705
1859
 
1706
1860
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1707
- { result = lexer.cmdarg.store(false) }
1861
+ { lexer.cmdarg.push false }
1708
1862
  opt_block_param
1709
1863
  bodystmt
1710
1864
  {
1711
- line, cmdarg, param, cmpstmt = val
1865
+ line, _cmdarg, param, cmpstmt = val
1712
1866
 
1713
1867
  result = new_do_body param, cmpstmt, line
1868
+ lexer.cmdarg.pop
1714
1869
  self.env.unextend
1715
- lexer.cmdarg.restore cmdarg
1716
1870
  }
1717
1871
 
1718
1872
  case_body: k_when
@@ -1733,7 +1887,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1733
1887
  (_, line), klasses, var, _, body, rest = val
1734
1888
 
1735
1889
  klasses ||= s(:array)
1736
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1890
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1737
1891
  klasses.line line
1738
1892
 
1739
1893
  result = new_resbody(klasses, body)
@@ -1746,7 +1900,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1746
1900
 
1747
1901
  exc_list: arg_value
1748
1902
  {
1749
- result = s(:array, val[0])
1903
+ arg, = val
1904
+ result = s(:array, arg).line arg.line
1750
1905
  }
1751
1906
  | mrhs
1752
1907
  | none
@@ -1759,26 +1914,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1759
1914
 
1760
1915
  opt_ensure: k_ensure compstmt
1761
1916
  {
1762
- _, body = val
1917
+ (_, line), body = val
1763
1918
 
1764
- result = body || s(:nil)
1919
+ result = body || s(:nil).line(line)
1765
1920
  }
1766
1921
  | none
1767
1922
 
1768
1923
  literal: numeric
1769
1924
  {
1925
+ line = lexer.lineno
1770
1926
  result = s(:lit, val[0])
1927
+ result.line = line
1771
1928
  }
1772
1929
  | symbol
1773
1930
  {
1931
+ line = lexer.lineno
1774
1932
  result = s(:lit, val[0])
1933
+ result.line = line
1775
1934
  }
1776
1935
  | dsym
1777
1936
 
1778
1937
  strings: string
1779
1938
  {
1780
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1781
- result = val[0]
1939
+ str, = val
1940
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1941
+ result = str
1782
1942
  }
1783
1943
 
1784
1944
  string: tCHAR
@@ -1793,7 +1953,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1793
1953
 
1794
1954
  string1: tSTRING_BEG string_contents tSTRING_END
1795
1955
  {
1796
- result = val[1]
1956
+ _, str, (_, func) = val
1957
+
1958
+ str = dedent str if func =~ RubyLexer::STR_FUNC_ICNTNT
1959
+
1960
+ result = str
1797
1961
  }
1798
1962
  | tSTRING
1799
1963
  {
@@ -1802,7 +1966,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1802
1966
 
1803
1967
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1804
1968
  {
1805
- result = new_xstring val[1]
1969
+ result = new_xstring val
1970
+ # TODO: dedent?!?! SERIOUSLY?!?
1806
1971
  }
1807
1972
 
1808
1973
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1812,7 +1977,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1812
1977
 
1813
1978
  words: tWORDS_BEG tSPACE tSTRING_END
1814
1979
  {
1815
- result = s(:array)
1980
+ result = s(:array).line lexer.lineno
1816
1981
  }
1817
1982
  | tWORDS_BEG word_list tSTRING_END
1818
1983
  {
@@ -1836,25 +2001,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1836
2001
 
1837
2002
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1838
2003
  {
1839
- result = s(:array)
2004
+ result = s(:array).line lexer.lineno
1840
2005
  }
1841
- | tSYMBOLS_BEG symbol_list tSTRING_END
2006
+ | tSYMBOLS_BEG { result = lexer.lineno } symbol_list tSTRING_END
1842
2007
  {
1843
- result = val[1]
2008
+ _, line, list, _, = val
2009
+ list.line = line
2010
+ result = list
1844
2011
  }
1845
2012
 
1846
2013
  symbol_list: none
1847
2014
  {
1848
- result = new_symbol_list
2015
+ result = new_symbol_list.line lexer.lineno
1849
2016
  }
1850
2017
  | symbol_list word tSPACE
1851
2018
  {
1852
- result = val[0].dup << new_symbol_list_entry(val)
2019
+ list, * = val
2020
+ result = list.dup << new_symbol_list_entry(val)
1853
2021
  }
1854
2022
 
1855
2023
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1856
2024
  {
1857
- result = s(:array)
2025
+ result = s(:array).line lexer.lineno
1858
2026
  }
1859
2027
  | tQWORDS_BEG qword_list tSTRING_END
1860
2028
  {
@@ -1863,7 +2031,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1863
2031
 
1864
2032
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1865
2033
  {
1866
- result = s(:array)
2034
+ result = s(:array).line lexer.lineno # FIX
1867
2035
  }
1868
2036
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1869
2037
  {
@@ -1890,11 +2058,12 @@ opt_block_args_tail: tCOMMA block_args_tail
1890
2058
 
1891
2059
  string_contents: none
1892
2060
  {
1893
- result = s(:str, "")
2061
+ result = s(:str, "").line lexer.lineno
1894
2062
  }
1895
2063
  | string_contents string_content
1896
2064
  {
1897
- result = literal_concat(val[0], val[1])
2065
+ v1, v2 = val
2066
+ result = literal_concat v1, v2
1898
2067
  }
1899
2068
 
1900
2069
  xstring_contents: none
@@ -1903,7 +2072,8 @@ xstring_contents: none
1903
2072
  }
1904
2073
  | xstring_contents string_content
1905
2074
  {
1906
- result = literal_concat(val[0], val[1])
2075
+ v1, v2 = val
2076
+ result = literal_concat v1, v2
1907
2077
  }
1908
2078
 
1909
2079
  regexp_contents: none
@@ -1912,7 +2082,8 @@ regexp_contents: none
1912
2082
  }
1913
2083
  | regexp_contents string_content
1914
2084
  {
1915
- result = literal_concat(val[0], val[1])
2085
+ v1, v2 = val
2086
+ result = literal_concat v1, v2
1916
2087
  }
1917
2088
 
1918
2089
  string_content: tSTRING_CONTENT
@@ -1924,42 +2095,46 @@ regexp_contents: none
1924
2095
  result = lexer.lex_strterm
1925
2096
 
1926
2097
  lexer.lex_strterm = nil
1927
- lexer.lex_state = :expr_beg
2098
+ lexer.lex_state = EXPR_BEG
1928
2099
  }
1929
2100
  string_dvar
1930
2101
  {
1931
- lexer.lex_strterm = val[1]
1932
- result = s(:evstr, val[2])
2102
+ _, strterm, str = val
2103
+ lexer.lex_strterm = strterm
2104
+ result = s(:evstr, str).line str.line
1933
2105
  }
1934
2106
  | tSTRING_DBEG
1935
2107
  {
1936
2108
  result = [lexer.lex_strterm,
1937
2109
  lexer.brace_nest,
1938
2110
  lexer.string_nest, # TODO: remove
1939
- lexer.cond.store,
1940
- lexer.cmdarg.store,
1941
2111
  lexer.lex_state,
2112
+ lexer.lineno,
1942
2113
  ]
1943
2114
 
2115
+ lexer.cmdarg.push false
2116
+ lexer.cond.push false
2117
+
1944
2118
  lexer.lex_strterm = nil
1945
2119
  lexer.brace_nest = 0
1946
2120
  lexer.string_nest = 0
1947
2121
 
1948
- lexer.lex_state = :expr_beg
2122
+ lexer.lex_state = EXPR_BEG
1949
2123
  }
1950
2124
  compstmt
1951
2125
  tSTRING_DEND
1952
2126
  {
1953
2127
  _, memo, stmt, _ = val
1954
2128
 
1955
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2129
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2130
+ # TODO: heredoc_indent
1956
2131
 
1957
2132
  lexer.lex_strterm = lex_strterm
1958
2133
  lexer.brace_nest = brace_nest
1959
2134
  lexer.string_nest = string_nest
1960
2135
 
1961
- lexer.cond.restore oldcond
1962
- lexer.cmdarg.restore oldcmdarg
2136
+ lexer.cmdarg.pop
2137
+ lexer.cond.pop
1963
2138
 
1964
2139
  lexer.lex_state = oldlex_state
1965
2140
 
@@ -1969,24 +2144,24 @@ regexp_contents: none
1969
2144
  when :str, :dstr, :evstr then
1970
2145
  result = stmt
1971
2146
  else
1972
- result = s(:evstr, stmt)
2147
+ result = s(:evstr, stmt).line line
1973
2148
  end
1974
2149
  when nil then
1975
- result = s(:evstr)
2150
+ result = s(:evstr).line line
1976
2151
  else
1977
2152
  debug20 25
1978
2153
  raise "unknown string body: #{stmt.inspect}"
1979
2154
  end
1980
2155
  }
1981
2156
 
1982
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1983
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1984
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2157
+ string_dvar: tGVAR { result = s(:gvar, val[0].to_sym).line lexer.lineno }
2158
+ | tIVAR { result = s(:ivar, val[0].to_sym).line lexer.lineno }
2159
+ | tCVAR { result = s(:cvar, val[0].to_sym).line lexer.lineno }
1985
2160
  | backref
1986
2161
 
1987
2162
  symbol: tSYMBEG sym
1988
2163
  {
1989
- lexer.lex_state = :expr_end
2164
+ lexer.lex_state = EXPR_END
1990
2165
  result = val[1].to_sym
1991
2166
  }
1992
2167
  | tSYMBOL
@@ -1998,18 +2173,19 @@ regexp_contents: none
1998
2173
 
1999
2174
  dsym: tSYMBEG xstring_contents tSTRING_END
2000
2175
  {
2001
- lexer.lex_state = :expr_end
2002
- result = val[1]
2176
+ _, result, _ = val
2177
+
2178
+ lexer.lex_state = EXPR_END
2003
2179
 
2004
- result ||= s(:str, "")
2180
+ result ||= s(:str, "").line lexer.lineno
2005
2181
 
2006
2182
  case result.sexp_type
2007
2183
  when :dstr then
2008
2184
  result.sexp_type = :dsym
2009
2185
  when :str then
2010
- result = s(:lit, result.last.to_sym)
2186
+ result = s(:lit, result.last.to_sym).line result.line
2011
2187
  when :evstr then
2012
- result = s(:dsym, "", result)
2188
+ result = s(:dsym, "", result).line result.line
2013
2189
  else
2014
2190
  debug20 26, val, result
2015
2191
  end
@@ -2032,19 +2208,20 @@ regexp_contents: none
2032
2208
  | tCONSTANT
2033
2209
  | tCVAR
2034
2210
 
2035
- keyword_variable: kNIL { result = s(:nil) }
2036
- | kSELF { result = s(:self) }
2037
- | kTRUE { result = s(:true) }
2038
- | kFALSE { result = s(:false) }
2039
- | k__FILE__ { result = s(:str, self.file) }
2040
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2211
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2212
+ | kSELF { result = s(:self).line lexer.lineno }
2213
+ | kTRUE { result = s(:true).line lexer.lineno }
2214
+ | kFALSE { result = s(:false).line lexer.lineno }
2215
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2216
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
2041
2217
  | k__ENCODING__
2042
2218
  {
2219
+ l = lexer.lineno
2043
2220
  result =
2044
2221
  if defined? Encoding then
2045
- s(:colon2, s(:const, :Encoding), :UTF_8)
2222
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2046
2223
  else
2047
- s(:str, "Unsupported!")
2224
+ s(:str, "Unsupported!").line l
2048
2225
  end
2049
2226
  }
2050
2227
 
@@ -2069,12 +2246,12 @@ keyword_variable: kNIL { result = s(:nil) }
2069
2246
  debug20 29, val, result
2070
2247
  }
2071
2248
 
2072
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2073
- | tBACK_REF { result = s(:back_ref, val[0]) }
2249
+ backref: tNTH_REF { result = s(:nth_ref, val[0]).line lexer.lineno }
2250
+ | tBACK_REF { result = s(:back_ref, val[0]).line lexer.lineno }
2074
2251
 
2075
2252
  superclass: tLT
2076
2253
  {
2077
- lexer.lex_state = :expr_beg
2254
+ lexer.lex_state = EXPR_BEG
2078
2255
  lexer.command_start = true
2079
2256
  }
2080
2257
  expr_value term
@@ -2089,13 +2266,13 @@ keyword_variable: kNIL { result = s(:nil) }
2089
2266
  f_arglist: tLPAREN2 f_args rparen
2090
2267
  {
2091
2268
  result = val[1]
2092
- self.lexer.lex_state = :expr_beg
2269
+ self.lexer.lex_state = EXPR_BEG
2093
2270
  self.lexer.command_start = true
2094
2271
  }
2095
2272
  | {
2096
2273
  result = self.in_kwarg
2097
2274
  self.in_kwarg = true
2098
- # TODO: self.lexer.lex_state |= :expr_label
2275
+ self.lexer.lex_state |= EXPR_LABEL
2099
2276
  }
2100
2277
  f_args term
2101
2278
  {
@@ -2103,7 +2280,7 @@ keyword_variable: kNIL { result = s(:nil) }
2103
2280
 
2104
2281
  self.in_kwarg = kwarg
2105
2282
  result = args
2106
- lexer.lex_state = :expr_beg
2283
+ lexer.lex_state = EXPR_BEG
2107
2284
  lexer.command_start = true
2108
2285
  }
2109
2286
 
@@ -2227,12 +2404,13 @@ keyword_variable: kNIL { result = s(:nil) }
2227
2404
 
2228
2405
  f_arg: f_arg_item
2229
2406
  {
2230
- case val[0]
2407
+ arg, = val
2408
+
2409
+ case arg
2231
2410
  when Symbol then
2232
- result = s(:args)
2233
- result << val[0]
2411
+ result = s(:args, arg).line lexer.lineno
2234
2412
  when Sexp then
2235
- result = val[0]
2413
+ result = arg
2236
2414
  else
2237
2415
  debug20 32
2238
2416
  raise "Unknown f_arg type: #{val.inspect}"
@@ -2245,7 +2423,7 @@ keyword_variable: kNIL { result = s(:nil) }
2245
2423
  if list.sexp_type == :args then
2246
2424
  result = list
2247
2425
  else
2248
- result = s(:args, list)
2426
+ result = s(:args, list).line list.line
2249
2427
  end
2250
2428
 
2251
2429
  result << item
@@ -2255,38 +2433,42 @@ keyword_variable: kNIL { result = s(:nil) }
2255
2433
 
2256
2434
  f_kw: f_label arg_value
2257
2435
  {
2258
- # TODO: call_args
2259
- label, _ = val[0] # TODO: fix lineno?
2436
+ # TODO: new_kw_arg
2437
+ (label, line), arg = val
2438
+
2260
2439
  identifier = label.to_sym
2261
2440
  self.env[identifier] = :lvar
2262
2441
 
2263
- result = s(:array, s(:kwarg, identifier, val[1]))
2442
+ kwarg = s(:kwarg, identifier, arg).line line
2443
+ result = s(:array, kwarg).line line
2264
2444
  }
2265
2445
  | f_label
2266
2446
  {
2267
- label, _ = val[0] # TODO: fix lineno?
2268
- identifier = label.to_sym
2269
- self.env[identifier] = :lvar
2447
+ (label, line), = val
2270
2448
 
2271
- result = s(:array, s(:kwarg, identifier))
2449
+ id = label.to_sym
2450
+ self.env[id] = :lvar
2451
+
2452
+ result = s(:array, s(:kwarg, id).line(line)).line line
2272
2453
  }
2273
2454
 
2274
2455
  f_block_kw: f_label primary_value
2275
2456
  {
2276
- # TODO: call_args
2277
- label, _ = val[0] # TODO: fix lineno?
2278
- identifier = label.to_sym
2279
- self.env[identifier] = :lvar
2457
+ # TODO: new_kw_arg
2458
+ (label, line), expr = val
2459
+ id = label.to_sym
2460
+ self.env[id] = :lvar
2280
2461
 
2281
- result = s(:array, s(:kwarg, identifier, val[1]))
2462
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2282
2463
  }
2283
2464
  | f_label
2284
2465
  {
2285
- label, _ = val[0] # TODO: fix lineno?
2286
- identifier = label.to_sym
2287
- self.env[identifier] = :lvar
2466
+ # TODO: new_kw_arg
2467
+ (label, line), = val
2468
+ id = label.to_sym
2469
+ self.env[id] = :lvar
2288
2470
 
2289
- result = s(:array, s(:kwarg, identifier))
2471
+ result = s(:array, s(:kwarg, id).line(line)).line line
2290
2472
  }
2291
2473
 
2292
2474
  f_block_kwarg: f_block_kw
@@ -2329,17 +2511,20 @@ keyword_variable: kNIL { result = s(:nil) }
2329
2511
 
2330
2512
  f_block_optarg: f_block_opt
2331
2513
  {
2332
- result = s(:block, val[0])
2514
+ optblk, = val
2515
+ result = s(:block, optblk).line optblk.line
2333
2516
  }
2334
2517
  | f_block_optarg tCOMMA f_block_opt
2335
2518
  {
2336
- result = val[0]
2337
- result << val[2]
2519
+ optarg, _, optblk = val
2520
+ result = optarg
2521
+ result << optblk
2338
2522
  }
2339
2523
 
2340
2524
  f_optarg: f_opt
2341
2525
  {
2342
- result = s(:block, val[0])
2526
+ opt, = val
2527
+ result = s(:block, opt).line opt.line
2343
2528
  }
2344
2529
  | f_optarg tCOMMA f_opt
2345
2530
  {
@@ -2384,7 +2569,7 @@ keyword_variable: kNIL { result = s(:nil) }
2384
2569
  singleton: var_ref
2385
2570
  | tLPAREN2
2386
2571
  {
2387
- lexer.lex_state = :expr_beg
2572
+ lexer.lex_state = EXPR_BEG
2388
2573
  }
2389
2574
  expr rparen
2390
2575
  {
@@ -2393,14 +2578,11 @@ keyword_variable: kNIL { result = s(:nil) }
2393
2578
  result.sexp_type == :lit
2394
2579
  }
2395
2580
 
2396
- assoc_list: none # [!nil]
2581
+ assoc_list: none
2397
2582
  {
2398
- result = s(:array)
2399
- }
2400
- | assocs trailer # [!nil]
2401
- {
2402
- result = val[0]
2583
+ result = s(:array).line lexer.lineno
2403
2584
  }
2585
+ | assocs trailer
2404
2586
 
2405
2587
  assocs: assoc
2406
2588
  | assocs tCOMMA assoc
@@ -2414,22 +2596,27 @@ keyword_variable: kNIL { result = s(:nil) }
2414
2596
 
2415
2597
  assoc: arg_value tASSOC arg_value
2416
2598
  {
2417
- result = s(:array, val[0], val[2])
2599
+ v1, _, v2 = val
2600
+ result = s(:array, v1, v2).line v1.line
2418
2601
  }
2419
2602
  | tLABEL arg_value
2420
2603
  {
2421
- (label, _), arg = val
2422
- result = s(:array, s(:lit, label.to_sym), arg)
2604
+ (label, line), arg = val
2605
+
2606
+ lit = s(:lit, label.to_sym).line line
2607
+ result = s(:array, lit, arg).line line
2423
2608
  }
2424
2609
  | tSTRING_BEG string_contents tLABEL_END arg_value
2425
2610
  {
2426
2611
  _, sym, _, value = val
2427
2612
  sym.sexp_type = :dsym
2428
- result = s(:array, sym, value)
2613
+ result = s(:array, sym, value).line sym.line
2429
2614
  }
2430
2615
  | tDSTAR arg_value
2431
2616
  {
2432
- result = s(:array, s(:kwsplat, val[1]))
2617
+ _, arg = val
2618
+ line = arg.line
2619
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2433
2620
  }
2434
2621
 
2435
2622
  operation: tIDENTIFIER | tCONSTANT | tFID
@@ -2461,6 +2648,7 @@ end
2461
2648
 
2462
2649
  require "ruby_lexer"
2463
2650
  require "ruby_parser_extras"
2651
+ include RubyLexer::State::Values
2464
2652
 
2465
2653
  # :stopdoc:
2466
2654