class Haml::Compiler

def call(ast)

def call(ast)
  return runtime_error(ast) if ast.is_a?(Error)
  compile(ast)
rescue Error => e
  runtime_error(e)
end

def compile(node)

def compile(node)
  case node.type
  when :root
    compile_children(node)
  when :comment
    compile_comment(node)
  when :doctype
    compile_doctype(node)
  when :filter
    compile_filter(node)
  when :plain
    compile_plain(node)
  when :script
    compile_script(node)
  when :silent_script
    compile_silent_script(node)
  when :tag
    compile_tag(node)
  when :haml_comment
    [:multi]
  else
    raise InternalError.new("Unexpected node type: #{node.type}")
  end
end

def compile_children(node)

def compile_children(node)
  @children_compiler.compile(node) { |n| compile(n) }
end

def compile_comment(node)

def compile_comment(node)
  @comment_compiler.compile(node) { |n| compile_children(n) }
end

def compile_doctype(node)

def compile_doctype(node)
  @doctype_compiler.compile(node)
end

def compile_filter(node)

def compile_filter(node)
  @filter_compiler.compile(node)
end

def compile_plain(node)

def compile_plain(node)
  [:static, node.value[:text]]
end

def compile_script(node)

def compile_script(node)
  @script_compiler.compile(node) { |n| compile_children(n) }
end

def compile_silent_script(node)

def compile_silent_script(node)
  @silent_script_compiler.compile(node) { |n| compile_children(n) }
end

def compile_tag(node)

def compile_tag(node)
  @tag_compiler.compile(node) { |n| compile_children(n) }
end

def initialize(options = {})

def initialize(options = {})
  identity                = Identity.new
  @children_compiler      = ChildrenCompiler.new
  @comment_compiler       = CommentCompiler.new
  @doctype_compiler       = DoctypeCompiler.new(options)
  @filter_compiler        = Filters.new(options)
  @script_compiler        = ScriptCompiler.new(identity, options)
  @silent_script_compiler = SilentScriptCompiler.new
  @tag_compiler           = TagCompiler.new(identity, options)
end

def runtime_error(error)

def runtime_error(error)
  [:multi].tap do |temple|
    error.line.times { temple << [:newline] } if error.line
    temple << [:code, %Q[raise #{error.class}.new(%q[#{error.message}], #{error.line.inspect})]]
  end
end