class Keisan::AST::CellAssignment

Attributes

assignment[R]
context[R]
lhs[R]
rhs[R]

Public Class Methods

new(assignment, context, lhs, rhs) click to toggle source
# File lib/keisan/ast/cell_assignment.rb, line 6
def initialize(assignment, context, lhs, rhs)
  @assignment = assignment
  @context = context
  @lhs = lhs
  @rhs = rhs
end

Public Instance Methods

evaluate() click to toggle source
# File lib/keisan/ast/cell_assignment.rb, line 13
def evaluate
  lhs = lhs_evaluate_and_check_modifiable

  unless lhs.is_a?(Cell)
    raise Exceptions::InvalidExpression.new("Unhandled left hand side #{lhs} in assignment")
  end

  case assignment.compound_operator
  when :"||"
    evaluate_cell_or_assignment(context, lhs, rhs)
  when :"&&"
    evaluate_cell_and_assignment(context, lhs, rhs)
  else
    evaluate_cell_non_logical_assignment(context, lhs, rhs)
  end
end

Private Instance Methods

evaluate_cell_and_assignment(context, lhs, rhs) click to toggle source
# File lib/keisan/ast/cell_assignment.rb, line 53
def evaluate_cell_and_assignment(context, lhs, rhs)
  if lhs.true?
    rhs = rhs.evaluate(context)
    lhs.node = rhs.is_a?(Cell) ? rhs.node.deep_dup : rhs
    rhs
  else
    lhs
  end
end
evaluate_cell_non_logical_assignment(context, lhs, rhs) click to toggle source
# File lib/keisan/ast/cell_assignment.rb, line 63
def evaluate_cell_non_logical_assignment(context, lhs, rhs)
  rhs = rhs.evaluate(context)
  if assignment.compound_operator
    rhs = rhs.send(assignment.compound_operator, lhs.node).evaluate(context)
  end

  lhs.node = rhs.is_a?(Cell) ? rhs.node.deep_dup : rhs
  rhs
end
evaluate_cell_or_assignment(context, lhs, rhs) click to toggle source
# File lib/keisan/ast/cell_assignment.rb, line 43
def evaluate_cell_or_assignment(context, lhs, rhs)
  if lhs.false?
    rhs = rhs.evaluate(context)
    lhs.node = rhs.is_a?(Cell) ? rhs.node.deep_dup : rhs
    rhs
  else
    lhs
  end
end
lhs_evaluate_and_check_modifiable() click to toggle source
# File lib/keisan/ast/cell_assignment.rb, line 32
def lhs_evaluate_and_check_modifiable
  res = lhs.evaluate(context)
  if res.frozen?
    raise Exceptions::UnmodifiableError.new("Cannot modify frozen variables")
  end
  res
rescue RuntimeError => e
  raise Exceptions::UnmodifiableError.new("Cannot modify frozen variables") if e.message =~ /can't modify frozen/
  raise
end