class Keisan::Evaluator

Attributes

calculator[R]

Public Class Methods

new(calculator, cache: nil) click to toggle source
# File lib/keisan/evaluator.rb, line 5
def initialize(calculator, cache: nil)
  @calculator = calculator
  @cache = cache
end

Public Instance Methods

evaluate(expression, definitions = {}) click to toggle source
# File lib/keisan/evaluator.rb, line 10
def evaluate(expression, definitions = {})
  context = calculator.context.spawn_child(definitions: definitions, transient: true)
  ast = parse_ast(expression)
  last_line = last_line(ast)

  evaluation = ast.evaluated(context)

  if last_line.is_a?(AST::Assignment)
    if last_line.children.first.is_a?(AST::Variable)
      context.variable(last_line.children.first.name).value(context)
    end
  else
    evaluation.value(context)
  end
end
parse_ast(expression) click to toggle source
# File lib/keisan/evaluator.rb, line 32
def parse_ast(expression)
  ast = @cache.nil? ? AST.parse(expression) : @cache.fetch_or_build(expression)
  disallowed = disallowed_nodes
  if !disallowed.empty? && ast.contains_a?(disallowed)
    raise Keisan::Exceptions::InvalidExpression.new("Context does not permit expressions with #{disallowed}")
  end
  ast
end
simplify(expression, definitions = {}) click to toggle source
# File lib/keisan/evaluator.rb, line 26
def simplify(expression, definitions = {})
  context = calculator.context.spawn_child(definitions: definitions, transient: true)
  ast = parse_ast(expression)
  ast.simplified(context)
end

Private Instance Methods

disallowed_nodes() click to toggle source
# File lib/keisan/evaluator.rb, line 43
def disallowed_nodes
  disallowed = []
  disallowed << Keisan::AST::Block unless calculator.allow_blocks
  disallowed << Keisan::AST::MultiLine unless calculator.allow_multiline
  disallowed
end
last_line(ast) click to toggle source
# File lib/keisan/evaluator.rb, line 50
def last_line(ast)
  ast.is_a?(AST::MultiLine) ? ast.children.last : ast
end