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.



11
12
13
14
# File 'lib/rubylisp/cons_cell.rb', line 11

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



182
183
184
185
186
187
188
# File 'lib/rubylisp/cons_cell.rb', line 182

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

#carObject (readonly)

Returns the value of attribute car.



5
6
7
# File 'lib/rubylisp/cons_cell.rb', line 5

def car
  @car
end

#cdrObject (readonly)

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



161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/rubylisp/cons_cell.rb', line 161

def self.array_to_list(cells, tail=nil)
  return tail if cells.empty?
  head = ConsCell.new
  last_cell = head
  cells.each do |d|
    new_cell = self.cons(d, 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



7
8
9
# File 'lib/rubylisp/cons_cell.rb', line 7

def self.cons(a=nil, b=nil)
  ConsCell.new(a, b)
end

Instance Method Details

#alist?Boolean

Returns:



96
97
98
# File 'lib/rubylisp/cons_cell.rb', line 96

def alist?
  false
end

#character?Boolean

Returns:



48
49
50
# File 'lib/rubylisp/cons_cell.rb', line 48

def character?
  false
end

#each(&block) ⇒ Object



151
152
153
154
155
156
157
158
159
# File 'lib/rubylisp/cons_cell.rb', line 151

def each &block
  c = self
  if self.length > 0
    until c.nil?
      yield c.car 
      c = c.cdr
    end
  end
end

#empty?Boolean

Returns:



40
41
42
# File 'lib/rubylisp/cons_cell.rb', line 40

def empty?
  @car.nil? && @cdr.nil?
end

#eq?(sexpr) ⇒ Boolean

Returns:



108
109
110
111
# File 'lib/rubylisp/cons_cell.rb', line 108

def eq?(sexpr)
  return false unless sexpr.pair?
  (@car == sexpr.car || @car.eq?(sexpr.car)) && (@cdr == sexpr.cdr || @cdr.eq?(sexpr.cdr))
end

#evaluate(env) ⇒ Object



208
209
210
211
212
213
# File 'lib/rubylisp/cons_cell.rb', line 208

def evaluate(env)
  return self if empty?
  func = @car.evaluate(env)
  raise "There is no function or macro named #{@car}" if func.nil?
  func.apply_to(@cdr, env)
end

#evaluate_each(env) ⇒ Object



215
216
217
218
219
# File 'lib/rubylisp/cons_cell.rb', line 215

def evaluate_each(env)
  result = @car.evaluate(env)
  return result if @cdr.nil?
  @cdr.evaluate_each(env)
end

#false?Boolean

Returns:



231
232
233
# File 'lib/rubylisp/cons_cell.rb', line 231

def false?
  false
end

#flattenObject



247
248
249
250
# File 'lib/rubylisp/cons_cell.rb', line 247

def flatten
  ary = to_a.collect {|s| s.list? ? s.to_a : s}
  ConsCell.array_to_list(ary.flatten)
end

#frame?Boolean

Returns:



100
101
102
# File 'lib/rubylisp/cons_cell.rb', line 100

def frame?
  false
end

#function?Boolean

Returns:



80
81
82
# File 'lib/rubylisp/cons_cell.rb', line 80

def function?
  false
end

#lastObject



239
240
241
242
243
244
245
# File 'lib/rubylisp/cons_cell.rb', line 239

def last
  c = self
  while !c.cdr.nil? && c.cdr.pair? do
    c = c.cdr
  end
  c
end

#lengthObject



221
222
223
224
225
# File 'lib/rubylisp/cons_cell.rb', line 221

def length
  return 0 if empty?
  return 1 if @cdr.nil?
  return 1 + @cdr.length
end

#lisp_object?Boolean

Returns:



24
25
26
# File 'lib/rubylisp/cons_cell.rb', line 24

def lisp_object?
  true
end

#list?Boolean

Returns:



92
93
94
# File 'lib/rubylisp/cons_cell.rb', line 92

def list?
  true
end

#macro?Boolean

Returns:



84
85
86
# File 'lib/rubylisp/cons_cell.rb', line 84

def macro?
  false
end

#negative?Boolean

Returns:



64
65
66
# File 'lib/rubylisp/cons_cell.rb', line 64

def negative?
  false
end

#nth(n) ⇒ Object



190
191
192
193
194
# File 'lib/rubylisp/cons_cell.rb', line 190

def nth(n)
  c = self
  (n-1).times {|i| c = c.cdr}
  c.car
end

#nth_tail(n) ⇒ Object



196
197
198
199
200
# File 'lib/rubylisp/cons_cell.rb', line 196

def nth_tail(n)
  c = self
  (n-1).times {|i| c = c.cdr}
  c
end

#number?Boolean

Returns:



52
53
54
# File 'lib/rubylisp/cons_cell.rb', line 52

def number?
  false
end

#objc_object_or_nil(obj) ⇒ Object



202
203
204
205
# File 'lib/rubylisp/cons_cell.rb', line 202

def objc_object_or_nil(obj)
  return nil unless obj.object?
  return obj.value
end

#pair?Boolean

Returns:



88
89
90
# File 'lib/rubylisp/cons_cell.rb', line 88

def pair?
  true
end

#positive?Boolean

Returns:



56
57
58
# File 'lib/rubylisp/cons_cell.rb', line 56

def positive?
  false
end

#primitive?Boolean

Returns:



72
73
74
# File 'lib/rubylisp/cons_cell.rb', line 72

def primitive?
  false
end


134
135
136
137
138
139
# File 'lib/rubylisp/cons_cell.rb', line 134

def print_string
  return "()" if self.empty?
  return "'#{@cdr.car.print_string}" if @car.symbol? && @car.name == "quote"
  return "(#{@car.print_string} . #{@cdr.print_string})" if !@cdr.nil? && !@cdr.pair?
  return "(#{self.print_string_helper})"
end


130
131
132
# File 'lib/rubylisp/cons_cell.rb', line 130

def print_string_helper
  @cdr.nil? ? "#{@car.print_string}" : "#{@car.print_string} #{@cdr.print_string_helper}"
end

#quotedObject



235
236
237
# File 'lib/rubylisp/cons_cell.rb', line 235

def quoted
  Lisp::ConsCell.array_to_list([Symbol.named("quote"), self])
end

#set_car!(d) ⇒ Object



20
21
22
# File 'lib/rubylisp/cons_cell.rb', line 20

def set_car!(d)
  @car = d
end

#set_cdr!(d) ⇒ Object



28
29
30
# File 'lib/rubylisp/cons_cell.rb', line 28

def set_cdr!(d)
  @cdr = d
end

#set_nth!(n, d) ⇒ Object



33
34
35
36
37
# File 'lib/rubylisp/cons_cell.rb', line 33

def set_nth!(n, d)
  c = self
  (n-1).times {|i| c = c.cdr}
  c.set_car!(d)
end

#special?Boolean

Returns:



76
77
78
# File 'lib/rubylisp/cons_cell.rb', line 76

def special?
  false
end

#string?Boolean

Returns:



44
45
46
# File 'lib/rubylisp/cons_cell.rb', line 44

def string?
  false
end

#symbol?Boolean

Returns:



68
69
70
# File 'lib/rubylisp/cons_cell.rb', line 68

def symbol?
  false
end

#to_aObject



141
142
143
144
145
146
147
148
149
# File 'lib/rubylisp/cons_cell.rb', line 141

def to_a
  a = []
  c = self
  until c.nil?
    a << c.car()
    c = c.cdr
  end
  a
end

#to_sObject



123
124
125
126
127
128
# File 'lib/rubylisp/cons_cell.rb', line 123

def to_s
  return "()" if self.empty?
  return "'#{@cdr.car.to_s}" if @car.symbol? && @car.name == "quote"
  return "(#{@car.to_s} . #{@cdr.to_s})" if !@cdr.nil? && !@cdr.pair?
  return "(#{self.to_s_helper})"
end

#to_s_helperObject



117
118
119
120
121
# File 'lib/rubylisp/cons_cell.rb', line 117

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



174
175
176
177
178
179
180
# File 'lib/rubylisp/cons_cell.rb', line 174

def traverse(path)
  return self if path.empty?
  next_cell = (path[0] == ?a) ? @car : @cdr
  return next_cell if path.length == 1
  return nil if next_cell.nil?  || !next_cell.pair?
  next_cell.traverse(path[1..-1])
end

#true?Boolean

Returns:



227
228
229
# File 'lib/rubylisp/cons_cell.rb', line 227

def true?
  true
end

#typeObject



113
114
115
# File 'lib/rubylisp/cons_cell.rb', line 113

def type
  :pair
end

#valueObject



16
17
18
# File 'lib/rubylisp/cons_cell.rb', line 16

def value
  self
end

#vector?Boolean

Returns:



104
105
106
# File 'lib/rubylisp/cons_cell.rb', line 104

def vector?
  false
end

#zero?Boolean

Returns:



60
61
62
# File 'lib/rubylisp/cons_cell.rb', line 60

def zero?
  false
end