Class: Lisp::Function
Instance Attribute Summary collapse
-
#arity ⇒ Object
readonly
Returns the value of attribute arity.
-
#body ⇒ Object
readonly
Returns the value of attribute body.
-
#doc ⇒ Object
readonly
Returns the value of attribute doc.
-
#env ⇒ Object
readonly
Returns the value of attribute env.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Attributes inherited from Atom
Instance Method Summary collapse
- #apply_to(parameters, env) ⇒ Object
- #apply_to_without_evaluating(parameters, env) ⇒ Object
- #compute_required_argument_count(args) ⇒ Object
- #function? ⇒ Boolean
-
#initialize(name, arguments, doc, body, env) ⇒ Function
constructor
A new instance of Function.
- #internal_apply_to(parameters, env, should_eval) ⇒ Object
- #to_s ⇒ Object
- #type ⇒ Object
Methods inherited from Atom
#all?, #car, #cdr, #character?, #class?, #copy, #environment?, #eof_object?, #eq?, #equal?, #eqv?, #evaluate, #false?, #frame?, #length, #lisp_object?, #list?, #macro?, #negative?, #number?, #object?, #pair?, #port?, #positive?, #primitive?, #print_string, #quoted, #set!, #set_location, #special?, #string?, #symbol?, #true?, #vector?, #zero?
Constructor Details
#initialize(name, arguments, doc, body, env) ⇒ Function
Returns a new instance of Function.
23 24 25 26 27 28 29 30 31 32 33 |
# 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 |
Instance Attribute Details
#arity ⇒ Object (readonly)
Returns the value of attribute arity.
5 6 7 |
# File 'lib/rubylisp/function.rb', line 5 def arity @arity end |
#body ⇒ Object (readonly)
Returns the value of attribute body.
5 6 7 |
# File 'lib/rubylisp/function.rb', line 5 def body @body end |
#doc ⇒ Object (readonly)
Returns the value of attribute doc.
5 6 7 |
# File 'lib/rubylisp/function.rb', line 5 def doc @doc end |
#env ⇒ Object (readonly)
Returns the value of attribute env.
5 6 7 |
# File 'lib/rubylisp/function.rb', line 5 def env @env end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
5 6 7 |
# File 'lib/rubylisp/function.rb', line 5 def name @name end |
Instance Method Details
#apply_to(parameters, env) ⇒ Object
72 73 74 |
# 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) ⇒ Object
76 77 78 |
# 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) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# 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 |
#internal_apply_to(parameters, env, should_eval) ⇒ Object
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
# 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 ⇒ Object
80 81 82 |
# File 'lib/rubylisp/function.rb', line 80 def to_s "<function: #{@name}>" end |
#type ⇒ Object
88 89 90 |
# File 'lib/rubylisp/function.rb', line 88 def type :function end |