Class: Atomy::Code::Pattern::QuasiQuote::AssignWalker

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

Instance Method Summary collapse

Constructor Details

#initialize(gen) ⇒ AssignWalker

Returns a new instance of AssignWalker.



88
89
90
91
92
93
# File 'lib/atomy/code/pattern/quasi_quote.rb', line 88

def initialize(gen)
  @gen = gen

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

Instance Method Details

#assign_using_path(pattern, splat_index = nil) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# 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) ⇒ Object



95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# 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) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# 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_pathObject



174
175
176
177
178
179
180
181
182
# 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