Class: Lisp::Primitive
- Inherits:
-
Atom
show all
- Defined in:
- lib/rubylisp/primitive.rb
Instance Attribute Summary collapse
Attributes inherited from Atom
#value
Class Method Summary
collapse
Instance Method Summary
collapse
Methods inherited from Atom
#all?, #car, #cdr, #character?, #class?, #copy, #environment?, #eof_object?, #eq?, #equal?, #eqv?, #evaluate, #false?, #frame?, #function?, #length, #lisp_object?, #list?, #macro?, #negative?, #number?, #object?, #pair?, #port?, #positive?, #print_string, #quoted, #set!, #set_location, #string?, #symbol?, #true?, #vector?, #zero?
Constructor Details
#initialize(name, arity, doc, special, &implementation) ⇒ Primitive
Returns a new instance of Primitive.
14
15
16
17
18
19
20
|
# File 'lib/rubylisp/primitive.rb', line 14
def initialize(name, arity, doc, special, &implementation)
@name = name
@arity = arity
@doc = doc
@special = special
@implementation = implementation
end
|
Instance Attribute Details
Returns the value of attribute doc.
5
6
7
|
# File 'lib/rubylisp/primitive.rb', line 5
def doc
@doc
end
|
Returns the value of attribute name.
5
6
7
|
# File 'lib/rubylisp/primitive.rb', line 5
def name
@name
end
|
Class Method Details
.register(name, arity, doc = "", special = false, env = Lisp::EnvironmentFrame.global, &implementation) ⇒ Object
8
9
10
11
|
# File 'lib/rubylisp/primitive.rb', line 8
def self.register(name, arity, doc="", special=false, env=Lisp::EnvironmentFrame.global, &implementation)
instance = self.new(name, arity, doc, special, &implementation)
env.bind(Symbol.named(name), instance)
end
|
Instance Method Details
#apply_to(args, env) ⇒ Object
43
44
45
46
47
48
49
50
51
52
|
# File 'lib/rubylisp/primitive.rb', line 43
def apply_to(args, env)
return Lisp::Debug.process_error("Wrong number of arguments to #{@name}. Expected #{@arity} but got #{args.length}.", env) unless check_arity(args)
cooked_args = if @special
args
else
Lisp::ConsCell.array_to_list(args.to_a.map {|i| i.evaluate(env)})
end
@implementation.call(cooked_args, env)
end
|
#apply_to_without_evaluating(args, env) ⇒ Object
55
56
57
58
|
# File 'lib/rubylisp/primitive.rb', line 55
def apply_to_without_evaluating(args, env)
return Lisp::Debug.process_error("Wrong number of arguments to #{@name}. Expected #{@arity} but got #{args.length}.", env) unless check_arity(args)
@implementation.call(args, env)
end
|
#check_arity(args) ⇒ Object
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/rubylisp/primitive.rb', line 23
def check_arity(args)
return true if @arity == "*"
number_of_args = args.length
@arity.split("|").map do |term|
m = /^(\d+)$/.match(term)
return true if m && number_of_args == m[1].to_i
m = /^>=(\d+)$/.match(term)
return true if m && number_of_args >= m[1].to_i
m = /^\((\d+),(\d+)\)$/.match(term)
return true if m && number_of_args >= m[1].to_i && number_of_args <= m[2].to_i
end
false
end
|
70
71
72
|
# File 'lib/rubylisp/primitive.rb', line 70
def primitive?
true
end
|
75
76
77
|
# File 'lib/rubylisp/primitive.rb', line 75
def special?
@special
end
|
61
62
63
64
65
66
67
|
# File 'lib/rubylisp/primitive.rb', line 61
def to_s
if @special
"<specialform: #{@name}>"
else
"<primitive: #{@name}>"
end
end
|
80
81
82
83
84
85
86
|
# File 'lib/rubylisp/primitive.rb', line 80
def type
if @special
:specialform
else
:primitive
end
end
|