Skip to content

Commit

Permalink
Clean up some new compiler nodes
Browse files Browse the repository at this point in the history
  • Loading branch information
adambeynon committed Oct 21, 2013
1 parent e439800 commit 000d364
Show file tree
Hide file tree
Showing 7 changed files with 154 additions and 111 deletions.
21 changes: 21 additions & 0 deletions lib/opal/nodes/base.rb
@@ -1,6 +1,15 @@
module Opal
class Parser
class Node

def self.children(*names)
names.each_with_index do |name, idx|
define_method(name) do
@sexp[idx + 1]
end
end
end

def initialize(sexp, level, parser)
@sexp = sexp
@level = level
Expand Down Expand Up @@ -54,6 +63,18 @@ def s(*args)
@parser.s(*args)
end

def expr?
@level == :expr
end

def recv?
@level == :recv
end

def stmt?
@level == :stmt
end

def expr(sexp)
@parser.process sexp, :expr
end
Expand Down
56 changes: 31 additions & 25 deletions lib/opal/nodes/constants.rb
Expand Up @@ -3,14 +3,14 @@
module Opal
class Parser
class ConstNode < Node
children :name

def initialize(*)
super
@const_missing = true
end

def compile
name = @sexp[1]

if @const_missing
with_temp do |tmp|
push "((#{tmp} = $scope.#{name}) == null ? $opal.cm('#{name}') : #{tmp})"
Expand All @@ -21,61 +21,67 @@ def compile
end
end

class CdeclNode < Node
class ConstDeclarationNode < Node
children :name, :base

def compile
push expr(@sexp[2])
wrap "$opal.cdecl($scope, '#{@sexp[1]}', ", ")"
push expr(base)
wrap "$opal.cdecl($scope, '#{name}', ", ")"
end
end

class CasgnNode < Node
class ConstAssignNode < Node
children :base, :name, :value

def compile
push "$opal.casgn("
push expr(@sexp[1])
push ", '#{@sexp[2]}', "
push expr(@sexp[3])
push expr(base)
push ", '#{name}', "
push expr(value)
push ")"
end
end

class Colon2Node < Node
class ConstGetNode < Node
children :base, :name

def initialize(*)
super
@const_missing = true
end

def lhs
expr @sexp[1]
end

def compile
if @const_missing
with_temp do |tmp|
push "((#{tmp} = ("
push lhs
push ")._scope).#{@sexp[2]} == null ? #{tmp}.cm('#{@sexp[2]}') : "
push "#{tmp}.#{@sexp[2]})"
push expr(base)
push ")._scope).#{name} == null ? #{tmp}.cm('#{name}') : "
push "#{tmp}.#{name})"
end
else
push lhs
wrap '(', ")._scope.#{@sexp[1]}"
push expr(base)
wrap '(', ")._scope.#{name}"
end
end
end

class Colon3Node < Node
class TopConstNode < Node
children :name

def compile
with_temp do |tmp|
push "((#{tmp} = $opal.Object._scope.#{@sexp[1]}) == null ? "
push "$opal.cm('#{@sexp[1]}') : #{tmp})"
push "((#{tmp} = $opal.Object._scope.#{name}) == null ? "
push "$opal.cm('#{name}') : #{tmp})"
end
end
end

class Casgn3Node < Node
class TopConstAssignNode < Node
children :name, :value

def compile
push "$opal.casgn($opal.Object, '#{@sexp[1]}', "
push expr(@sexp[2])
push "$opal.casgn($opal.Object, '#{name}', "
push expr(value)
push ")"
end
end
Expand Down
12 changes: 8 additions & 4 deletions lib/opal/nodes/definitions.rb
Expand Up @@ -9,26 +9,30 @@ def in_scope(type, &block)
end
end

class SClassNode < BaseScopeNode
class SingletonClassNode < BaseScopeNode
children :object, :body

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

push scope.to_vars
push stmt(@sexp[2])
push stmt(body)
end

push "})("
push recv(@sexp[1])
push recv(object)
wrap "(function(self) {", ".$singleton_class())"
end
end

class UndefNode < Node
children :mid

# FIXME: we should be setting method to a stub method here
def compile
push "delete #{scope.proto}#{@parser.mid_to_jsid @sexp[1][1].to_s}"
push "delete #{scope.proto}#{@parser.mid_to_jsid mid[1].to_s}"
end
end
end
Expand Down
30 changes: 16 additions & 14 deletions lib/opal/nodes/literal.rb
Expand Up @@ -4,38 +4,37 @@ module Opal
class Parser
class ValueNode < Node
def compile
# :self, :true, :false, :nil
push type.to_s
end
end

class LiteralNode < Node
def literal
@sexp[1]
end
children :value
end

class NumericNode < LiteralNode
def compile
push literal.to_s
wrap '(', ')' if @level == :recv
push value.to_s
wrap '(', ')' if recv?
end
end

class StringNode < LiteralNode
def compile
push literal.inspect
push value.inspect
end
end

class SymbolNode < LiteralNode
def compile
push literal.to_s.inspect
push value.to_s.inspect
end
end

class RegexpNode < LiteralNode
def compile
push((literal == // ? /^/ : literal).inspect)
push((value == // ? /^/ : value).inspect)
end
end

Expand All @@ -56,7 +55,7 @@ def compile
raise "Bad dstr part"
end

wrap '(', ')' if @level == :recv
wrap '(', ')' if recv?
end
end
end
Expand Down Expand Up @@ -100,28 +99,31 @@ def compile
end

class ExclusiveRangeNode < Node
children :start, :finish

def compile
helper :range

push "$range("
push expr(@sexp[1])
push expr(start)
push ", "
push expr(@sexp[2])
push expr(finish)
push ", false)"
end
end

class InclusiveRangeNode < Node
children :start, :finish

def compile
helper :range

push "$range("
push expr(@sexp[1])
push expr(start)
push ", "
push expr(@sexp[2])
push expr(finish)
push ", true)"
end
end

end
end
30 changes: 15 additions & 15 deletions lib/opal/nodes/logic.rb
Expand Up @@ -3,55 +3,55 @@
module Opal
class Parser
class NextNode < Node
children :value

def compile
return push "continue;" if in_while?

push expr_or_nil(@sexp[1])
push expr_or_nil(value)
wrap "return ", ";"
end
end

class NotNode < Node
children :value

def compile
with_temp do |tmp|
push expr(@sexp[1])
push expr(value)
wrap "(#{tmp} = ", ", (#{tmp} === nil || #{tmp} === false))"
end
end
end

class SplatNode < Node
children :value

def empty_splat?
@sexp[1] == [:nil] or @sexp[1] == [:paren, [:nil]]
value == [:nil] or value == [:paren, [:nil]]
end

def compile
if empty_splat?
push '[]'
elsif @sexp[1].type == :sym
push expr(@sexp[1])
elsif value.type == :sym
push expr(value)
wrap '[', ']'
else
push recv(@sexp[1])
push recv(value)
end
end
end

class OrNode < Node
def lhs
expr @sexp[1]
end

def rhs
expr @sexp[2]
end
children :lhs, :rhs

def compile
with_temp do |tmp|
push "(((#{tmp} = "
push lhs
push expr(lhs)
push ") !== false && #{tmp} !== nil) ? #{tmp} : "
push rhs
push expr(rhs)
push ")"
end
end
Expand Down

0 comments on commit 000d364

Please sign in to comment.