Class: Lisp::ConsCell
- Inherits:
-
Object
show all
- Includes:
- Enumerable
- Defined in:
- lib/rubylisp/cons_cell.rb
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(car = nil, cdr = nil) ⇒ ConsCell
Returns a new instance of ConsCell.
16
17
18
19
|
# File 'lib/rubylisp/cons_cell.rb', line 16
def initialize(car=nil, cdr=nil)
@car = car
@cdr = cdr
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args, &block) ⇒ Object
202
203
204
205
206
207
208
|
# File 'lib/rubylisp/cons_cell.rb', line 202
def method_missing(name, *args, &block)
if name[0] == ?c && name[-1] == ?r && (name[1..-2].chars.all? {|e| "ad".include?(e)})
self.traverse(name[1..-2].reverse)
else
super
end
end
|
Instance Attribute Details
Returns the value of attribute car.
5
6
7
|
# File 'lib/rubylisp/cons_cell.rb', line 5
def car
@car
end
|
Returns the value of attribute cdr.
5
6
7
|
# File 'lib/rubylisp/cons_cell.rb', line 5
def cdr
@cdr
end
|
Class Method Details
.array_to_list(cells, tail = nil) ⇒ Object
180
181
182
183
184
185
186
187
188
189
190
191
|
# File 'lib/rubylisp/cons_cell.rb', line 180
def self.array_to_list(cells, tail=nil)
return cons() if cells.empty? && tail.nil?
head = ConsCell.new
last_cell = head
(0...cells.length).each do |i|
new_cell = self.cons(cells[i], nil)
last_cell.set_cdr!(new_cell)
last_cell = new_cell
end
last_cell.set_cdr!(tail)
head.cdr
end
|
.cons(a = nil, b = nil) ⇒ Object
11
12
13
14
|
# File 'lib/rubylisp/cons_cell.rb', line 11
def self.cons(a=nil, b=nil)
b = nil if b.pair? && b.empty?
ConsCell.new(a, b)
end
|
Instance Method Details
54
55
56
|
# File 'lib/rubylisp/cons_cell.rb', line 54
def character?
false
end
|
#each(&block) ⇒ Object
169
170
171
172
173
174
175
176
177
178
|
# File 'lib/rubylisp/cons_cell.rb', line 169
def each &block
return if empty?
c = self
if self.length > 0
until c.nil?
yield c.car
c = c.cdr
end
end
end
|
46
47
48
|
# File 'lib/rubylisp/cons_cell.rb', line 46
def empty?
@car.nil? && @cdr.nil?
end
|
110
111
112
113
|
# File 'lib/rubylisp/cons_cell.rb', line 110
def eq?(other)
return true if empty? && (other.nil? || (other.pair? && other.empty?))
other.pair? && self == other
end
|
#equal?(other) ⇒ Boolean
120
121
122
123
124
|
# File 'lib/rubylisp/cons_cell.rb', line 120
def equal?(other)
return true if empty? && (other.nil? || (other.pair? && other.empty?))
return false unless other.pair?
@car.equal?(other.car) && @cdr.equal?(other.cdr)
end
|
#eqv?(other) ⇒ Boolean
115
116
117
118
|
# File 'lib/rubylisp/cons_cell.rb', line 115
def eqv?(other)
return true if empty? && (other.nil? || (other.pair? && other.empty?))
other.pair? && self == other
end
|
#evaluate(env) ⇒ Object
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
|
# File 'lib/rubylisp/cons_cell.rb', line 256
def evaluate(env)
return self if empty?
sexpr = if @car.symbol?
throw :named_let_application, @cdr.to_a.map {|a| a.evaluate(env)} if @car.eq?(Lisp.named_let_stack[-1])
key = @car
frame = nth(1)
value = nth(2)
s = key.name
if s.end_with?(":")
ConsCell.array_to_list([Symbol.named("get-slot"), frame, key])
elsif s.end_with?(":!")
ConsCell.array_to_list([Symbol.named("set-slot!"), frame, Symbol.named(s[0..-2]), value])
elsif s.end_with?(":?")
ConsCell.array_to_list([Symbol.named("has-slot?"), frame, Symbol.named(s[0..-2])])
elsif s.end_with?(":>")
ConsCell.array_to_list([Symbol.named("send"), frame, Symbol.named(s[0..-2])] << self.cdddr)
elsif s.end_with?(":^")
ConsCell.array_to_list([Symbol.named("send-super"), frame, Symbol.named(s[0..-2])] << self.cdddr)
else
self
end
else
self
end
sexpr.inner_eval(env)
end
|
#evaluate_each(env) ⇒ Object
284
285
286
287
288
289
|
# File 'lib/rubylisp/cons_cell.rb', line 284
def evaluate_each(env)
return nil if empty?
result = @car.evaluate(env)
return result if @cdr.nil?
@cdr.evaluate_each(env)
end
|
301
302
303
|
# File 'lib/rubylisp/cons_cell.rb', line 301
def false?
false
end
|
321
322
323
324
325
326
327
328
329
330
331
332
333
|
# File 'lib/rubylisp/cons_cell.rb', line 321
def flatten
ary = []
to_a.each do |s|
if s.nil?
ary << nil
elsif s.list?
s.to_a.each {|e| ary << e}
else
ary << s
end
end
ConsCell.array_to_list(ary)
end
|
102
103
104
|
# File 'lib/rubylisp/cons_cell.rb', line 102
def frame?
false
end
|
86
87
88
|
# File 'lib/rubylisp/cons_cell.rb', line 86
def function?
false
end
|
309
310
311
312
313
314
315
|
# File 'lib/rubylisp/cons_cell.rb', line 309
def last
c = self
while !c.cdr.nil? && c.cdr.pair? do
c = c.cdr
end
c
end
|
291
292
293
294
295
|
# File 'lib/rubylisp/cons_cell.rb', line 291
def length
return 0 if empty?
return 1 if @cdr.nil?
return 1 + @cdr.length
end
|
#lisp_object? ⇒ Boolean
29
30
31
|
# File 'lib/rubylisp/cons_cell.rb', line 29
def lisp_object?
true
end
|
98
99
100
|
# File 'lib/rubylisp/cons_cell.rb', line 98
def list?
true
end
|
90
91
92
|
# File 'lib/rubylisp/cons_cell.rb', line 90
def macro?
false
end
|
70
71
72
|
# File 'lib/rubylisp/cons_cell.rb', line 70
def negative?
false
end
|
210
211
212
213
214
|
# File 'lib/rubylisp/cons_cell.rb', line 210
def nth(n)
c = self
n.times {|i| c = c.cdr}
c.car
end
|
#nth_tail(n) ⇒ Object
216
217
218
219
220
|
# File 'lib/rubylisp/cons_cell.rb', line 216
def nth_tail(n)
c = self
n.times {|i| c = c.cdr}
c
end
|
58
59
60
|
# File 'lib/rubylisp/cons_cell.rb', line 58
def number?
false
end
|
#objc_object_or_nil(obj) ⇒ Object
222
223
224
225
|
# File 'lib/rubylisp/cons_cell.rb', line 222
def objc_object_or_nil(obj)
return nil unless obj.object?
return obj.value
end
|
94
95
96
|
# File 'lib/rubylisp/cons_cell.rb', line 94
def pair?
true
end
|
62
63
64
|
# File 'lib/rubylisp/cons_cell.rb', line 62
def positive?
false
end
|
78
79
80
|
# File 'lib/rubylisp/cons_cell.rb', line 78
def primitive?
false
end
|
#print_ary(a) ⇒ Object
317
318
319
|
# File 'lib/rubylisp/cons_cell.rb', line 317
def print_ary(a)
(0...a.length).map {|i| puts (a[i].nil? ? "nil" : a[i])}
end
|
#print_string ⇒ Object
149
150
151
152
153
154
155
156
|
# File 'lib/rubylisp/cons_cell.rb', line 149
def print_string
return "()" if self.empty?
return "'#{@cdr.car.print_string}" if @car.symbol? && @car.name == "quote"
return "{#{@cdr.print_string_helper}}" if @car.symbol? && @car.name == "make-frame"
return "#(#{@cdr.print_string_helper})" if @car.symbol? && @car.name == "make-vector"
return "(#{@car.print_string} . #{@cdr.print_string})" if !@cdr.nil? && !@cdr.pair?
return "(#{self.print_string_helper})"
end
|
#print_string_helper ⇒ Object
145
146
147
|
# File 'lib/rubylisp/cons_cell.rb', line 145
def print_string_helper
@cdr.nil? ? "#{@car.print_string}" : "#{@car.print_string} #{@cdr.print_string_helper}"
end
|
#push_current_code ⇒ Object
228
229
230
|
# File 'lib/rubylisp/cons_cell.rb', line 228
def push_current_code
env.push_code(self.print_string)
end
|
#set_car!(d) ⇒ Object
25
26
27
|
# File 'lib/rubylisp/cons_cell.rb', line 25
def set_car!(d)
@car = d
end
|
#set_cdr!(d) ⇒ Object
33
34
35
|
# File 'lib/rubylisp/cons_cell.rb', line 33
def set_cdr!(d)
@cdr = d
end
|
#set_location(type, package, file, start, length) ⇒ Object
7
8
|
# File 'lib/rubylisp/cons_cell.rb', line 7
def set_location(type, package, file, start, length)
end
|
#set_nth!(n, d) ⇒ Object
38
39
40
41
42
43
|
# File 'lib/rubylisp/cons_cell.rb', line 38
def set_nth!(n, d)
return nil if empty?
c = self
n.times {|i| c = c.cdr}
c.set_car!(d)
end
|
82
83
84
|
# File 'lib/rubylisp/cons_cell.rb', line 82
def special?
false
end
|
50
51
52
|
# File 'lib/rubylisp/cons_cell.rb', line 50
def string?
false
end
|
74
75
76
|
# File 'lib/rubylisp/cons_cell.rb', line 74
def symbol?
false
end
|
158
159
160
161
162
163
164
165
166
167
|
# File 'lib/rubylisp/cons_cell.rb', line 158
def to_a
a = []
return a if empty?
c = self
until c.nil?
a << c.car
c = c.cdr
end
a
end
|
136
137
138
139
140
141
142
143
|
# File 'lib/rubylisp/cons_cell.rb', line 136
def to_s
return "()" if self.empty?
return "'#{@cdr.car.to_s}" if @car.symbol? && @car.name == "quote"
return "{#{@cdr.to_s_helper}}" if @car.symbol? && @car.name == "make-frame"
return "#(#{@cdr.to_s_helper})" if @car.symbol? && @car.name == "make-vector"
return "(#{@car.to_s} . #{@cdr.to_s})" if !@cdr.nil? && !@cdr.pair?
return "(#{self.to_s_helper})"
end
|
#to_s_helper ⇒ Object
130
131
132
133
134
|
# File 'lib/rubylisp/cons_cell.rb', line 130
def to_s_helper
return "#{@car.to_s}" if @cdr.nil?
return "#{@car.to_s} . #{@cdr.to_s}" unless @cdr.pair?
"#{@car.to_s} #{@cdr.to_s_helper}"
end
|
#traverse(path) ⇒ Object
193
194
195
196
197
198
199
200
|
# File 'lib/rubylisp/cons_cell.rb', line 193
def traverse(path)
next_cell = self
path.chars.each do |p|
return nil if next_cell.nil? || !next_cell.pair?
next_cell = ((p == ?a) ? next_cell.car : next_cell.cdr)
end
next_cell
end
|
297
298
299
|
# File 'lib/rubylisp/cons_cell.rb', line 297
def true?
true
end
|
126
127
128
|
# File 'lib/rubylisp/cons_cell.rb', line 126
def type
:pair
end
|
21
22
23
|
# File 'lib/rubylisp/cons_cell.rb', line 21
def value
self
end
|
106
107
108
|
# File 'lib/rubylisp/cons_cell.rb', line 106
def vector?
false
end
|
66
67
68
|
# File 'lib/rubylisp/cons_cell.rb', line 66
def zero?
false
end
|