Skip to content

Commit 2a5ac56

Browse files
committed
Get test/natalie/assign_test.rb parsing
1 parent 7ddfbc9 commit 2a5ac56

File tree

2 files changed

+136
-31
lines changed

2 files changed

+136
-31
lines changed

lib/natalie/compiler/multiple_assignment.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@ def transform_arg(arg)
4141
when :splat
4242
_, name = arg
4343
transform_splat_arg(name)
44-
when :attrasgn
44+
when :attrasgn, :call
4545
_, receiver, message, *args = arg
4646
transform_attr_assign_arg(receiver, message, args)
4747
else
48-
raise "I don't yet know how to compile #{arg.inspect}"
48+
raise "I don't yet know how to compile #{arg.inspect} #{arg.file}##{arg.line}"
4949
end
5050
else
5151
raise "I don't yet know how to compile #{arg.inspect}"

lib/natalie/parser.rb

Lines changed: 134 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,15 @@ def visit_assoc_splat_node(node)
3333
end
3434

3535
def visit_begin_node(node)
36-
if node.ensure_clause && !node.rescue_clause && !node.else_clause
37-
s(:ensure,
38-
visit(node.statements),
39-
visit(node.ensure_clause.statements),
40-
location: node.location)
36+
if !node.rescue_clause && !node.else_clause
37+
if node.ensure_clause
38+
s(:ensure,
39+
visit(node.statements),
40+
visit(node.ensure_clause.statements),
41+
location: node.location)
42+
else
43+
visit(node.statements)
44+
end
4145
else
4246
ary = s(:array,
4347
*node.rescue_clause.exceptions.map { |n| visit(n) },
@@ -153,10 +157,33 @@ def visit_constant_read_node(node)
153157
s(:const, name, location: node.location)
154158
end
155159

160+
def visit_constant_target_node(node)
161+
s(:cdecl, node.slice.to_sym, location: node.location)
162+
end
163+
156164
def visit_constant_write_node(node)
157165
s(:cdecl, node.name.to_sym, visit(node.value), location: node.location)
158166
end
159167

168+
def visit_call_operator_write_node(node)
169+
if node.target.name.to_sym == :[]=
170+
args = node.target.arguments&.child_nodes || []
171+
s(:op_asgn1,
172+
visit(node.target.receiver),
173+
s(:arglist, *args.map { |n| visit(n) }, location: node.location),
174+
node.operator,
175+
visit(node.value),
176+
location: node.location)
177+
else
178+
s(:op_asgn2,
179+
visit(node.target.receiver),
180+
node.target.name.to_sym,
181+
node.operator,
182+
visit(node.value),
183+
location: node.location)
184+
end
185+
end
186+
160187
def visit_def_node(node)
161188
if node.receiver
162189
receiver = visit(node.receiver)
@@ -191,6 +218,39 @@ def visit_float_node(node)
191218
s(:lit, node.value, location: node.location)
192219
end
193220

221+
def visit_forwarding_arguments_node(node)
222+
s(:forward_args, location: node.location)
223+
end
224+
225+
def visit_forwarding_parameter_node(node)
226+
s(:forward_args, location: node.location)
227+
end
228+
229+
def visit_global_variable_and_write_node(node)
230+
s(:op_asgn_and,
231+
s(:gvar, node.name, location: node.location),
232+
s(:gasgn, node.name, visit(node.value), location: node.location),
233+
location: node.location)
234+
end
235+
236+
def visit_global_variable_operator_write_node(node)
237+
s(:gasgn,
238+
node.name,
239+
s(:call,
240+
s(:gvar, node.name, location: node.location),
241+
node.operator,
242+
visit(node.value),
243+
location: node.location),
244+
location: node.location)
245+
end
246+
247+
def visit_global_variable_or_write_node(node)
248+
s(:op_asgn_or,
249+
s(:gvar, node.name, location: node.location),
250+
s(:gasgn, node.name, visit(node.value), location: node.location),
251+
location: node.location)
252+
end
253+
194254
def visit_global_variable_read_node(node)
195255
s(:gvar, node.name, location: node.location)
196256
end
@@ -218,12 +278,41 @@ def visit_if_node(node)
218278
end
219279

220280
def visit_call_operator_or_write_node(node)
221-
args = node.target.arguments&.child_nodes || []
222-
s(:op_asgn1,
223-
visit(node.target.receiver),
224-
s(:arglist, *args.map { |n| visit(n) }, location: node.location),
225-
node.operator.tr('=', '').to_sym,
226-
visit(node.value),
281+
if node.target.name.to_sym == :[]=
282+
args = node.target.arguments&.child_nodes || []
283+
s(:op_asgn1,
284+
visit(node.target.receiver),
285+
s(:arglist, *args.map { |n| visit(n) }, location: node.location),
286+
node.operator.tr('=', '').to_sym,
287+
visit(node.value),
288+
location: node.location)
289+
elsif node.operator.to_sym == :'||='
290+
receiver = visit(node.target.receiver)
291+
s(:op_asgn_or,
292+
s(:call,
293+
receiver,
294+
node.target.name.tr('=', '').to_sym,
295+
location: node.target.location),
296+
s(:attrasgn,
297+
receiver,
298+
node.target.name.to_sym,
299+
visit(node.value),
300+
location: node.value.location),
301+
location: node.location)
302+
else
303+
s(:op_asgn2,
304+
visit(node.target.receiver),
305+
node.target.name.to_sym,
306+
node.operator.tr('=', '').to_sym,
307+
visit(node.value),
308+
location: node.location)
309+
end
310+
end
311+
312+
def visit_instance_variable_and_write_node(node)
313+
s(:op_asgn_and,
314+
s(:ivar, node.name, location: node.location),
315+
s(:iasgn, node.name, visit(node.value), location: node.location),
227316
location: node.location)
228317
end
229318

@@ -269,7 +358,7 @@ def visit_interpolated_stringish_node(node, sexp_type:)
269358
segments = node.child_nodes.map do |n|
270359
case n
271360
when YARP::StringNode
272-
s(:str, n.content, location: n.location)
361+
s(:str, n.unescaped, location: n.location)
273362
when YARP::EmbeddedStatementsNode
274363
s(:evstr, visit(n.statements), location: n.location)
275364
else
@@ -311,18 +400,19 @@ def visit_lambda_node(node)
311400
location: node.location)
312401
end
313402

314-
def visit_local_variable_operator_write_node(node)
315-
s(:lasgn,
316-
node.name,
317-
s(:call,
318-
s(:lvar, node.name, location: node.location),
319-
node.operator,
403+
def visit_local_variable_and_write_node(node)
404+
s(:op_asgn_and,
405+
s(:lvar,
406+
node.name,
407+
location: node.location),
408+
s(:lasgn,
409+
node.name,
320410
visit(node.value),
321411
location: node.location),
322412
location: node.location)
323413
end
324414

325-
def visit_local_variable_or_write_node(node)
415+
def visit_local_variable_operator_write_node(node)
326416
s(:lasgn,
327417
node.name,
328418
s(:call,
@@ -333,6 +423,13 @@ def visit_local_variable_or_write_node(node)
333423
location: node.location)
334424
end
335425

426+
def visit_local_variable_or_write_node(node)
427+
s(:op_asgn_or,
428+
s(:lvar, node.name, location: node.location),
429+
s(:lasgn, node.name, visit(node.value), location: node.location),
430+
location: node.location)
431+
end
432+
336433
def visit_local_variable_read_node(node)
337434
s(:lvar, node.name, location: node.location)
338435
end
@@ -353,14 +450,19 @@ def visit_module_node(node)
353450
end
354451

355452
def visit_multi_write_node(node)
356-
value = visit(node.value)
357-
unless value.sexp_type == :array
358-
value = s(:to_ary, value, location: node.location)
453+
return visit(node.targets.first) if node.targets.size == 1 && !node.value
454+
455+
masgn = s(:masgn,
456+
s(:array, *node.targets.map { |n| visit(n) }, location: node.location),
457+
location: node.location)
458+
if node.value
459+
value = visit(node.value)
460+
unless value.sexp_type == :array
461+
value = s(:to_ary, value, location: node.location)
462+
end
463+
masgn << value
359464
end
360-
s(:masgn,
361-
s(:array, *node.targets.map { |n| visit(n) }, location: node.location),
362-
value,
363-
location: node.location)
465+
masgn
364466
end
365467

366468
def visit_next_node(node)
@@ -394,6 +496,10 @@ def visit_parentheses_node(node)
394496
visit(node.body)
395497
end
396498

499+
def visit_program_node(node)
500+
visit(node.child_nodes.first)
501+
end
502+
397503
def visit_range_node(node)
398504
if node.left.is_a?(YARP::IntegerNode) && node.right.is_a?(YARP::IntegerNode)
399505
left = node.left.value
@@ -464,7 +570,6 @@ def visit_source_file_node(node)
464570
def visit_statements_node(node)
465571
s(:block, *node.child_nodes.map { |n| visit(n) }, location: node.location)
466572
end
467-
alias visit_program_node visit_statements_node
468573

469574
def visit_string_concat_node(node)
470575
left = visit(node.left)
@@ -488,7 +593,7 @@ def visit_string_concat_node(node)
488593
end
489594

490595
def visit_string_node(node)
491-
s(:str, node.content, location: node.location)
596+
s(:str, node.unescaped, location: node.location)
492597
end
493598

494599
def visit_super_node(node)
@@ -541,7 +646,7 @@ def visit_yield_node(node)
541646
end
542647

543648
def visit_x_string_node(node)
544-
s(:xstr, node.content, location: node.location)
649+
s(:xstr, node.unescaped, location: node.location)
545650
end
546651

547652
def method_missing(meth, *args)

0 commit comments

Comments
 (0)