ruby_parser 3.13.1 → 3.21.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.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.autotest +18 -29
  4. data/History.rdoc +312 -0
  5. data/Manifest.txt +16 -15
  6. data/README.rdoc +13 -9
  7. data/Rakefile +237 -106
  8. data/bin/ruby_parse +3 -1
  9. data/bin/ruby_parse_extract_error +9 -4
  10. data/compare/normalize.rb +54 -6
  11. data/debugging.md +172 -0
  12. data/gauntlet.md +107 -0
  13. data/lib/rp_extensions.rb +15 -36
  14. data/lib/rp_stringscanner.rb +20 -51
  15. data/lib/ruby_lexer.rb +515 -812
  16. data/lib/ruby_lexer.rex +33 -27
  17. data/lib/ruby_lexer.rex.rb +64 -31
  18. data/lib/ruby_lexer_strings.rb +638 -0
  19. data/lib/ruby_parser.rb +46 -36
  20. data/lib/{ruby_parser.yy → ruby_parser2.yy} +1400 -488
  21. data/lib/ruby_parser20.rb +10953 -0
  22. data/lib/ruby_parser21.rb +10978 -0
  23. data/lib/ruby_parser22.rb +11119 -0
  24. data/lib/ruby_parser23.rb +11160 -0
  25. data/lib/ruby_parser24.rb +11209 -0
  26. data/lib/ruby_parser25.rb +11209 -0
  27. data/lib/ruby_parser26.rb +11231 -0
  28. data/lib/ruby_parser27.rb +12960 -0
  29. data/lib/{ruby26_parser.y → ruby_parser3.yy} +1652 -521
  30. data/lib/ruby_parser30.rb +13292 -0
  31. data/lib/ruby_parser31.rb +13625 -0
  32. data/lib/ruby_parser32.rb +13577 -0
  33. data/lib/ruby_parser33.rb +13577 -0
  34. data/lib/ruby_parser_extras.rb +988 -474
  35. data/test/test_ruby_lexer.rb +1339 -1155
  36. data/test/test_ruby_parser.rb +4255 -2103
  37. data/test/test_ruby_parser_extras.rb +39 -4
  38. data/tools/munge.rb +52 -13
  39. data/tools/ripper.rb +24 -6
  40. data.tar.gz.sig +0 -0
  41. metadata +73 -56
  42. metadata.gz.sig +0 -0
  43. data/lib/ruby20_parser.rb +0 -6869
  44. data/lib/ruby20_parser.y +0 -2431
  45. data/lib/ruby21_parser.rb +0 -6944
  46. data/lib/ruby21_parser.y +0 -2449
  47. data/lib/ruby22_parser.rb +0 -6968
  48. data/lib/ruby22_parser.y +0 -2458
  49. data/lib/ruby23_parser.rb +0 -6987
  50. data/lib/ruby23_parser.y +0 -2460
  51. data/lib/ruby24_parser.rb +0 -6994
  52. data/lib/ruby24_parser.y +0 -2466
  53. data/lib/ruby25_parser.rb +0 -6994
  54. data/lib/ruby25_parser.y +0 -2466
  55. data/lib/ruby26_parser.rb +0 -7012
@@ -1,6 +1,16 @@
1
1
  # -*- racc -*-
2
2
 
3
- class Ruby26Parser
3
+ #if V == 30
4
+ class Ruby30Parser
5
+ #elif V == 31
6
+ class Ruby31Parser
7
+ #elif V == 32
8
+ class Ruby32Parser
9
+ #elif V == 33
10
+ class Ruby33Parser
11
+ #else
12
+ fail "version not specified or supported on code generation"
13
+ #endif
4
14
 
5
15
  token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
6
16
  kTHEN kELSIF kELSE kCASE kWHEN kWHILE kUNTIL kFOR kBREAK kNEXT
@@ -18,35 +28,36 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
28
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
29
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
30
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
31
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
32
  tRATIONAL tIMAGINARY
23
33
  tLABEL_END
24
- tLONELY
34
+ tLONELY
35
+ tBDOT2 tBDOT3
25
36
 
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
37
  preclow
38
+ nonassoc tLOWEST
39
+ nonassoc tLBRACE_ARG
40
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
41
+ left kOR kAND
42
+ right kNOT
43
+ nonassoc kDEFINED
44
+ right tEQL tOP_ASGN
45
+ left kRESCUE_MOD
46
+ right tEH tCOLON
47
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
48
+ left tOROP
49
+ left tANDOP
50
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
51
+ left tGT tGEQ tLT tLEQ
52
+ left tPIPE tCARET
53
+ left tAMPER2
54
+ left tLSHFT tRSHFT
55
+ left tPLUS tMINUS
56
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
57
+ right tUMINUS_NUM tUMINUS
58
+ right tPOW
59
+ right tBANG tTILDE tUPLUS
60
+ prechigh
50
61
 
51
62
  rule
52
63
 
@@ -56,11 +67,15 @@ rule
56
67
  top_compstmt
57
68
  {
58
69
  result = new_compstmt val
70
+
71
+ lexer.cond.pop # local_pop
72
+ lexer.cmdarg.pop
59
73
  }
60
74
 
61
75
  top_compstmt: top_stmts opt_terms
62
76
  {
63
- result = val[0]
77
+ stmt, _ = val
78
+ result = stmt
64
79
  }
65
80
 
66
81
  top_stmts: none
@@ -72,32 +87,29 @@ rule
72
87
  | error top_stmt
73
88
 
74
89
  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
90
  | klBEGIN
84
91
  {
85
92
  if (self.in_def || self.in_single > 0) then
86
- debug20 1
93
+ debug 1
87
94
  yyerror "BEGIN in method"
88
95
  end
89
96
  self.env.extend
90
97
  }
91
98
  begin_block
92
99
  {
93
- _, _, block = val
94
- result = block
100
+ (_, lineno), _, iter = val
101
+ iter.line lineno
102
+
103
+ (_, preexe,) = iter
104
+ preexe.line lineno
105
+
106
+ result = iter
95
107
  }
96
108
 
97
109
  begin_block: tLCURLY top_compstmt tRCURLY
98
110
  {
99
- _, stmt, _ = val
100
- result = new_iter s(:preexe), 0, stmt
111
+ (_, line), stmt, _ = val
112
+ result = new_iter s(:preexe).line(line), 0, stmt
101
113
  }
102
114
 
103
115
  bodystmt: compstmt opt_rescue k_else
@@ -133,40 +145,37 @@ rule
133
145
  | error stmt
134
146
  {
135
147
  result = val[1]
136
- debug20 2, val, result
148
+ debug 2
137
149
  }
138
150
 
139
151
  stmt_or_begin: stmt
140
152
  | klBEGIN
141
153
  {
142
- if (self.in_def || self.in_single > 0) then
143
- debug20 1
144
- yyerror "BEGIN in method"
145
- end
146
- self.env.extend
154
+ yyerror "BEGIN is permitted only at toplevel"
147
155
  }
148
- begin_block
156
+ begin_block
149
157
  {
150
- _, _, stmt = val
151
- result = stmt
158
+ result = val[2] # wtf?
152
159
  }
153
160
 
154
161
  stmt: kALIAS fitem
155
162
  {
156
163
  lexer.lex_state = EXPR_FNAME
157
- result = self.lexer.lineno
158
164
  }
159
165
  fitem
160
166
  {
161
- result = s(:alias, val[1], val[3]).line(val[2])
167
+ (_, line), lhs, _, rhs = val
168
+ result = s(:alias, lhs, rhs).line(line).line line
162
169
  }
163
170
  | kALIAS tGVAR tGVAR
164
171
  {
165
- result = s(:valias, val[1].to_sym, val[2].to_sym)
172
+ (_, line), (lhs, _), (rhs, _) = val
173
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
166
174
  }
167
175
  | kALIAS tGVAR tBACK_REF
168
176
  {
169
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
177
+ (_, line), (lhs, _), (rhs, _) = val
178
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
170
179
  }
171
180
  | kALIAS tGVAR tNTH_REF
172
181
  {
@@ -178,32 +187,41 @@ rule
178
187
  }
179
188
  | stmt kIF_MOD expr_value
180
189
  {
181
- result = new_if val[2], val[0], nil
190
+ t, _, c = val
191
+ result = new_if c, t, nil
182
192
  }
183
193
  | stmt kUNLESS_MOD expr_value
184
194
  {
185
- result = new_if val[2], nil, val[0]
195
+ f, _, c = val
196
+ result = new_if c, nil, f
186
197
  }
187
198
  | stmt kWHILE_MOD expr_value
188
199
  {
189
- result = new_while val[0], val[2], true
200
+ e, _, c = val
201
+ result = new_while e, c, true
190
202
  }
191
203
  | stmt kUNTIL_MOD expr_value
192
204
  {
193
- result = new_until val[0], val[2], true
205
+ e, _, c = val
206
+ result = new_until e, c, true
194
207
  }
195
208
  | stmt kRESCUE_MOD stmt
196
209
  {
197
210
  body, _, resbody = val
198
- result = new_rescue body, new_resbody(s(:array), resbody)
211
+
212
+ resbody = new_resbody s(:array).line(resbody.line), resbody
213
+ result = new_rescue body, resbody
199
214
  }
200
215
  | klEND tLCURLY compstmt tRCURLY
201
216
  {
217
+ (_, line), _, stmt, _ = val
218
+
202
219
  if (self.in_def || self.in_single > 0) then
203
- debug20 3
220
+ debug 3
204
221
  yyerror "END in method; use at_exit"
205
222
  end
206
- result = new_iter s(:postexe), 0, val[2]
223
+
224
+ result = new_iter s(:postexe).line(line), 0, stmt
207
225
  }
208
226
  | command_asgn
209
227
  | mlhs tEQL command_call
@@ -212,7 +230,18 @@ rule
212
230
  }
213
231
  | lhs tEQL mrhs
214
232
  {
215
- result = new_assign val[0], s(:svalue, val[2])
233
+ lhs, _, rhs = val
234
+
235
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
236
+ }
237
+ | mlhs tEQL mrhs_arg kRESCUE_MOD stmt
238
+ {
239
+ # unwraps s(:to_ary, rhs)
240
+ lhs, _, (_, rhs), _, resbody = val
241
+
242
+ resbody = new_resbody s(:array).line(resbody.line), resbody
243
+
244
+ result = new_masgn lhs, new_rescue(rhs, resbody), :wrap
216
245
  }
217
246
  | mlhs tEQL mrhs_arg
218
247
  {
@@ -234,34 +263,54 @@ rule
234
263
  }
235
264
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
236
265
  {
237
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
266
+ result = new_op_asgn1 val
238
267
  }
239
268
  | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
240
269
  {
241
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
242
- if val[1] == '&.'
243
- result.sexp_type = :safe_op_asgn
244
- end
245
- result.line = val[0].line
270
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
271
+
272
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
273
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
274
+ result.line prim.line
246
275
  }
247
276
  | primary_value call_op tCONSTANT tOP_ASGN command_rhs
248
277
  {
249
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
250
- if val[1] == '&.'
251
- result.sexp_type = :safe_op_asgn
252
- end
253
- result.line = val[0].line
278
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
279
+
280
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
281
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
282
+ result.line prim.line
254
283
  }
255
284
  | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
256
285
  {
257
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
258
- debug20 4, val, result
286
+ lhs1, _, (lhs2, line), (id, _), rhs = val
287
+
288
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
259
289
  }
260
290
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
261
291
  {
262
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
263
- debug20 5, val, result
292
+ lhs1, _, (lhs2, line), (id, _), rhs = val
293
+
294
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
295
+ }
296
+ #if V > 30
297
+ | defn_head f_opt_paren_args tEQL command
298
+ {
299
+ result = new_endless_defn val
300
+ }
301
+ | defn_head f_opt_paren_args tEQL command kRESCUE_MOD arg
302
+ {
303
+ result = new_endless_defn val
304
+ }
305
+ | defs_head f_opt_paren_args tEQL command
306
+ {
307
+ result = new_endless_defs val
264
308
  }
309
+ | defs_head f_opt_paren_args tEQL command kRESCUE_MOD arg
310
+ {
311
+ result = new_endless_defs val
312
+ }
313
+ #endif
265
314
  | backref tOP_ASGN command_rhs
266
315
  {
267
316
  self.backref_assign_error val[0]
@@ -274,30 +323,124 @@ rule
274
323
  }
275
324
  | command_call kRESCUE_MOD stmt
276
325
  {
277
- expr, _, resbody = val
326
+ expr, (_, line), resbody = val
327
+
278
328
  expr = value_expr expr
279
- result = new_rescue(expr, new_resbody(s(:array), resbody))
329
+ ary = s(:array).line line
330
+ result = new_rescue(expr, new_resbody(ary, resbody))
280
331
  }
281
332
  | command_asgn
282
333
 
283
334
  expr: command_call
284
335
  | expr kAND expr
285
336
  {
286
- result = logical_op :and, val[0], val[2]
337
+ lhs, _, rhs = val
338
+ result = logical_op :and, lhs, rhs
287
339
  }
288
340
  | expr kOR expr
289
341
  {
290
- result = logical_op :or, val[0], val[2]
342
+ lhs, _, rhs = val
343
+ result = logical_op :or, lhs, rhs
291
344
  }
292
345
  | kNOT opt_nl expr
293
346
  {
294
- result = s(:call, val[2], :"!")
347
+ (_, line), _, expr = val
348
+ result = new_call(expr, :"!").line line
349
+ # REFACTOR: call_uni_op
295
350
  }
296
351
  | tBANG command_call
297
352
  {
298
- result = s(:call, val[1], :"!")
353
+ _, cmd = val
354
+ result = new_call(cmd, :"!").line cmd.line
355
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
356
+ # REFACTOR: call_uni_op -- see parse26.y
357
+ }
358
+ | arg tASSOC
359
+ {
360
+ # value_expr($1);
361
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
362
+ self.lexer.command_start = false
363
+ result = self.in_kwarg
364
+ self.in_kwarg = true
365
+ self.env.extend
366
+ }
367
+ #if V == 30
368
+ p_expr
369
+ #else
370
+ p_top_expr_body
371
+ #endif
372
+ {
373
+ lhs, _, in_kwarg, rhs = val
374
+
375
+ self.env.unextend
376
+ self.in_kwarg = in_kwarg
377
+
378
+ rhs = new_in rhs, nil, nil, rhs.line
379
+ result = new_case lhs, rhs, rhs.line
299
380
  }
300
381
  | arg
382
+ kIN
383
+ {
384
+ # TODO? value_expr($1);
385
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
386
+ self.lexer.command_start = false
387
+ result = self.in_kwarg
388
+ self.in_kwarg = true
389
+ self.env.extend
390
+ }
391
+ #if V == 30
392
+ p_expr
393
+ #else
394
+ p_top_expr_body
395
+ #endif
396
+ {
397
+ self.env.unextend
398
+
399
+ expr, _, old_kwarg, pat = val
400
+
401
+ expr = value_expr expr
402
+
403
+ self.in_kwarg = old_kwarg
404
+ pat_in = new_in pat, nil, nil, expr.line
405
+ result = new_case expr, pat_in, expr.line
406
+ }
407
+ | arg =tLBRACE_ARG
408
+
409
+ def_name: fname
410
+ {
411
+ # TODO: numparam_name(p, fname);
412
+
413
+ (id, line), = val
414
+ old_in_def = self.in_def
415
+
416
+ self.in_def = true # group = local_push
417
+ self.env.extend
418
+ lexer.cmdarg.push false
419
+ lexer.cond.push false
420
+
421
+ result = [id.to_sym, line, old_in_def]
422
+ }
423
+ defn_head: k_def def_name
424
+ {
425
+ result = val
426
+ }
427
+ defs_head: k_def singleton dot_or_colon
428
+ {
429
+ lexer.lex_state = EXPR_FNAME
430
+ self.in_argdef = true
431
+ }
432
+ def_name
433
+ {
434
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
435
+ self.in_single += 1 # TODO: remove?
436
+
437
+ # self.in_def = true # local_push
438
+ # self.env.extend
439
+ # lexer.cmdarg.push false
440
+ # lexer.cond.push false
441
+
442
+ result = val
443
+ }
301
444
 
302
445
  expr_value: expr
303
446
  {
@@ -322,7 +465,8 @@ rule
322
465
  block_command: block_call
323
466
  | block_call call_op2 operation2 command_args
324
467
  {
325
- result = new_call val[0], val[2].to_sym, val[3]
468
+ blk, _, (msg, _line), args = val
469
+ result = new_call(blk, msg.to_sym, args).line blk.line
326
470
  }
327
471
 
328
472
  cmd_brace_block: tLBRACE_ARG
@@ -335,37 +479,45 @@ rule
335
479
  _, line, body, _ = val
336
480
 
337
481
  result = body
338
- result.line = line
482
+ result.line line
339
483
 
340
484
  # self.env.unextend
341
485
  }
342
486
 
343
487
  fcall: operation
344
488
  {
345
- result = new_call nil, val[0].to_sym
489
+ (msg, line), = val
490
+ result = new_call(nil, msg.to_sym).line line
346
491
  }
347
492
 
348
493
  command: fcall command_args =tLOWEST
349
494
  {
350
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
495
+ call, args = val
496
+ result = call.concat args.sexp_body
351
497
  }
352
498
  | fcall command_args cmd_brace_block
353
499
  {
354
- result = val[0].concat val[1].sexp_body
355
- if val[2] then
356
- block_dup_check result, val[2]
500
+ call, args, block = val
501
+
502
+ result = call.concat args.sexp_body
357
503
 
358
- result, operation = val[2], result
504
+ if block then
505
+ block_dup_check result, block
506
+
507
+ result, operation = block, result
359
508
  result.insert 1, operation
360
509
  end
361
510
  }
362
511
  | primary_value call_op operation2 command_args =tLOWEST
363
512
  {
364
- result = new_call val[0], val[2].to_sym, val[3], val[1]
513
+ lhs, callop, (op, _), args = val
514
+
515
+ result = new_call lhs, op.to_sym, args, callop
516
+ result.line lhs.line
365
517
  }
366
518
  | primary_value call_op operation2 command_args cmd_brace_block
367
519
  {
368
- recv, _, msg, args, block = val
520
+ recv, _, (msg, _line), args, block = val
369
521
  call = new_call recv, msg.to_sym, args, val[1]
370
522
 
371
523
  block_dup_check call, block
@@ -375,11 +527,14 @@ rule
375
527
  }
376
528
  | primary_value tCOLON2 operation2 command_args =tLOWEST
377
529
  {
378
- result = new_call val[0], val[2].to_sym, val[3]
530
+ lhs, _, (id, line), args = val
531
+
532
+ result = new_call lhs, id.to_sym, args
533
+ result.line line
379
534
  }
380
535
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
381
536
  {
382
- recv, _, msg, args, block = val
537
+ recv, _, (msg, _line), args, block = val
383
538
  call = new_call recv, msg.to_sym, args
384
539
 
385
540
  block_dup_check call, block
@@ -393,7 +548,9 @@ rule
393
548
  }
394
549
  | kYIELD command_args
395
550
  {
396
- result = new_yield val[1]
551
+ (_, line), args = val
552
+ result = new_yield args
553
+ result.line line # TODO: push to new_yield
397
554
  }
398
555
  | k_return call_args
399
556
  {
@@ -402,8 +559,8 @@ rule
402
559
  }
403
560
  | kBREAK call_args
404
561
  {
405
- line = val[0].last
406
- result = s(:break, ret_args(val[1])).line(line)
562
+ (_, line), args = val
563
+ result = s(:break, ret_args(args)).line line
407
564
  }
408
565
  | kNEXT call_args
409
566
  {
@@ -420,56 +577,79 @@ rule
420
577
  mlhs_inner: mlhs_basic
421
578
  | tLPAREN mlhs_inner rparen
422
579
  {
423
- result = s(:masgn, s(:array, val[1]))
580
+ _, arg, _ = val
581
+ l = arg.line
582
+
583
+ result = s(:masgn, s(:array, arg).line(l)).line l
424
584
  }
425
585
 
426
586
  mlhs_basic: mlhs_head
427
587
  {
428
- result = s(:masgn, val[0])
588
+ head, = val
589
+ result = s(:masgn, head).line head.line
429
590
  }
430
591
  | mlhs_head mlhs_item
431
592
  {
432
- result = s(:masgn, val[0] << val[1].compact)
593
+ lhs, rhs = val
594
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
433
595
  }
434
596
  | mlhs_head tSTAR mlhs_node
435
597
  {
436
- result = s(:masgn, val[0] << s(:splat, val[2]))
598
+ head, _, tail = val
599
+ head << s(:splat, tail).line(tail.line)
600
+ result = s(:masgn, head).line head.line
437
601
  }
438
602
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
439
603
  {
440
604
  ary1, _, splat, _, ary2 = val
441
605
 
442
- result = list_append ary1, s(:splat, splat)
606
+ result = list_append ary1, s(:splat, splat).line(splat.line)
443
607
  result.concat ary2.sexp_body
444
- result = s(:masgn, result)
608
+ result = s(:masgn, result).line result.line
445
609
  }
446
610
  | mlhs_head tSTAR
447
611
  {
448
- result = s(:masgn, val[0] << s(:splat))
612
+ head, _ = val
613
+ l = head.line
614
+ result = s(:masgn, head << s(:splat).line(l)).line l
449
615
  }
450
616
  | mlhs_head tSTAR tCOMMA mlhs_post
451
617
  {
452
- ary = list_append val[0], s(:splat)
453
- ary.concat val[3].sexp_body
454
- result = s(:masgn, ary)
618
+ head, _, _, post = val
619
+ ary = list_append head, s(:splat).line(head.line)
620
+ ary.concat post.sexp_body
621
+ result = s(:masgn, ary).line ary.line
455
622
  }
456
623
  | tSTAR mlhs_node
457
624
  {
458
- result = s(:masgn, s(:array, s(:splat, val[1])))
625
+ _, node = val
626
+ l = node.line
627
+ splat = s(:splat, node).line l
628
+ ary = s(:array, splat).line l
629
+ result = s(:masgn, ary).line l
459
630
  }
460
631
  | tSTAR mlhs_node tCOMMA mlhs_post
461
632
  {
462
- ary = s(:array, s(:splat, val[1]))
463
- ary.concat val[3].sexp_body
464
- result = s(:masgn, ary)
633
+ _, node, _, post = val
634
+
635
+ splat = s(:splat, node).line node.line
636
+ ary = s(:array, splat).line splat.line
637
+ ary.concat post.sexp_body
638
+ result = s(:masgn, ary).line ary.line
465
639
  }
466
640
  | tSTAR
467
641
  {
468
- result = s(:masgn, s(:array, s(:splat)))
642
+ (_, l), = val
643
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
469
644
  }
470
645
  | tSTAR tCOMMA mlhs_post
471
646
  {
472
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
647
+ _, _, post = val
648
+ l = post.line
649
+
650
+ splat = s(:splat).line l
651
+ ary = s(:array, splat, *post.sexp_body).line l
652
+ result = s(:masgn, ary).line l
473
653
  }
474
654
 
475
655
  mlhs_item: mlhs_node
@@ -480,7 +660,8 @@ rule
480
660
 
481
661
  mlhs_head: mlhs_item tCOMMA
482
662
  {
483
- result = s(:array, val[0])
663
+ lhs, _ = val
664
+ result = s(:array, lhs).line lhs.line
484
665
  }
485
666
  | mlhs_head mlhs_item tCOMMA
486
667
  {
@@ -489,7 +670,8 @@ rule
489
670
 
490
671
  mlhs_post: mlhs_item
491
672
  {
492
- result = s(:array, val[0])
673
+ item, = val
674
+ result = s(:array, item).line item.line
493
675
  }
494
676
  | mlhs_post tCOMMA mlhs_item
495
677
  {
@@ -510,81 +692,111 @@ rule
510
692
  }
511
693
  | primary_value call_op tIDENTIFIER
512
694
  {
513
- result = new_attrasgn val[0], val[2], val[1]
695
+ lhs, call_op, (id, _line) = val
696
+
697
+ result = new_attrasgn lhs, id, call_op
514
698
  }
515
699
  | primary_value tCOLON2 tIDENTIFIER
516
700
  {
517
- result = s(:attrasgn, val[0], :"#{val[2]}=")
701
+ recv, _, (id, _line) = val
702
+ result = new_attrasgn recv, id
518
703
  }
519
704
  | primary_value call_op tCONSTANT
520
705
  {
521
- result = new_attrasgn val[0], val[2], val[1]
706
+ lhs, call_op, (id, _line) = val
707
+
708
+ result = new_attrasgn lhs, id, call_op
522
709
  }
523
710
  | primary_value tCOLON2 tCONSTANT
524
711
  {
525
712
  if (self.in_def || self.in_single > 0) then
526
- debug20 7
713
+ debug 4
527
714
  yyerror "dynamic constant assignment"
528
715
  end
529
716
 
530
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
717
+ expr, _, (id, _line) = val
718
+ l = expr.line
719
+
720
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
531
721
  }
532
722
  | tCOLON3 tCONSTANT
533
723
  {
534
724
  if (self.in_def || self.in_single > 0) then
535
- debug20 8
725
+ debug 5
536
726
  yyerror "dynamic constant assignment"
537
727
  end
538
728
 
539
- result = s(:const, nil, s(:colon3, val[1].to_sym))
729
+ _, (id, l) = val
730
+
731
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
540
732
  }
541
733
  | backref
542
734
  {
543
- self.backref_assign_error val[0]
735
+ ref, = val
736
+
737
+ self.backref_assign_error ref
544
738
  }
545
739
 
546
740
  lhs: user_variable
547
741
  {
548
- result = self.assignable val[0]
742
+ var, = val
743
+
744
+ result = self.assignable var
549
745
  }
550
746
  | keyword_variable
551
747
  {
552
- result = self.assignable val[0]
553
- debug20 9, val, result
748
+ var, = val
749
+
750
+ result = self.assignable var
751
+
752
+ debug 6
554
753
  }
555
754
  | primary_value tLBRACK2 opt_call_args rbracket
556
755
  {
557
- result = self.aryset val[0], val[2]
756
+ lhs, _, args, _ = val
757
+
758
+ result = self.aryset lhs, args
558
759
  }
559
760
  | primary_value call_op tIDENTIFIER # REFACTOR
560
761
  {
561
- result = new_attrasgn val[0], val[2], val[1]
762
+ lhs, op, (id, _line) = val
763
+
764
+ result = new_attrasgn lhs, id, op
562
765
  }
563
766
  | primary_value tCOLON2 tIDENTIFIER
564
767
  {
565
- result = s(:attrasgn, val[0], :"#{val[2]}=")
768
+ lhs, _, (id, _line) = val
769
+
770
+ result = new_attrasgn lhs, id
566
771
  }
567
772
  | primary_value call_op tCONSTANT # REFACTOR?
568
773
  {
569
- result = new_attrasgn val[0], val[2], val[1]
774
+ lhs, call_op, (id, _line) = val
775
+
776
+ result = new_attrasgn lhs, id, call_op
570
777
  }
571
778
  | primary_value tCOLON2 tCONSTANT
572
779
  {
780
+ expr, _, (id, _line) = val
781
+
573
782
  if (self.in_def || self.in_single > 0) then
574
- debug20 10
783
+ debug 7
575
784
  yyerror "dynamic constant assignment"
576
785
  end
577
786
 
578
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
787
+ l = expr.line
788
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
579
789
  }
580
790
  | tCOLON3 tCONSTANT
581
791
  {
792
+ _, (id, l) = val
793
+
582
794
  if (self.in_def || self.in_single > 0) then
583
- debug20 11
795
+ debug 8
584
796
  yyerror "dynamic constant assignment"
585
797
  end
586
798
 
587
- result = s(:const, s(:colon3, val[1].to_sym))
799
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
588
800
  }
589
801
  | backref
590
802
  {
@@ -599,38 +811,34 @@ rule
599
811
 
600
812
  cpath: tCOLON3 cname
601
813
  {
602
- result = s(:colon3, val[1].to_sym)
814
+ result = wrap :colon3, val[1]
603
815
  }
604
816
  | cname
605
817
  {
606
- result = val[0].to_sym
818
+ (id, line), = val
819
+ result = [id.to_sym, line] # TODO: sexp?
607
820
  }
608
821
  | primary_value tCOLON2 cname
609
822
  {
610
- result = s(:colon2, val[0], val[2].to_sym)
823
+ pval, _, (name, _line) = val
824
+
825
+ result = s(:colon2, pval, name.to_sym)
826
+ result.line pval.line
611
827
  }
612
828
 
613
829
  fname: tIDENTIFIER | tCONSTANT | tFID
614
830
  | op
615
831
  {
616
832
  lexer.lex_state = EXPR_END
617
- result = val[0]
618
833
  }
619
834
 
620
835
  | reswords
621
- {
622
- (sym, _line), = val
623
- lexer.lex_state = EXPR_END
624
- result = sym
625
- }
626
836
 
627
- fsym: fname | symbol
628
-
629
- fitem: fsym
837
+ fitem: fname
630
838
  {
631
- result = s(:lit, val[0].to_sym)
839
+ result = wrap :lit, val[0]
632
840
  }
633
- | dsym
841
+ | symbol
634
842
 
635
843
  undef_list: fitem
636
844
  {
@@ -651,7 +859,6 @@ rule
651
859
  | tNEQ | tLSHFT | tRSHFT | tPLUS | tMINUS | tSTAR2
652
860
  | tSTAR | tDIVIDE | tPERCENT | tPOW | tDSTAR | tBANG | tTILDE
653
861
  | tUPLUS | tUMINUS | tAREF | tASET | tBACK_REF2
654
- | tUBANG
655
862
 
656
863
  reswords: k__LINE__ | k__FILE__ | k__ENCODING__ | klBEGIN | klEND
657
864
  | kALIAS | kAND | kBEGIN | kBREAK | kCASE
@@ -673,8 +880,7 @@ rule
673
880
  }
674
881
  | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
675
882
  {
676
- val[2].sexp_type = :arglist if val[2]
677
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
883
+ result = new_op_asgn1 val
678
884
  }
679
885
  | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
680
886
  {
@@ -686,24 +892,22 @@ rule
686
892
  }
687
893
  | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
688
894
  {
689
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
895
+ lhs, _, (id, _line), (op, _), rhs = val
896
+
897
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
690
898
  }
691
899
  | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
692
900
  {
693
- lhs1, _, lhs2, op, rhs = val
901
+ lhs1, _, (lhs2, _line), op, rhs = val
694
902
 
695
903
  lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
696
904
  result = new_const_op_asgn [lhs, op, rhs]
697
905
  }
698
- | tCOLON3 tCONSTANT
699
- {
700
- result = self.lexer.lineno
701
- }
702
- tOP_ASGN arg_rhs
906
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
703
907
  {
704
- _, lhs, line, op, rhs = val
908
+ _, lhs, op, rhs = val
705
909
 
706
- lhs = s(:colon3, lhs.to_sym).line line
910
+ lhs = wrap :colon3, lhs
707
911
  result = new_const_op_asgn [lhs, op, rhs]
708
912
  }
709
913
  | backref tOP_ASGN arg_rhs
@@ -715,33 +919,51 @@ rule
715
919
  | arg tDOT2 arg
716
920
  {
717
921
  v1, v2 = val[0], val[2]
718
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
719
- result = s(:lit, (v1.last)..(v2.last))
922
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
923
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
720
924
  else
721
- result = s(:dot2, v1, v2)
925
+ result = s(:dot2, v1, v2).line v1.line
722
926
  end
723
927
  }
724
928
  | arg tDOT3 arg
725
929
  {
726
930
  v1, v2 = val[0], val[2]
727
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
728
- result = s(:lit, (v1.last)...(v2.last))
931
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
932
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
729
933
  else
730
- result = s(:dot3, v1, v2)
934
+ result = s(:dot3, v1, v2).line v1.line
731
935
  end
732
936
  }
733
937
  | arg tDOT2
734
938
  {
735
- v1, v2 = val[0], nil
939
+ v1, _ = val
940
+ v2 = nil
736
941
 
737
- result = s(:dot2, v1, v2)
942
+ result = s(:dot2, v1, v2).line v1.line
738
943
  }
739
944
  | arg tDOT3
740
945
  {
741
- v1, v2 = val[0], nil
946
+ v1, _ = val
947
+ v2 = nil
948
+
949
+ result = s(:dot3, v1, v2).line v1.line
950
+ }
951
+
952
+ | tBDOT2 arg
953
+ {
954
+ _, v2, = val
955
+ v1 = nil
956
+
957
+ result = s(:dot2, v1, v2).line v2.line
958
+ }
959
+ | tBDOT3 arg
960
+ {
961
+ _, v2 = val
962
+ v1 = nil
742
963
 
743
- result = s(:dot3, v1, v2)
964
+ result = s(:dot3, v1, v2).line v2.line
744
965
  }
966
+
745
967
  | arg tPLUS arg
746
968
  {
747
969
  result = new_call val[0], :+, argl(val[2])
@@ -768,7 +990,10 @@ rule
768
990
  }
769
991
  | tUMINUS_NUM simple_numeric tPOW arg
770
992
  {
771
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
993
+ _, num, _, arg = val
994
+ lit = wrap :lit, num
995
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
996
+
772
997
  }
773
998
  | tUPLUS arg
774
999
  {
@@ -809,15 +1034,19 @@ rule
809
1034
  }
810
1035
  | arg tMATCH arg
811
1036
  {
812
- result = new_match val[0], val[2]
1037
+ lhs, _, rhs = val
1038
+ result = new_match lhs, rhs
813
1039
  }
814
1040
  | arg tNMATCH arg
815
1041
  {
816
- result = s(:not, new_match(val[0], val[2]))
1042
+ lhs, _, rhs = val
1043
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
817
1044
  }
818
1045
  | tBANG arg
819
1046
  {
820
- result = new_call val[1], :"!"
1047
+ _, arg = val
1048
+ result = new_call arg, :"!"
1049
+ result.line arg.line
821
1050
  }
822
1051
  | tTILDE arg
823
1052
  {
@@ -845,11 +1074,29 @@ rule
845
1074
  }
846
1075
  | kDEFINED opt_nl arg
847
1076
  {
848
- result = s(:defined, val[2])
1077
+ (_, line), _, arg = val
1078
+ result = s(:defined, arg).line line
849
1079
  }
850
1080
  | arg tEH arg opt_nl tCOLON arg
851
1081
  {
852
- result = s(:if, val[0], val[2], val[5])
1082
+ c, _, t, _, _, f = val
1083
+ result = s(:if, c, t, f).line c.line
1084
+ }
1085
+ | defn_head f_opt_paren_args tEQL arg
1086
+ {
1087
+ result = new_endless_defn val
1088
+ }
1089
+ | defn_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1090
+ {
1091
+ result = new_endless_defn val
1092
+ }
1093
+ | defs_head f_opt_paren_args tEQL arg
1094
+ {
1095
+ result = new_endless_defs val
1096
+ }
1097
+ | defs_head f_opt_paren_args tEQL arg kRESCUE_MOD arg
1098
+ {
1099
+ result = new_endless_defs val
853
1100
  }
854
1101
  | primary
855
1102
 
@@ -860,12 +1107,12 @@ rule
860
1107
 
861
1108
  rel_expr: arg relop arg =tGT
862
1109
  {
863
- lhs, op, rhs = val
1110
+ lhs, (op, _), rhs = val
864
1111
  result = new_call lhs, op.to_sym, argl(rhs)
865
1112
  }
866
1113
  | rel_expr relop arg =tGT
867
1114
  {
868
- lhs, op, rhs = val
1115
+ lhs, (op, _), rhs = val
869
1116
  warn "comparison '%s' after comparison", op
870
1117
  result = new_call lhs, op.to_sym, argl(rhs)
871
1118
  }
@@ -892,28 +1139,45 @@ rule
892
1139
  arg_rhs: arg =tOP_ASGN
893
1140
  | arg kRESCUE_MOD arg
894
1141
  {
895
- body, _, resbody = val
1142
+ body, (_, line), resbody = val
896
1143
  body = value_expr body
897
1144
  resbody = remove_begin resbody
898
- result = new_rescue(body, new_resbody(s(:array), resbody))
1145
+
1146
+ ary = s(:array).line line
1147
+ result = new_rescue(body, new_resbody(ary, resbody))
899
1148
  }
900
1149
 
901
1150
  paren_args: tLPAREN2 opt_call_args rparen
902
1151
  {
903
- result = val[1]
1152
+ _, args, (_, line_max) = val
1153
+
1154
+ result = args
1155
+ result.line_max = line_max if args
1156
+ }
1157
+ | tLPAREN2 args tCOMMA args_forward rparen
1158
+ {
1159
+ yyerror "Unexpected ..." unless
1160
+ self.lexer.is_local_id(:"*") &&
1161
+ self.lexer.is_local_id(:"**") &&
1162
+ self.lexer.is_local_id(:"&")
1163
+
1164
+ result = call_args val
1165
+ }
1166
+ | tLPAREN2 args_forward rparen
1167
+ {
1168
+ yyerror "Unexpected ..." unless
1169
+ self.lexer.is_local_id(:"*") &&
1170
+ self.lexer.is_local_id(:"**") &&
1171
+ self.lexer.is_local_id(:"&")
1172
+
1173
+ result = call_args val
904
1174
  }
905
1175
 
906
1176
  opt_paren_args: none
907
1177
  | paren_args
908
1178
 
909
1179
  opt_call_args: none
910
- {
911
- result = val[0]
912
- }
913
1180
  | call_args
914
- {
915
- result = val[0]
916
- }
917
1181
  | args tCOMMA
918
1182
  {
919
1183
  result = args val
@@ -935,17 +1199,14 @@ rule
935
1199
  | args opt_block_arg
936
1200
  {
937
1201
  result = call_args val
938
- result = self.arg_blk_pass val[0], val[1]
939
1202
  }
940
1203
  | assocs opt_block_arg
941
1204
  {
942
- result = call_args [array_to_hash(val[0])]
943
- result = self.arg_blk_pass result, val[1]
1205
+ result = call_args [array_to_hash(val[0]), val[1]]
944
1206
  }
945
1207
  | args tCOMMA assocs opt_block_arg
946
1208
  {
947
- result = call_args [val[0], array_to_hash(val[2])]
948
- result = self.arg_blk_pass result, val[3]
1209
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
949
1210
  }
950
1211
  | block_arg
951
1212
  {
@@ -953,18 +1214,53 @@ rule
953
1214
  }
954
1215
 
955
1216
  command_args: {
956
- result = lexer.cmdarg.store true
1217
+ # parse26.y line 2200
1218
+
1219
+ # If call_args starts with a open paren '(' or
1220
+ # '[', look-ahead reading of the letters calls
1221
+ # CMDARG_PUSH(0), but the push must be done
1222
+ # after CMDARG_PUSH(1). So this code makes them
1223
+ # consistent by first cancelling the premature
1224
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1225
+ # finally redoing CMDARG_PUSH(0).
1226
+
1227
+ result = yychar = self.last_token_type.first
1228
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1229
+ lexer.cmdarg.pop if lookahead
1230
+ lexer.cmdarg.push true
1231
+ lexer.cmdarg.push false if lookahead
957
1232
  }
958
1233
  call_args
959
1234
  {
960
- lexer.cmdarg.restore val[0]
961
- result = val[1]
1235
+ yychar, args = val
1236
+
1237
+ # call_args can be followed by tLBRACE_ARG (that
1238
+ # does CMDARG_PUSH(0) in the lexer) but the push
1239
+ # must be done after CMDARG_POP() in the parser.
1240
+ # So this code does CMDARG_POP() to pop 0 pushed
1241
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1242
+ # by command_args, and CMDARG_PUSH(0) to restore
1243
+ # back the flag set by tLBRACE_ARG.
1244
+
1245
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1246
+ lexer.cmdarg.pop if lookahead
1247
+ lexer.cmdarg.pop
1248
+ lexer.cmdarg.push false if lookahead
1249
+ result = args
962
1250
  }
963
1251
 
964
1252
  block_arg: tAMPER arg_value
965
1253
  {
966
- result = s(:block_pass, val[1])
1254
+ _, arg = val
1255
+ result = s(:block_pass, arg).line arg.line
1256
+ }
1257
+ #if V > 30
1258
+ | tAMPER
1259
+ {
1260
+ (_, line), = val
1261
+ result = s(:block_pass).line line
967
1262
  }
1263
+ #endif
968
1264
 
969
1265
  opt_block_arg: tCOMMA block_arg
970
1266
  {
@@ -974,20 +1270,40 @@ rule
974
1270
 
975
1271
  args: arg_value
976
1272
  {
977
- result = s(:array, val[0])
1273
+ arg, = val
1274
+ lineno = arg.line
1275
+
1276
+ result = s(:array, arg).line lineno
978
1277
  }
979
1278
  | tSTAR arg_value
980
1279
  {
981
- result = s(:array, s(:splat, val[1]))
1280
+ _, arg = val
1281
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1282
+ }
1283
+ #if V >= 32
1284
+ | tSTAR
1285
+ {
1286
+ (_, line), = val
1287
+ result = s(:array, s(:splat).line(line)).line line
982
1288
  }
1289
+ #endif
983
1290
  | args tCOMMA arg_value
984
1291
  {
985
- result = self.list_append val[0], val[2]
1292
+ args, _, id = val
1293
+ result = self.list_append args, id
986
1294
  }
987
1295
  | args tCOMMA tSTAR arg_value
988
1296
  {
989
- result = self.list_append val[0], s(:splat, val[3])
1297
+ args, _, (_, line), id = val
1298
+ result = self.list_append args, s(:splat, id).line(line)
990
1299
  }
1300
+ #if V >= 32
1301
+ | args tCOMMA tSTAR
1302
+ {
1303
+ args, _, (_, line) = val
1304
+ result = self.list_append args, s(:splat).line(line)
1305
+ }
1306
+ #endif
991
1307
 
992
1308
  mrhs_arg: mrhs
993
1309
  {
@@ -1004,11 +1320,13 @@ rule
1004
1320
  }
1005
1321
  | args tCOMMA tSTAR arg_value
1006
1322
  {
1007
- result = self.arg_concat val[0], val[3]
1323
+ arg, _, _, splat = val
1324
+ result = self.arg_concat arg, splat
1008
1325
  }
1009
1326
  | tSTAR arg_value
1010
1327
  {
1011
- result = s(:splat, val[1])
1328
+ _, arg = val
1329
+ result = s(:splat, arg).line arg.line
1012
1330
  }
1013
1331
 
1014
1332
  primary: literal
@@ -1023,65 +1341,63 @@ rule
1023
1341
  | backref
1024
1342
  | tFID
1025
1343
  {
1026
- result = new_call nil, val[0].to_sym
1344
+ (msg, line), = val
1345
+ result = new_call nil, msg.to_sym
1346
+ result.line line
1027
1347
  }
1028
1348
  | k_begin
1029
1349
  {
1030
- result = self.lexer.lineno
1031
- # TODO:
1032
- # $<val>1 = cmdarg_stack;
1033
- # CMDARG_SET(0);
1350
+ lexer.cmdarg.push false
1034
1351
  }
1035
1352
  bodystmt k_end
1036
1353
  {
1037
- # TODO: CMDARG_SET($<val>1);
1038
- unless val[2] then
1039
- result = s(:nil)
1040
- else
1041
- result = s(:begin, val[2])
1042
- end
1043
-
1044
- result.line = val[1]
1354
+ lexer.cmdarg.pop
1355
+ result = new_begin val
1045
1356
  }
1046
- | tLPAREN_ARG rparen
1357
+ | tLPAREN_ARG
1047
1358
  {
1048
- # TODO: lex_state = EXPR_ENDARG in between
1049
- debug20 13, val, result
1359
+ lexer.lex_state = EXPR_ENDARG
1050
1360
  }
1051
- | tLPAREN_ARG
1361
+ rparen
1052
1362
  {
1053
- result = lexer.cmdarg.store false
1054
- # result = self.lexer.cmdarg.stack.dup
1055
- # lexer.cmdarg.stack.replace [false] # TODO add api for these
1363
+ (_, line), _, _ = val
1364
+ result = s(:begin).line line
1056
1365
  }
1366
+ | tLPAREN_ARG
1057
1367
  stmt
1058
1368
  {
1059
1369
  lexer.lex_state = EXPR_ENDARG
1060
1370
  }
1061
1371
  rparen
1062
1372
  {
1063
- _, cmdarg, stmt, _, _, = val
1064
- warning "(...) interpreted as grouped expression"
1065
- lexer.cmdarg.restore cmdarg
1373
+ _, stmt, _, _, = val
1374
+ # warning "(...) interpreted as grouped expression"
1066
1375
  result = stmt
1067
1376
  }
1068
1377
  | tLPAREN compstmt tRPAREN
1069
1378
  {
1070
- result = val[1] || s(:nil)
1379
+ (_, line), stmt, _ = val
1380
+ result = stmt || s(:nil).line(line)
1071
1381
  result.paren = true
1072
1382
  }
1073
1383
  | primary_value tCOLON2 tCONSTANT
1074
1384
  {
1075
- result = s(:colon2, val[0], val[2].to_sym)
1385
+ expr, _, (id, _line) = val
1386
+
1387
+ result = s(:colon2, expr, id.to_sym).line expr.line
1076
1388
  }
1077
1389
  | tCOLON3 tCONSTANT
1078
1390
  {
1079
- result = s(:colon3, val[1].to_sym)
1391
+ result = wrap :colon3, val[1]
1080
1392
  }
1081
- | tLBRACK aref_args tRBRACK
1393
+ | tLBRACK aref_args rbracket
1082
1394
  {
1083
- result = val[1] || s(:array)
1395
+ (_, line), args, (_, line_max) = val
1396
+
1397
+ result = args || s(:array)
1084
1398
  result.sexp_type = :array # aref_args is :args
1399
+ result.line line
1400
+ result.line_max = line_max
1085
1401
  }
1086
1402
  | tLBRACE
1087
1403
  {
@@ -1093,39 +1409,49 @@ rule
1093
1409
  }
1094
1410
  | k_return
1095
1411
  {
1096
- result = s(:return)
1412
+ (_, line), = val
1413
+ result = s(:return).line line
1097
1414
  }
1098
1415
  | kYIELD tLPAREN2 call_args rparen
1099
1416
  {
1100
- result = new_yield val[2]
1417
+ (_, line), _, args, _ = val
1418
+
1419
+ result = new_yield(args).line line
1101
1420
  }
1102
1421
  | kYIELD tLPAREN2 rparen
1103
1422
  {
1104
- result = new_yield
1423
+ (_, line), _, _ = val
1424
+
1425
+ result = new_yield.line line
1105
1426
  }
1106
1427
  | kYIELD
1107
1428
  {
1108
- result = new_yield
1429
+ (_, line), = val
1430
+
1431
+ result = new_yield.line line
1109
1432
  }
1110
1433
  | kDEFINED opt_nl tLPAREN2 expr rparen
1111
1434
  {
1112
- result = s(:defined, val[3])
1435
+ (_, line), _, _, arg, _ = val
1436
+
1437
+ result = s(:defined, arg).line line
1113
1438
  }
1114
1439
  | kNOT tLPAREN2 expr rparen
1115
1440
  {
1116
- result = s(:call, val[2], :"!")
1441
+ _, _, lhs, _ = val
1442
+ result = new_call lhs, :"!"
1117
1443
  }
1118
1444
  | kNOT tLPAREN2 rparen
1119
1445
  {
1120
- debug20 14, val, result
1446
+ debug 9
1121
1447
  }
1122
1448
  | fcall brace_block
1123
1449
  {
1124
- oper, iter = val[0], val[1]
1125
- call = oper # FIX
1450
+ call, iter = val
1451
+
1126
1452
  iter.insert 1, call
1127
1453
  result = iter
1128
- call.line = iter.line
1454
+ # FIX: probably not: call.line = iter.line
1129
1455
  }
1130
1456
  | method_call
1131
1457
  | method_call brace_block
@@ -1135,9 +1461,10 @@ rule
1135
1461
  iter.insert 1, call # FIX
1136
1462
  result = iter
1137
1463
  }
1138
- | tLAMBDA lambda
1464
+ | lambda
1139
1465
  {
1140
- result = val[1] # TODO: fix lineno
1466
+ expr, = val
1467
+ result = expr
1141
1468
  }
1142
1469
  | k_if expr_value then compstmt if_tail k_end
1143
1470
  {
@@ -1169,18 +1496,20 @@ rule
1169
1496
  (_, line), _, body, _ = val
1170
1497
  result = new_case nil, body, line
1171
1498
  }
1499
+ | k_case expr_value opt_terms p_case_body k_end
1500
+ {
1501
+ (_, line), expr, _, body, _ = val
1502
+
1503
+ result = new_case expr, body, line
1504
+ }
1172
1505
  | k_for for_var kIN expr_value_do compstmt k_end
1173
1506
  {
1174
1507
  _, var, _, iter, body, _ = val
1175
1508
  result = new_for iter, var, body
1176
1509
  }
1177
1510
  | k_class
1178
- {
1179
- result = self.lexer.lineno
1180
- }
1181
1511
  cpath superclass
1182
1512
  {
1183
- self.comments.push self.lexer.comments
1184
1513
  if (self.in_def || self.in_single > 0) then
1185
1514
  yyerror "class definition in method body"
1186
1515
  end
@@ -1190,12 +1519,8 @@ rule
1190
1519
  {
1191
1520
  result = new_class val
1192
1521
  self.env.unextend
1193
- self.lexer.comments # we don't care about comments in the body
1194
1522
  }
1195
1523
  | k_class tLSHFT
1196
- {
1197
- result = self.lexer.lineno
1198
- }
1199
1524
  expr
1200
1525
  {
1201
1526
  result = self.in_def
@@ -1207,19 +1532,15 @@ rule
1207
1532
  self.in_single = 0
1208
1533
  self.env.extend
1209
1534
  }
1210
- bodystmt k_end
1535
+ bodystmt
1536
+ k_end
1211
1537
  {
1212
1538
  result = new_sclass val
1213
1539
  self.env.unextend
1214
- self.lexer.comments # we don't care about comments in the body
1215
1540
  }
1216
1541
  | k_module
1217
- {
1218
- result = self.lexer.lineno
1219
- }
1220
1542
  cpath
1221
1543
  {
1222
- self.comments.push self.lexer.comments
1223
1544
  yyerror "module definition in method body" if
1224
1545
  self.in_def or self.in_single > 0
1225
1546
 
@@ -1229,70 +1550,48 @@ rule
1229
1550
  {
1230
1551
  result = new_module val
1231
1552
  self.env.unextend
1232
- self.lexer.comments # we don't care about comments in the body
1233
1553
  }
1234
- | k_def fname
1554
+ | defn_head f_arglist bodystmt k_end
1235
1555
  {
1236
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1556
+ result, in_def = new_defn val
1237
1557
 
1238
- self.comments.push self.lexer.comments
1239
- self.in_def = true
1240
- self.env.extend
1241
- # TODO: local->cmdargs = cmdarg_stack;
1242
- # TODO: port local_push_gen and local_pop_gen
1243
- lexer.cmdarg.stack.replace [false]
1558
+ lexer.cond.pop # group = local_pop
1559
+ lexer.cmdarg.pop
1560
+ self.env.unextend
1561
+ self.in_def = in_def
1244
1562
  }
1245
- f_arglist bodystmt k_end
1563
+ | defs_head f_arglist bodystmt k_end
1246
1564
  {
1247
- in_def, cmdarg = val[2]
1248
-
1249
- result = new_defn val
1565
+ result, in_def = new_defs val
1250
1566
 
1251
- lexer.cmdarg.stack.replace cmdarg
1567
+ lexer.cond.pop # group = local_pop
1568
+ lexer.cmdarg.pop
1252
1569
  self.env.unextend
1253
1570
  self.in_def = in_def
1254
- self.lexer.comments # we don't care about comments in the body
1571
+
1572
+ self.in_single -= 1
1573
+
1574
+ # TODO: restore cur_arg ? what's cur_arg?
1255
1575
  }
1256
- | k_def singleton dot_or_colon
1576
+ | kBREAK
1257
1577
  {
1258
- self.comments.push self.lexer.comments
1259
- lexer.lex_state = EXPR_FNAME
1578
+ (_, line), = val
1579
+ result = s(:break).line line
1260
1580
  }
1261
- fname
1581
+ | kNEXT
1262
1582
  {
1263
- self.in_single += 1
1264
- self.env.extend
1265
- lexer.lex_state = EXPR_ENDFN # force for args
1266
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1267
- lexer.cmdarg.stack.replace [false]
1268
- }
1269
- f_arglist bodystmt k_end
1270
- {
1271
- line, cmdarg = val[5]
1272
- result = new_defs val
1273
- result[3].line line
1274
-
1275
- lexer.cmdarg.stack.replace cmdarg
1276
-
1277
- self.env.unextend
1278
- self.in_single -= 1
1279
- self.lexer.comments # we don't care about comments in the body
1280
- }
1281
- | kBREAK
1282
- {
1283
- result = s(:break)
1284
- }
1285
- | kNEXT
1286
- {
1287
- result = s(:next)
1583
+ (_, line), = val
1584
+ result = s(:next).line line
1288
1585
  }
1289
1586
  | kREDO
1290
1587
  {
1291
- result = s(:redo)
1588
+ (_, line), = val
1589
+ result = s(:redo).line line
1292
1590
  }
1293
1591
  | kRETRY
1294
1592
  {
1295
- result = s(:retry)
1593
+ (_, line), = val
1594
+ result = s(:retry).line line
1296
1595
  }
1297
1596
 
1298
1597
  primary_value: primary
@@ -1309,8 +1608,18 @@ rule
1309
1608
  k_case: kCASE
1310
1609
  k_for: kFOR
1311
1610
  k_class: kCLASS
1611
+ {
1612
+ result << self.lexer.comment
1613
+ }
1312
1614
  k_module: kMODULE
1615
+ {
1616
+ result << self.lexer.comment
1617
+ }
1313
1618
  k_def: kDEF
1619
+ {
1620
+ self.in_argdef = true
1621
+ result << self.lexer.comment
1622
+ }
1314
1623
  k_do: kDO
1315
1624
  k_do_block: kDO_BLOCK
1316
1625
  k_rescue: kRESCUE
@@ -1331,7 +1640,9 @@ rule
1331
1640
  if_tail: opt_else
1332
1641
  | k_elsif expr_value then compstmt if_tail
1333
1642
  {
1334
- result = s(:if, val[1], val[3], val[4])
1643
+ (_, line), c, _, t, rest = val
1644
+
1645
+ result = s(:if, c, t, rest).line line
1335
1646
  }
1336
1647
 
1337
1648
  opt_else: none
@@ -1347,18 +1658,33 @@ rule
1347
1658
  }
1348
1659
 
1349
1660
  f_marg: f_norm_arg
1661
+ {
1662
+ (sym, line), = val
1663
+
1664
+ result = s(:dummy, sym).line line
1665
+ }
1350
1666
  | tLPAREN f_margs rparen
1351
1667
  {
1352
- result = val[1]
1668
+ _, args, _ = val
1669
+ result = args
1353
1670
  }
1354
1671
 
1355
1672
  f_marg_list: f_marg
1356
1673
  {
1357
- result = s(:array, val[0])
1674
+ arg, = val
1675
+ line = arg.line
1676
+
1677
+ arg = arg.last if arg.sexp_type == :dummy
1678
+
1679
+ result = s(:array, arg).line line
1358
1680
  }
1359
1681
  | f_marg_list tCOMMA f_marg
1360
1682
  {
1361
- result = list_append val[0], val[2]
1683
+ args, _, arg = val
1684
+
1685
+ arg = arg.last if arg.sexp_type == :dummy
1686
+
1687
+ result = list_append args, arg
1362
1688
  }
1363
1689
 
1364
1690
  f_margs: f_marg_list
@@ -1367,52 +1693,50 @@ rule
1367
1693
 
1368
1694
  result = block_var args
1369
1695
  }
1370
- | f_marg_list tCOMMA tSTAR f_norm_arg
1696
+ | f_marg_list tCOMMA f_rest_marg
1371
1697
  {
1372
- args, _, _, splat = val
1698
+ args, _, rest = val
1373
1699
 
1374
- result = block_var args, "*#{splat}".to_sym
1700
+ result = block_var args, rest
1375
1701
  }
1376
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1702
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1377
1703
  {
1378
- args, _, _, splat, _, args2 = val
1704
+ lhs, _, splat, _, rhs = val
1379
1705
 
1380
- result = block_var args, "*#{splat}".to_sym, args2
1706
+ result = block_var lhs, splat, rhs
1381
1707
  }
1382
- | f_marg_list tCOMMA tSTAR
1708
+ | f_rest_marg
1383
1709
  {
1384
- args, _, _ = val
1710
+ rest, = val
1385
1711
 
1386
- result = block_var args, :*
1712
+ result = block_var rest
1387
1713
  }
1388
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1714
+ | f_rest_marg tCOMMA f_marg_list
1389
1715
  {
1390
- args, _, _, _, args2 = val
1716
+ splat, _, rest = val
1391
1717
 
1392
- result = block_var args, :*, args2
1718
+ result = block_var splat, rest
1393
1719
  }
1394
- | tSTAR f_norm_arg
1395
- {
1396
- _, splat = val
1397
1720
 
1398
- result = block_var :"*#{splat}"
1399
- }
1400
- | tSTAR f_norm_arg tCOMMA f_marg_list
1721
+ f_rest_marg: tSTAR f_norm_arg
1401
1722
  {
1402
- _, splat, _, args = val
1723
+ _, (id, line) = val
1403
1724
 
1404
- result = block_var :"*#{splat}", args
1725
+ result = args ["*#{id}".to_sym]
1726
+ result.line line
1405
1727
  }
1406
1728
  | tSTAR
1407
1729
  {
1408
- result = block_var :*
1730
+ (_, line), = val
1731
+ result = args([:*]).line line
1409
1732
  }
1410
- | tSTAR tCOMMA f_marg_list
1411
- {
1412
- _, _, args = val
1413
1733
 
1414
- result = block_var :*, args
1415
- }
1734
+ f_any_kwrest: f_kwrest
1735
+ | f_no_kwarg
1736
+
1737
+ #if V > 30
1738
+ f_eq: { self.in_argdef = false } tEQL
1739
+ #endif
1416
1740
 
1417
1741
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
1418
1742
  {
@@ -1422,13 +1746,15 @@ rule
1422
1746
  {
1423
1747
  result = call_args val
1424
1748
  }
1425
- | f_kwrest opt_f_block_arg
1749
+ | f_any_kwrest opt_f_block_arg
1426
1750
  {
1427
1751
  result = call_args val
1428
1752
  }
1429
1753
  | f_block_arg
1430
1754
  {
1431
- result = call_args val
1755
+ (id, line), = val
1756
+ result = call_args [id]
1757
+ result.line line
1432
1758
  }
1433
1759
 
1434
1760
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1437,6 +1763,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1437
1763
  }
1438
1764
  | none
1439
1765
 
1766
+ excessed_comma: tCOMMA
1767
+ {
1768
+ result = s(:WTF_COMMA!)
1769
+ }
1770
+
1440
1771
  block_param: f_arg tCOMMA f_block_optarg tCOMMA f_rest_arg opt_block_args_tail
1441
1772
  {
1442
1773
  result = args val
@@ -1457,9 +1788,10 @@ opt_block_args_tail: tCOMMA block_args_tail
1457
1788
  {
1458
1789
  result = args val
1459
1790
  }
1460
- | f_arg tCOMMA
1791
+ | f_arg excessed_comma
1461
1792
  {
1462
- result = args val
1793
+ arg, _ = val
1794
+ result = arg << nil
1463
1795
  }
1464
1796
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1465
1797
  {
@@ -1508,15 +1840,19 @@ opt_block_args_tail: tCOMMA block_args_tail
1508
1840
  {
1509
1841
  # TODO: current_arg = 0
1510
1842
  result = args val
1843
+ self.in_argdef = false
1511
1844
  }
1512
1845
  | tOROP
1513
1846
  {
1514
- result = s(:args)
1847
+ (_, line), = val
1848
+
1849
+ result = s(:args).line line
1515
1850
  }
1516
1851
  | tPIPE block_param opt_bv_decl tPIPE
1517
1852
  {
1518
1853
  # TODO: current_arg = 0
1519
1854
  result = args val
1855
+ self.in_argdef = false
1520
1856
  }
1521
1857
 
1522
1858
  opt_bv_decl: opt_nl
@@ -1536,42 +1872,42 @@ opt_block_args_tail: tCOMMA block_args_tail
1536
1872
 
1537
1873
  bvar: tIDENTIFIER
1538
1874
  {
1539
- result = s(:shadow, val[0].to_sym)
1875
+ result = wrap :shadow, val[0]
1540
1876
  }
1541
1877
  | f_bad_arg
1542
1878
 
1543
- lambda: {
1879
+ lambda: tLAMBDA
1880
+ {
1544
1881
  self.env.extend :dynamic
1545
- result = self.lexer.lineno
1546
-
1547
1882
  result = lexer.lpar_beg
1548
1883
  lexer.paren_nest += 1
1549
1884
  lexer.lpar_beg = lexer.paren_nest
1550
1885
  }
1551
1886
  f_larglist
1552
1887
  {
1553
- result = [lexer.cmdarg.store(false), self.lexer.lineno]
1888
+ lexer.cmdarg.push false
1554
1889
  }
1555
1890
  lambda_body
1556
1891
  {
1557
- lpar, args, (cmdarg, lineno), body = val
1892
+ (_, line), lpar, args, _cmdarg, body = val
1558
1893
  lexer.lpar_beg = lpar
1559
1894
 
1560
- lexer.cmdarg.restore cmdarg
1561
- lexer.cmdarg.lexpop
1895
+ lexer.cmdarg.pop
1562
1896
 
1563
- call = new_call nil, :lambda
1897
+ call = s(:lambda).line line
1564
1898
  result = new_iter call, args, body
1565
- result.line = lineno
1566
- self.env.unextend
1899
+ result.line line
1900
+ self.env.unextend # TODO: dynapush & dynapop
1567
1901
  }
1568
1902
 
1569
1903
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
1570
1904
  {
1905
+ self.in_argdef = false
1571
1906
  result = args val
1572
1907
  }
1573
1908
  | f_args
1574
1909
  {
1910
+ self.in_argdef = false
1575
1911
  result = val[0]
1576
1912
  result = 0 if result == s(:args)
1577
1913
  }
@@ -1587,8 +1923,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1587
1923
 
1588
1924
  do_block: k_do_block do_body kEND
1589
1925
  {
1590
- # TODO: maybe fix lineno to kDO's lineno?
1591
- result = val[1]
1926
+ (_, line), iter, _ = val
1927
+ result = iter.line line
1592
1928
  }
1593
1929
 
1594
1930
  block_call: command do_block
@@ -1597,21 +1933,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1597
1933
  ## if (nd_type($1) == NODE_YIELD) {
1598
1934
  ## compile_error(PARSER_ARG "block given to yield");
1599
1935
 
1936
+ cmd, blk = val
1937
+
1600
1938
  syntax_error "Both block arg and actual block given." if
1601
- val[0].block_pass?
1939
+ cmd.block_pass?
1602
1940
 
1603
- val = invert_block_call val if inverted? val
1941
+ if inverted? val then
1942
+ val = invert_block_call val
1943
+ cmd, blk = val
1944
+ end
1604
1945
 
1605
- result = val[1]
1606
- result.insert 1, val[0]
1946
+ result = blk
1947
+ result.insert 1, cmd
1607
1948
  }
1608
1949
  | block_call call_op2 operation2 opt_paren_args
1609
1950
  {
1610
- result = new_call val[0], val[2].to_sym, val[3]
1951
+ lhs, _, (id, _line), args = val
1952
+
1953
+ result = new_call lhs, id.to_sym, args
1611
1954
  }
1612
1955
  | block_call call_op2 operation2 opt_paren_args brace_block
1613
1956
  {
1614
- iter1, _, name, args, iter2 = val
1957
+ iter1, _, (name, _line), args, iter2 = val
1615
1958
 
1616
1959
  call = new_call iter1, name.to_sym, args
1617
1960
  iter2.insert 1, call
@@ -1620,7 +1963,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1620
1963
  }
1621
1964
  | block_call call_op2 operation2 command_args do_block
1622
1965
  {
1623
- iter1, _, name, args, iter2 = val
1966
+ iter1, _, (name, _line), args, iter2 = val
1624
1967
 
1625
1968
  call = new_call iter1, name.to_sym, args
1626
1969
  iter2.insert 1, call
@@ -1628,26 +1971,35 @@ opt_block_args_tail: tCOMMA block_args_tail
1628
1971
  result = iter2
1629
1972
  }
1630
1973
 
1631
- method_call: fcall
1632
- {
1633
- result = self.lexer.lineno
1634
- }
1635
- paren_args
1974
+ method_call: fcall paren_args
1636
1975
  {
1637
- args = self.call_args val[2..-1]
1638
- result = val[0].concat args.sexp_body
1976
+ call, args = val
1977
+
1978
+ result = call
1979
+
1980
+ if args then
1981
+ call.concat args.sexp_body
1982
+ result.line_max = args.line_max
1983
+ end
1639
1984
  }
1640
1985
  | primary_value call_op operation2 opt_paren_args
1641
1986
  {
1642
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1987
+ recv, call_op, (op, op_line), args = val
1988
+
1989
+ result = new_call recv, op.to_sym, args, call_op
1990
+ result.line_max = op_line unless args
1643
1991
  }
1644
1992
  | primary_value tCOLON2 operation2 paren_args
1645
1993
  {
1646
- result = new_call val[0], val[2].to_sym, val[3]
1994
+ recv, _, (op, _line), args = val
1995
+
1996
+ result = new_call recv, op.to_sym, args
1647
1997
  }
1648
1998
  | primary_value tCOLON2 operation3
1649
1999
  {
1650
- result = new_call val[0], val[2].to_sym
2000
+ lhs, _, (id, _line) = val
2001
+
2002
+ result = new_call lhs, id.to_sym
1651
2003
  }
1652
2004
  | primary_value call_op paren_args
1653
2005
  {
@@ -1663,7 +2015,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1663
2015
  }
1664
2016
  | kSUPER
1665
2017
  {
1666
- result = s(:zsuper)
2018
+ (_, line), = val
2019
+ result = s(:zsuper).line line
1667
2020
  }
1668
2021
  | primary_value tLBRACK2 opt_call_args rbracket
1669
2022
  {
@@ -1673,28 +2026,28 @@ opt_block_args_tail: tCOMMA block_args_tail
1673
2026
  brace_block: tLCURLY
1674
2027
  {
1675
2028
  self.env.extend :dynamic
1676
- result = self.lexer.lineno
1677
2029
  }
1678
- brace_body tRCURLY
2030
+ brace_body
2031
+ tRCURLY
1679
2032
  {
1680
- _, line, body, _ = val
2033
+ (_, line), _, body, _ = val
1681
2034
 
1682
2035
  result = body
1683
- result.line = line
2036
+ result.line line
1684
2037
 
1685
2038
  self.env.unextend
1686
2039
  }
1687
2040
  | k_do
1688
2041
  {
1689
2042
  self.env.extend :dynamic
1690
- result = self.lexer.lineno
1691
2043
  }
1692
- do_body kEND
2044
+ do_body
2045
+ kEND
1693
2046
  {
1694
- _, line, body, _ = val
2047
+ (_, line), _, body, _ = val
1695
2048
 
1696
2049
  result = body
1697
- result.line = line
2050
+ result.line line
1698
2051
 
1699
2052
  self.env.unextend
1700
2053
  }
@@ -1712,36 +2065,631 @@ opt_block_args_tail: tCOMMA block_args_tail
1712
2065
  }
1713
2066
 
1714
2067
  do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1715
- { result = lexer.cmdarg.store(false) }
2068
+ { lexer.cmdarg.push false }
1716
2069
  opt_block_param
1717
2070
  bodystmt
1718
2071
  {
1719
- line, cmdarg, param, cmpstmt = val
2072
+ line, _cmdarg, param, cmpstmt = val
1720
2073
 
1721
2074
  result = new_do_body param, cmpstmt, line
2075
+ lexer.cmdarg.pop
1722
2076
  self.env.unextend
1723
- lexer.cmdarg.restore cmdarg
1724
2077
  }
1725
2078
 
1726
- case_body: k_when
2079
+ case_args: arg_value
1727
2080
  {
1728
- result = self.lexer.lineno
2081
+ arg, = val
2082
+
2083
+ result = s(:array, arg).line arg.line
2084
+ }
2085
+ | tSTAR arg_value
2086
+ {
2087
+ _, arg = val
2088
+
2089
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
2090
+ }
2091
+ | case_args tCOMMA arg_value
2092
+ {
2093
+ args, _, id = val
2094
+
2095
+ result = self.list_append args, id
1729
2096
  }
1730
- args then compstmt cases
2097
+ | case_args tCOMMA tSTAR arg_value
1731
2098
  {
1732
- result = new_when(val[2], val[4])
1733
- result.line = val[1]
1734
- result << val[5] if val[5]
2099
+ args, _, _, id = val
2100
+
2101
+ result = self.list_append args, s(:splat, id).line(id.line)
2102
+ }
2103
+
2104
+ case_body: k_when
2105
+ case_args then compstmt cases
2106
+ {
2107
+ (_, line), case_args, _then, body, cases = val
2108
+
2109
+ result = new_when case_args, body
2110
+ result.line line
2111
+ result << cases if cases
1735
2112
  }
1736
2113
 
1737
2114
  cases: opt_else | case_body
2115
+ ######################################################################
2116
+
2117
+ p_case_body: kIN
2118
+ {
2119
+ self.lexer.lex_state = EXPR_BEG|EXPR_LABEL
2120
+ self.lexer.command_start = false
2121
+ result = self.in_kwarg
2122
+ self.in_kwarg = true
2123
+ push_pvtbl
2124
+ push_pktbl
2125
+ }
2126
+ p_top_expr then
2127
+ {
2128
+ pop_pktbl
2129
+ pop_pvtbl
2130
+ old_kwargs = _values[-3]
2131
+ self.in_kwarg = old_kwargs
2132
+ }
2133
+ compstmt
2134
+ p_cases
2135
+ {
2136
+ (_, line), _, pat, _, _, body, cases = val
2137
+
2138
+ result = new_in pat, body, cases, line
2139
+ }
2140
+
2141
+ p_cases: opt_else
2142
+ | p_case_body
2143
+
2144
+ p_top_expr: p_top_expr_body
2145
+ | p_top_expr_body kIF_MOD expr_value
2146
+ {
2147
+ body, _, cond = val
2148
+ body = remove_begin body
2149
+
2150
+ result = s(:if, cond, body, nil).line body.line
2151
+ }
2152
+ | p_top_expr_body kUNLESS_MOD expr_value
2153
+ {
2154
+ body, _, cond = val
2155
+ body = remove_begin body
2156
+
2157
+ result = s(:if, cond, nil, body).line body.line
2158
+ }
2159
+
2160
+ p_top_expr_body: p_expr
2161
+ | p_expr tCOMMA
2162
+ {
2163
+ expr, _ = val
2164
+
2165
+ tail = new_array_pattern_tail nil, true, nil, nil
2166
+ result = new_array_pattern nil, expr, tail, expr.line
2167
+ }
2168
+ | p_expr tCOMMA p_args
2169
+ {
2170
+ expr, _, args = val
2171
+
2172
+ result = new_array_pattern nil, expr, args, expr.line
2173
+ }
2174
+ | p_find
2175
+ {
2176
+ find, = val
2177
+
2178
+ result = new_find_pattern nil, find
2179
+ }
2180
+ | p_args_tail
2181
+ {
2182
+ args, = val
2183
+ result = new_array_pattern nil, nil, args, args.line
2184
+ }
2185
+ | p_kwargs
2186
+ {
2187
+ kwargs, = val
2188
+ result = new_hash_pattern nil, kwargs, kwargs.line
2189
+ }
2190
+
2191
+ p_expr: p_as
2192
+
2193
+ p_as: p_expr tASSOC p_variable
2194
+ {
2195
+ # NODE *n = NEW_LIST($1, &@$);
2196
+ # n = list_append(p, n, $3);
2197
+ # $$ = new_hash(p, n, &@$);
2198
+
2199
+ expr, _, var = val
2200
+
2201
+ id = var.last
2202
+
2203
+ self.env[id] = :lvar # HACK: need to extend env
2204
+ lhs = s(:lasgn, id).line var.line
2205
+
2206
+ result = new_assign lhs, expr
2207
+ }
2208
+ | p_alt
2209
+
2210
+ p_alt: p_alt tPIPE p_expr_basic
2211
+ {
2212
+ lhs, _, rhs = val
2213
+
2214
+ result = s(:or, lhs, rhs).line lhs.line
2215
+ }
2216
+ | p_expr_basic
2217
+
2218
+ p_lparen: tLPAREN2 { push_pktbl }
2219
+ p_lbracket: tLBRACK2 { push_pktbl }
2220
+
2221
+ p_expr_basic: p_value
2222
+ #if V > 30
2223
+ | p_variable
2224
+ #endif
2225
+ | p_const p_lparen p_args tRPAREN
2226
+ {
2227
+ lhs, _, args, _ = val
2228
+
2229
+ pop_pktbl
2230
+ result = new_array_pattern(lhs, nil, args, lhs.line)
2231
+ }
2232
+ | p_const p_lparen p_find tRPAREN
2233
+ {
2234
+ const, _, find, _ = val
2235
+
2236
+ pop_pktbl
2237
+ result = new_find_pattern(const, find).line const.line
2238
+ }
2239
+ | p_const p_lparen p_kwargs tRPAREN
2240
+ {
2241
+ lhs, _, kwargs, _ = val
2242
+
2243
+ pop_pktbl
2244
+ result = new_hash_pattern(lhs, kwargs, lhs.line)
2245
+ }
2246
+ | p_const tLPAREN2 tRPAREN
2247
+ {
2248
+ const, _, _ = val
2249
+
2250
+ tail = new_array_pattern_tail nil, nil, nil, nil
2251
+ result = new_array_pattern const, nil, tail, const.line
2252
+ }
2253
+ | p_const p_lbracket p_args rbracket
2254
+ {
2255
+ const, _, pre_arg, _ = val
2256
+
2257
+ pop_pktbl
2258
+ result = new_array_pattern const, nil, pre_arg, const.line
2259
+ }
2260
+ | p_const p_lbracket p_find rbracket
2261
+ {
2262
+ const, _, find, _ = val
2263
+
2264
+ pop_pktbl
2265
+ result = new_find_pattern(const, find).line const.line
2266
+ }
2267
+ | p_const p_lbracket p_kwargs rbracket
2268
+ {
2269
+ const, _, kwargs, _ = val
2270
+
2271
+ result = new_hash_pattern const, kwargs, const.line
2272
+ }
2273
+ | p_const tLBRACK2 rbracket
2274
+ {
2275
+ const, _, _ = val
2276
+
2277
+ tail = new_array_pattern_tail nil, nil, nil, nil
2278
+ result = new_array_pattern const, nil, tail, const.line
2279
+ }
2280
+ | tLBRACK p_args rbracket
2281
+ {
2282
+ _, pat, _ = val
2283
+
2284
+ result = new_array_pattern nil, nil, pat, pat.line
2285
+ }
2286
+ | tLBRACK p_find rbracket
2287
+ {
2288
+ _, find, _ = val
2289
+
2290
+ result = new_find_pattern nil, find
2291
+ }
2292
+ | tLBRACK rbracket
2293
+ {
2294
+ (_, line), _ = val
2295
+
2296
+ result = s(:array_pat).line line
2297
+ }
2298
+ | tLBRACE
2299
+ {
2300
+ push_pktbl
2301
+ result = self.in_kwarg
2302
+ self.in_kwarg = false
2303
+ }
2304
+ p_kwargs rbrace
2305
+ {
2306
+ _, in_kwarg, kwargs, _ = val
2307
+
2308
+ pop_pktbl
2309
+ self.in_kwarg = in_kwarg
2310
+
2311
+ result = new_hash_pattern(nil, kwargs, kwargs.line)
2312
+ }
2313
+ | tLBRACE rbrace
2314
+ {
2315
+ (_, line), _ = val
2316
+
2317
+ tail = new_hash_pattern_tail nil, nil, line
2318
+ result = new_hash_pattern nil, tail, line
2319
+ }
2320
+ | tLPAREN { push_pktbl } p_expr tRPAREN
2321
+ {
2322
+ _, _, expr, _ = val
2323
+
2324
+ pop_pktbl
2325
+ result = expr
2326
+ }
2327
+
2328
+ p_args: p_expr
2329
+ {
2330
+ expr, = val
2331
+
2332
+ ary = s(:array_TAIL, expr).line expr.line
2333
+ result = new_array_pattern_tail(ary, nil, nil, nil).line expr.line
2334
+ }
2335
+ | p_args_head
2336
+ {
2337
+ head, = val
2338
+
2339
+ result = new_array_pattern_tail head, true, nil, nil
2340
+ }
2341
+ | p_args_head p_arg
2342
+ {
2343
+ head, tail = val
2344
+
2345
+ both = array_pat_concat head, tail
2346
+
2347
+ result = new_array_pattern_tail both, nil, nil, nil
2348
+ result.line head.line
2349
+ }
2350
+ #if V < 32
2351
+ | p_args_head tSTAR tIDENTIFIER
2352
+ {
2353
+ head, _, (id, _line) = val
2354
+
2355
+ result = new_array_pattern_tail head, true, id.to_sym, nil
2356
+ result.line head.line
2357
+ }
2358
+ | p_args_head tSTAR tIDENTIFIER tCOMMA p_args_post
2359
+ {
2360
+ head, _, (id, _line), _, post = val
2361
+
2362
+ result = new_array_pattern_tail head, true, id.to_sym, post
2363
+ result.line head.line
2364
+ }
2365
+ | p_args_head tSTAR
2366
+ {
2367
+ expr, _ = val
2368
+
2369
+ result = new_array_pattern_tail(expr, true, nil, nil).line expr.line
2370
+ }
2371
+ | p_args_head tSTAR tCOMMA p_args_post
2372
+ {
2373
+ head, _, _, post = val
2374
+
2375
+ result = new_array_pattern_tail(head, true, nil, post).line head.line
2376
+ }
2377
+ #else
2378
+ | p_args_head p_rest
2379
+ {
2380
+ head, (rest, _) = val
2381
+
2382
+ result = new_array_pattern_tail(head, true, rest, nil).line head.line
2383
+ }
2384
+ | p_args_head p_rest tCOMMA p_args_post
2385
+ {
2386
+ head, (rest, _), _, post = val
2387
+
2388
+ result = new_array_pattern_tail(head, true, rest, post).line head.line
2389
+ }
2390
+ #endif
2391
+ | p_args_tail
2392
+
2393
+ p_args_head: p_arg tCOMMA
2394
+ {
2395
+ arg, _ = val
2396
+ result = arg
2397
+ }
2398
+ | p_args_head p_arg tCOMMA
2399
+ {
2400
+ head, tail, _ = val
2401
+
2402
+ result = s(:PATTERN, *head.sexp_body, *tail.sexp_body)
2403
+ result.line head.line
2404
+ }
2405
+
2406
+ p_args_tail: p_rest
2407
+ {
2408
+ (id, line), = val
2409
+
2410
+ result = new_array_pattern_tail nil, true, id, nil
2411
+ result.line line
2412
+ }
2413
+ | p_rest tCOMMA p_args_post
2414
+ {
2415
+ (id, line), _, rhs = val
2416
+
2417
+ result = new_array_pattern_tail nil, true, id, rhs
2418
+ result.line line
2419
+ }
2420
+
2421
+ p_find: p_rest tCOMMA p_args_post tCOMMA p_rest
2422
+ {
2423
+ lhs, _, mid, _, rhs = val
2424
+
2425
+ result = new_find_pattern_tail lhs, mid, rhs
2426
+ }
2427
+
2428
+ p_rest: tSTAR tIDENTIFIER
2429
+ {
2430
+ _, (id, line) = val
2431
+
2432
+ result = [id.to_sym, line]
2433
+ }
2434
+ | tSTAR
2435
+ {
2436
+ (_id, line), = val
2437
+
2438
+ result = [nil, line]
2439
+ }
2440
+
2441
+ p_args_post: p_arg
2442
+ | p_args_post tCOMMA p_arg
2443
+ {
2444
+ lhs, _, rhs = val
2445
+
2446
+ result = array_pat_concat lhs, rhs
2447
+ }
2448
+
2449
+ p_arg: p_expr
2450
+ {
2451
+ expr, = val
2452
+ expr = s(:array_TAIL, expr).line expr.line unless
2453
+ expr.sexp_type == :array_TAIL
2454
+ result = expr
2455
+ }
2456
+
2457
+ p_kwargs: p_kwarg tCOMMA p_any_kwrest
2458
+ {
2459
+ kw_arg, _, rest = val
2460
+ # TODO? new_unique_key_hash(p, $1, &@$)
2461
+ result = new_hash_pattern_tail kw_arg, rest, kw_arg.line
2462
+ }
2463
+ | p_kwarg
2464
+ {
2465
+ kwarg, = val
2466
+ # TODO? new_unique_key_hash(p, $1, &@$)
2467
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2468
+ }
2469
+ | p_kwarg tCOMMA
2470
+ {
2471
+ kwarg, _ = val
2472
+ # TODO? new_unique_key_hash(p, $1, &@$)
2473
+ result = new_hash_pattern_tail kwarg, nil, kwarg.line
2474
+ }
2475
+ | p_any_kwrest
2476
+ {
2477
+ rest, = val
2478
+
2479
+ result = new_hash_pattern_tail nil, rest, rest.line
2480
+ }
2481
+
2482
+ p_kwarg: p_kw # TODO? rb_ary_new_from_args(1, $1)
2483
+ | p_kwarg tCOMMA p_kw
2484
+ {
2485
+ kwarg, _, kw = val
2486
+ kwarg.concat kw.sexp_body
2487
+ result = kwarg
2488
+ }
2489
+
2490
+ p_kw: p_kw_label p_expr
2491
+ {
2492
+ # TODO: error_duplicate_pattern_key(p, get_id($1), &@1);
2493
+ lhs, rhs = val
2494
+
2495
+ result = s(:PAIR, lhs, rhs).line lhs.line
2496
+ }
2497
+ | p_kw_label
2498
+ {
2499
+ lhs, = val
2500
+
2501
+ # TODO: error_duplicate_pattern_variable(p, get_id($1), &@1);
2502
+
2503
+ # TODO: if ($1 && !is_local_id(get_id($1))) {
2504
+ # yyerror1(&@1, "key must be valid as local variables");
2505
+ # }
2506
+
2507
+ # $$ = list_append(p, NEW_LIST(NEW_LIT(ID2SYM($1), &@$), &@$),
2508
+ # assignable(p, $1, 0, &@$));
2509
+
2510
+ case lhs.sexp_type
2511
+ when :lit then
2512
+ assignable [lhs.value, lhs.line]
2513
+ else
2514
+ # TODO or done?
2515
+ debug 10
2516
+ end
2517
+
2518
+ # TODO PAIR -> LIST ?
2519
+ result = s(:PAIR, lhs, nil).line lhs.line
2520
+ }
2521
+
2522
+ p_kw_label: tLABEL
2523
+ {
2524
+ result = wrap :lit, val[0]
2525
+ }
2526
+ #if V > 30
2527
+ | tSTRING_BEG string_contents tLABEL_END
2528
+ {
2529
+ # you can't actually get here the way I lex labels
2530
+ debug 11
2531
+ }
2532
+ #endif
2533
+
2534
+ p_kwrest: kwrest_mark tIDENTIFIER
2535
+ {
2536
+ _, (id, line) = val
2537
+
2538
+ name = id.to_sym
2539
+ self.assignable [name, line]
2540
+ result = s(:kwrest, :"**#{name}").line line
2541
+ }
2542
+ | kwrest_mark
2543
+ {
2544
+ (_, line), = val
2545
+
2546
+ result = s(:kwrest, :"**").line line
2547
+ }
2548
+
2549
+ p_kwnorest: kwrest_mark kNIL
2550
+ {
2551
+ (_, line), _ = val
2552
+
2553
+ # TODO: or s(:norest)? s(:**nil)?
2554
+ result = s(:kwrest, :"**nil").line line
2555
+ }
2556
+
2557
+ p_any_kwrest: p_kwrest
2558
+ | p_kwnorest
2559
+
2560
+ p_value: p_primitive
2561
+ | p_primitive tDOT2 p_primitive
2562
+ {
2563
+ lhs, _, rhs = val
2564
+
2565
+ lhs = value_expr lhs
2566
+ rhs = value_expr rhs
2567
+
2568
+ result = s(:dot2, lhs, rhs).line lhs.line
2569
+ }
2570
+ | p_primitive tDOT3 p_primitive
2571
+ {
2572
+ lhs, _, rhs = val
2573
+
2574
+ lhs = value_expr lhs
2575
+ rhs = value_expr rhs
2576
+
2577
+ result = s(:dot3, lhs, rhs).line lhs.line
2578
+ }
2579
+ | p_primitive tDOT2
2580
+ {
2581
+ v1, _ = val
2582
+
2583
+ result = s(:dot2, v1, nil).line v1.line
2584
+ }
2585
+ | p_primitive tDOT3
2586
+ {
2587
+ v1, _ = val
2588
+
2589
+ result = s(:dot3, v1, nil).line v1.line
2590
+ }
2591
+ #if V == 30
2592
+ | p_variable
2593
+ #endif
2594
+ | p_var_ref
2595
+ #if V > 30
2596
+ | p_expr_ref
2597
+ #endif
2598
+ | p_const
2599
+ | tBDOT2 p_primitive
2600
+ {
2601
+ _, v1 = val
2602
+
2603
+ result = s(:dot2, nil, v1).line v1.line
2604
+ }
2605
+ | tBDOT3 p_primitive
2606
+ {
2607
+ _, v1 = val
2608
+
2609
+ result = s(:dot3, nil, v1).line v1.line
2610
+ }
2611
+
2612
+ p_primitive: literal
2613
+ | strings
2614
+ | xstring
2615
+ | regexp
2616
+ | words
2617
+ {
2618
+ result = ary_to_pat val[0]
2619
+ }
2620
+ | qwords
2621
+ {
2622
+ result = ary_to_pat val[0]
2623
+ }
2624
+ | symbols
2625
+ {
2626
+ result = ary_to_pat val[0]
2627
+ }
2628
+ | qsymbols
2629
+ {
2630
+ result = ary_to_pat val[0]
2631
+ }
2632
+ | keyword_variable
2633
+ {
2634
+ # TODO? if (!($$ = gettable(p, $1, &@$))) $$ = NEW_BEGIN(0, &@$);
2635
+ var, = val
2636
+
2637
+ result = var
2638
+ }
2639
+ | lambda
2640
+
2641
+ p_variable: tIDENTIFIER
2642
+ {
2643
+ # TODO: error_duplicate_pattern_variable(p, $1, &@1);
2644
+ # TODO: assignable(p, $1, 0, &@$);
2645
+ result = wrap :lasgn, val[0]
2646
+ }
2647
+
2648
+ p_var_ref: tCARET tIDENTIFIER
2649
+ {
2650
+ # TODO: check id against env for lvar or dvar
2651
+ result = wrap :lvar, val[1]
2652
+ }
2653
+ #if V > 30
2654
+ | tCARET nonlocal_var
2655
+ {
2656
+ _, var = val
2657
+ result = var
2658
+ }
2659
+ #endif
2660
+
2661
+ #if V > 30
2662
+ p_expr_ref: tCARET tLPAREN expr_value rparen
2663
+ {
2664
+ _, _, expr, _ = val
2665
+ result = expr # TODO? s(:begin, expr).line expr.line
2666
+ }
2667
+ #endif
2668
+
2669
+ p_const: tCOLON3 cname
2670
+ {
2671
+ result = wrap :colon3, val[1]
2672
+ }
2673
+ | p_const tCOLON2 cname
2674
+ {
2675
+ lhs, _, (id, _line) = val
2676
+
2677
+ l = lhs.line
2678
+ result = s(:const, s(:colon2, lhs, id.to_sym).line(l)).line l
2679
+ }
2680
+ | tCONSTANT
2681
+ {
2682
+ # TODO $$ = gettable(p, $1, &@$);
2683
+ result = wrap :const, val[0]
2684
+ }
2685
+ ######################################################################
1738
2686
 
1739
2687
  opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1740
2688
  {
1741
2689
  (_, line), klasses, var, _, body, rest = val
1742
2690
 
1743
2691
  klasses ||= s(:array)
1744
- klasses << new_assign(var, s(:gvar, :"$!")) if var
2692
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1745
2693
  klasses.line line
1746
2694
 
1747
2695
  result = new_resbody(klasses, body)
@@ -1754,7 +2702,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1754
2702
 
1755
2703
  exc_list: arg_value
1756
2704
  {
1757
- result = s(:array, val[0])
2705
+ arg, = val
2706
+ result = s(:array, arg).line arg.line
1758
2707
  }
1759
2708
  | mrhs
1760
2709
  | none
@@ -1767,31 +2716,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1767
2716
 
1768
2717
  opt_ensure: k_ensure compstmt
1769
2718
  {
1770
- _, body = val
2719
+ (_, line), body = val
1771
2720
 
1772
- result = body || s(:nil)
2721
+ result = body || s(:nil).line(line)
1773
2722
  }
1774
2723
  | none
1775
2724
 
1776
2725
  literal: numeric
1777
2726
  {
1778
- result = s(:lit, val[0])
2727
+ (lit, line), = val
2728
+ result = s(:lit, lit).line line
1779
2729
  }
1780
2730
  | symbol
1781
- {
1782
- result = s(:lit, val[0])
1783
- }
1784
- | dsym
1785
2731
 
1786
2732
  strings: string
1787
2733
  {
1788
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1789
- result = val[0]
2734
+ str, = val
2735
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
2736
+ result = str
1790
2737
  }
1791
2738
 
1792
2739
  string: tCHAR
1793
2740
  {
1794
- debug20 23, val, result
2741
+ debug 12
1795
2742
  }
1796
2743
  | string1
1797
2744
  | string string1
@@ -1801,7 +2748,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1801
2748
 
1802
2749
  string1: tSTRING_BEG string_contents tSTRING_END
1803
2750
  {
1804
- result = val[1]
2751
+ (_, line), str, (_, func) = val
2752
+
2753
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
2754
+
2755
+ result = str.line line
1805
2756
  }
1806
2757
  | tSTRING
1807
2758
  {
@@ -1810,7 +2761,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1810
2761
 
1811
2762
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1812
2763
  {
1813
- result = new_xstring val[1]
2764
+ result = new_xstring val
2765
+ # TODO: dedent?!?! SERIOUSLY?!?
1814
2766
  }
1815
2767
 
1816
2768
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1820,11 +2772,17 @@ opt_block_args_tail: tCOMMA block_args_tail
1820
2772
 
1821
2773
  words: tWORDS_BEG tSPACE tSTRING_END
1822
2774
  {
1823
- result = s(:array)
2775
+ (_, line), _, (_, line_max) = val
2776
+
2777
+ result = s(:array).line line
2778
+ result.line_max = line_max
1824
2779
  }
1825
2780
  | tWORDS_BEG word_list tSTRING_END
1826
2781
  {
1827
- result = val[1]
2782
+ (_, line), list, (_, line_max) = val
2783
+
2784
+ result = list.line line
2785
+ result.line_max = line_max
1828
2786
  }
1829
2787
 
1830
2788
  word_list: none
@@ -1844,11 +2802,17 @@ opt_block_args_tail: tCOMMA block_args_tail
1844
2802
 
1845
2803
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1846
2804
  {
1847
- result = s(:array)
2805
+ (_, line), _, (_, line_max) = val
2806
+
2807
+ result = s(:array).line line
2808
+ result.line_max = line_max
1848
2809
  }
1849
2810
  | tSYMBOLS_BEG symbol_list tSTRING_END
1850
2811
  {
1851
- result = val[1]
2812
+ (_, line), list, (_, line_max), = val
2813
+
2814
+ result = list.line line
2815
+ result.line_max = line_max
1852
2816
  }
1853
2817
 
1854
2818
  symbol_list: none
@@ -1857,25 +2821,38 @@ opt_block_args_tail: tCOMMA block_args_tail
1857
2821
  }
1858
2822
  | symbol_list word tSPACE
1859
2823
  {
1860
- result = val[0].dup << new_symbol_list_entry(val)
2824
+ list, * = val
2825
+ result = list.dup << new_symbol_list_entry(val)
1861
2826
  }
1862
2827
 
1863
2828
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1864
2829
  {
1865
- result = s(:array)
2830
+ (_, line), _, (_, line_max) = val
2831
+
2832
+ result = s(:array).line line
2833
+ result.line_max = line_max
1866
2834
  }
1867
2835
  | tQWORDS_BEG qword_list tSTRING_END
1868
2836
  {
1869
- result = val[1]
2837
+ (_, line), list, (_, line_max) = val
2838
+
2839
+ result = list.line line
2840
+ result.line_max = line_max
1870
2841
  }
1871
2842
 
1872
2843
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1873
2844
  {
1874
- result = s(:array)
2845
+ (_, line), _, (_, line_max) = val
2846
+
2847
+ result = s(:array).line line
2848
+ result.line_max = line_max
1875
2849
  }
1876
2850
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1877
2851
  {
1878
- result = val[1]
2852
+ (_, line), list, (_, line_max) = val
2853
+
2854
+ result = list.line line
2855
+ result.line_max = line_max
1879
2856
  }
1880
2857
 
1881
2858
  qword_list: none
@@ -1898,11 +2875,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1898
2875
 
1899
2876
  string_contents: none
1900
2877
  {
1901
- result = s(:str, "")
2878
+ line = prev_value_to_lineno _values.last
2879
+ result = s(:str, +"").line line
1902
2880
  }
1903
2881
  | string_contents string_content
1904
2882
  {
1905
- result = literal_concat(val[0], val[1])
2883
+ v1, v2 = val
2884
+ result = literal_concat v1, v2
1906
2885
  }
1907
2886
 
1908
2887
  xstring_contents: none
@@ -1911,7 +2890,8 @@ xstring_contents: none
1911
2890
  }
1912
2891
  | xstring_contents string_content
1913
2892
  {
1914
- result = literal_concat(val[0], val[1])
2893
+ v1, v2 = val
2894
+ result = literal_concat v1, v2
1915
2895
  }
1916
2896
 
1917
2897
  regexp_contents: none
@@ -1920,7 +2900,8 @@ regexp_contents: none
1920
2900
  }
1921
2901
  | regexp_contents string_content
1922
2902
  {
1923
- result = literal_concat(val[0], val[1])
2903
+ v1, v2 = val
2904
+ result = literal_concat v1, v2
1924
2905
  }
1925
2906
 
1926
2907
  string_content: tSTRING_CONTENT
@@ -1936,19 +2917,21 @@ regexp_contents: none
1936
2917
  }
1937
2918
  string_dvar
1938
2919
  {
1939
- lexer.lex_strterm = val[1]
1940
- result = s(:evstr, val[2])
2920
+ _, strterm, str = val
2921
+ lexer.lex_strterm = strterm
2922
+ result = s(:evstr, str).line str.line
1941
2923
  }
1942
2924
  | tSTRING_DBEG
1943
2925
  {
1944
2926
  result = [lexer.lex_strterm,
1945
2927
  lexer.brace_nest,
1946
2928
  lexer.string_nest, # TODO: remove
1947
- lexer.cond.store,
1948
- lexer.cmdarg.store,
1949
2929
  lexer.lex_state,
1950
2930
  ]
1951
2931
 
2932
+ lexer.cmdarg.push false
2933
+ lexer.cond.push false
2934
+
1952
2935
  lexer.lex_strterm = nil
1953
2936
  lexer.brace_nest = 0
1954
2937
  lexer.string_nest = 0
@@ -1958,16 +2941,17 @@ regexp_contents: none
1958
2941
  compstmt
1959
2942
  tSTRING_DEND
1960
2943
  {
1961
- _, memo, stmt, _ = val
2944
+ (_, line), memo, stmt, _ = val
1962
2945
 
1963
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2946
+ lex_strterm, brace_nest, string_nest, oldlex_state = memo
2947
+ # TODO: heredoc_indent
1964
2948
 
1965
2949
  lexer.lex_strterm = lex_strterm
1966
2950
  lexer.brace_nest = brace_nest
1967
2951
  lexer.string_nest = string_nest
1968
2952
 
1969
- lexer.cond.restore oldcond
1970
- lexer.cmdarg.restore oldcmdarg
2953
+ lexer.cond.pop
2954
+ lexer.cmdarg.pop
1971
2955
 
1972
2956
  lexer.lex_state = oldlex_state
1973
2957
 
@@ -1977,56 +2961,71 @@ regexp_contents: none
1977
2961
  when :str, :dstr, :evstr then
1978
2962
  result = stmt
1979
2963
  else
1980
- result = s(:evstr, stmt)
2964
+ result = s(:evstr, stmt).line line
1981
2965
  end
1982
2966
  when nil then
1983
- result = s(:evstr)
2967
+ result = s(:evstr).line line
1984
2968
  else
1985
- debug20 25
2969
+ debug 13
1986
2970
  raise "unknown string body: #{stmt.inspect}"
1987
2971
  end
1988
2972
  }
1989
2973
 
1990
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1991
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1992
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2974
+ string_dvar: tGVAR
2975
+ {
2976
+ result = wrap :gvar, val[0]
2977
+ }
2978
+ | tIVAR
2979
+ {
2980
+ result = wrap :ivar, val[0]
2981
+ }
2982
+ | tCVAR
2983
+ {
2984
+ result = wrap :cvar, val[0]
2985
+ }
1993
2986
  | backref
1994
2987
 
1995
- symbol: tSYMBEG sym
2988
+ symbol: ssym
2989
+ | dsym
2990
+
2991
+ ssym: tSYMBEG sym
1996
2992
  {
1997
2993
  lexer.lex_state = EXPR_END
1998
- result = val[1].to_sym
2994
+ result = wrap :lit, val[1]
1999
2995
  }
2000
2996
  | tSYMBOL
2001
2997
  {
2002
- result = val[0].to_sym
2998
+ lexer.lex_state = EXPR_END
2999
+ result = wrap :lit, val[0]
2003
3000
  }
2004
3001
 
2005
3002
  sym: fname | tIVAR | tGVAR | tCVAR
2006
3003
 
2007
- dsym: tSYMBEG xstring_contents tSTRING_END
3004
+ dsym: tSYMBEG string_contents tSTRING_END
2008
3005
  {
3006
+ (_, line), result, _ = val
3007
+
2009
3008
  lexer.lex_state = EXPR_END
2010
- result = val[1]
2011
3009
 
2012
- result ||= s(:str, "")
3010
+ result ||= s(:str, "").line line
2013
3011
 
2014
3012
  case result.sexp_type
2015
3013
  when :dstr then
2016
3014
  result.sexp_type = :dsym
2017
3015
  when :str then
2018
- result = s(:lit, result.last.to_sym)
3016
+ result = s(:lit, result.last.to_sym).line result.line
2019
3017
  when :evstr then
2020
- result = s(:dsym, "", result)
3018
+ result = s(:dsym, "", result).line result.line
2021
3019
  else
2022
- debug20 26, val, result
3020
+ debug 14
2023
3021
  end
2024
3022
  }
2025
3023
 
2026
3024
  numeric: simple_numeric
2027
- | tUMINUS_NUM simple_numeric
3025
+ | tUMINUS_NUM simple_numeric =tLOWEST
2028
3026
  {
2029
- result = -val[1] # TODO: pt_testcase
3027
+ _, (num, line) = val
3028
+ result = [-num, line]
2030
3029
  }
2031
3030
 
2032
3031
  simple_numeric: tINTEGER
@@ -2034,32 +3033,42 @@ regexp_contents: none
2034
3033
  | tRATIONAL
2035
3034
  | tIMAGINARY
2036
3035
 
3036
+ #if V > 30
3037
+ nonlocal_var: tIVAR { result = wrap :ivar, val[0] }
3038
+ | tGVAR { result = wrap :gvar, val[0] }
3039
+ | tCVAR { result = wrap :cvar, val[0] }
3040
+ #endif
3041
+
2037
3042
  user_variable: tIDENTIFIER
2038
3043
  | tIVAR
2039
3044
  | tGVAR
2040
3045
  | tCONSTANT
2041
3046
  | tCVAR
2042
3047
 
2043
- keyword_variable: kNIL { result = s(:nil) }
2044
- | kSELF { result = s(:self) }
2045
- | kTRUE { result = s(:true) }
2046
- | kFALSE { result = s(:false) }
2047
- | k__FILE__ { result = s(:str, self.file) }
2048
- | k__LINE__ { result = s(:lit, lexer.lineno) }
3048
+ keyword_variable: kNIL { (_, line), = val; result = s(:nil).line line }
3049
+ | kSELF { (_, line), = val; result = s(:self).line line }
3050
+ | kTRUE { (_, line), = val; result = s(:true).line line }
3051
+ | kFALSE { (_, line), = val; result = s(:false).line line }
3052
+ | k__FILE__ { (_, line), = val; result = s(:str, self.file).line line }
3053
+ | k__LINE__ { (_, line), = val; result = s(:lit, line).line line }
2049
3054
  | k__ENCODING__
2050
3055
  {
3056
+ (_, l), = val
2051
3057
  result =
2052
3058
  if defined? Encoding then
2053
- s(:colon2, s(:const, :Encoding), :UTF_8)
3059
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
2054
3060
  else
2055
- s(:str, "Unsupported!")
3061
+ s(:str, "Unsupported!").line l
2056
3062
  end
2057
3063
  }
2058
3064
 
2059
3065
  var_ref: user_variable
2060
3066
  {
2061
- var = val[0]
3067
+ raise "NO: #{val.inspect}" if Sexp === val.first
3068
+ (var, line), = val
2062
3069
  result = Sexp === var ? var : self.gettable(var)
3070
+
3071
+ result.line line
2063
3072
  }
2064
3073
  | keyword_variable
2065
3074
  {
@@ -2074,11 +3083,19 @@ keyword_variable: kNIL { result = s(:nil) }
2074
3083
  | keyword_variable
2075
3084
  {
2076
3085
  result = self.assignable val[0]
2077
- debug20 29, val, result
3086
+ debug 15
2078
3087
  }
2079
3088
 
2080
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
2081
- | tBACK_REF { result = s(:back_ref, val[0]) }
3089
+ backref: tNTH_REF
3090
+ {
3091
+ (ref, line), = val
3092
+ result = s(:nth_ref, ref).line line
3093
+ }
3094
+ | tBACK_REF
3095
+ {
3096
+ (ref, line), = val
3097
+ result = s(:back_ref, ref).line line
3098
+ }
2082
3099
 
2083
3100
  superclass: tLT
2084
3101
  {
@@ -2094,25 +3111,40 @@ keyword_variable: kNIL { result = s(:nil) }
2094
3111
  result = nil
2095
3112
  }
2096
3113
 
2097
- f_arglist: tLPAREN2 f_args rparen
3114
+ f_opt_paren_args: f_paren_args
3115
+ | none
2098
3116
  {
2099
- result = val[1]
2100
- self.lexer.lex_state = EXPR_BEG
2101
- self.lexer.command_start = true
3117
+ self.in_argdef = false
3118
+ result = end_args val
3119
+ }
3120
+
3121
+ f_paren_args: tLPAREN2 f_args rparen
3122
+ {
3123
+ self.in_argdef = false
3124
+ result = end_args val
2102
3125
  }
3126
+ #if V == 30
3127
+ | tLPAREN2 f_arg tCOMMA args_forward rparen
3128
+ {
3129
+ result = end_args val
3130
+ }
3131
+ | tLPAREN2 args_forward rparen
3132
+ {
3133
+ result = end_args val
3134
+ }
3135
+ #endif
3136
+
3137
+ f_arglist: f_paren_args
2103
3138
  | {
2104
3139
  result = self.in_kwarg
2105
3140
  self.in_kwarg = true
3141
+ self.in_argdef = true
2106
3142
  self.lexer.lex_state |= EXPR_LABEL
2107
3143
  }
2108
3144
  f_args term
2109
3145
  {
2110
- kwarg, args, _ = val
2111
-
2112
- self.in_kwarg = kwarg
2113
- result = args
2114
- lexer.lex_state = EXPR_BEG
2115
- lexer.command_start = true
3146
+ self.in_argdef = false
3147
+ result = end_args val
2116
3148
  }
2117
3149
 
2118
3150
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2123,11 +3155,14 @@ keyword_variable: kNIL { result = s(:nil) }
2123
3155
  {
2124
3156
  result = args val
2125
3157
  }
2126
- | f_kwrest opt_f_block_arg
3158
+ | f_any_kwrest opt_f_block_arg
2127
3159
  {
2128
3160
  result = args val
2129
3161
  }
2130
3162
  | f_block_arg
3163
+ #if V > 30
3164
+ | args_forward
3165
+ #endif
2131
3166
 
2132
3167
  opt_args_tail: tCOMMA args_tail
2133
3168
  {
@@ -2199,6 +3234,12 @@ keyword_variable: kNIL { result = s(:nil) }
2199
3234
  result = args val
2200
3235
  }
2201
3236
 
3237
+ args_forward: tBDOT3
3238
+ {
3239
+ (_, line), = val
3240
+ result = s(:forward_args).line line
3241
+ }
3242
+
2202
3243
  f_bad_arg: tCONSTANT
2203
3244
  {
2204
3245
  yyerror "formal argument cannot be a constant"
@@ -2219,10 +3260,11 @@ keyword_variable: kNIL { result = s(:nil) }
2219
3260
  f_norm_arg: f_bad_arg
2220
3261
  | tIDENTIFIER
2221
3262
  {
2222
- identifier = val[0].to_sym
3263
+ (id, line), = val
3264
+ identifier = id.to_sym
2223
3265
  self.env[identifier] = :lvar
2224
3266
 
2225
- result = identifier
3267
+ result = [identifier, line]
2226
3268
  }
2227
3269
 
2228
3270
  f_arg_asgn: f_norm_arg
@@ -2230,21 +3272,14 @@ keyword_variable: kNIL { result = s(:nil) }
2230
3272
  f_arg_item: f_arg_asgn
2231
3273
  | tLPAREN f_margs rparen
2232
3274
  {
2233
- result = val[1]
3275
+ _, margs, _ = val
3276
+
3277
+ result = margs
2234
3278
  }
2235
3279
 
2236
3280
  f_arg: f_arg_item
2237
3281
  {
2238
- case val[0]
2239
- when Symbol then
2240
- result = s(:args)
2241
- result << val[0]
2242
- when Sexp then
2243
- result = val[0]
2244
- else
2245
- debug20 32
2246
- raise "Unknown f_arg type: #{val.inspect}"
2247
- end
3282
+ result = new_arg val
2248
3283
  }
2249
3284
  | f_arg tCOMMA f_arg_item
2250
3285
  {
@@ -2253,48 +3288,71 @@ keyword_variable: kNIL { result = s(:nil) }
2253
3288
  if list.sexp_type == :args then
2254
3289
  result = list
2255
3290
  else
2256
- result = s(:args, list)
3291
+ result = s(:args, list).line list.line
3292
+ end
3293
+
3294
+ if Sexp === item then
3295
+ line_max = item.line_max
3296
+ else
3297
+ item, line_max = item
2257
3298
  end
2258
3299
 
2259
3300
  result << item
3301
+ result.line_max = line_max
2260
3302
  }
2261
3303
 
2262
3304
  f_label: tLABEL
3305
+ {
3306
+ label, = val
3307
+ # arg_var(p, formal_argument(p, $1));
3308
+ # p->cur_arg = get_id($1);
3309
+ # p->max_numparam = ORDINAL_PARAM;
3310
+ self.in_argdef = false
3311
+ result = label
3312
+ }
2263
3313
 
2264
3314
  f_kw: f_label arg_value
2265
3315
  {
2266
- # TODO: call_args
2267
- label, _ = val[0] # TODO: fix lineno?
3316
+ # TODO: new_kw_arg
3317
+ (label, line), arg = val
3318
+
2268
3319
  identifier = label.to_sym
2269
3320
  self.env[identifier] = :lvar
3321
+ self.in_argdef = true
2270
3322
 
2271
- result = s(:array, s(:kwarg, identifier, val[1]))
3323
+ kwarg = s(:kwarg, identifier, arg).line line
3324
+ result = s(:array, kwarg).line line
2272
3325
  }
2273
3326
  | f_label
2274
3327
  {
2275
- label, _ = val[0] # TODO: fix lineno?
2276
- identifier = label.to_sym
2277
- self.env[identifier] = :lvar
3328
+ (label, line), = val
2278
3329
 
2279
- result = s(:array, s(:kwarg, identifier))
3330
+ id = label.to_sym
3331
+ self.env[id] = :lvar
3332
+ self.in_argdef = true
3333
+
3334
+ result = s(:array, s(:kwarg, id).line(line)).line line
2280
3335
  }
2281
3336
 
2282
3337
  f_block_kw: f_label primary_value
2283
3338
  {
2284
- # TODO: call_args
2285
- label, _ = val[0] # TODO: fix lineno?
2286
- identifier = label.to_sym
2287
- self.env[identifier] = :lvar
3339
+ # TODO: new_kw_arg
3340
+ (label, line), expr = val
3341
+ id = label.to_sym
3342
+ self.env[id] = :lvar
3343
+ self.in_argdef = true
2288
3344
 
2289
- result = s(:array, s(:kwarg, identifier, val[1]))
3345
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2290
3346
  }
2291
3347
  | f_label
2292
3348
  {
2293
- label, _ = val[0] # TODO: fix lineno?
2294
- identifier = label.to_sym
2295
- self.env[identifier] = :lvar
3349
+ # TODO: new_kw_arg
3350
+ (label, line), = val
3351
+ id = label.to_sym
3352
+ self.env[id] = :lvar
3353
+ self.in_argdef = true
2296
3354
 
2297
- result = s(:array, s(:kwarg, identifier))
3355
+ result = s(:array, s(:kwarg, id).line(line)).line line
2298
3356
  }
2299
3357
 
2300
3358
  f_block_kwarg: f_block_kw
@@ -2313,41 +3371,73 @@ keyword_variable: kNIL { result = s(:nil) }
2313
3371
  kwrest_mark: tPOW
2314
3372
  | tDSTAR
2315
3373
 
3374
+ f_no_kwarg: kwrest_mark kNIL
3375
+ {
3376
+ (_, line), _ = val
3377
+ result = [:"**nil", line]
3378
+ }
3379
+
2316
3380
  f_kwrest: kwrest_mark tIDENTIFIER
2317
3381
  {
2318
- name = val[1].to_sym
2319
- self.assignable name
2320
- result = :"**#{name}"
3382
+ _, (id, line) = val
3383
+
3384
+ name = id.to_sym
3385
+ self.assignable [name, line]
3386
+ result = [:"**#{name}", line]
2321
3387
  }
2322
3388
  | kwrest_mark
2323
3389
  {
2324
- result = :"**"
3390
+ (_, line), = val
3391
+ id = :"**"
3392
+ self.env[id] = :lvar
3393
+ result = [id, line]
2325
3394
  }
2326
3395
 
2327
- f_opt: f_arg_asgn tEQL arg_value
3396
+ f_opt: f_arg_asgn
3397
+ #if V > 30
3398
+ f_eq
3399
+ #else
3400
+ tEQL
3401
+ #endif
3402
+ arg_value
2328
3403
  {
2329
- result = self.assignable val[0], val[2]
3404
+ lhs, _, rhs = val
3405
+ self.in_argdef = true
3406
+ result = self.assignable lhs, rhs
2330
3407
  # TODO: detect duplicate names
3408
+ # TODO? p->cur_arg = 0;
2331
3409
  }
2332
3410
 
2333
- f_block_opt: f_arg_asgn tEQL primary_value
3411
+ f_block_opt: f_arg_asgn
3412
+ #if V > 30
3413
+ f_eq
3414
+ #else
3415
+ tEQL
3416
+ #endif
3417
+ primary_value
2334
3418
  {
2335
- result = self.assignable val[0], val[2]
3419
+ lhs, _, rhs = val
3420
+ self.in_argdef = true
3421
+ result = self.assignable lhs, rhs
3422
+ # TODO? p->cur_arg = 0;
2336
3423
  }
2337
3424
 
2338
3425
  f_block_optarg: f_block_opt
2339
3426
  {
2340
- result = s(:block, val[0])
3427
+ optblk, = val
3428
+ result = s(:block, optblk).line optblk.line
2341
3429
  }
2342
3430
  | f_block_optarg tCOMMA f_block_opt
2343
3431
  {
2344
- result = val[0]
2345
- result << val[2]
3432
+ optarg, _, optblk = val
3433
+ result = optarg
3434
+ result << optblk
2346
3435
  }
2347
3436
 
2348
3437
  f_optarg: f_opt
2349
3438
  {
2350
- result = s(:block, val[0])
3439
+ opt, = val
3440
+ result = s(:block, opt).line opt.line
2351
3441
  }
2352
3442
  | f_optarg tCOMMA f_opt
2353
3443
  {
@@ -2359,30 +3449,40 @@ keyword_variable: kNIL { result = s(:nil) }
2359
3449
  f_rest_arg: restarg_mark tIDENTIFIER
2360
3450
  {
2361
3451
  # TODO: differs from parse.y - needs tests
2362
- name = val[1].to_sym
2363
- self.assignable name
2364
- result = :"*#{name}"
3452
+ _, (id, line) = val
3453
+ name = id.to_sym
3454
+ self.assignable [name, line]
3455
+ result = [:"*#{name}", line]
2365
3456
  }
2366
3457
  | restarg_mark
2367
3458
  {
3459
+ (_, line), = val
2368
3460
  name = :"*"
2369
3461
  self.env[name] = :lvar
2370
- result = name
3462
+ result = [name, line]
2371
3463
  }
2372
3464
 
2373
3465
  blkarg_mark: tAMPER2 | tAMPER
2374
3466
 
2375
3467
  f_block_arg: blkarg_mark tIDENTIFIER
2376
3468
  {
2377
- identifier = val[1].to_sym
3469
+ _, (id, line) = val
3470
+ identifier = id.to_sym
2378
3471
 
2379
3472
  self.env[identifier] = :lvar
2380
- result = "&#{identifier}".to_sym
3473
+ result = ["&#{identifier}".to_sym, line]
3474
+ }
3475
+ | blkarg_mark
3476
+ {
3477
+ (_, line), = val
3478
+
3479
+ result = [:&, line]
2381
3480
  }
2382
3481
 
2383
3482
  opt_f_block_arg: tCOMMA f_block_arg
2384
3483
  {
2385
- result = val[1]
3484
+ _, arg = val
3485
+ result = arg
2386
3486
  }
2387
3487
  |
2388
3488
  {
@@ -2401,14 +3501,11 @@ keyword_variable: kNIL { result = s(:nil) }
2401
3501
  result.sexp_type == :lit
2402
3502
  }
2403
3503
 
2404
- assoc_list: none # [!nil]
3504
+ assoc_list: none
2405
3505
  {
2406
- result = s(:array)
2407
- }
2408
- | assocs trailer # [!nil]
2409
- {
2410
- result = val[0]
3506
+ result = s(:array).line lexer.lineno
2411
3507
  }
3508
+ | assocs trailer
2412
3509
 
2413
3510
  assocs: assoc
2414
3511
  | assocs tCOMMA assoc
@@ -2422,23 +3519,44 @@ keyword_variable: kNIL { result = s(:nil) }
2422
3519
 
2423
3520
  assoc: arg_value tASSOC arg_value
2424
3521
  {
2425
- result = s(:array, val[0], val[2])
3522
+ v1, _, v2 = val
3523
+ result = s(:array, v1, v2).line v1.line
2426
3524
  }
2427
3525
  | tLABEL arg_value
2428
3526
  {
2429
- (label, _), arg = val
2430
- result = s(:array, s(:lit, label.to_sym), arg)
3527
+ label, arg = val
3528
+
3529
+ lit = wrap :lit, label
3530
+ result = s(:array, lit, arg).line lit.line
3531
+ }
3532
+ | tLABEL
3533
+ {
3534
+ lit = wrap :lit, val[0]
3535
+ arg = nil
3536
+
3537
+ result = s(:array, lit, arg).line lit.line
2431
3538
  }
2432
3539
  | tSTRING_BEG string_contents tLABEL_END arg_value
2433
3540
  {
2434
- _, sym, _, value = val
3541
+ (_, line), sym, _, value = val
3542
+
2435
3543
  sym.sexp_type = :dsym
2436
- result = s(:array, sym, value)
3544
+
3545
+ result = s(:array, sym, value).line line
2437
3546
  }
2438
3547
  | tDSTAR arg_value
2439
3548
  {
2440
- result = s(:array, s(:kwsplat, val[1]))
3549
+ _, arg = val
3550
+ line = arg.line
3551
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
3552
+ }
3553
+ #if V >= 32
3554
+ | tDSTAR
3555
+ {
3556
+ (_, line), = val
3557
+ result = s(:array, s(:kwsplat).line(line)).line line
2441
3558
  }
3559
+ #endif
2442
3560
 
2443
3561
  operation: tIDENTIFIER | tCONSTANT | tFID
2444
3562
  operation2: tIDENTIFIER | tCONSTANT | tFID | op
@@ -2453,7 +3571,20 @@ keyword_variable: kNIL { result = s(:nil) }
2453
3571
  opt_terms: | terms
2454
3572
  opt_nl: | tNL
2455
3573
  rparen: opt_nl tRPAREN
3574
+ {
3575
+ _, close = val # TODO: include lineno in close?
3576
+ result = [close, lexer.lineno]
3577
+ }
2456
3578
  rbracket: opt_nl tRBRACK
3579
+ {
3580
+ _, close = val
3581
+ result = [close, lexer.lineno]
3582
+ }
3583
+ rbrace: opt_nl tRCURLY
3584
+ {
3585
+ _, close = val
3586
+ result = [close, lexer.lineno]
3587
+ }
2457
3588
  trailer: | tNL | tCOMMA
2458
3589
 
2459
3590
  term: tSEMI { yyerrok }