Class: Atomy::Code::QuasiQuote::Constructor

Inherits:
Object
  • Object
show all
Defined in:
lib/atomy/code/quasi_quote.rb

Instance Method Summary collapse

Constructor Details

#initialize(gen, mod) ⇒ Constructor

Returns a new instance of Constructor.



15
16
17
18
19
# File 'lib/atomy/code/quasi_quote.rb', line 15

def initialize(gen, mod)
  @gen = gen
  @module = mod
  @depth = 1
end

Instance Method Details

#construct_many(c) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# 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) ⇒ Object



21
22
23
# File 'lib/atomy/code/quasi_quote.rb', line 21

def go(x)
  x.accept(self)
end

#push_class(cls) ⇒ Object



109
110
111
112
113
114
# 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) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
# 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) ⇒ Object



25
26
27
# File 'lib/atomy/code/quasi_quote.rb', line 25

def unquote(x)
  @module.compile(@gen, x.node)
end

#visit(x) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 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) ⇒ Object



50
51
52
53
54
55
# File 'lib/atomy/code/quasi_quote.rb', line 50

def visit_quasiquote(qq)
  @depth += 1
  visit(qq)
ensure
  @depth -= 1
end

#visit_unquote(x) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
# 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