ruby_parser 3.12.0 → 3.18.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.autotest +18 -29
  4. data/History.rdoc +283 -0
  5. data/Manifest.txt +12 -4
  6. data/README.rdoc +4 -3
  7. data/Rakefile +189 -51
  8. data/bin/ruby_parse +3 -1
  9. data/bin/ruby_parse_extract_error +19 -36
  10. data/compare/normalize.rb +76 -4
  11. data/debugging.md +190 -0
  12. data/gauntlet.md +106 -0
  13. data/lib/rp_extensions.rb +14 -42
  14. data/lib/rp_stringscanner.rb +20 -51
  15. data/lib/ruby20_parser.rb +4659 -4218
  16. data/lib/ruby20_parser.y +953 -602
  17. data/lib/ruby21_parser.rb +4723 -4308
  18. data/lib/ruby21_parser.y +956 -605
  19. data/lib/ruby22_parser.rb +4762 -4337
  20. data/lib/ruby22_parser.y +960 -612
  21. data/lib/ruby23_parser.rb +4761 -4342
  22. data/lib/ruby23_parser.y +961 -613
  23. data/lib/ruby24_parser.rb +4791 -4341
  24. data/lib/ruby24_parser.y +968 -612
  25. data/lib/ruby25_parser.rb +4791 -4341
  26. data/lib/ruby25_parser.y +968 -612
  27. data/lib/ruby26_parser.rb +7287 -0
  28. data/lib/ruby26_parser.y +2749 -0
  29. data/lib/ruby27_parser.rb +8517 -0
  30. data/lib/ruby27_parser.y +3346 -0
  31. data/lib/ruby30_parser.rb +8751 -0
  32. data/lib/ruby30_parser.y +3472 -0
  33. data/lib/ruby3_parser.yy +3476 -0
  34. data/lib/ruby_lexer.rb +611 -826
  35. data/lib/ruby_lexer.rex +48 -40
  36. data/lib/ruby_lexer.rex.rb +122 -46
  37. data/lib/ruby_lexer_strings.rb +638 -0
  38. data/lib/ruby_parser.rb +38 -34
  39. data/lib/ruby_parser.yy +1710 -704
  40. data/lib/ruby_parser_extras.rb +987 -553
  41. data/test/test_ruby_lexer.rb +1718 -1539
  42. data/test/test_ruby_parser.rb +3957 -2164
  43. data/test/test_ruby_parser_extras.rb +39 -4
  44. data/tools/munge.rb +250 -0
  45. data/tools/ripper.rb +44 -0
  46. data.tar.gz.sig +0 -0
  47. metadata +68 -47
  48. metadata.gz.sig +0 -0
  49. data/lib/ruby18_parser.rb +0 -5793
  50. data/lib/ruby18_parser.y +0 -1908
  51. data/lib/ruby19_parser.rb +0 -6185
  52. data/lib/ruby19_parser.y +0 -2116
data/lib/ruby24_parser.y CHANGED
@@ -18,49 +18,53 @@ token kCLASS kMODULE kDEF kUNDEF kBEGIN kRESCUE kENSURE kEND kIF kUNLESS
18
18
  tBACK_REF2 tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG
19
19
  tWORDS_BEG tQWORDS_BEG tSTRING_DBEG tSTRING_DVAR tSTRING_END
20
20
  tSTRING tSYMBOL tNL tEH tCOLON tCOMMA tSPACE tSEMI tLAMBDA
21
- tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND tUBANG
21
+ tLAMBEG tDSTAR tCHAR tSYMBOLS_BEG tQSYMBOLS_BEG tSTRING_DEND
22
22
  tRATIONAL tIMAGINARY
23
23
  tLABEL_END
24
24
  tLONELY
25
25
 
26
- prechigh
27
- right tBANG tTILDE tUPLUS
28
- right tPOW
29
- right tUMINUS_NUM tUMINUS
30
- left tSTAR2 tDIVIDE tPERCENT
31
- left tPLUS tMINUS
32
- left tLSHFT tRSHFT
33
- left tAMPER2
34
- left tPIPE tCARET
35
- left tGT tGEQ tLT tLEQ
36
- nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
37
- left tANDOP
38
- left tOROP
39
- nonassoc tDOT2 tDOT3
40
- right tEH tCOLON
41
- left kRESCUE_MOD
42
- right tEQL tOP_ASGN
43
- nonassoc kDEFINED
44
- right kNOT
45
- left kOR kAND
46
- nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
47
- nonassoc tLBRACE_ARG
48
- nonassoc tLOWEST
49
26
  preclow
27
+ nonassoc tLOWEST
28
+ nonassoc tLBRACE_ARG
29
+ nonassoc kIF_MOD kUNLESS_MOD kWHILE_MOD kUNTIL_MOD
30
+ left kOR kAND
31
+ right kNOT
32
+ nonassoc kDEFINED
33
+ right tEQL tOP_ASGN
34
+ left kRESCUE_MOD
35
+ right tEH tCOLON
36
+ nonassoc tDOT2 tDOT3 tBDOT2 tBDOT3
37
+ left tOROP
38
+ left tANDOP
39
+ nonassoc tCMP tEQ tEQQ tNEQ tMATCH tNMATCH
40
+ left tGT tGEQ tLT tLEQ
41
+ left tPIPE tCARET
42
+ left tAMPER2
43
+ left tLSHFT tRSHFT
44
+ left tPLUS tMINUS
45
+ left tSTAR2 tDIVIDE tPERCENT # TODO: tSTAR2 -> tMULT
46
+ right tUMINUS_NUM tUMINUS
47
+ right tPOW
48
+ right tBANG tTILDE tUPLUS
49
+ prechigh
50
50
 
51
51
  rule
52
52
 
53
53
  program: {
54
- self.lexer.lex_state = :expr_beg
54
+ self.lexer.lex_state = EXPR_BEG
55
55
  }
56
56
  top_compstmt
57
57
  {
58
58
  result = new_compstmt val
59
+
60
+ lexer.cond.pop # local_pop
61
+ lexer.cmdarg.pop
59
62
  }
60
63
 
61
64
  top_compstmt: top_stmts opt_terms
62
65
  {
63
- result = val[0]
66
+ stmt, _ = val
67
+ result = stmt
64
68
  }
65
69
 
66
70
  top_stmts: none
@@ -72,30 +76,50 @@ rule
72
76
  | error top_stmt
73
77
 
74
78
  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
79
  | klBEGIN
84
80
  {
85
81
  if (self.in_def || self.in_single > 0) then
86
- debug20 1
82
+ debug 11
87
83
  yyerror "BEGIN in method"
88
84
  end
89
85
  self.env.extend
90
86
  }
91
- tLCURLY top_compstmt tRCURLY
87
+ begin_block
88
+ {
89
+ (_, lineno), _, iter = val
90
+ iter.line lineno
91
+
92
+ (_, preexe,) = iter
93
+ preexe.line lineno
94
+
95
+ result = iter
96
+ }
97
+
98
+ begin_block: tLCURLY { result = lexer.lineno } top_compstmt tRCURLY
92
99
  {
93
- result = new_iter s(:preexe), nil, val[3]
100
+ _, line, stmt, _ = val
101
+ result = new_iter s(:preexe).line(line), 0, stmt
94
102
  }
95
103
 
96
- bodystmt: compstmt opt_rescue opt_else opt_ensure
104
+ bodystmt: compstmt opt_rescue k_else
97
105
  {
98
- result = new_body val
106
+ res = _values[-2]
107
+ # TODO: move down to main match so I can just use val
108
+
109
+ warn "else without rescue is useless" unless res
110
+ }
111
+ compstmt
112
+ opt_ensure
113
+ {
114
+ body, resc, _, _, els, ens = val
115
+
116
+ result = new_body [body, resc, els, ens]
117
+ }
118
+ | compstmt opt_rescue opt_ensure
119
+ {
120
+ body, resc, ens = val
121
+
122
+ result = new_body [body, resc, nil, ens]
99
123
  }
100
124
 
101
125
  compstmt: stmts opt_terms
@@ -104,33 +128,45 @@ rule
104
128
  }
105
129
 
106
130
  stmts: none
107
- | stmt
108
- | stmts terms stmt
131
+ | stmt_or_begin # TODO: newline_node ?
132
+ | stmts terms stmt_or_begin
109
133
  {
110
134
  result = self.block_append val[0], val[2]
111
135
  }
112
136
  | error stmt
113
137
  {
114
138
  result = val[1]
115
- debug20 2, val, result
139
+ debug 12
140
+ }
141
+
142
+ stmt_or_begin: stmt
143
+ | klBEGIN
144
+ {
145
+ yyerror "BEGIN is permitted only at toplevel"
146
+ }
147
+ begin_block
148
+ {
149
+ result = val[2] # wtf?
116
150
  }
117
151
 
118
152
  stmt: kALIAS fitem
119
153
  {
120
- lexer.lex_state = :expr_fname
121
- result = self.lexer.lineno
154
+ lexer.lex_state = EXPR_FNAME
122
155
  }
123
156
  fitem
124
157
  {
125
- result = s(:alias, val[1], val[3]).line(val[2])
158
+ (_, line), lhs, _, rhs = val
159
+ result = s(:alias, lhs, rhs).line(line).line line
126
160
  }
127
161
  | kALIAS tGVAR tGVAR
128
162
  {
129
- result = s(:valias, val[1].to_sym, val[2].to_sym)
163
+ (_, line), (lhs, _), (rhs, _) = val
164
+ result = s(:valias, lhs.to_sym, rhs.to_sym).line line
130
165
  }
131
166
  | kALIAS tGVAR tBACK_REF
132
167
  {
133
- result = s(:valias, val[1].to_sym, :"$#{val[2]}")
168
+ (_, line), (lhs, _), (rhs, _) = val
169
+ result = s(:valias, lhs.to_sym, :"$#{rhs}").line line
134
170
  }
135
171
  | kALIAS tGVAR tNTH_REF
136
172
  {
@@ -142,170 +178,224 @@ rule
142
178
  }
143
179
  | stmt kIF_MOD expr_value
144
180
  {
145
- result = new_if val[2], val[0], nil
181
+ t, _, c = val
182
+ result = new_if c, t, nil
146
183
  }
147
184
  | stmt kUNLESS_MOD expr_value
148
185
  {
149
- result = new_if val[2], nil, val[0]
186
+ f, _, c = val
187
+ result = new_if c, nil, f
150
188
  }
151
189
  | stmt kWHILE_MOD expr_value
152
190
  {
153
- result = new_while val[0], val[2], true
191
+ e, _, c = val
192
+ result = new_while e, c, true
154
193
  }
155
194
  | stmt kUNTIL_MOD expr_value
156
195
  {
157
- result = new_until val[0], val[2], true
196
+ e, _, c = val
197
+ result = new_until e, c, true
158
198
  }
159
199
  | stmt kRESCUE_MOD stmt
160
200
  {
161
- result = s(:rescue, val[0], new_resbody(s(:array), val[2]))
201
+ body, _, resbody = val
202
+
203
+ resbody = new_resbody s(:array).line(resbody.line), resbody
204
+ result = new_rescue body, resbody
162
205
  }
163
206
  | klEND tLCURLY compstmt tRCURLY
164
207
  {
208
+ (_, line), _, stmt, _ = val
209
+
165
210
  if (self.in_def || self.in_single > 0) then
166
- debug20 3
211
+ debug 13
167
212
  yyerror "END in method; use at_exit"
168
213
  end
169
- result = new_iter s(:postexe), 0, val[2]
214
+
215
+ result = new_iter s(:postexe).line(line), 0, stmt
170
216
  }
171
217
  | command_asgn
172
218
  | mlhs tEQL command_call
173
219
  {
174
220
  result = new_masgn val[0], val[2], :wrap
175
221
  }
176
- | var_lhs tOP_ASGN command_call
222
+ | lhs tEQL mrhs
177
223
  {
178
- result = new_op_asgn val
224
+ lhs, _, rhs = val
225
+ result = new_assign lhs, s(:svalue, rhs).line(rhs.line)
226
+ }
227
+ | mlhs tEQL mrhs_arg
228
+ {
229
+ result = new_masgn val[0], val[2]
179
230
  }
180
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_call
231
+ | expr
232
+
233
+ command_asgn: lhs tEQL command_rhs
181
234
  {
182
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
235
+ result = new_assign val[0], val[2]
183
236
  }
184
- | primary_value call_op tIDENTIFIER tOP_ASGN command_call
237
+ # | lhs tEQL command_asgn
238
+ # {
239
+ # result = new_assign val[0], val[2]
240
+ # }
241
+ | var_lhs tOP_ASGN command_rhs
185
242
  {
186
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
187
- if val[1] == '&.'
188
- result.sexp_type = :safe_op_asgn
189
- end
190
- result.line = val[0].line
243
+ result = new_op_asgn val
191
244
  }
192
- | primary_value call_op tCONSTANT tOP_ASGN command_call
245
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN command_rhs
193
246
  {
194
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
195
- if val[1] == '&.'
196
- result.sexp_type = :safe_op_asgn
197
- end
198
- result.line = val[0].line
247
+ result = new_op_asgn1 val
199
248
  }
200
- | primary_value tCOLON2 tCONSTANT tOP_ASGN command_call
249
+ | primary_value call_op tIDENTIFIER tOP_ASGN command_rhs
201
250
  {
202
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
203
- debug20 4, val, result
251
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
252
+
253
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
254
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
255
+ result.line prim.line
204
256
  }
205
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_call
257
+ | primary_value call_op tCONSTANT tOP_ASGN command_rhs
206
258
  {
207
- result = s(:op_asgn, val[0], val[4], val[2], val[3])
208
- debug20 5, val, result
259
+ prim, (call_op, _), (id, _), (op_asgn, _), rhs = val
260
+
261
+ result = s(:op_asgn, prim, rhs, id.to_sym, op_asgn.to_sym)
262
+ result.sexp_type = :safe_op_asgn if call_op == '&.'
263
+ result.line prim.line
209
264
  }
210
- | backref tOP_ASGN command_call
265
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN command_rhs
211
266
  {
212
- self.backref_assign_error val[0]
267
+ lhs1, _, (lhs2, line), (id, _), rhs = val
268
+
269
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
213
270
  }
214
- | lhs tEQL mrhs
271
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN command_rhs
215
272
  {
216
- result = new_assign val[0], s(:svalue, val[2])
273
+ lhs1, _, (lhs2, line), (id, _), rhs = val
274
+
275
+ result = s(:op_asgn, lhs1, rhs, lhs2.to_sym, id.to_sym).line line
217
276
  }
218
- | mlhs tEQL mrhs_arg
277
+ | backref tOP_ASGN command_rhs
219
278
  {
220
- result = new_masgn val[0], val[2]
279
+ self.backref_assign_error val[0]
221
280
  }
222
- | expr
223
281
 
224
- command_asgn: lhs tEQL command_call
282
+ command_rhs: command_call =tOP_ASGN
225
283
  {
226
- result = new_assign val[0], val[2]
284
+ expr, = val
285
+ result = value_expr expr
227
286
  }
228
- | lhs tEQL command_asgn
287
+ | command_call kRESCUE_MOD stmt
229
288
  {
230
- result = new_assign val[0], val[2]
289
+ expr, (_, line), resbody = val
290
+
291
+ expr = value_expr expr
292
+ ary = s(:array).line line
293
+ result = new_rescue(expr, new_resbody(ary, resbody))
231
294
  }
295
+ | command_asgn
232
296
 
233
297
  expr: command_call
234
298
  | expr kAND expr
235
299
  {
236
- result = logical_op :and, val[0], val[2]
300
+ lhs, _, rhs = val
301
+ result = logical_op :and, lhs, rhs
237
302
  }
238
303
  | expr kOR expr
239
304
  {
240
- result = logical_op :or, val[0], val[2]
305
+ lhs, _, rhs = val
306
+ result = logical_op :or, lhs, rhs
241
307
  }
242
308
  | kNOT opt_nl expr
243
309
  {
244
- result = s(:call, val[2], :"!")
310
+ (_, line), _, expr = val
311
+ result = new_call(expr, :"!").line line
312
+ # REFACTOR: call_uni_op
245
313
  }
246
314
  | tBANG command_call
247
315
  {
248
- result = s(:call, val[1], :"!")
316
+ _, cmd = val
317
+ result = new_call(cmd, :"!").line cmd.line
318
+ # TODO: fix line number to tBANG... but causes BAD shift/reduce conflict
319
+ # REFACTOR: call_uni_op -- see parse26.y
249
320
  }
250
- | arg
321
+ | arg =tLBRACE_ARG
251
322
 
252
323
  expr_value: expr
253
324
  {
254
325
  result = value_expr(val[0])
255
326
  }
256
327
 
328
+ expr_value_do: {
329
+ lexer.cond.push true
330
+ }
331
+ expr_value do
332
+ {
333
+ lexer.cond.pop
334
+ }
335
+ {
336
+ _, expr, _, _ = val
337
+ result = expr
338
+ }
339
+
257
340
  command_call: command
258
341
  | block_command
259
342
 
260
343
  block_command: block_call
261
- | block_call dot_or_colon operation2 command_args
344
+ | block_call call_op2 operation2 command_args
262
345
  {
263
- result = new_call val[0], val[2].to_sym, val[3]
346
+ blk, _, (msg, _line), args = val
347
+ result = new_call(blk, msg.to_sym, args).line blk.line
264
348
  }
265
349
 
266
350
  cmd_brace_block: tLBRACE_ARG
267
351
  {
268
- self.env.extend(:dynamic)
352
+ # self.env.extend(:dynamic)
269
353
  result = self.lexer.lineno
270
354
  }
271
- opt_block_param
272
- {
273
- result = nil # self.env.dynamic.keys
274
- }
275
- compstmt tRCURLY
355
+ brace_body tRCURLY
276
356
  {
277
- result = new_iter nil, val[2], val[4]
278
- result.line = val[1]
357
+ _, line, body, _ = val
279
358
 
280
- self.env.unextend
359
+ result = body
360
+ result.line line
361
+
362
+ # self.env.unextend
281
363
  }
282
364
 
283
365
  fcall: operation
284
366
  {
285
- result = new_call nil, val[0].to_sym
367
+ (msg, line), = val
368
+ result = new_call(nil, msg.to_sym).line line
286
369
  }
287
370
 
288
371
  command: fcall command_args =tLOWEST
289
372
  {
290
- result = val[0].concat val[1].sexp_body # REFACTOR pattern
373
+ call, args = val
374
+ result = call.concat args.sexp_body
291
375
  }
292
376
  | fcall command_args cmd_brace_block
293
377
  {
294
- result = val[0].concat val[1].sexp_body
295
- if val[2] then
296
- block_dup_check result, val[2]
378
+ call, args, block = val
297
379
 
298
- result, operation = val[2], result
380
+ result = call.concat args.sexp_body
381
+
382
+ if block then
383
+ block_dup_check result, block
384
+
385
+ result, operation = block, result
299
386
  result.insert 1, operation
300
387
  end
301
388
  }
302
389
  | primary_value call_op operation2 command_args =tLOWEST
303
390
  {
304
- result = new_call val[0], val[2].to_sym, val[3], val[1]
391
+ lhs, callop, (op, _), args = val
392
+
393
+ result = new_call lhs, op.to_sym, args, callop
394
+ result.line lhs.line
305
395
  }
306
396
  | primary_value call_op operation2 command_args cmd_brace_block
307
397
  {
308
- recv, _, msg, args, block = val
398
+ recv, _, (msg, _line), args, block = val
309
399
  call = new_call recv, msg.to_sym, args, val[1]
310
400
 
311
401
  block_dup_check call, block
@@ -315,11 +405,14 @@ rule
315
405
  }
316
406
  | primary_value tCOLON2 operation2 command_args =tLOWEST
317
407
  {
318
- result = new_call val[0], val[2].to_sym, val[3]
408
+ lhs, _, (id, line), args = val
409
+
410
+ result = new_call lhs, id.to_sym, args
411
+ result.line line
319
412
  }
320
413
  | primary_value tCOLON2 operation2 command_args cmd_brace_block
321
414
  {
322
- recv, _, msg, args, block = val
415
+ recv, _, (msg, _line), args, block = val
323
416
  call = new_call recv, msg.to_sym, args
324
417
 
325
418
  block_dup_check call, block
@@ -333,17 +426,19 @@ rule
333
426
  }
334
427
  | kYIELD command_args
335
428
  {
336
- result = new_yield val[1]
429
+ (_, line), args = val
430
+ result = new_yield args
431
+ result.line line # TODO: push to new_yield
337
432
  }
338
- | kRETURN call_args
433
+ | k_return call_args
339
434
  {
340
435
  line = val[0].last
341
436
  result = s(:return, ret_args(val[1])).line(line)
342
437
  }
343
438
  | kBREAK call_args
344
439
  {
345
- line = val[0].last
346
- result = s(:break, ret_args(val[1])).line(line)
440
+ (_, line), args = val
441
+ result = s(:break, ret_args(args)).line line
347
442
  }
348
443
  | kNEXT call_args
349
444
  {
@@ -360,56 +455,79 @@ rule
360
455
  mlhs_inner: mlhs_basic
361
456
  | tLPAREN mlhs_inner rparen
362
457
  {
363
- result = s(:masgn, s(:array, val[1]))
458
+ _, arg, _ = val
459
+ l = arg.line
460
+
461
+ result = s(:masgn, s(:array, arg).line(l)).line l
364
462
  }
365
463
 
366
464
  mlhs_basic: mlhs_head
367
465
  {
368
- result = s(:masgn, val[0])
466
+ head, = val
467
+ result = s(:masgn, head).line head.line
369
468
  }
370
469
  | mlhs_head mlhs_item
371
470
  {
372
- result = s(:masgn, val[0] << val[1].compact)
471
+ lhs, rhs = val
472
+ result = s(:masgn, lhs << rhs.compact).line lhs.line
373
473
  }
374
474
  | mlhs_head tSTAR mlhs_node
375
475
  {
376
- result = s(:masgn, val[0] << s(:splat, val[2]))
476
+ head, _, tail = val
477
+ head << s(:splat, tail).line(tail.line)
478
+ result = s(:masgn, head).line head.line
377
479
  }
378
480
  | mlhs_head tSTAR mlhs_node tCOMMA mlhs_post
379
481
  {
380
482
  ary1, _, splat, _, ary2 = val
381
483
 
382
- result = list_append ary1, s(:splat, splat)
484
+ result = list_append ary1, s(:splat, splat).line(splat.line)
383
485
  result.concat ary2.sexp_body
384
- result = s(:masgn, result)
486
+ result = s(:masgn, result).line result.line
385
487
  }
386
488
  | mlhs_head tSTAR
387
489
  {
388
- result = s(:masgn, val[0] << s(:splat))
490
+ head, _ = val
491
+ l = head.line
492
+ result = s(:masgn, head << s(:splat).line(l)).line l
389
493
  }
390
494
  | mlhs_head tSTAR tCOMMA mlhs_post
391
495
  {
392
- ary = list_append val[0], s(:splat)
393
- ary.concat val[3].sexp_body
394
- result = s(:masgn, ary)
496
+ head, _, _, post = val
497
+ ary = list_append head, s(:splat).line(head.line)
498
+ ary.concat post.sexp_body
499
+ result = s(:masgn, ary).line ary.line
395
500
  }
396
501
  | tSTAR mlhs_node
397
502
  {
398
- result = s(:masgn, s(:array, s(:splat, val[1])))
503
+ _, node = val
504
+ l = node.line
505
+ splat = s(:splat, node).line l
506
+ ary = s(:array, splat).line l
507
+ result = s(:masgn, ary).line l
399
508
  }
400
509
  | tSTAR mlhs_node tCOMMA mlhs_post
401
510
  {
402
- ary = s(:array, s(:splat, val[1]))
403
- ary.concat val[3].sexp_body
404
- result = s(:masgn, ary)
511
+ _, node, _, post = val
512
+
513
+ splat = s(:splat, node).line node.line
514
+ ary = s(:array, splat).line splat.line
515
+ ary.concat post.sexp_body
516
+ result = s(:masgn, ary).line ary.line
405
517
  }
406
518
  | tSTAR
407
519
  {
408
- result = s(:masgn, s(:array, s(:splat)))
520
+ l = lexer.lineno
521
+ result = s(:masgn, s(:array, s(:splat).line(l)).line(l)).line l
409
522
  }
410
523
  | tSTAR tCOMMA mlhs_post
411
524
  {
412
- result = s(:masgn, s(:array, s(:splat), *val[2].sexp_body))
525
+ _, _, post = val
526
+ l = post.line
527
+
528
+ splat = s(:splat).line l
529
+ ary = s(:array, splat, *post.sexp_body).line l
530
+ result = s(:masgn, ary).line l
413
531
  }
414
532
 
415
533
  mlhs_item: mlhs_node
@@ -420,7 +538,8 @@ rule
420
538
 
421
539
  mlhs_head: mlhs_item tCOMMA
422
540
  {
423
- result = s(:array, val[0])
541
+ lhs, _ = val
542
+ result = s(:array, lhs).line lhs.line
424
543
  }
425
544
  | mlhs_head mlhs_item tCOMMA
426
545
  {
@@ -429,7 +548,8 @@ rule
429
548
 
430
549
  mlhs_post: mlhs_item
431
550
  {
432
- result = s(:array, val[0])
551
+ item, = val
552
+ result = s(:array, item).line item.line
433
553
  }
434
554
  | mlhs_post tCOMMA mlhs_item
435
555
  {
@@ -450,81 +570,111 @@ rule
450
570
  }
451
571
  | primary_value call_op tIDENTIFIER
452
572
  {
453
- result = new_attrasgn val[0], val[2], val[1]
573
+ lhs, call_op, (id, _line) = val
574
+
575
+ result = new_attrasgn lhs, id, call_op
454
576
  }
455
577
  | primary_value tCOLON2 tIDENTIFIER
456
578
  {
457
- result = s(:attrasgn, val[0], :"#{val[2]}=")
579
+ recv, _, (id, _line) = val
580
+ result = new_attrasgn recv, id
458
581
  }
459
582
  | primary_value call_op tCONSTANT
460
583
  {
461
- result = new_attrasgn val[0], val[2], val[1]
584
+ lhs, call_op, (id, _line) = val
585
+
586
+ result = new_attrasgn lhs, id, call_op
462
587
  }
463
588
  | primary_value tCOLON2 tCONSTANT
464
589
  {
465
590
  if (self.in_def || self.in_single > 0) then
466
- debug20 7
591
+ debug 14
467
592
  yyerror "dynamic constant assignment"
468
593
  end
469
594
 
470
- result = s(:const, s(:colon2, val[0], val[2].to_sym), nil)
595
+ expr, _, (id, _line) = val
596
+ l = expr.line
597
+
598
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l), nil).line l
471
599
  }
472
600
  | tCOLON3 tCONSTANT
473
601
  {
474
602
  if (self.in_def || self.in_single > 0) then
475
- debug20 8
603
+ debug 15
476
604
  yyerror "dynamic constant assignment"
477
605
  end
478
606
 
479
- result = s(:const, nil, s(:colon3, val[1].to_sym))
607
+ _, (id, l) = val
608
+
609
+ result = s(:const, nil, s(:colon3, id.to_sym).line(l)).line l
480
610
  }
481
611
  | backref
482
612
  {
483
- self.backref_assign_error val[0]
613
+ ref, = val
614
+
615
+ self.backref_assign_error ref
484
616
  }
485
617
 
486
618
  lhs: user_variable
487
619
  {
488
- result = self.assignable val[0]
620
+ var, = val
621
+
622
+ result = self.assignable var
489
623
  }
490
624
  | keyword_variable
491
625
  {
492
- result = self.assignable val[0]
493
- debug20 9, val, result
626
+ var, = val
627
+
628
+ result = self.assignable var
629
+
630
+ debug 16
494
631
  }
495
632
  | primary_value tLBRACK2 opt_call_args rbracket
496
633
  {
497
- result = self.aryset val[0], val[2]
634
+ lhs, _, args, _ = val
635
+
636
+ result = self.aryset lhs, args
498
637
  }
499
638
  | primary_value call_op tIDENTIFIER # REFACTOR
500
639
  {
501
- result = new_attrasgn val[0], val[2], val[1]
640
+ lhs, op, (id, _line) = val
641
+
642
+ result = new_attrasgn lhs, id, op
502
643
  }
503
644
  | primary_value tCOLON2 tIDENTIFIER
504
645
  {
505
- result = s(:attrasgn, val[0], :"#{val[2]}=")
646
+ lhs, _, (id, _line) = val
647
+
648
+ result = new_attrasgn lhs, id
506
649
  }
507
650
  | primary_value call_op tCONSTANT # REFACTOR?
508
651
  {
509
- result = new_attrasgn val[0], val[2], val[1]
652
+ lhs, call_op, (id, _line) = val
653
+
654
+ result = new_attrasgn lhs, id, call_op
510
655
  }
511
656
  | primary_value tCOLON2 tCONSTANT
512
657
  {
658
+ expr, _, (id, _line) = val
659
+
513
660
  if (self.in_def || self.in_single > 0) then
514
- debug20 10
661
+ debug 17
515
662
  yyerror "dynamic constant assignment"
516
663
  end
517
664
 
518
- result = s(:const, s(:colon2, val[0], val[2].to_sym))
665
+ l = expr.line
666
+ result = s(:const, s(:colon2, expr, id.to_sym).line(l)).line l
519
667
  }
520
668
  | tCOLON3 tCONSTANT
521
669
  {
670
+ _, (id, l) = val
671
+
522
672
  if (self.in_def || self.in_single > 0) then
523
- debug20 11
673
+ debug 18
524
674
  yyerror "dynamic constant assignment"
525
675
  end
526
676
 
527
- result = s(:const, s(:colon3, val[1].to_sym))
677
+ result = s(:const, s(:colon3, id.to_sym).line(l)).line l
528
678
  }
529
679
  | backref
530
680
  {
@@ -539,37 +689,37 @@ rule
539
689
 
540
690
  cpath: tCOLON3 cname
541
691
  {
542
- result = s(:colon3, val[1].to_sym)
692
+ _, (name, line) = val
693
+ result = s(:colon3, name.to_sym).line line
543
694
  }
544
695
  | cname
545
696
  {
546
- result = val[0].to_sym
697
+ (id, line), = val
698
+ result = [id.to_sym, line] # TODO: sexp?
547
699
  }
548
700
  | primary_value tCOLON2 cname
549
701
  {
550
- result = s(:colon2, val[0], val[2].to_sym)
702
+ pval, _, (name, _line) = val
703
+
704
+ result = s(:colon2, pval, name.to_sym)
705
+ result.line pval.line
551
706
  }
552
707
 
553
708
  fname: tIDENTIFIER | tCONSTANT | tFID
554
709
  | op
555
710
  {
556
- lexer.lex_state = :expr_end
557
- result = val[0]
711
+ lexer.lex_state = EXPR_END
558
712
  }
559
713
 
560
714
  | reswords
561
- {
562
- lexer.lex_state = :expr_end
563
- result = val[0]
564
- }
565
715
 
566
- fsym: fname | symbol
567
-
568
- fitem: fsym
716
+ fitem: fname
569
717
  {
570
- result = s(:lit, val[0].to_sym)
718
+ (id, line), = val
719
+
720
+ result = s(:lit, id.to_sym).line line
571
721
  }
572
- | dsym
722
+ | symbol
573
723
 
574
724
  undef_list: fitem
575
725
  {
@@ -578,7 +728,7 @@ rule
578
728
  |
579
729
  undef_list tCOMMA
580
730
  {
581
- lexer.lex_state = :expr_fname
731
+ lexer.lex_state = EXPR_FNAME
582
732
  }
583
733
  fitem
584
734
  {
@@ -601,70 +751,72 @@ rule
601
751
  | kWHEN | kYIELD | kIF | kUNLESS | kWHILE
602
752
  | kUNTIL
603
753
 
604
- arg: lhs tEQL arg
754
+ arg: lhs tEQL arg_rhs
605
755
  {
606
756
  result = new_assign val[0], val[2]
607
757
  }
608
- | lhs tEQL arg kRESCUE_MOD arg
609
- {
610
- result = new_assign val[0], s(:rescue, val[2], new_resbody(s(:array), val[4]))
611
- }
612
- | var_lhs tOP_ASGN arg
758
+ | var_lhs tOP_ASGN arg_rhs
613
759
  {
614
760
  result = new_op_asgn val
615
761
  }
616
- | var_lhs tOP_ASGN arg kRESCUE_MOD arg
762
+ | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg_rhs
617
763
  {
618
- result = new_op_asgn val
619
- result = s(:rescue, result, new_resbody(s(:array), val[4]))
620
- }
621
- | primary_value tLBRACK2 opt_call_args rbracket tOP_ASGN arg
622
- {
623
- val[2].sexp_type = :arglist if val[2]
624
- result = s(:op_asgn1, val[0], val[2], val[4].to_sym, val[5])
764
+ result = new_op_asgn1 val
625
765
  }
626
- | primary_value call_op tIDENTIFIER tOP_ASGN arg
766
+ | primary_value call_op tIDENTIFIER tOP_ASGN arg_rhs
627
767
  {
628
768
  result = new_op_asgn2 val
629
769
  }
630
- | primary_value call_op tCONSTANT tOP_ASGN arg
770
+ | primary_value call_op tCONSTANT tOP_ASGN arg_rhs
631
771
  {
632
772
  result = new_op_asgn2 val
633
773
  }
634
- | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg
774
+ | primary_value tCOLON2 tIDENTIFIER tOP_ASGN arg_rhs
635
775
  {
636
- result = s(:op_asgn, val[0], val[4], val[2].to_sym, val[3].to_sym)
776
+ lhs, _, (id, _line), (op, _), rhs = val
777
+
778
+ result = s(:op_asgn, lhs, rhs, id.to_sym, op.to_sym).line lhs.line
637
779
  }
638
- | primary_value tCOLON2 tCONSTANT tOP_ASGN arg
780
+ | primary_value tCOLON2 tCONSTANT tOP_ASGN arg_rhs
639
781
  {
640
- yyerror "constant re-assignment"
782
+ lhs1, _, (lhs2, _line), op, rhs = val
783
+
784
+ lhs = s(:colon2, lhs1, lhs2.to_sym).line lhs1.line
785
+ result = new_const_op_asgn [lhs, op, rhs]
641
786
  }
642
- | tCOLON3 tCONSTANT tOP_ASGN arg
787
+ | tCOLON3 tCONSTANT tOP_ASGN arg_rhs
643
788
  {
644
- yyerror "constant re-assignment"
789
+ _, (lhs, line), op, rhs = val
790
+
791
+ lhs = s(:colon3, lhs.to_sym).line line
792
+ result = new_const_op_asgn [lhs, op, rhs]
645
793
  }
646
- | backref tOP_ASGN arg
794
+ | backref tOP_ASGN arg_rhs
647
795
  {
648
- self.backref_assign_error val[0]
796
+ # TODO: lhs = var_field val[0]
797
+ asgn = new_op_asgn val
798
+ result = self.backref_assign_error asgn
649
799
  }
650
800
  | arg tDOT2 arg
651
801
  {
652
802
  v1, v2 = val[0], val[2]
653
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
654
- result = s(:lit, (v1.last)..(v2.last))
803
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
804
+ result = s(:lit, (v1.last)..(v2.last)).line v1.line
655
805
  else
656
- result = s(:dot2, v1, v2)
806
+ result = s(:dot2, v1, v2).line v1.line
657
807
  end
658
808
  }
659
809
  | arg tDOT3 arg
660
810
  {
661
811
  v1, v2 = val[0], val[2]
662
- if v1.node_type == :lit and v2.node_type == :lit and Integer === v1.last and Integer === v2.last then
663
- result = s(:lit, (v1.last)...(v2.last))
812
+ if v1.sexp_type == :lit and v2.sexp_type == :lit and Integer === v1.last and Integer === v2.last then
813
+ result = s(:lit, (v1.last)...(v2.last)).line v1.line
664
814
  else
665
- result = s(:dot3, v1, v2)
815
+ result = s(:dot3, v1, v2).line v1.line
666
816
  end
667
817
  }
818
+
819
+
668
820
  | arg tPLUS arg
669
821
  {
670
822
  result = new_call val[0], :+, argl(val[2])
@@ -691,7 +843,10 @@ rule
691
843
  }
692
844
  | tUMINUS_NUM simple_numeric tPOW arg
693
845
  {
694
- result = new_call(new_call(s(:lit, val[1]), :"**", argl(val[3])), :"-@")
846
+ _, (num, line), _, arg = val
847
+ lit = s(:lit, num).line line
848
+ result = new_call(new_call(lit, :"**", argl(arg)), :"-@")
849
+
695
850
  }
696
851
  | tUPLUS arg
697
852
  {
@@ -717,22 +872,7 @@ rule
717
872
  {
718
873
  result = new_call val[0], :"<=>", argl(val[2])
719
874
  }
720
- | arg tGT arg
721
- {
722
- result = new_call val[0], :">", argl(val[2])
723
- }
724
- | arg tGEQ arg
725
- {
726
- result = new_call val[0], :">=", argl(val[2])
727
- }
728
- | arg tLT arg
729
- {
730
- result = new_call val[0], :"<", argl(val[2])
731
- }
732
- | arg tLEQ arg
733
- {
734
- result = new_call val[0], :"<=", argl(val[2])
735
- }
875
+ | rel_expr =tCMP
736
876
  | arg tEQ arg
737
877
  {
738
878
  result = new_call val[0], :"==", argl(val[2])
@@ -747,15 +887,19 @@ rule
747
887
  }
748
888
  | arg tMATCH arg
749
889
  {
750
- result = new_match val[0], val[2]
890
+ lhs, _, rhs = val
891
+ result = new_match lhs, rhs
751
892
  }
752
893
  | arg tNMATCH arg
753
894
  {
754
- result = s(:not, new_match(val[0], val[2]))
895
+ lhs, _, rhs = val
896
+ result = s(:not, new_match(lhs, rhs)).line lhs.line
755
897
  }
756
898
  | tBANG arg
757
899
  {
758
- result = new_call val[1], :"!"
900
+ _, arg = val
901
+ result = new_call arg, :"!"
902
+ result.line arg.line
759
903
  }
760
904
  | tTILDE arg
761
905
  {
@@ -783,14 +927,33 @@ rule
783
927
  }
784
928
  | kDEFINED opt_nl arg
785
929
  {
786
- result = s(:defined, val[2])
930
+ (_, line), _, arg = val
931
+ result = s(:defined, arg).line line
787
932
  }
788
933
  | arg tEH arg opt_nl tCOLON arg
789
934
  {
790
- result = s(:if, val[0], val[2], val[5])
935
+ c, _, t, _, _, f = val
936
+ result = s(:if, c, t, f).line c.line
791
937
  }
792
938
  | primary
793
939
 
940
+ relop: tGT
941
+ | tLT
942
+ | tGEQ
943
+ | tLEQ
944
+
945
+ rel_expr: arg relop arg =tGT
946
+ {
947
+ lhs, (op, _), rhs = val
948
+ result = new_call lhs, op.to_sym, argl(rhs)
949
+ }
950
+ | rel_expr relop arg =tGT
951
+ {
952
+ lhs, (op, _), rhs = val
953
+ warn "comparison '%s' after comparison", op
954
+ result = new_call lhs, op.to_sym, argl(rhs)
955
+ }
956
+
794
957
  arg_value: arg
795
958
  {
796
959
  result = value_expr(val[0])
@@ -810,22 +973,28 @@ rule
810
973
  result = args [array_to_hash(val[0])]
811
974
  }
812
975
 
976
+ arg_rhs: arg =tOP_ASGN
977
+ | arg kRESCUE_MOD arg
978
+ {
979
+ body, (_, line), resbody = val
980
+ body = value_expr body
981
+ resbody = remove_begin resbody
982
+
983
+ ary = s(:array).line line
984
+ result = new_rescue(body, new_resbody(ary, resbody))
985
+ }
986
+
813
987
  paren_args: tLPAREN2 opt_call_args rparen
814
988
  {
815
- result = val[1]
989
+ _, args, _ = val
990
+ result = args
816
991
  }
817
992
 
818
993
  opt_paren_args: none
819
994
  | paren_args
820
995
 
821
996
  opt_call_args: none
822
- {
823
- result = val[0]
824
- }
825
997
  | call_args
826
- {
827
- result = val[0]
828
- }
829
998
  | args tCOMMA
830
999
  {
831
1000
  result = args val
@@ -847,17 +1016,14 @@ rule
847
1016
  | args opt_block_arg
848
1017
  {
849
1018
  result = call_args val
850
- result = self.arg_blk_pass val[0], val[1]
851
1019
  }
852
1020
  | assocs opt_block_arg
853
1021
  {
854
- result = call_args [array_to_hash(val[0])]
855
- result = self.arg_blk_pass result, val[1]
1022
+ result = call_args [array_to_hash(val[0]), val[1]]
856
1023
  }
857
1024
  | args tCOMMA assocs opt_block_arg
858
1025
  {
859
- result = call_args [val[0], array_to_hash(val[2])]
860
- result = self.arg_blk_pass result, val[3]
1026
+ result = call_args [val[0], array_to_hash(val[2]), val[3]]
861
1027
  }
862
1028
  | block_arg
863
1029
  {
@@ -865,18 +1031,45 @@ rule
865
1031
  }
866
1032
 
867
1033
  command_args: {
868
- result = lexer.cmdarg.stack.dup # TODO: smell?
1034
+ # parse26.y line 2200
1035
+
1036
+ # If call_args starts with a open paren '(' or
1037
+ # '[', look-ahead reading of the letters calls
1038
+ # CMDARG_PUSH(0), but the push must be done
1039
+ # after CMDARG_PUSH(1). So this code makes them
1040
+ # consistent by first cancelling the premature
1041
+ # CMDARG_PUSH(0), doing CMDARG_PUSH(1), and
1042
+ # finally redoing CMDARG_PUSH(0).
1043
+
1044
+ result = yychar = self.last_token_type.first
1045
+ lookahead = [:tLPAREN, :tLPAREN_ARG, :tLPAREN2, :tLBRACK, :tLBRACK2].include?(yychar)
1046
+ lexer.cmdarg.pop if lookahead
869
1047
  lexer.cmdarg.push true
1048
+ lexer.cmdarg.push false if lookahead
870
1049
  }
871
1050
  call_args
872
1051
  {
873
- lexer.cmdarg.stack.replace val[0]
874
- result = val[1]
1052
+ yychar, args = val
1053
+
1054
+ # call_args can be followed by tLBRACE_ARG (that
1055
+ # does CMDARG_PUSH(0) in the lexer) but the push
1056
+ # must be done after CMDARG_POP() in the parser.
1057
+ # So this code does CMDARG_POP() to pop 0 pushed
1058
+ # by tLBRACE_ARG, CMDARG_POP() to pop 1 pushed
1059
+ # by command_args, and CMDARG_PUSH(0) to restore
1060
+ # back the flag set by tLBRACE_ARG.
1061
+
1062
+ lookahead = [:tLBRACE_ARG].include?(yychar)
1063
+ lexer.cmdarg.pop if lookahead
1064
+ lexer.cmdarg.pop
1065
+ lexer.cmdarg.push false if lookahead
1066
+ result = args
875
1067
  }
876
1068
 
877
1069
  block_arg: tAMPER arg_value
878
1070
  {
879
- result = s(:block_pass, val[1])
1071
+ _, arg = val
1072
+ result = s(:block_pass, arg).line arg.line
880
1073
  }
881
1074
 
882
1075
  opt_block_arg: tCOMMA block_arg
@@ -887,19 +1080,27 @@ rule
887
1080
 
888
1081
  args: arg_value
889
1082
  {
890
- result = s(:array, val[0])
1083
+ arg, = val
1084
+ lineno = arg.line || lexer.lineno # HACK
1085
+
1086
+ result = s(:array, arg).line lineno
891
1087
  }
892
1088
  | tSTAR arg_value
893
1089
  {
894
- result = s(:array, s(:splat, val[1]))
1090
+ _, arg = val
1091
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
895
1092
  }
896
1093
  | args tCOMMA arg_value
897
1094
  {
898
- result = self.list_append val[0], val[2]
1095
+ args, _, id = val
1096
+ result = self.list_append args, id
899
1097
  }
900
1098
  | args tCOMMA tSTAR arg_value
901
1099
  {
902
- result = self.list_append val[0], s(:splat, val[3])
1100
+ # TODO: the line number from tSTAR has been dropped
1101
+ args, _, _, id = val
1102
+ line = lexer.lineno
1103
+ result = self.list_append args, s(:splat, id).line(line)
903
1104
  }
904
1105
 
905
1106
  mrhs_arg: mrhs
@@ -917,11 +1118,14 @@ rule
917
1118
  }
918
1119
  | args tCOMMA tSTAR arg_value
919
1120
  {
920
- result = self.arg_concat val[0], val[3]
1121
+ # TODO: make all tXXXX terminals include lexer.lineno
1122
+ arg, _, _, splat = val
1123
+ result = self.arg_concat arg, splat
921
1124
  }
922
1125
  | tSTAR arg_value
923
1126
  {
924
- result = s(:splat, val[1])
1127
+ _, arg = val
1128
+ result = s(:splat, arg).line arg.line
925
1129
  }
926
1130
 
927
1131
  primary: literal
@@ -936,58 +1140,66 @@ rule
936
1140
  | backref
937
1141
  | tFID
938
1142
  {
939
- result = new_call nil, val[0].to_sym
1143
+ (msg, line), = val
1144
+ result = new_call nil, msg.to_sym
1145
+ result.line line
940
1146
  }
941
- | kBEGIN
1147
+ | k_begin
942
1148
  {
1149
+ lexer.cmdarg.push false
943
1150
  result = self.lexer.lineno
944
1151
  }
945
- bodystmt kEND
1152
+ bodystmt k_end
946
1153
  {
947
- unless val[2] then
948
- result = s(:nil)
949
- else
950
- result = s(:begin, val[2])
951
- end
952
-
953
- result.line = val[1]
1154
+ lexer.cmdarg.pop
1155
+ result = new_begin val
954
1156
  }
955
- | tLPAREN_ARG rparen
1157
+ | tLPAREN_ARG
956
1158
  {
957
- debug20 13, val, result
1159
+ lexer.lex_state = EXPR_ENDARG
1160
+ result = lexer.lineno
958
1161
  }
959
- | tLPAREN_ARG
1162
+ rparen
960
1163
  {
961
- result = self.lexer.cmdarg.stack.dup
962
- lexer.cmdarg.stack.replace [false] # TODO add api for these
1164
+ _, line, _ = val
1165
+ result = s(:begin).line line
963
1166
  }
964
- expr
1167
+ | tLPAREN_ARG
1168
+ stmt
965
1169
  {
966
- lexer.lex_state = :expr_endarg
1170
+ lexer.lex_state = EXPR_ENDARG
967
1171
  }
968
1172
  rparen
969
1173
  {
970
- warning "(...) interpreted as grouped expression"
971
- lexer.cmdarg.stack.replace val[1]
972
- result = val[2]
1174
+ _, stmt, _, _, = val
1175
+ # warning "(...) interpreted as grouped expression"
1176
+ result = stmt
973
1177
  }
974
1178
  | tLPAREN compstmt tRPAREN
975
1179
  {
976
- result = val[1] || s(:nil)
1180
+ _, stmt, _ = val
1181
+ result = stmt
1182
+ result ||= s(:nil).line lexer.lineno
977
1183
  result.paren = true
978
1184
  }
979
1185
  | primary_value tCOLON2 tCONSTANT
980
1186
  {
981
- result = s(:colon2, val[0], val[2].to_sym)
1187
+ expr, _, (id, _line) = val
1188
+
1189
+ result = s(:colon2, expr, id.to_sym).line expr.line
982
1190
  }
983
1191
  | tCOLON3 tCONSTANT
984
1192
  {
985
- result = s(:colon3, val[1].to_sym)
1193
+ _, (id, line) = val
1194
+
1195
+ result = s(:colon3, id.to_sym).line line
986
1196
  }
987
- | tLBRACK aref_args tRBRACK
1197
+ | tLBRACK { result = lexer.lineno } aref_args tRBRACK
988
1198
  {
989
- result = val[1] || s(:array)
1199
+ _, line, args, _ = val
1200
+ result = args || s(:array)
990
1201
  result.sexp_type = :array # aref_args is :args
1202
+ result.line line
991
1203
  }
992
1204
  | tLBRACE
993
1205
  {
@@ -997,41 +1209,51 @@ rule
997
1209
  {
998
1210
  result = new_hash val
999
1211
  }
1000
- | kRETURN
1212
+ | k_return
1001
1213
  {
1002
- result = s(:return)
1214
+ (_, line), = val
1215
+ result = s(:return).line line
1003
1216
  }
1004
1217
  | kYIELD tLPAREN2 call_args rparen
1005
1218
  {
1006
- result = new_yield val[2]
1219
+ (_, line), _, args, _ = val
1220
+
1221
+ result = new_yield(args).line line
1007
1222
  }
1008
1223
  | kYIELD tLPAREN2 rparen
1009
1224
  {
1010
- result = new_yield
1225
+ (_, line), _, _ = val
1226
+
1227
+ result = new_yield.line line
1011
1228
  }
1012
1229
  | kYIELD
1013
1230
  {
1014
- result = new_yield
1231
+ (_, line), = val
1232
+
1233
+ result = new_yield.line line
1015
1234
  }
1016
1235
  | kDEFINED opt_nl tLPAREN2 expr rparen
1017
1236
  {
1018
- result = s(:defined, val[3])
1237
+ (_, line), _, _, arg, _ = val
1238
+
1239
+ result = s(:defined, arg).line line
1019
1240
  }
1020
1241
  | kNOT tLPAREN2 expr rparen
1021
1242
  {
1022
- result = s(:call, val[2], :"!")
1243
+ _, _, lhs, _ = val
1244
+ result = new_call lhs, :"!"
1023
1245
  }
1024
1246
  | kNOT tLPAREN2 rparen
1025
1247
  {
1026
- debug20 14, val, result
1248
+ debug 20
1027
1249
  }
1028
1250
  | fcall brace_block
1029
1251
  {
1030
- oper, iter = val[0], val[1]
1031
- call = oper # FIX
1252
+ call, iter = val
1253
+
1032
1254
  iter.insert 1, call
1033
1255
  result = iter
1034
- call.line = iter.line
1256
+ # FIX: probably not: call.line = iter.line
1035
1257
  }
1036
1258
  | method_call
1037
1259
  | method_call brace_block
@@ -1041,83 +1263,64 @@ rule
1041
1263
  iter.insert 1, call # FIX
1042
1264
  result = iter
1043
1265
  }
1044
- | tLAMBDA lambda
1266
+ | lambda
1045
1267
  {
1046
- result = val[1] # TODO: fix lineno
1268
+ expr, = val
1269
+ result = expr
1047
1270
  }
1048
- | kIF expr_value then compstmt if_tail kEND
1271
+ | k_if expr_value then compstmt if_tail k_end
1049
1272
  {
1050
- result = new_if val[1], val[3], val[4]
1273
+ _, c, _, t, f, _ = val
1274
+ result = new_if c, t, f
1051
1275
  }
1052
- | kUNLESS expr_value then compstmt opt_else kEND
1276
+ | k_unless expr_value then compstmt opt_else k_end
1053
1277
  {
1054
- result = new_if val[1], val[4], val[3]
1278
+ _, c, _, t, f, _ = val
1279
+ result = new_if c, f, t
1055
1280
  }
1056
- | kWHILE
1281
+ | k_while expr_value_do compstmt k_end
1057
1282
  {
1058
- lexer.cond.push true
1283
+ _, cond, body, _ = val
1284
+ result = new_while body, cond, true
1059
1285
  }
1060
- expr_value do
1061
- {
1062
- lexer.cond.pop
1063
- }
1064
- compstmt kEND
1286
+ | k_until expr_value_do compstmt k_end
1065
1287
  {
1066
- result = new_while val[5], val[2], true
1288
+ _, cond, body, _ = val
1289
+ result = new_until body, cond, true
1067
1290
  }
1068
- | kUNTIL
1069
- {
1070
- lexer.cond.push true
1071
- }
1072
- expr_value do
1073
- {
1074
- lexer.cond.pop
1075
- }
1076
- compstmt kEND
1077
- {
1078
- result = new_until val[5], val[2], true
1079
- }
1080
- | kCASE expr_value opt_terms case_body kEND
1291
+ | k_case expr_value opt_terms case_body k_end
1081
1292
  {
1082
1293
  (_, line), expr, _, body, _ = val
1083
1294
  result = new_case expr, body, line
1084
1295
  }
1085
- | kCASE opt_terms case_body kEND
1296
+ | k_case opt_terms case_body k_end
1086
1297
  {
1087
1298
  (_, line), _, body, _ = val
1088
1299
  result = new_case nil, body, line
1089
1300
  }
1090
- | kFOR for_var kIN
1091
- {
1092
- lexer.cond.push true
1093
- }
1094
- expr_value do
1095
- {
1096
- lexer.cond.pop
1097
- }
1098
- compstmt kEND
1301
+ | k_for for_var kIN expr_value_do compstmt k_end
1099
1302
  {
1100
- result = new_for val[4], val[1], val[7]
1303
+ _, var, _, iter, body, _ = val
1304
+ result = new_for iter, var, body
1101
1305
  }
1102
- | kCLASS
1306
+ | k_class
1103
1307
  {
1104
1308
  result = self.lexer.lineno
1105
1309
  }
1106
1310
  cpath superclass
1107
1311
  {
1108
- self.comments.push self.lexer.comments
1109
1312
  if (self.in_def || self.in_single > 0) then
1110
1313
  yyerror "class definition in method body"
1111
1314
  end
1112
1315
  self.env.extend
1113
1316
  }
1114
- bodystmt kEND
1317
+ bodystmt k_end
1115
1318
  {
1116
1319
  result = new_class val
1117
1320
  self.env.unextend
1118
- self.lexer.comments # we don't care about comments in the body
1321
+ self.lexer.ignore_body_comments
1119
1322
  }
1120
- | kCLASS tLSHFT
1323
+ | k_class tLSHFT
1121
1324
  {
1122
1325
  result = self.lexer.lineno
1123
1326
  }
@@ -1132,92 +1335,108 @@ rule
1132
1335
  self.in_single = 0
1133
1336
  self.env.extend
1134
1337
  }
1135
- bodystmt kEND
1338
+ bodystmt k_end
1136
1339
  {
1137
1340
  result = new_sclass val
1138
1341
  self.env.unextend
1139
- self.lexer.comments # we don't care about comments in the body
1342
+ self.lexer.ignore_body_comments
1140
1343
  }
1141
- | kMODULE
1344
+ | k_module
1142
1345
  {
1143
1346
  result = self.lexer.lineno
1144
1347
  }
1145
1348
  cpath
1146
1349
  {
1147
- self.comments.push self.lexer.comments
1148
1350
  yyerror "module definition in method body" if
1149
1351
  self.in_def or self.in_single > 0
1150
1352
 
1151
1353
  self.env.extend
1152
1354
  }
1153
- bodystmt kEND
1355
+ bodystmt k_end
1154
1356
  {
1155
1357
  result = new_module val
1156
1358
  self.env.unextend
1157
- self.lexer.comments # we don't care about comments in the body
1359
+ self.lexer.ignore_body_comments
1158
1360
  }
1159
- | kDEF fname
1361
+ | k_def fname
1160
1362
  {
1161
- result = [self.in_def, self.lexer.cmdarg.stack.dup]
1363
+ result = self.in_def
1162
1364
 
1163
- self.comments.push self.lexer.comments
1164
- self.in_def = true
1365
+ self.in_def = true # group = local_push
1165
1366
  self.env.extend
1166
- # TODO: local->cmdargs = cmdarg_stack;
1167
- # TODO: port local_push_gen and local_pop_gen
1168
- lexer.cmdarg.stack.replace [false]
1367
+ lexer.cmdarg.push false
1368
+ lexer.cond.push false
1169
1369
  }
1170
- f_arglist bodystmt kEND
1370
+ f_arglist bodystmt k_end
1171
1371
  {
1172
- in_def, cmdarg = val[2]
1372
+ result, in_def = new_defn val
1173
1373
 
1174
- result = new_defn val
1175
-
1176
- lexer.cmdarg.stack.replace cmdarg
1374
+ lexer.cond.pop # group = local_pop
1375
+ lexer.cmdarg.pop
1177
1376
  self.env.unextend
1178
1377
  self.in_def = in_def
1179
- self.lexer.comments # we don't care about comments in the body
1378
+
1379
+ self.lexer.ignore_body_comments
1180
1380
  }
1181
- | kDEF singleton dot_or_colon
1381
+ | k_def singleton dot_or_colon
1182
1382
  {
1183
- self.comments.push self.lexer.comments
1184
- lexer.lex_state = :expr_fname
1383
+ lexer.lex_state = EXPR_FNAME
1185
1384
  }
1186
1385
  fname
1187
1386
  {
1188
- self.in_single += 1
1387
+ result = self.in_def
1388
+
1389
+ self.in_single += 1 # TODO: remove?
1390
+
1391
+ self.in_def = true # local_push
1189
1392
  self.env.extend
1190
- lexer.lex_state = :expr_endfn # force for args
1191
- result = [lexer.lineno, self.lexer.cmdarg.stack.dup]
1192
- lexer.cmdarg.stack.replace [false]
1393
+ lexer.cmdarg.push false
1394
+ lexer.cond.push false
1395
+
1396
+ lexer.lex_state = EXPR_ENDFN|EXPR_LABEL
1193
1397
  }
1194
- f_arglist bodystmt kEND
1398
+ f_arglist bodystmt k_end
1195
1399
  {
1196
- line, cmdarg = val[5]
1197
- result = new_defs val
1198
- result[3].line line
1199
1400
 
1200
- lexer.cmdarg.stack.replace cmdarg
1401
+ # [kdef, recv, _, _, (name, line), in_def, args, body, kend]
1402
+ # =>
1403
+ # [kdef, recv, (name, line), in_def, args, body, kend]
1404
+
1405
+ val.delete_at 3
1406
+ val.delete_at 2
1407
+
1408
+ result, in_def = new_defs val
1201
1409
 
1410
+ lexer.cond.pop # group = local_pop
1411
+ lexer.cmdarg.pop
1202
1412
  self.env.unextend
1413
+ self.in_def = in_def
1414
+
1203
1415
  self.in_single -= 1
1204
- self.lexer.comments # we don't care about comments in the body
1416
+
1417
+ # TODO: restore cur_arg ? what's cur_arg?
1418
+
1419
+ self.lexer.ignore_body_comments
1205
1420
  }
1206
1421
  | kBREAK
1207
1422
  {
1208
- result = s(:break)
1423
+ (_, line), = val
1424
+ result = s(:break).line line
1209
1425
  }
1210
1426
  | kNEXT
1211
1427
  {
1212
- result = s(:next)
1428
+ (_, line), = val
1429
+ result = s(:next).line line
1213
1430
  }
1214
1431
  | kREDO
1215
1432
  {
1216
- result = s(:redo)
1433
+ (_, line), = val
1434
+ result = s(:redo).line line
1217
1435
  }
1218
1436
  | kRETRY
1219
1437
  {
1220
- result = s(:retry)
1438
+ (_, line), = val
1439
+ result = s(:retry).line line
1221
1440
  }
1222
1441
 
1223
1442
  primary_value: primary
@@ -1234,9 +1453,26 @@ rule
1234
1453
  k_case: kCASE
1235
1454
  k_for: kFOR
1236
1455
  k_class: kCLASS
1456
+ {
1457
+ self.comments.push self.lexer.comments
1458
+ }
1237
1459
  k_module: kMODULE
1460
+ {
1461
+ self.comments.push self.lexer.comments
1462
+ }
1238
1463
  k_def: kDEF
1464
+ {
1465
+ self.comments.push self.lexer.comments
1466
+ }
1467
+ k_do: kDO
1468
+ k_do_block: kDO_BLOCK
1469
+ k_rescue: kRESCUE
1470
+ k_ensure: kENSURE
1471
+ k_when: kWHEN
1472
+ k_else: kELSE
1473
+ k_elsif: kELSIF
1239
1474
  k_end: kEND
1475
+ k_return: kRETURN
1240
1476
 
1241
1477
  then: term
1242
1478
  | kTHEN
@@ -1246,9 +1482,11 @@ rule
1246
1482
  | kDO_COND
1247
1483
 
1248
1484
  if_tail: opt_else
1249
- | kELSIF expr_value then compstmt if_tail
1485
+ | k_elsif expr_value then compstmt if_tail
1250
1486
  {
1251
- result = s(:if, val[1], val[3], val[4])
1487
+ (_, line), c, _, t, rest = val
1488
+
1489
+ result = s(:if, c, t, rest).line line
1252
1490
  }
1253
1491
 
1254
1492
  opt_else: none
@@ -1271,7 +1509,9 @@ rule
1271
1509
 
1272
1510
  f_marg_list: f_marg
1273
1511
  {
1274
- result = s(:array, val[0])
1512
+ sym, = val
1513
+
1514
+ result = s(:array, sym).line lexer.lineno
1275
1515
  }
1276
1516
  | f_marg_list tCOMMA f_marg
1277
1517
  {
@@ -1284,51 +1524,42 @@ rule
1284
1524
 
1285
1525
  result = block_var args
1286
1526
  }
1287
- | f_marg_list tCOMMA tSTAR f_norm_arg
1527
+ | f_marg_list tCOMMA f_rest_marg
1288
1528
  {
1289
- args, _, _, splat = val
1529
+ args, _, rest = val
1290
1530
 
1291
- result = block_var args, "*#{splat}".to_sym
1531
+ result = block_var args, rest
1292
1532
  }
1293
- | f_marg_list tCOMMA tSTAR f_norm_arg tCOMMA f_marg_list
1533
+ | f_marg_list tCOMMA f_rest_marg tCOMMA f_marg_list
1294
1534
  {
1295
- args, _, _, splat, _, args2 = val
1535
+ lhs, _, splat, _, rhs = val
1296
1536
 
1297
- result = block_var args, "*#{splat}".to_sym, args2
1537
+ result = block_var lhs, splat, rhs
1298
1538
  }
1299
- | f_marg_list tCOMMA tSTAR
1539
+ | f_rest_marg
1300
1540
  {
1301
- args, _, _ = val
1541
+ rest, = val
1302
1542
 
1303
- result = block_var args, :*
1543
+ result = block_var rest
1304
1544
  }
1305
- | f_marg_list tCOMMA tSTAR tCOMMA f_marg_list
1545
+ | f_rest_marg tCOMMA f_marg_list
1306
1546
  {
1307
- args, _, _, _, args2 = val
1547
+ splat, _, rest = val
1308
1548
 
1309
- result = block_var args, :*, args2
1549
+ result = block_var splat, rest
1310
1550
  }
1311
- | tSTAR f_norm_arg
1312
- {
1313
- _, splat = val
1314
1551
 
1315
- result = block_var :"*#{splat}"
1316
- }
1317
- | tSTAR f_norm_arg tCOMMA f_marg_list
1552
+ f_rest_marg: tSTAR f_norm_arg
1318
1553
  {
1319
- _, splat, _, args = val
1554
+ _, (id, line) = val
1320
1555
 
1321
- result = block_var :"*#{splat}", args
1556
+ result = args ["*#{id}".to_sym]
1557
+ result.line line
1322
1558
  }
1323
1559
  | tSTAR
1324
1560
  {
1325
- result = block_var :*
1326
- }
1327
- | tSTAR tCOMMA f_marg_list
1328
- {
1329
- _, _, args = val
1330
-
1331
- result = block_var :*, args
1561
+ result = args [:*]
1562
+ result.line lexer.lineno # FIX: tSTAR -> line
1332
1563
  }
1333
1564
 
1334
1565
  block_args_tail: f_block_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -1345,7 +1576,9 @@ rule
1345
1576
  }
1346
1577
  | f_block_arg
1347
1578
  {
1348
- result = call_args val
1579
+ (id, line), = val
1580
+ result = call_args [id]
1581
+ result.line line
1349
1582
  }
1350
1583
 
1351
1584
  opt_block_args_tail: tCOMMA block_args_tail
@@ -1376,7 +1609,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1376
1609
  }
1377
1610
  | f_arg tCOMMA
1378
1611
  {
1379
- result = args val
1612
+ result = args(val) << nil
1380
1613
  }
1381
1614
  | f_arg tCOMMA f_rest_arg tCOMMA f_arg opt_block_args_tail
1382
1615
  {
@@ -1417,18 +1650,22 @@ opt_block_args_tail: tCOMMA block_args_tail
1417
1650
 
1418
1651
  opt_block_param: none { result = 0 }
1419
1652
  | block_param_def
1653
+ {
1654
+ self.lexer.command_start = true
1655
+ }
1420
1656
 
1421
1657
  block_param_def: tPIPE opt_bv_decl tPIPE
1422
1658
  {
1659
+ # TODO: current_arg = 0
1423
1660
  result = args val
1424
1661
  }
1425
1662
  | tOROP
1426
1663
  {
1427
- self.lexer.command_start = true
1428
- result = s(:args)
1664
+ result = s(:args).line lexer.lineno
1429
1665
  }
1430
1666
  | tPIPE block_param opt_bv_decl tPIPE
1431
1667
  {
1668
+ # TODO: current_arg = 0
1432
1669
  result = args val
1433
1670
  }
1434
1671
 
@@ -1449,26 +1686,33 @@ opt_block_args_tail: tCOMMA block_args_tail
1449
1686
 
1450
1687
  bvar: tIDENTIFIER
1451
1688
  {
1452
- result = s(:shadow, val[0].to_sym)
1689
+ (id, line), = val
1690
+ result = s(:shadow, id.to_sym).line line
1453
1691
  }
1454
1692
  | f_bad_arg
1455
1693
 
1456
- lambda: {
1694
+ lambda: tLAMBDA
1695
+ {
1457
1696
  self.env.extend :dynamic
1458
- result = self.lexer.lineno
1459
-
1460
- result = lexer.lpar_beg
1697
+ result = [lexer.lineno, lexer.lpar_beg]
1461
1698
  lexer.paren_nest += 1
1462
1699
  lexer.lpar_beg = lexer.paren_nest
1463
1700
  }
1464
- f_larglist lambda_body
1701
+ f_larglist
1702
+ {
1703
+ lexer.cmdarg.push false
1704
+ }
1705
+ lambda_body
1465
1706
  {
1466
- lpar, args, body = val
1707
+ _, (line, lpar), args, _cmdarg, body = val
1467
1708
  lexer.lpar_beg = lpar
1468
1709
 
1469
- call = new_call nil, :lambda
1710
+ lexer.cmdarg.pop
1711
+
1712
+ call = s(:lambda).line line
1470
1713
  result = new_iter call, args, body
1471
- self.env.unextend
1714
+ result.line line
1715
+ self.env.unextend # TODO: dynapush & dynapop
1472
1716
  }
1473
1717
 
1474
1718
  f_larglist: tLPAREN2 f_args opt_bv_decl rparen
@@ -1485,28 +1729,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1485
1729
  {
1486
1730
  result = val[1]
1487
1731
  }
1488
- | kDO_LAMBDA compstmt kEND
1732
+ | kDO_LAMBDA bodystmt kEND
1489
1733
  {
1490
1734
  result = val[1]
1491
1735
  }
1492
1736
 
1493
- do_block: kDO_BLOCK
1494
- {
1495
- self.env.extend :dynamic
1496
- result = self.lexer.lineno
1497
- }
1498
- opt_block_param
1737
+ do_block: k_do_block do_body kEND
1499
1738
  {
1500
- result = nil # self.env.dynamic.keys
1501
- }
1502
- compstmt kEND
1503
- {
1504
- args = val[2]
1505
- body = val[4]
1506
- result = new_iter nil, args, body
1507
- result.line = val[1]
1508
-
1509
- self.env.unextend
1739
+ (_, line), iter, _ = val
1740
+ result = iter.line line
1510
1741
  }
1511
1742
 
1512
1743
  block_call: command do_block
@@ -1515,30 +1746,37 @@ opt_block_args_tail: tCOMMA block_args_tail
1515
1746
  ## if (nd_type($1) == NODE_YIELD) {
1516
1747
  ## compile_error(PARSER_ARG "block given to yield");
1517
1748
 
1749
+ cmd, blk = val
1750
+
1518
1751
  syntax_error "Both block arg and actual block given." if
1519
- val[0].block_pass?
1752
+ cmd.block_pass?
1520
1753
 
1521
- val = invert_block_call val if inverted? val
1754
+ if inverted? val then
1755
+ val = invert_block_call val
1756
+ cmd, blk = val
1757
+ end
1522
1758
 
1523
- result = val[1]
1524
- result.insert 1, val[0]
1759
+ result = blk
1760
+ result.insert 1, cmd
1525
1761
  }
1526
- | block_call dot_or_colon operation2 opt_paren_args
1762
+ | block_call call_op2 operation2 opt_paren_args
1527
1763
  {
1528
- result = new_call val[0], val[2].to_sym, val[3]
1764
+ lhs, _, (id, _line), args = val
1765
+
1766
+ result = new_call lhs, id.to_sym, args
1529
1767
  }
1530
- | block_call dot_or_colon operation2 opt_paren_args brace_block
1768
+ | block_call call_op2 operation2 opt_paren_args brace_block
1531
1769
  {
1532
- iter1, _, name, args, iter2 = val
1770
+ iter1, _, (name, _line), args, iter2 = val
1533
1771
 
1534
1772
  call = new_call iter1, name.to_sym, args
1535
1773
  iter2.insert 1, call
1536
1774
 
1537
1775
  result = iter2
1538
1776
  }
1539
- | block_call dot_or_colon operation2 command_args do_block
1777
+ | block_call call_op2 operation2 command_args do_block
1540
1778
  {
1541
- iter1, _, name, args, iter2 = val
1779
+ iter1, _, (name, _line), args, iter2 = val
1542
1780
 
1543
1781
  call = new_call iter1, name.to_sym, args
1544
1782
  iter2.insert 1, call
@@ -1546,26 +1784,29 @@ opt_block_args_tail: tCOMMA block_args_tail
1546
1784
  result = iter2
1547
1785
  }
1548
1786
 
1549
- method_call: fcall
1787
+ method_call: fcall paren_args
1550
1788
  {
1551
- result = self.lexer.lineno
1552
- }
1553
- paren_args
1554
- {
1555
- args = self.call_args val[2..-1]
1556
- result = val[0].concat args.sexp_body
1789
+ call, args = val
1790
+
1791
+ result = call.concat args.sexp_body if args
1557
1792
  }
1558
1793
  | primary_value call_op operation2 opt_paren_args
1559
1794
  {
1560
- result = new_call val[0], val[2].to_sym, val[3], val[1]
1795
+ recv, call_op, (op, _line), args = val
1796
+
1797
+ result = new_call recv, op.to_sym, args, call_op
1561
1798
  }
1562
1799
  | primary_value tCOLON2 operation2 paren_args
1563
1800
  {
1564
- result = new_call val[0], val[2].to_sym, val[3]
1801
+ recv, _, (op, _line), args = val
1802
+
1803
+ result = new_call recv, op.to_sym, args
1565
1804
  }
1566
1805
  | primary_value tCOLON2 operation3
1567
1806
  {
1568
- result = new_call val[0], val[2].to_sym
1807
+ lhs, _, (id, _line) = val
1808
+
1809
+ result = new_call lhs, id.to_sym
1569
1810
  }
1570
1811
  | primary_value call_op paren_args
1571
1812
  {
@@ -1581,7 +1822,7 @@ opt_block_args_tail: tCOMMA block_args_tail
1581
1822
  }
1582
1823
  | kSUPER
1583
1824
  {
1584
- result = s(:zsuper)
1825
+ result = s(:zsuper).line lexer.lineno
1585
1826
  }
1586
1827
  | primary_value tLBRACK2 opt_call_args rbracket
1587
1828
  {
@@ -1593,57 +1834,98 @@ opt_block_args_tail: tCOMMA block_args_tail
1593
1834
  self.env.extend :dynamic
1594
1835
  result = self.lexer.lineno
1595
1836
  }
1596
- opt_block_param
1597
- {
1598
- result = nil # self.env.dynamic.keys
1599
- }
1600
- compstmt tRCURLY
1837
+ brace_body tRCURLY
1601
1838
  {
1602
- _, line, args, _, body, _ = val
1839
+ _, line, body, _ = val
1603
1840
 
1604
- result = new_iter nil, args, body
1605
- result.line = line
1841
+ result = body
1842
+ result.line line
1606
1843
 
1607
1844
  self.env.unextend
1608
1845
  }
1609
- | kDO
1846
+ | k_do
1610
1847
  {
1611
1848
  self.env.extend :dynamic
1612
1849
  result = self.lexer.lineno
1613
1850
  }
1614
- opt_block_param
1851
+ do_body kEND
1615
1852
  {
1616
- result = nil # self.env.dynamic.keys
1853
+ _, line, body, _ = val
1854
+
1855
+ result = body
1856
+ result.line line
1857
+
1858
+ self.env.unextend
1617
1859
  }
1618
- compstmt kEND
1860
+
1861
+ brace_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1862
+ { result = lexer.cmdarg.store(false) }
1863
+ opt_block_param compstmt
1619
1864
  {
1620
- _, line, args, _, body, _ = val
1865
+ line, cmdarg, param, cmpstmt = val
1621
1866
 
1622
- result = new_iter nil, args, body
1623
- result.line = line
1867
+ result = new_brace_body param, cmpstmt, line
1868
+ self.env.unextend
1869
+ lexer.cmdarg.restore cmdarg
1870
+ lexer.cmdarg.pop # because of: cmdarg_stack >> 1 ?
1871
+ }
1872
+
1873
+ do_body: { self.env.extend :dynamic; result = self.lexer.lineno }
1874
+ { lexer.cmdarg.push false }
1875
+ opt_block_param
1876
+ compstmt
1877
+ {
1878
+ line, _cmdarg, param, cmpstmt = val
1624
1879
 
1880
+ result = new_do_body param, cmpstmt, line
1881
+ lexer.cmdarg.pop
1625
1882
  self.env.unextend
1626
1883
  }
1627
1884
 
1628
- case_body: kWHEN
1885
+ case_args: arg_value
1886
+ {
1887
+ arg, = val
1888
+
1889
+ result = s(:array, arg).line arg.line
1890
+ }
1891
+ | tSTAR arg_value
1892
+ {
1893
+ _, arg = val
1894
+
1895
+ result = s(:array, s(:splat, arg).line(arg.line)).line arg.line
1896
+ }
1897
+ | case_args tCOMMA arg_value
1898
+ {
1899
+ args, _, id = val
1900
+
1901
+ result = self.list_append args, id
1902
+ }
1903
+ | case_args tCOMMA tSTAR arg_value
1904
+ {
1905
+ args, _, _, id = val
1906
+
1907
+ result = self.list_append args, s(:splat, id).line(id.line)
1908
+ }
1909
+
1910
+ case_body: k_when
1629
1911
  {
1630
1912
  result = self.lexer.lineno
1631
1913
  }
1632
- args then compstmt cases
1914
+ case_args then compstmt cases
1633
1915
  {
1634
1916
  result = new_when(val[2], val[4])
1635
- result.line = val[1]
1917
+ result.line val[1]
1636
1918
  result << val[5] if val[5]
1637
1919
  }
1638
1920
 
1639
1921
  cases: opt_else | case_body
1640
1922
 
1641
- opt_rescue: kRESCUE exc_list exc_var then compstmt opt_rescue
1923
+ opt_rescue: k_rescue exc_list exc_var then compstmt opt_rescue
1642
1924
  {
1643
1925
  (_, line), klasses, var, _, body, rest = val
1644
1926
 
1645
1927
  klasses ||= s(:array)
1646
- klasses << new_assign(var, s(:gvar, :"$!")) if var
1928
+ klasses << new_assign(var, s(:gvar, :"$!").line(var.line)) if var
1647
1929
  klasses.line line
1648
1930
 
1649
1931
  result = new_resbody(klasses, body)
@@ -1656,7 +1938,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1656
1938
 
1657
1939
  exc_list: arg_value
1658
1940
  {
1659
- result = s(:array, val[0])
1941
+ arg, = val
1942
+ result = s(:array, arg).line arg.line
1660
1943
  }
1661
1944
  | mrhs
1662
1945
  | none
@@ -1667,33 +1950,31 @@ opt_block_args_tail: tCOMMA block_args_tail
1667
1950
  }
1668
1951
  | none
1669
1952
 
1670
- opt_ensure: kENSURE compstmt
1953
+ opt_ensure: k_ensure compstmt
1671
1954
  {
1672
- _, body = val
1955
+ (_, line), body = val
1673
1956
 
1674
- result = body || s(:nil)
1957
+ result = body || s(:nil).line(line)
1675
1958
  }
1676
1959
  | none
1677
1960
 
1678
1961
  literal: numeric
1679
1962
  {
1680
- result = s(:lit, val[0])
1963
+ (lit, line), = val
1964
+ result = s(:lit, lit).line line
1681
1965
  }
1682
1966
  | symbol
1683
- {
1684
- result = s(:lit, val[0])
1685
- }
1686
- | dsym
1687
1967
 
1688
1968
  strings: string
1689
1969
  {
1690
- val[0] = s(:dstr, val[0].value) if val[0].sexp_type == :evstr
1691
- result = val[0]
1970
+ str, = val
1971
+ str = s(:dstr, str.value) if str.sexp_type == :evstr
1972
+ result = str
1692
1973
  }
1693
1974
 
1694
1975
  string: tCHAR
1695
1976
  {
1696
- debug20 23, val, result
1977
+ debug 37
1697
1978
  }
1698
1979
  | string1
1699
1980
  | string string1
@@ -1703,7 +1984,11 @@ opt_block_args_tail: tCOMMA block_args_tail
1703
1984
 
1704
1985
  string1: tSTRING_BEG string_contents tSTRING_END
1705
1986
  {
1706
- result = val[1]
1987
+ (_, line), str, (_, func) = val
1988
+
1989
+ str = dedent str if func =~ RubyLexer::STR_FUNC_DEDENT
1990
+
1991
+ result = str.line line
1707
1992
  }
1708
1993
  | tSTRING
1709
1994
  {
@@ -1712,7 +1997,8 @@ opt_block_args_tail: tCOMMA block_args_tail
1712
1997
 
1713
1998
  xstring: tXSTRING_BEG xstring_contents tSTRING_END
1714
1999
  {
1715
- result = new_xstring val[1]
2000
+ result = new_xstring val
2001
+ # TODO: dedent?!?! SERIOUSLY?!?
1716
2002
  }
1717
2003
 
1718
2004
  regexp: tREGEXP_BEG regexp_contents tREGEXP_END
@@ -1722,11 +2008,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1722
2008
 
1723
2009
  words: tWORDS_BEG tSPACE tSTRING_END
1724
2010
  {
1725
- result = s(:array)
2011
+ (_, line), _, _ = val
2012
+
2013
+ result = s(:array).line line
1726
2014
  }
1727
2015
  | tWORDS_BEG word_list tSTRING_END
1728
2016
  {
1729
- result = val[1]
2017
+ (_, line), list, _ = val
2018
+
2019
+ result = list.line line
1730
2020
  }
1731
2021
 
1732
2022
  word_list: none
@@ -1746,11 +2036,15 @@ opt_block_args_tail: tCOMMA block_args_tail
1746
2036
 
1747
2037
  symbols: tSYMBOLS_BEG tSPACE tSTRING_END
1748
2038
  {
1749
- result = s(:array)
2039
+ (_, line), _, _ = val
2040
+
2041
+ result = s(:array).line line
1750
2042
  }
1751
2043
  | tSYMBOLS_BEG symbol_list tSTRING_END
1752
2044
  {
1753
- result = val[1]
2045
+ (_, line), list, _, = val
2046
+ list.line line
2047
+ result = list
1754
2048
  }
1755
2049
 
1756
2050
  symbol_list: none
@@ -1759,25 +2053,34 @@ opt_block_args_tail: tCOMMA block_args_tail
1759
2053
  }
1760
2054
  | symbol_list word tSPACE
1761
2055
  {
1762
- result = val[0].dup << new_symbol_list_entry(val)
2056
+ list, * = val
2057
+ result = list.dup << new_symbol_list_entry(val)
1763
2058
  }
1764
2059
 
1765
2060
  qwords: tQWORDS_BEG tSPACE tSTRING_END
1766
2061
  {
1767
- result = s(:array)
2062
+ (_, line), _, _ = val
2063
+
2064
+ result = s(:array).line line
1768
2065
  }
1769
2066
  | tQWORDS_BEG qword_list tSTRING_END
1770
2067
  {
1771
- result = val[1]
2068
+ (_, line), list, _ = val
2069
+
2070
+ result = list.line line
1772
2071
  }
1773
2072
 
1774
2073
  qsymbols: tQSYMBOLS_BEG tSPACE tSTRING_END
1775
2074
  {
1776
- result = s(:array)
2075
+ (_, line), _, _ = val
2076
+
2077
+ result = s(:array).line line
1777
2078
  }
1778
2079
  | tQSYMBOLS_BEG qsym_list tSTRING_END
1779
2080
  {
1780
- result = val[1]
2081
+ (_, line), list, _ = val
2082
+
2083
+ result = list.line line
1781
2084
  }
1782
2085
 
1783
2086
  qword_list: none
@@ -1800,11 +2103,13 @@ opt_block_args_tail: tCOMMA block_args_tail
1800
2103
 
1801
2104
  string_contents: none
1802
2105
  {
1803
- result = s(:str, "")
2106
+ line = prev_value_to_lineno _values.last
2107
+ result = s(:str, +"").line line
1804
2108
  }
1805
2109
  | string_contents string_content
1806
2110
  {
1807
- result = literal_concat(val[0], val[1])
2111
+ v1, v2 = val
2112
+ result = literal_concat v1, v2
1808
2113
  }
1809
2114
 
1810
2115
  xstring_contents: none
@@ -1813,7 +2118,8 @@ xstring_contents: none
1813
2118
  }
1814
2119
  | xstring_contents string_content
1815
2120
  {
1816
- result = literal_concat(val[0], val[1])
2121
+ v1, v2 = val
2122
+ result = literal_concat v1, v2
1817
2123
  }
1818
2124
 
1819
2125
  regexp_contents: none
@@ -1822,7 +2128,8 @@ regexp_contents: none
1822
2128
  }
1823
2129
  | regexp_contents string_content
1824
2130
  {
1825
- result = literal_concat(val[0], val[1])
2131
+ v1, v2 = val
2132
+ result = literal_concat v1, v2
1826
2133
  }
1827
2134
 
1828
2135
  string_content: tSTRING_CONTENT
@@ -1834,42 +2141,46 @@ regexp_contents: none
1834
2141
  result = lexer.lex_strterm
1835
2142
 
1836
2143
  lexer.lex_strterm = nil
1837
- lexer.lex_state = :expr_beg # TODO: expr_value ?
2144
+ lexer.lex_state = EXPR_BEG
1838
2145
  }
1839
2146
  string_dvar
1840
2147
  {
1841
- lexer.lex_strterm = val[1]
1842
- result = s(:evstr, val[2])
2148
+ _, strterm, str = val
2149
+ lexer.lex_strterm = strterm
2150
+ result = s(:evstr, str).line str.line
1843
2151
  }
1844
2152
  | tSTRING_DBEG
1845
2153
  {
1846
2154
  result = [lexer.lex_strterm,
1847
2155
  lexer.brace_nest,
1848
2156
  lexer.string_nest, # TODO: remove
1849
- lexer.cond.store,
1850
- lexer.cmdarg.store,
1851
2157
  lexer.lex_state,
2158
+ lexer.lineno,
1852
2159
  ]
1853
2160
 
2161
+ lexer.cmdarg.push false
2162
+ lexer.cond.push false
2163
+
1854
2164
  lexer.lex_strterm = nil
1855
2165
  lexer.brace_nest = 0
1856
2166
  lexer.string_nest = 0
1857
2167
 
1858
- lexer.lex_state = :expr_value
2168
+ lexer.lex_state = EXPR_BEG
1859
2169
  }
1860
- compstmt tRCURLY
2170
+ compstmt
2171
+ tSTRING_DEND
1861
2172
  {
1862
- # TODO: tRCURLY -> tSTRING_END
1863
2173
  _, memo, stmt, _ = val
1864
2174
 
1865
- lex_strterm, brace_nest, string_nest, oldcond, oldcmdarg, oldlex_state = memo
2175
+ lex_strterm, brace_nest, string_nest, oldlex_state, line = memo
2176
+ # TODO: heredoc_indent
1866
2177
 
1867
2178
  lexer.lex_strterm = lex_strterm
1868
2179
  lexer.brace_nest = brace_nest
1869
2180
  lexer.string_nest = string_nest
1870
2181
 
1871
- lexer.cond.restore oldcond
1872
- lexer.cmdarg.restore oldcmdarg
2182
+ lexer.cond.pop
2183
+ lexer.cmdarg.pop
1873
2184
 
1874
2185
  lexer.lex_state = oldlex_state
1875
2186
 
@@ -1879,56 +2190,78 @@ regexp_contents: none
1879
2190
  when :str, :dstr, :evstr then
1880
2191
  result = stmt
1881
2192
  else
1882
- result = s(:evstr, stmt)
2193
+ result = s(:evstr, stmt).line line
1883
2194
  end
1884
2195
  when nil then
1885
- result = s(:evstr)
2196
+ result = s(:evstr).line line
1886
2197
  else
1887
- debug20 25
2198
+ debug 38
1888
2199
  raise "unknown string body: #{stmt.inspect}"
1889
2200
  end
1890
2201
  }
1891
2202
 
1892
- string_dvar: tGVAR { result = s(:gvar, val[0].to_sym) }
1893
- | tIVAR { result = s(:ivar, val[0].to_sym) }
1894
- | tCVAR { result = s(:cvar, val[0].to_sym) }
2203
+ string_dvar: tGVAR
2204
+ {
2205
+ (id, line), = val
2206
+ result = s(:gvar, id.to_sym).line line
2207
+ }
2208
+ | tIVAR
2209
+ {
2210
+ (id, line), = val
2211
+ result = s(:ivar, id.to_sym).line line
2212
+ }
2213
+ | tCVAR
2214
+ {
2215
+ (id, line), = val
2216
+ result = s(:cvar, id.to_sym).line line
2217
+ }
1895
2218
  | backref
1896
2219
 
1897
- symbol: tSYMBEG sym
2220
+ symbol: ssym
2221
+ | dsym
2222
+
2223
+ ssym: tSYMBEG sym
1898
2224
  {
1899
- lexer.lex_state = :expr_end
1900
- result = val[1].to_sym
2225
+ _, (id, line) = val
2226
+
2227
+ lexer.lex_state = EXPR_END
2228
+ result = s(:lit, id.to_sym).line line
1901
2229
  }
1902
2230
  | tSYMBOL
1903
2231
  {
1904
- result = val[0].to_sym
2232
+ (id, line), = val
2233
+
2234
+ lexer.lex_state = EXPR_END
2235
+ result = s(:lit, id.to_sym).line line
1905
2236
  }
1906
2237
 
1907
2238
  sym: fname | tIVAR | tGVAR | tCVAR
1908
2239
 
1909
- dsym: tSYMBEG xstring_contents tSTRING_END
2240
+ dsym: tSYMBEG string_contents tSTRING_END
1910
2241
  {
1911
- lexer.lex_state = :expr_end
1912
- result = val[1]
2242
+ _, result, _ = val
2243
+
2244
+ lexer.lex_state = EXPR_END
1913
2245
 
1914
- result ||= s(:str, "")
2246
+ result ||= s(:str, "").line lexer.lineno
1915
2247
 
1916
2248
  case result.sexp_type
1917
2249
  when :dstr then
1918
2250
  result.sexp_type = :dsym
1919
2251
  when :str then
1920
- result = s(:lit, result.last.to_sym)
2252
+ result = s(:lit, result.last.to_sym).line result.line
1921
2253
  when :evstr then
1922
- result = s(:dsym, "", result)
2254
+ result = s(:dsym, "", result).line result.line
1923
2255
  else
1924
- debug20 26, val, result
2256
+ debug 39
1925
2257
  end
1926
2258
  }
1927
2259
 
1928
2260
  numeric: simple_numeric
1929
- | tUMINUS_NUM simple_numeric
2261
+ | tUMINUS_NUM simple_numeric =tLOWEST
1930
2262
  {
1931
- result = -val[1] # TODO: pt_testcase
2263
+ _, (num, line) = val
2264
+ result = [-num, line]
1932
2265
  }
1933
2266
 
1934
2267
  simple_numeric: tINTEGER
@@ -1942,26 +2275,29 @@ regexp_contents: none
1942
2275
  | tCONSTANT
1943
2276
  | tCVAR
1944
2277
 
1945
- keyword_variable: kNIL { result = s(:nil) }
1946
- | kSELF { result = s(:self) }
1947
- | kTRUE { result = s(:true) }
1948
- | kFALSE { result = s(:false) }
1949
- | k__FILE__ { result = s(:str, self.file) }
1950
- | k__LINE__ { result = s(:lit, lexer.lineno) }
2278
+ keyword_variable: kNIL { result = s(:nil).line lexer.lineno }
2279
+ | kSELF { result = s(:self).line lexer.lineno }
2280
+ | kTRUE { result = s(:true).line lexer.lineno }
2281
+ | kFALSE { result = s(:false).line lexer.lineno }
2282
+ | k__FILE__ { result = s(:str, self.file).line lexer.lineno }
2283
+ | k__LINE__ { result = s(:lit, lexer.lineno).line lexer.lineno }
1951
2284
  | k__ENCODING__
1952
2285
  {
2286
+ l = lexer.lineno
1953
2287
  result =
1954
2288
  if defined? Encoding then
1955
- s(:colon2, s(:const, :Encoding), :UTF_8)
2289
+ s(:colon2, s(:const, :Encoding).line(l), :UTF_8).line l
1956
2290
  else
1957
- s(:str, "Unsupported!")
2291
+ s(:str, "Unsupported!").line l
1958
2292
  end
1959
2293
  }
1960
2294
 
1961
2295
  var_ref: user_variable
1962
2296
  {
1963
- var = val[0]
2297
+ raise "NO: #{val.inspect}" if Sexp === val.first
2298
+ (var, line), = val
1964
2299
  result = Sexp === var ? var : self.gettable(var)
2300
+ result.line line
1965
2301
  }
1966
2302
  | keyword_variable
1967
2303
  {
@@ -1976,46 +2312,46 @@ keyword_variable: kNIL { result = s(:nil) }
1976
2312
  | keyword_variable
1977
2313
  {
1978
2314
  result = self.assignable val[0]
1979
- debug20 29, val, result
2315
+ debug 40
1980
2316
  }
1981
2317
 
1982
- backref: tNTH_REF { result = s(:nth_ref, val[0]) }
1983
- | tBACK_REF { result = s(:back_ref, val[0]) }
1984
-
1985
- superclass: term
2318
+ backref: tNTH_REF
1986
2319
  {
1987
- result = nil
2320
+ (ref, line), = val
2321
+ result = s(:nth_ref, ref).line line
1988
2322
  }
1989
- | tLT
2323
+ | tBACK_REF
2324
+ {
2325
+ (ref, line), = val
2326
+ result = s(:back_ref, ref).line line
2327
+ }
2328
+
2329
+ superclass: tLT
1990
2330
  {
1991
- lexer.lex_state = :expr_beg
2331
+ lexer.lex_state = EXPR_BEG
2332
+ lexer.command_start = true
1992
2333
  }
1993
2334
  expr_value term
1994
2335
  {
1995
2336
  result = val[2]
1996
2337
  }
1997
- | error term
2338
+ | none
1998
2339
  {
1999
- yyerrok
2000
2340
  result = nil
2001
- debug20 30, val, result
2002
2341
  }
2003
2342
 
2004
2343
  f_arglist: tLPAREN2 f_args rparen
2005
2344
  {
2006
- result = val[1]
2007
- self.lexer.lex_state = :expr_beg
2008
- self.lexer.command_start = true
2009
- # TODO:
2010
- # $<num>$ = parser->parser_in_kwarg;
2011
- # parser->parser_in_kwarg = 1;
2345
+ result = end_args val
2346
+ }
2347
+ | {
2348
+ result = self.in_kwarg
2349
+ self.in_kwarg = true
2350
+ self.lexer.lex_state |= EXPR_LABEL
2012
2351
  }
2013
- | f_args term
2352
+ f_args term
2014
2353
  {
2015
- # TODO: parser->parser_in_kwarg = $<num>1;
2016
- result = val[0]
2017
- self.lexer.lex_state = :expr_beg
2018
- self.lexer.command_start = true
2354
+ result = end_args val
2019
2355
  }
2020
2356
 
2021
2357
  args_tail: f_kwarg tCOMMA f_kwrest opt_f_block_arg
@@ -2100,8 +2436,10 @@ keyword_variable: kNIL { result = s(:nil) }
2100
2436
  |
2101
2437
  {
2102
2438
  result = args val
2439
+ # result.line lexer.lineno
2103
2440
  }
2104
2441
 
2442
+
2105
2443
  f_bad_arg: tCONSTANT
2106
2444
  {
2107
2445
  yyerror "formal argument cannot be a constant"
@@ -2122,10 +2460,11 @@ keyword_variable: kNIL { result = s(:nil) }
2122
2460
  f_norm_arg: f_bad_arg
2123
2461
  | tIDENTIFIER
2124
2462
  {
2125
- identifier = val[0].to_sym
2463
+ (id, line), = val
2464
+ identifier = id.to_sym
2126
2465
  self.env[identifier] = :lvar
2127
2466
 
2128
- result = identifier
2467
+ result = [identifier, line]
2129
2468
  }
2130
2469
 
2131
2470
  f_arg_asgn: f_norm_arg
@@ -2133,21 +2472,14 @@ keyword_variable: kNIL { result = s(:nil) }
2133
2472
  f_arg_item: f_arg_asgn
2134
2473
  | tLPAREN f_margs rparen
2135
2474
  {
2136
- result = val[1]
2475
+ _, margs, _ = val
2476
+
2477
+ result = margs
2137
2478
  }
2138
2479
 
2139
2480
  f_arg: f_arg_item
2140
2481
  {
2141
- case val[0]
2142
- when Symbol then
2143
- result = s(:args)
2144
- result << val[0]
2145
- when Sexp then
2146
- result = val[0]
2147
- else
2148
- debug20 32
2149
- raise "Unknown f_arg type: #{val.inspect}"
2150
- end
2482
+ result = new_arg val
2151
2483
  }
2152
2484
  | f_arg tCOMMA f_arg_item
2153
2485
  {
@@ -2156,48 +2488,52 @@ keyword_variable: kNIL { result = s(:nil) }
2156
2488
  if list.sexp_type == :args then
2157
2489
  result = list
2158
2490
  else
2159
- result = s(:args, list)
2491
+ result = s(:args, list).line list.line
2160
2492
  end
2161
2493
 
2162
- result << item
2494
+ result << (Sexp === item ? item : item.first)
2163
2495
  }
2164
2496
 
2165
2497
  f_label: tLABEL
2166
2498
 
2167
2499
  f_kw: f_label arg_value
2168
2500
  {
2169
- # TODO: call_args
2170
- label, _ = val[0] # TODO: fix lineno?
2501
+ # TODO: new_kw_arg
2502
+ (label, line), arg = val
2503
+
2171
2504
  identifier = label.to_sym
2172
2505
  self.env[identifier] = :lvar
2173
2506
 
2174
- result = s(:array, s(:kwarg, identifier, val[1]))
2507
+ kwarg = s(:kwarg, identifier, arg).line line
2508
+ result = s(:array, kwarg).line line
2175
2509
  }
2176
2510
  | f_label
2177
2511
  {
2178
- label, _ = val[0] # TODO: fix lineno?
2179
- identifier = label.to_sym
2180
- self.env[identifier] = :lvar
2512
+ (label, line), = val
2513
+
2514
+ id = label.to_sym
2515
+ self.env[id] = :lvar
2181
2516
 
2182
- result = s(:array, s(:kwarg, identifier))
2517
+ result = s(:array, s(:kwarg, id).line(line)).line line
2183
2518
  }
2184
2519
 
2185
2520
  f_block_kw: f_label primary_value
2186
2521
  {
2187
- # TODO: call_args
2188
- label, _ = val[0] # TODO: fix lineno?
2189
- identifier = label.to_sym
2190
- self.env[identifier] = :lvar
2522
+ # TODO: new_kw_arg
2523
+ (label, line), expr = val
2524
+ id = label.to_sym
2525
+ self.env[id] = :lvar
2191
2526
 
2192
- result = s(:array, s(:kwarg, identifier, val[1]))
2527
+ result = s(:array, s(:kwarg, id, expr).line(line)).line line
2193
2528
  }
2194
2529
  | f_label
2195
2530
  {
2196
- label, _ = val[0] # TODO: fix lineno?
2197
- identifier = label.to_sym
2198
- self.env[identifier] = :lvar
2531
+ # TODO: new_kw_arg
2532
+ (label, line), = val
2533
+ id = label.to_sym
2534
+ self.env[id] = :lvar
2199
2535
 
2200
- result = s(:array, s(:kwarg, identifier))
2536
+ result = s(:array, s(:kwarg, id).line(line)).line line
2201
2537
  }
2202
2538
 
2203
2539
  f_block_kwarg: f_block_kw
@@ -2216,39 +2552,51 @@ keyword_variable: kNIL { result = s(:nil) }
2216
2552
  kwrest_mark: tPOW
2217
2553
  | tDSTAR
2218
2554
 
2555
+
2219
2556
  f_kwrest: kwrest_mark tIDENTIFIER
2220
2557
  {
2221
- result = :"**#{val[1]}"
2558
+ _, (id, line) = val
2559
+
2560
+ name = id.to_sym
2561
+ self.assignable [name, line]
2562
+ result = [:"**#{name}", line]
2222
2563
  }
2223
2564
  | kwrest_mark
2224
2565
  {
2225
- result = :"**"
2566
+ id = :"**"
2567
+ self.env[id] = :lvar # TODO: needed?!?
2568
+ result = [id, lexer.lineno] # TODO: tPOW/tDSTAR include lineno
2226
2569
  }
2227
2570
 
2228
2571
  f_opt: f_arg_asgn tEQL arg_value
2229
2572
  {
2230
- result = self.assignable val[0], val[2]
2573
+ lhs, _, rhs = val
2574
+ result = self.assignable lhs, rhs
2231
2575
  # TODO: detect duplicate names
2232
2576
  }
2233
2577
 
2234
2578
  f_block_opt: f_arg_asgn tEQL primary_value
2235
2579
  {
2236
- result = self.assignable val[0], val[2]
2580
+ lhs, _, rhs = val
2581
+ result = self.assignable lhs, rhs
2237
2582
  }
2238
2583
 
2239
2584
  f_block_optarg: f_block_opt
2240
2585
  {
2241
- result = s(:block, val[0])
2586
+ optblk, = val
2587
+ result = s(:block, optblk).line optblk.line
2242
2588
  }
2243
2589
  | f_block_optarg tCOMMA f_block_opt
2244
2590
  {
2245
- result = val[0]
2246
- result << val[2]
2591
+ optarg, _, optblk = val
2592
+ result = optarg
2593
+ result << optblk
2247
2594
  }
2248
2595
 
2249
2596
  f_optarg: f_opt
2250
2597
  {
2251
- result = s(:block, val[0])
2598
+ opt, = val
2599
+ result = s(:block, opt).line opt.line
2252
2600
  }
2253
2601
  | f_optarg tCOMMA f_opt
2254
2602
  {
@@ -2260,30 +2608,33 @@ keyword_variable: kNIL { result = s(:nil) }
2260
2608
  f_rest_arg: restarg_mark tIDENTIFIER
2261
2609
  {
2262
2610
  # TODO: differs from parse.y - needs tests
2263
- name = val[1].to_sym
2264
- self.assignable name
2265
- result = :"*#{name}"
2611
+ _, (id, line) = val
2612
+ name = id.to_sym
2613
+ self.assignable [name, line]
2614
+ result = [:"*#{name}", line]
2266
2615
  }
2267
2616
  | restarg_mark
2268
2617
  {
2269
2618
  name = :"*"
2270
2619
  self.env[name] = :lvar
2271
- result = name
2620
+ result = [name, lexer.lineno] # FIX: tSTAR to include lineno
2272
2621
  }
2273
2622
 
2274
2623
  blkarg_mark: tAMPER2 | tAMPER
2275
2624
 
2276
2625
  f_block_arg: blkarg_mark tIDENTIFIER
2277
2626
  {
2278
- identifier = val[1].to_sym
2627
+ _, (id, line) = val
2628
+ identifier = id.to_sym
2279
2629
 
2280
2630
  self.env[identifier] = :lvar
2281
- result = "&#{identifier}".to_sym
2631
+ result = ["&#{identifier}".to_sym, line]
2282
2632
  }
2283
2633
 
2284
2634
  opt_f_block_arg: tCOMMA f_block_arg
2285
2635
  {
2286
- result = val[1]
2636
+ _, arg = val
2637
+ result = arg
2287
2638
  }
2288
2639
  |
2289
2640
  {
@@ -2293,7 +2644,7 @@ keyword_variable: kNIL { result = s(:nil) }
2293
2644
  singleton: var_ref
2294
2645
  | tLPAREN2
2295
2646
  {
2296
- lexer.lex_state = :expr_beg
2647
+ lexer.lex_state = EXPR_BEG
2297
2648
  }
2298
2649
  expr rparen
2299
2650
  {
@@ -2302,14 +2653,11 @@ keyword_variable: kNIL { result = s(:nil) }
2302
2653
  result.sexp_type == :lit
2303
2654
  }
2304
2655
 
2305
- assoc_list: none # [!nil]
2306
- {
2307
- result = s(:array)
2308
- }
2309
- | assocs trailer # [!nil]
2656
+ assoc_list: none
2310
2657
  {
2311
- result = val[0]
2658
+ result = s(:array).line lexer.lineno
2312
2659
  }
2660
+ | assocs trailer
2313
2661
 
2314
2662
  assocs: assoc
2315
2663
  | assocs tCOMMA assoc
@@ -2323,26 +2671,29 @@ keyword_variable: kNIL { result = s(:nil) }
2323
2671
 
2324
2672
  assoc: arg_value tASSOC arg_value
2325
2673
  {
2326
- result = s(:array, val[0], val[2])
2674
+ v1, _, v2 = val
2675
+ result = s(:array, v1, v2).line v1.line
2327
2676
  }
2328
- | tLABEL opt_nl arg_value
2677
+ | tLABEL arg_value
2329
2678
  {
2330
- result = s(:array, s(:lit, val[0][0].to_sym), val.last)
2679
+ (label, line), arg = val
2680
+
2681
+ lit = s(:lit, label.to_sym).line line
2682
+ result = s(:array, lit, arg).line line
2331
2683
  }
2332
2684
  | tSTRING_BEG string_contents tLABEL_END arg_value
2333
2685
  {
2334
- _, sym, _, value = val
2686
+ (_, line), sym, _, value = val
2687
+
2335
2688
  sym.sexp_type = :dsym
2336
- result = s(:array, sym, value)
2337
- }
2338
- | tSYMBOL arg_value
2339
- {
2340
- raise "not yet: #{val.inspect}"
2341
- # result = s(:array, s(:lit, val[1].to_sym), val[1])
2689
+
2690
+ result = s(:array, sym, value).line line
2342
2691
  }
2343
2692
  | tDSTAR arg_value
2344
2693
  {
2345
- result = s(:array, s(:kwsplat, val[1]))
2694
+ _, arg = val
2695
+ line = arg.line
2696
+ result = s(:array, s(:kwsplat, arg).line(line)).line line
2346
2697
  }
2347
2698
 
2348
2699
  operation: tIDENTIFIER | tCONSTANT | tFID
@@ -2350,7 +2701,11 @@ keyword_variable: kNIL { result = s(:nil) }
2350
2701
  operation3: tIDENTIFIER | tFID | op
2351
2702
  dot_or_colon: tDOT | tCOLON2
2352
2703
  call_op: tDOT
2353
- | tLONELY
2704
+ | tLONELY # TODO: rename tANDDOT?
2705
+
2706
+ call_op2: call_op
2707
+ | tCOLON2
2708
+
2354
2709
  opt_terms: | terms
2355
2710
  opt_nl: | tNL
2356
2711
  rparen: opt_nl tRPAREN
@@ -2370,6 +2725,7 @@ end
2370
2725
 
2371
2726
  require "ruby_lexer"
2372
2727
  require "ruby_parser_extras"
2728
+ include RubyLexer::State::Values
2373
2729
 
2374
2730
  # :stopdoc:
2375
2731