class Keisan::Functions::While
Public Class Methods
new()
click to toggle source
Calls superclass method
Keisan::Function::new
# File lib/keisan/functions/while.rb, line 7 def initialize super("while", 2) end
Public Instance Methods
evaluate(ast_function, context = nil)
click to toggle source
# File lib/keisan/functions/while.rb, line 16 def evaluate(ast_function, context = nil) validate_arguments!(ast_function.children.count) context ||= Keisan::Context.new while_loop(ast_function, context, simplify: false) end
simplify(ast_function, context = nil)
click to toggle source
# File lib/keisan/functions/while.rb, line 22 def simplify(ast_function, context = nil) validate_arguments!(ast_function.children.count) context ||= Context.new while_loop(ast_function, context, simplify: true) end
value(ast_function, context = nil)
click to toggle source
# File lib/keisan/functions/while.rb, line 11 def value(ast_function, context = nil) validate_arguments!(ast_function.children.count) evaluate(ast_function, context) end
Private Instance Methods
logical_node_evaluates_to_true(logical_node, context)
click to toggle source
# File lib/keisan/functions/while.rb, line 62 def logical_node_evaluates_to_true(logical_node, context) bool = logical_node.evaluated(context).to_node if bool.is_a?(AST::Boolean) bool.value(context) elsif bool.is_constant? raise WhileLogicalNodeIsNonBoolConstant.new else raise WhileLogicalNodeIsNotConstant.new end end
while_loop(ast_function, context, simplify: true)
click to toggle source
# File lib/keisan/functions/while.rb, line 30 def while_loop(ast_function, context, simplify: true) logical_node, body_node = ast_function.children[0], ast_function.children[1] current = Keisan::AST::Null.new begin while logical_node_evaluates_to_true(logical_node, context) begin current = body_node.evaluated(context) rescue Exceptions::BreakError break rescue Exceptions::ContinueError next end end # While loops should work on booleans, not other types of constants rescue WhileLogicalNodeIsNonBoolConstant raise Keisan::Exceptions::InvalidFunctionError.new("while condition must evaluate to a boolean") # If the logical expression is not constant (e.g. boolean), then we # cannot simplify the while loop, and an evaluate should raise an error. rescue WhileLogicalNodeIsNotConstant if simplify return ast_function else raise Keisan::Exceptions::InvalidFunctionError.new("while condition must evaluate to a boolean") end end current end