Skip to content

Commit

Permalink
masgn compiler node
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Oct 22, 2013
1 parent c398329 commit 137d6e2
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 52 deletions.
55 changes: 55 additions & 0 deletions lib/opal/nodes/variables.rb
Expand Up @@ -131,5 +131,60 @@ def compile
push ")"
end
end

class MassAssignNode < Node
children :lhs, :rhs

def compile
tmp = scope.new_temp
len = 0 # how many rhs items are we sure we have

if rhs.type == :array
len = rhs.size - 1
push "#{tmp} = ", expr(rhs)
elsif rhs.type == :to_ary
push "#{tmp} = $opal.to_ary(", expr(rhs[1]), ")"
elsif rhs.type == :splat
push "(#{tmp} = ", expr(rhs[1]), ")['$to_a'] ? (#{tmp} = #{tmp}['$to_a']())"
push " : (#{tmp})._isArray ? #{tmp} : (#{tmp} = [#{tmp}])"
else
raise "unsupported mlhs type"
end

lhs.children.each_with_index do |child, idx|
push ', '

if child.type == :splat
if part = child[1]
part = part.dup
part << s(:js_tmp, "$slice.call(#{tmp}, #{idx})")
push expr(part)
end
else
if idx >= len
assign = s(:js_tmp, "(#{tmp}[#{idx}] == null ? nil : #{tmp}[#{idx}])")
else
assign = s(:js_tmp, "#{tmp}[#{idx}]")
end

part = child.dup
if child.type == :lasgn or child.type == :iasgn or child.type == :lvar
part << assign
elsif child.type == :call
part[2] = "#{part[2]}=".to_sym
part.last << assign
elsif child.type == :attrasgn
part.last << assign
else
raise "Bad lhs for masgn"
end

push expr(part)
end
end

scope.queue_temp tmp
end
end
end
end
53 changes: 1 addition & 52 deletions lib/opal/parser.rb
Expand Up @@ -62,6 +62,7 @@ def add_handler(klass, *types)
add_handler ClassVariableNode, :cvar
add_handler ClassVarAssignNode, :cvasgn
add_handler ClassVarDeclNode, :cvdecl
add_handler MassAssignNode, :masgn

# constants
add_handler ConstDeclarationNode, :cdecl
Expand Down Expand Up @@ -986,58 +987,6 @@ def process_array(sexp, level)
code
end

def process_masgn(sexp, level)
lhs, rhs = sexp
tmp = @scope.new_temp
len = 0
code = []

if rhs[0] == :array
len = rhs.length - 1 # we are guaranteed an array of this length
code << f("#{tmp} = ", sexp) << process(rhs)
elsif rhs[0] == :to_ary
code << [f("#{tmp} = $opal.to_ary("), process(rhs[1]), f(")")]
elsif rhs[0] == :splat
code << f("(#{tmp} = ", sexp) << process(rhs[1])
code << f(")['$to_a'] ? (#{tmp} = #{tmp}['$to_a']()) : (#{tmp})._isArray ? #{tmp} : (#{tmp} = [#{tmp}])", sexp)
else
raise "Unsupported mlhs type"
end

lhs[1..-1].each_with_index do |l, idx|
code << f(", ", sexp) unless code.empty?

if l.first == :splat
if s = l[1]
s << s(:js_tmp, "$slice.call(#{tmp}, #{idx})")
code << process(s)
end
else
if idx >= len
assign = s(:js_tmp, "(#{tmp}[#{idx}] == null ? nil : #{tmp}[#{idx}])")
else
assign = s(:js_tmp, "#{tmp}[#{idx}]")
end

if l[0] == :lasgn or l[0] == :iasgn or l[0] == :lvar
l << assign
elsif l[0] == :call
l[2] = "#{l[2]}=".to_sym
l.last << assign
elsif l[0] == :attrasgn
l.last << assign
else
raise "bad lhs for masgn: #{l.inspect}"
end

code << process(l)
end
end

@scope.queue_temp tmp
code
end

def js_truthy_optimize(sexp)
if sexp.first == :call
mid = sexp[2]
Expand Down

0 comments on commit 137d6e2

Please sign in to comment.