class Atomy::Code::QuasiQuote::Constructor

Public Class Methods

new(gen, mod) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 15
def initialize(gen, mod)
  @gen = gen
  @module = mod
  @depth = 1
end

Public Instance Methods

construct_many(c) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 69
def construct_many(c)
  size = 0
  splats = 0
  c.each do |e|
    if @depth == 1 && e.is_a?(Atomy::Grammar::AST::Unquote) && \
        e.node.is_a?(Atomy::Grammar::AST::Prefix) && \
        e.node.operator == :*
      splat = true
      @gen.make_array(size)
      @module.compile(@gen, e.node.node)
      @gen.send(:+, 1)

      splats += 1
      size = 0
    else
      size += 1
      go(e)
    end
  end

  @gen.make_array(size)

  splats.times do
    @gen.send(:+, 1)
  end
end
go(x) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 21
def go(x)
  x.accept(self)
end
push_class(cls) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 109
def push_class(cls)
  @gen.push_cpath_top
  cls.name.split("::").each do |n|
    @gen.find_const(n.to_sym)
  end
end
push_literal(x) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 96
def push_literal(x)
  case x
  when Array
    x.each { |v| push_literal(v) }
    @gen.make_array(x.size)
  when String
    @gen.push_literal(x)
    @gen.string_dup
  else
    @gen.push_literal(x)
  end
end
unquote(x) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 25
def unquote(x)
  @module.compile(@gen, x.node)
end
visit(x) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 29
def visit(x)
  push_class(x.class)

  args = 0
  x.each_child do |_, c|
    if c.is_a?(Array)
      construct_many(c)
    else
      go(c)
    end
    args += 1
  end

  x.each_attribute do |_, a|
    push_literal(a)
    args += 1
  end

  @gen.send(:new, args)
end
visit_quasiquote(qq) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 50
def visit_quasiquote(qq)
  @depth += 1
  visit(qq)
ensure
  @depth -= 1
end
visit_unquote(x) click to toggle source
# File lib/atomy/code/quasi_quote.rb, line 57
def visit_unquote(x)
  @depth -= 1

  if @depth == 0
    unquote(x)
  else
    visit(x)
  end
ensure
  @depth += 1
end