cleanups getting underscore to compile

This commit is contained in:
Jeremy Ashkenas
2009-12-17 10:33:57 -05:00
parent 1eec05d23a
commit 9249ceaef5
3 changed files with 663 additions and 663 deletions

View File

@@ -245,8 +245,10 @@ class CodeNode < Node
end
def compile(indent, scope, opts={})
opts = opts.merge(:return => true)
code = @body.compile(indent + TAB, Scope.new(scope), opts)
scope = Scope.new(scope)
@params.each {|id| scope.find(id) }
opts = opts.merge(:return => true)
code = @body.compile(indent + TAB, scope, opts)
"function(#{@params.join(', ')}) {\n#{code}\n#{indent}}"
end
end
@@ -273,66 +275,6 @@ class ArrayNode < Node
end
end
# "if-else" control structure. Look at this node if you want to implement other control
# structures like while, for, loop, etc.
class IfNode < Node
FORCE_STATEMENT = [Nodes, ReturnNode, AssignNode, IfNode]
def initialize(condition, body, else_body=nil, tag=nil)
@condition = condition
@body = body && body.flatten
@else_body = else_body && else_body.flatten
@condition = OpNode.new("!", @condition) if tag == :invert
end
def <<(else_body)
eb = else_body.flatten
@else_body ? @else_body << eb : @else_body = eb
self
end
# Rewrite a chain of IfNodes with their switch condition for equality.
def rewrite_condition(expression)
@condition = OpNode.new("is", expression, @condition)
@else_body.rewrite_condition(expression) if chain?
self
end
# Rewrite a chain of IfNodes to add a default case as the final else.
def add_default(expressions)
chain? ? @else_body.add_default(expressions) : @else_body = expressions
self
end
def chain?
@chain ||= @else_body && @else_body.is_a?(IfNode)
end
def statement?
@is_statement ||= (FORCE_STATEMENT.include?(@body.class) || FORCE_STATEMENT.include?(@else_body.class))
end
def line_ending
statement? ? '' : ';'
end
def compile(indent, scope, opts={})
statement? ? compile_statement(indent, scope, opts) : compile_ternary(indent, scope)
end
def compile_statement(indent, scope, opts)
if_part = "if (#{@condition.compile(indent, scope, :no_paren => true)}) {\n#{Nodes.wrap(@body).compile(indent + TAB, scope, opts)}\n#{indent}}"
else_part = @else_body ? " else {\n#{Nodes.wrap(@else_body).compile(indent + TAB, scope, opts)}\n#{indent}}" : ''
if_part + else_part
end
def compile_ternary(indent, scope)
if_part = "#{@condition.compile(indent, scope)} ? #{@body.compile(indent, scope)}"
else_part = @else_body ? "#{@else_body.compile(indent, scope)}" : 'null'
"#{if_part} : #{else_part}"
end
end
class WhileNode < Node
def initialize(condition, body)
@condition, @body = condition, body
@@ -369,6 +311,10 @@ class ForNode < Node
true
end
def statement?
true
end
def compile(indent, scope, opts={})
svar = scope.free_variable
ivar = scope.free_variable
@@ -439,3 +385,63 @@ class ParentheticalNode < Node
opts[:no_paren] ? compiled : "(#{compiled})"
end
end
# "if-else" control structure. Look at this node if you want to implement other control
# structures like while, for, loop, etc.
class IfNode < Node
FORCE_STATEMENT = [Nodes, ReturnNode, AssignNode, IfNode, ForNode, ThrowNode, WhileNode]
def initialize(condition, body, else_body=nil, tag=nil)
@condition = condition
@body = body && body.flatten
@else_body = else_body && else_body.flatten
@condition = OpNode.new("!", @condition) if tag == :invert
end
def <<(else_body)
eb = else_body.flatten
@else_body ? @else_body << eb : @else_body = eb
self
end
# Rewrite a chain of IfNodes with their switch condition for equality.
def rewrite_condition(expression)
@condition = OpNode.new("is", expression, @condition)
@else_body.rewrite_condition(expression) if chain?
self
end
# Rewrite a chain of IfNodes to add a default case as the final else.
def add_default(expressions)
chain? ? @else_body.add_default(expressions) : @else_body = expressions
self
end
def chain?
@chain ||= @else_body && @else_body.is_a?(IfNode)
end
def statement?
@is_statement ||= (FORCE_STATEMENT.include?(@body.class) || FORCE_STATEMENT.include?(@else_body.class))
end
def line_ending
statement? ? '' : ';'
end
def compile(indent, scope, opts={})
statement? ? compile_statement(indent, scope, opts) : compile_ternary(indent, scope)
end
def compile_statement(indent, scope, opts)
if_part = "if (#{@condition.compile(indent, scope, :no_paren => true)}) {\n#{Nodes.wrap(@body).compile(indent + TAB, scope, opts)}\n#{indent}}"
else_part = @else_body ? " else {\n#{Nodes.wrap(@else_body).compile(indent + TAB, scope, opts)}\n#{indent}}" : ''
if_part + else_part
end
def compile_ternary(indent, scope)
if_part = "#{@condition.compile(indent, scope)} ? #{@body.compile(indent, scope)}"
else_part = @else_body ? "#{@else_body.compile(indent, scope)}" : 'null'
"#{if_part} : #{else_part}"
end
end