Class: Subaltern::Function

Inherits:
Object
  • Object
show all
Defined in:
lib/subaltern/evaluator.rb

Overview

Wrapper for function trees when stored in Context instances.

Direct Known Subclasses

LoopFunction

Instance Method Summary collapse

Constructor Details

#initialize(tree) ⇒ Function

Returns a new instance of Function.



185
186
187
188
189
190
# File 'lib/subaltern/evaluator.rb', line 185

def initialize(tree)

  @tree = tree

  # TODO : eventually, follow Block's example and split the tree here
end

Instance Method Details

#call(context, tree) ⇒ Object



192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
# File 'lib/subaltern/evaluator.rb', line 192

def call(context, tree)

  meth_args = @tree[2][1..-1]
  l = meth_args.last
  meth_arg_defaults = l.is_a?(Array) && l.first == :block ? l[1..-1] : []
  call_args = tree[3][1..-1].collect { |t| Subaltern.eval_tree(context, t) }

  con = Context.new(context, {})

  # bind arguments

  call_args.each_with_index do |arg, i|
    name = meth_args[i].to_s
    if m = name.match(/^\*(.+)$/)
      con[m[1]] = call_args[i..-1]
      break
    end
    con[name] = arg
  end

  # bind default arguments (when necessary)

  meth_arg_defaults.each do |d|
    name = d[1].to_s
    con[name] = Subaltern.eval_tree(context, d[2]) unless con.has_key?(name)
  end

  # is there a block ?

  if m = (meth_args.last || '').to_s.match(/^&(.+)/)
    con[m[1]] = context['__block']
  end

  # now do it

  begin
    Subaltern.eval_tree(con, @tree[3])
  rescue Return => r
    r.value
  end
end