Skip to content

Commit

Permalink
Cleanup node hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Oct 23, 2013
1 parent 9e04360 commit 05ed472
Show file tree
Hide file tree
Showing 20 changed files with 535 additions and 488 deletions.
7 changes: 7 additions & 0 deletions lib/opal/nodes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
require 'opal/nodes/constants'
require 'opal/nodes/call'
require 'opal/nodes/call_special'
require 'opal/nodes/module'
require 'opal/nodes/class'
require 'opal/nodes/singleton_class'
require 'opal/nodes/iter'
require 'opal/nodes/def'
require 'opal/nodes/if'
Expand All @@ -15,3 +17,8 @@
require 'opal/nodes/case'
require 'opal/nodes/super'
require 'opal/nodes/top'
require 'opal/nodes/while'
require 'opal/nodes/hash'
require 'opal/nodes/array'
require 'opal/nodes/defined'
require 'opal/nodes/masgn'
54 changes: 54 additions & 0 deletions lib/opal/nodes/array.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
require 'opal/nodes/array'

module Opal
module Nodes
class ArrayNode < Base
handle :array

def compile
return push('[]') if children.empty?

code, work = [], []

children.each do |child|
splat = child.type == :splat
part = expr(child)

if splat
if work.empty?
if code.empty?
code << fragment("[].concat(") << part << fragment(")")
else
code << fragment(".concat(") << part << fragment(")")
end
else
if code.empty?
code << fragment("[") << work << fragment("]")
else
code << fragment(".concat([") << work << fragment("])")
end

code << fragment(".concat(") << part << fragment(")")
end
work = []
else
work << fragment(", ") unless work.empty?
work << part
end
end

unless work.empty?
join = [fragment("["), work, fragment("]")]

if code.empty?
code = join
else
code.push([fragment(".concat("), join, fragment(")")])
end
end

push code
end
end
end
end
11 changes: 11 additions & 0 deletions lib/opal/nodes/base_scope.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'opal/nodes/base'

module Opal
module Nodes
class BaseScopeNode < Base
def in_scope(type, &block)
indent { compiler.in_scope(type, &block) }
end
end
end
end
51 changes: 51 additions & 0 deletions lib/opal/nodes/call.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,56 @@ def using_irb?
@compiler.irb_vars? and scope.top? and arglist == s(:arglist) and recvr.nil? and iter.nil?
end
end

# FIXME: needs rewrite
class ArglistNode < Base
handle :arglist

def compile
code, work = [], []

children.each do |current|
splat = current.first == :splat
arg = expr(current)

if splat
if work.empty?
if code.empty?
code << fragment("[].concat(")
code << arg
code << fragment(")")
else
code += ".concat(#{arg})"
end
else
if code.empty?
code << [fragment("["), work, fragment("]")]
else
code << [fragment(".concat(["), work, fragment("])")]
end

code << [fragment(".concat("), arg, fragment(")")]
end

work = []
else
work << fragment(", ") unless work.empty?
work << arg
end
end

unless work.empty?
join = work

if code.empty?
code = join
else
code << fragment(".concat(") << join << fragment(")")
end
end

push(*code)
end
end
end
end
69 changes: 1 addition & 68 deletions lib/opal/nodes/class.rb
Original file line number Diff line number Diff line change
@@ -1,74 +1,7 @@
require 'opal/nodes/base'
require 'opal/nodes/module'

module Opal
module Nodes
class BaseScopeNode < Base
def in_scope(type, &block)
indent { compiler.in_scope(type, &block) }
end
end

class SingletonClassNode < BaseScopeNode
handle :sclass

children :object, :body

def compile
push "(function(self) {"

in_scope(:sclass) do
add_temp '$scope = self._scope'
add_temp 'def = self._proto'

line scope.to_vars
line stmt(body)
end

line "})(", recv(object), ".$singleton_class())"
end
end

class ModuleNode < BaseScopeNode
handle :module

children :cid, :body

def compile
name, base = name_and_base
helper :module

push "(function($base) {"
line " var self = $module($base, '#{name}');"

in_scope(:module) do
scope.name = name
add_temp "#{scope.proto} = self._proto"
add_temp '$scope = self._scope'

body_code = stmt(body)
empty_line

line scope.to_vars
line body_code
line scope.to_donate_methods
end

line "})(", base, ")"
end

def name_and_base
if Symbol === cid or String === cid
[cid.to_s, 'self']
elsif cid.type == :colon2
[cid[2].to_s, expr(cid[1])]
elsif cid.type == :colon3
[cid[1].to_s, '$opal.Object']
else
raise "Bad receiver in module"
end
end
end

class ClassNode < ModuleNode
handle :class

Expand Down
58 changes: 12 additions & 46 deletions lib/opal/nodes/def.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
require 'opal/nodes/class'
require 'opal/nodes/base_scope'

module Opal
module Nodes
Expand Down Expand Up @@ -138,54 +138,20 @@ def arity_check(args, opt, splat, block_name, mid)
end
end

# FIXME: needs rewrite
class ArglistNode < Base
handle :arglist
# def args list
class ArgsNode < Base
handle :args

def compile
code, work = [], []

children.each do |current|
splat = current.first == :splat
arg = expr(current)

if splat
if work.empty?
if code.empty?
code << fragment("[].concat(")
code << arg
code << fragment(")")
else
code += ".concat(#{arg})"
end
else
if code.empty?
code << [fragment("["), work, fragment("]")]
else
code << [fragment(".concat(["), work, fragment("])")]
end

code << [fragment(".concat("), arg, fragment(")")]
end

work = []
else
work << fragment(", ") unless work.empty?
work << arg
end
children.each_with_index do |child, idx|
next if child.to_s == '*'

child = child.to_sym
push ', ' unless idx == 0
child = variable(child)
scope.add_arg child.to_sym
push child.to_s
end

unless work.empty?
join = work

if code.empty?
code = join
else
code << fragment(".concat(") << join << fragment(")")
end
end

push(*code)
end
end
end
Expand Down
Loading

0 comments on commit 05ed472

Please sign in to comment.