Class: Lisp::Function
- Inherits:
-
Atom
show all
- Defined in:
- lib/rubylisp/function.rb
Instance Attribute Summary collapse
Attributes inherited from Atom
#value
Instance Method Summary
collapse
Methods inherited from Atom
#alist?, #all?, #car, #cdr, #character?, #class?, #copy, #eq?, #evaluate, #false?, #frame?, #length, #lisp_object?, #list?, #macro?, #negative?, #number?, #object?, #pair?, #positive?, #primitive?, #print_string, #quoted, #set!, #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
Returns the value of attribute arity.
5
6
7
|
# File 'lib/rubylisp/function.rb', line 5
def arity
@arity
end
|
Returns the value of attribute doc.
5
6
7
|
# File 'lib/rubylisp/function.rb', line 5
def doc
@doc
end
|
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
71
72
73
|
# File 'lib/rubylisp/function.rb', line 71
def apply_to(parameters, env)
internal_apply_to(parameters, env, true)
end
|
#apply_to_without_evaluating(parameters, env) ⇒ Object
75
76
77
|
# File 'lib/rubylisp/function.rb', line 75
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
|
83
84
85
|
# File 'lib/rubylisp/function.rb', line 83
def function?
true
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
|
# 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
return Lisp::Debug.process_error("#{@name} expected #{@arity} parameters, received #{parameters.length}.", env) unless parameters.length == @arity
end
local_env = EnvironmentFrame.extending(@env, 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
|
79
80
81
|
# File 'lib/rubylisp/function.rb', line 79
def to_s
"<function: #{@name}>"
end
|
87
88
89
|
# File 'lib/rubylisp/function.rb', line 87
def type
:function
end
|