class Eqn::Expression
Node class for an expression.
Public Instance Methods
left_associative?()
click to toggle source
# File lib/eqn/expression.rb, line 4 def left_associative? elements.any? && elements.last.left_associative? end
value(vars = {})
click to toggle source
# File lib/eqn/expression.rb, line 8 def value(vars = {}) base = elements.shift.value(vars) # Aggressively consume left associative operators to maintain associativity. base = consume_while_left_associative(base, vars) # Apply next right-associative operator (if any) or return. apply_next_operator(base, vars) end
Private Instance Methods
apply_left_associative(base, vars, operator, num_expr)
click to toggle source
# File lib/eqn/expression.rb, line 39 def apply_left_associative(base, vars, operator, num_expr) num_expr_operand = num_expr.elements.shift elements.push(num_expr.elements.shift) unless num_expr.term? base.send(operator, num_expr_operand.value(vars)) end
apply_next_operator(base, vars)
click to toggle source
# File lib/eqn/expression.rb, line 27 def apply_next_operator(base, vars) return base if term? left_associative = elements.last.left_associative? op, num_expr = elements.shift.value(vars) if left_associative apply_left_associative(base, vars, op, num_expr) else base.send(op, num_expr.value(vars)) end end
consume_while_left_associative(base, vars)
click to toggle source
# File lib/eqn/expression.rb, line 20 def consume_while_left_associative(base, vars) return base unless left_associative? base = apply_next_operator(base, vars) consume_while_left_associative(base, vars) end