class Keisan::Functions::Range
Public Class Methods
new()
click to toggle source
Calls superclass method
Keisan::Function::new
# File lib/keisan/functions/range.rb, line 4 def initialize super("range", ::Range.new(1,3)) end
Public Instance Methods
call(context, *args)
click to toggle source
# File lib/keisan/functions/range.rb, line 8 def call(context, *args) start, finish, shift = start_finish_shift_from_args(*args) if shift == 1 start_finish_range(start, finish) else start_finish_shift_range(start, finish, shift) end end
evaluate(ast_function, context = nil)
click to toggle source
# File lib/keisan/functions/range.rb, line 23 def evaluate(ast_function, context = nil) validate_arguments!(ast_function.children.count) context ||= Keisan::Context.new simplify(ast_function, context) end
simplify(ast_function, context = nil)
click to toggle source
# File lib/keisan/functions/range.rb, line 29 def simplify(ast_function, context = nil) validate_arguments!(ast_function.children.count) context ||= Context.new simplified_children = ast_function.children.map {|child| child.simplify(context)} if simplified_children.all? {|child| child.is_a?(Keisan::AST::Number)} Keisan::AST::List.new(call(context, *simplified_children.map(&:value))) else Keisan::AST::Function.new(simplified_children, "range") end end
value(ast_function, context = nil)
click to toggle source
# File lib/keisan/functions/range.rb, line 18 def value(ast_function, context = nil) validate_arguments!(ast_function.children.count) evaluate(ast_function, context) end
Private Instance Methods
start_finish_range(start, finish)
click to toggle source
# File lib/keisan/functions/range.rb, line 57 def start_finish_range(start, finish) (start...finish).to_a end
start_finish_shift_from_args(*args)
click to toggle source
# File lib/keisan/functions/range.rb, line 44 def start_finish_shift_from_args(*args) case args.count when 1 [0, args[0], 1] when 2 [args[0], args[1], 1] when 3 [args[0], args[1], args[2]] else [0, 0, 0] end end
start_finish_shift_range(start, finish, shift)
click to toggle source
# File lib/keisan/functions/range.rb, line 61 def start_finish_shift_range(start, finish, shift) if shift == 0 or !shift.is_a?(Integer) raise Keisan::Exceptions::InvalidFunctionError.new("shift argument for Range must be non-zero integer") end if shift > 0 (start...finish).select {|i| (i - start) % shift == 0} else (finish+1...start+1).select {|i| (i - finish) % shift == 0}.reverse end end