class Lisp::Function
Attributes
arity[R]
body[R]
doc[R]
env[R]
name[R]
Public Class Methods
new(name, arguments, doc, body, env)
click to toggle source
# File lib/rubylisp/function.rb, line 23 def initialize(name, arguments, doc, body, env) sig = ([name] << arguments.to_a).flatten @doc = "(#{(sig.collect {|e| e.to_s}).join(" ")})" @name = name @arguments = arguments @doc = [@doc, doc].join("\n\n") unless doc.nil? || doc.to_s.empty? @body = body @env = env @local_env = nil compute_required_argument_count(@arguments) end
Public Instance Methods
apply_to(parameters, env)
click to toggle source
# File lib/rubylisp/function.rb, line 72 def apply_to(parameters, env) internal_apply_to(parameters, env, true) end
apply_to_without_evaluating(parameters, env)
click to toggle source
# File lib/rubylisp/function.rb, line 76 def apply_to_without_evaluating(parameters, env) internal_apply_to(parameters, env, false) end
compute_required_argument_count(args)
click to toggle source
# File lib/rubylisp/function.rb, line 7 def compute_required_argument_count(args) a = args @arity = 0 @var_args = false while a if a.symbol? @var_args = true return else @arity += 1 end a = a.cdr end end
function?()
click to toggle source
# File lib/rubylisp/function.rb, line 84 def function? true end
internal_apply_to(parameters, env, should_eval)
click to toggle source
# File lib/rubylisp/function.rb, line 36 def internal_apply_to(parameters, env, should_eval) if @var_args return Lisp::Debug.process_error("#{@name} expected at least #{@arity} parameters, received #{parameters.length}.", env) if parameters.length < @arity else puts "#{@name} #{@arguments.print_string} #{@body.print_string}" unless parameters.length == @arity puts caller unless parameters.length == @arity return Lisp::Debug.process_error("#{@name} expected #{@arity} parameters, received #{parameters.length}.", env) unless parameters.length == @arity end local_env = EnvironmentFrame.extending(@env, @name, env.frame) local_env.previous = env self_sym = Symbol.named("self") if env.frame local_env.bind_locally(self_sym, env.frame) elsif env.local_binding_for(self_sym) local_env.bind_locally(self_sym, env.value_of(self_sym)) end arg = @arguments param = parameters accumulating_arg = nil accumulated_params = [] while !param.nil? param_value = should_eval ? param.car.evaluate(env) : param.car if accumulating_arg accumulated_params << param_value else local_env.bind_locally(arg.car, param_value) unless arg.car.nil? end param = param.cdr arg = arg.cdr unless accumulating_arg accumulating_arg = arg if arg.symbol? end local_env.bind_locally(accumulating_arg, Lisp::ConsCell.array_to_list(accumulated_params)) if accumulating_arg @body.evaluate_each(local_env) end
to_s()
click to toggle source
# File lib/rubylisp/function.rb, line 80 def to_s "<function: #{@name}>" end
type()
click to toggle source
# File lib/rubylisp/function.rb, line 88 def type :function end