class Atomy::Code::Pattern::QuasiQuote::AssignWalker

Public Class Methods

new(gen) click to toggle source
# File lib/atomy/code/pattern/quasi_quote.rb, line 88
def initialize(gen)
  @gen = gen

  # [[msg, [args...]]]
  @path = []
end

Public Instance Methods

assign_using_path(pattern, splat_index = nil) click to toggle source
# File lib/atomy/code/pattern/quasi_quote.rb, line 140
def assign_using_path(pattern, splat_index = nil)
  @gen.dup_many(2)

  # get path from value
  push_path

  if splat_index
    @gen.push_int(splat_index)
    @gen.send(:drop, 1)
  end

  @gen.swap

  # get quasiquote tree of pattern
  @gen.send(:node, 0)

  # get path from pattern
  push_path

  if splat_index
    @gen.push_int(splat_index)
    @gen.send(:[], 1)
    @gen.send(:pattern, 0)
  end

  # restore original order
  @gen.swap

  # assign sub-pattern against sub-value
  pattern.assign(@gen)

  @gen.pop_many(2)
end
go(a) click to toggle source
# File lib/atomy/code/pattern/quasi_quote.rb, line 95
def go(a)
  if a.is_a?(Atomy::Code::Pattern)
    @path.pop # remove .node call from following through the unquote
    assign_using_path(a)
    @path << :node # add it back so the parent .pop doesn't break
  else
    a.each_child do |attr, val|
      @path << [attr, []]

      if val.is_a?(Array)
        go_array(val)
      else
        go(val)
      end

      @path.pop
    end
  end
end
go_array(as) click to toggle source
# File lib/atomy/code/pattern/quasi_quote.rb, line 115
def go_array(as)
  splat = nil
  req_size = 0
  as.each do |a|
    if a.is_a?(Atomy::Grammar::AST::Unquote) && a.node.is_a?(Atomy::Code::Pattern) && a.node.splat?
      splat = a.node
      break
    end

    req_size += 1
  end

  req_size.times do |i|
    @path << [:[], [i]]
    go(as[i])
    @path.pop
  end

  if splat
    assign_using_path(splat, req_size)
  end

  true
end
push_path() click to toggle source
# File lib/atomy/code/pattern/quasi_quote.rb, line 174
def push_path
  @path.each do |m, args|
    args.each do |a|
      @gen.push_int(a)
    end

    @gen.send(m, args.size)
  end
end