Class: FunctioncallNode

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

Overview

Class for calling functions.

Instance Method Summary collapse

Methods included from STL

delete_element, get_element, pop, print, push, size

Constructor Details

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

Returns a new instance of FunctioncallNode.



127
128
129
130
131
# File 'lib/nodes.rb', line 127

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

Instance Method Details

#evaluate(scope) ⇒ Object



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/nodes.rb', line 162

def evaluate(scope)

  # Check if scope of identifier. If it exist but is not defined as a function: raise TypeError
  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

  
  # Check if the function has been called as a method on a object (Ex. a.print();). Add object as a argument if true.

  if @object && !@arguments.include?(@object)
    @arguments.unshift(@object)
  end

  # Check if no identifier has been found in scope.
  if !id_scope

    # Check if function part of STL. if true: call function, else raise NameError.
    if STL.respond_to?(@identifier)
      method = STL.method(@identifier)
      parameters = method.parameters
      validate_arguments(parameters)
      evaluate_STL_function(scope)
    else
      raise NameError, "Function #{@identifier} not defined."
    end

    # If identifier is user defined function, call it.
  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, declared_scope) ⇒ Object

Evaluate code-block of user defined function.



148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/nodes.rb', line 148

def evaluate_block(parameters, block, current_scope, declared_scope)
  
  # Create new scope for function with the scope where the function was declared as its parent scope. 
  new_scope = Scope.new(declared_scope)

  # Set local variables for function with values from arguments
  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_STL_function(scope) ⇒ Object

Calls builtin-function.



141
142
143
144
145
# File 'lib/nodes.rb', line 141

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

#validate_arguments(parameters) ⇒ Object

Checks if the arguments given is the same number of expected parameters.



134
135
136
137
138
# File 'lib/nodes.rb', line 134

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