Skip to content

Commit

Permalink
Implement ForNode
Browse files Browse the repository at this point in the history
  • Loading branch information
yui-knk committed Jul 8, 2024
1 parent 8b1bc39 commit 4d4af77
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 1 deletion.
75 changes: 74 additions & 1 deletion lib/ast_to_prism/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,63 @@ def convert_errinfo_assignment(node)
end
end

def convert_for_args(node)
check_node_type(node, :ARGS)

pre_num, pre_init, opt, first_post, post_num, post_init, rest, kw, kwrest, block = node.children

case [pre_num, opt, first_post, post_num, post_init, rest, kw, kwrest, block]
when [1, nil, nil, 0, nil, nil, nil, nil, nil]
check_node_type(pre_init, :LASGN)

vid, value = pre_init.children

Prism::LocalVariableTargetNode.new(
source, # source
vid, # name
0, # depth
location(pre_init) # location
)
when [0, nil, nil, 0, nil, nil, nil, nil, nil]
check_node_type(pre_init, :MASGN)

nd_value, nd_head, nd_args = pre_init.children
lefts = []
rest = nil
rights = []

if nd_head
check_node_type(nd_head, :LIST)

# TODO: node.children should not include last nil
lefts = nd_head.children[0...-1].map do |node|
check_node_type(node, :LASGN)

nd_vid, nd_value = node.children

Prism::LocalVariableTargetNode.new(
source, # source
nd_vid, # name
0, # depth
location(node) # location
)
end
end

Prism::MultiTargetNode.new(
source, # source
lefts, # lefts
rest, # rest
rights, # rights
null_location, # lparen_loc
null_location, # rparen_loc
location(node) # location
)
else
raise "#{nd_args} has not expected format."
end
end

def convert_node(node, block: nil)
return nil if node.nil?

Expand Down Expand Up @@ -825,7 +882,23 @@ def convert_node(node, block: nil)
block = convert_block(nd_body)
iter = convert_node(nd_iter, block: block)
when :FOR
not_supported(node)
nd_iter, nd_body = node.children

check_node_type(nd_body, :SCOPE)
nd_tbl, nd_args, nd_body2 = nd_body.children
index = convert_for_args(nd_args)

Prism::ForNode.new(
source, # source
index, # index
convert_node(nd_iter), # collection
convert_stmts(nd_body2), # statements
null_location, # for_keyword_loc
null_location, # in_keyword_loc
null_location, # do_keyword_loc
null_location, # end_keyword_loc
location(node) # location
)
when :FOR_MASGN
not_supported(node)
when :BREAK
Expand Down
34 changes: 34 additions & 0 deletions spec/basic_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1444,6 +1444,40 @@ def foo(a, b, opt1=1, opt2=2, *rest, y, z, kw: 1, **kwrest, &blk)
end
end

describe "for" do
it "tests" do
pending "ForNode locations are not supported"

test_code(<<~CODE)
for i in 1..3 do
foo
end
CODE
end

it "tests" do
pending "ForNode locations are not supported"

test_code(<<~CODE)
for x, y in 1..3 do
foo
end
CODE
end

it "tests" do
pending "ForNode locations are not supported"

test_code(<<~CODE)
for (x, y) in 1..3 do
foo
end
CODE
end

# TODO: Need more test cases for mlhs
end

describe "flip-flap" do
it "tests" do
pending "IfNode and StringNode need to support locations"
Expand Down
13 changes: 13 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,19 @@ def ===(other)
end
}
end

class ForNode
prepend Module.new {
def ===(other)
super(other) &&
self.location == other.location &&
self.for_keyword_loc == other.for_keyword_loc &&
self.in_keyword_loc == other.in_keyword_loc &&
self.do_keyword_loc == other.do_keyword_loc &&
self.end_keyword_loc == other.end_keyword_loc
end
}
end
end

require "simplecov"
Expand Down

0 comments on commit 4d4af77

Please sign in to comment.