class Keisan::AST::FunctionAssignment
Attributes
context[R]
lhs[R]
local[R]
rhs[R]
Public Class Methods
new(context, lhs, rhs, local)
click to toggle source
# File lib/keisan/ast/function_assignment.rb, line 6 def initialize(context, lhs, rhs, local) @context = context @lhs = lhs @rhs = rhs @local = local unless lhs.children.all? {|arg| arg.is_a?(Variable)} raise Exceptions::InvalidExpression.new("Left hand side function must have variables as arguments") end end
Public Instance Methods
argument_names()
click to toggle source
# File lib/keisan/ast/function_assignment.rb, line 17 def argument_names @argument_names ||= lhs.children.map(&:name) end
evaluate()
click to toggle source
# File lib/keisan/ast/function_assignment.rb, line 30 def evaluate # Blocks might have local variable/function definitions, so skip check verify_rhs_of_function_assignment_is_valid! context.register_function!(lhs.name, expression_function, local: local) rhs end
expression_function()
click to toggle source
# File lib/keisan/ast/function_assignment.rb, line 21 def expression_function Functions::ExpressionFunction.new( lhs.name, argument_names, rhs.evaluate_assignments(context.spawn_child(shadowed: argument_names, transient: true)), context.transient_definitions ) end
Private Instance Methods
verify_rhs_of_function_assignment_is_valid!()
click to toggle source
# File lib/keisan/ast/function_assignment.rb, line 39 def verify_rhs_of_function_assignment_is_valid! verify_unbound_functions! verify_unbound_variables! end
verify_unbound_functions!()
click to toggle source
# File lib/keisan/ast/function_assignment.rb, line 44 def verify_unbound_functions! # Cannot have undefined functions unless allowed by context unless context.allow_recursive || rhs.unbound_functions(context).empty? raise Exceptions::InvalidExpression.new("Unbound function definitions are not allowed by current context") end end
verify_unbound_variables!()
click to toggle source
# File lib/keisan/ast/function_assignment.rb, line 51 def verify_unbound_variables! # We allow unbound variables inside block statements, as they could be temporary # variables assigned locally return if rhs.is_a?(Block) # Only variables that can appear are those that are arguments to the function unless rhs.unbound_variables(context) <= Set.new(argument_names) raise Exceptions::InvalidExpression.new("Unbound variables found in function definition") end end