Class: FunctioncallNode

Inherits:
Object
  • Object
show all
Includes:
STL
Defined in:
lib/nodes.rb

Instance Method Summary collapse

Methods included from STL

delete_element, get_element, pop, print, push, size

Constructor Details

#initialize(identifier, object = nil, arguments = []) ⇒ FunctioncallNode



103
104
105
106
107
# File 'lib/nodes.rb', line 103

def initialize(identifier, object = nil, arguments = [])
  @identifier = identifier.value
  @arguments = arguments
  @object = object
end

Instance Method Details

#evaluate(scope) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/nodes.rb', line 131

def evaluate(scope)

  id_scope = scope.get_scope(@identifier)
  if id_scope && !id_scope.is_function?(@identifier)
    raise TypeError, "Identifier #{@identifier} is not defined as a function."
  end
  if @object
    @arguments.unshift(@object)
  end
  if !id_scope
    if STL.respond_to?(@identifier)
      method = STL.method(@identifier)
      parameters = method.parameters
      validate_arguments(parameters)
      evaluate_method(scope)
    else
      raise NameError, "Function #{@identifier} not defined."
    end
  else
    function = id_scope.get_identifier(@identifier)
    parameters = function[:parameters]
    block = function[:block]
    validate_arguments(parameters)
    evaluate_block(parameters, block,scope,id_scope)
  end
end

#evaluate_block(parameters, block, current_scope, id_scope) ⇒ Object



121
122
123
124
125
126
127
128
129
# File 'lib/nodes.rb', line 121

def evaluate_block(parameters, block, current_scope, id_scope)
  new_scope = Scope.new(id_scope)
  parameters.zip(@arguments).each do |parameter, argument|
    new_scope.set_variable(parameter, '=', argument.evaluate(current_scope))
  end

  result = block.evaluate(new_scope)
  return result.value if result.is_a?(ReturnValue)
end

#evaluate_method(scope) ⇒ Object



115
116
117
118
119
# File 'lib/nodes.rb', line 115

def evaluate_method(scope)
  args = @arguments.map {|arg| arg.evaluate(scope)}
  result = STL.send(@identifier, *args)
  return result
end

#validate_arguments(parameters) ⇒ Object



109
110
111
112
113
# File 'lib/nodes.rb', line 109

def validate_arguments(parameters)
  if @arguments.size != parameters.size
    raise ArgumentError, "Wrong number of arguments (given: #{@arguments.size} expected: #{parameters.size})."
  end
end