Class: Lisp::ConsCell
- Includes:
- Enumerable
- Defined in:
- lib/rubylisp/cons_cell.rb
Instance Attribute Summary collapse
-
#car ⇒ Object
readonly
Returns the value of attribute car.
-
#cdr ⇒ Object
readonly
Returns the value of attribute cdr.
Class Method Summary collapse
Instance Method Summary collapse
- #character? ⇒ Boolean
- #each(&block) ⇒ Object
- #empty? ⇒ Boolean
- #eq?(other) ⇒ Boolean
- #equal?(other) ⇒ Boolean
- #eqv?(other) ⇒ Boolean
- #evaluate(env) ⇒ Object
- #evaluate_each(env) ⇒ Object
- #false? ⇒ Boolean
- #flatten ⇒ Object
- #frame? ⇒ Boolean
- #function? ⇒ Boolean
-
#initialize(car = nil, cdr = nil) ⇒ ConsCell
constructor
A new instance of ConsCell.
- #inner_eval(env) ⇒ Object
- #last ⇒ Object
- #length ⇒ Object
- #lisp_object? ⇒ Boolean
- #list? ⇒ Boolean
- #macro? ⇒ Boolean
- #method_missing(name, *args, &block) ⇒ Object
- #negative? ⇒ Boolean
- #nth(n) ⇒ Object
- #nth_tail(n) ⇒ Object
- #number? ⇒ Boolean
- #objc_object_or_nil(obj) ⇒ Object
- #pair? ⇒ Boolean
- #positive? ⇒ Boolean
- #primitive? ⇒ Boolean
- #print_ary(a) ⇒ Object
- #print_string ⇒ Object
- #print_string_helper ⇒ Object
- #quoted ⇒ Object
- #set_car!(d) ⇒ Object
- #set_cdr!(d) ⇒ Object
- #set_nth!(n, d) ⇒ Object
- #special? ⇒ Boolean
- #string? ⇒ Boolean
- #symbol? ⇒ Boolean
- #to_a ⇒ Object
- #to_s ⇒ Object
- #to_s_helper ⇒ Object
- #traverse(path) ⇒ Object
- #true? ⇒ Boolean
- #type ⇒ Object
- #value ⇒ Object
- #vector? ⇒ Boolean
- #zero? ⇒ Boolean
Constructor Details
#initialize(car = nil, cdr = nil) ⇒ ConsCell
Returns a new instance of ConsCell.
12 13 14 15 |
# File 'lib/rubylisp/cons_cell.rb', line 12 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
198 199 200 201 202 203 204 |
# File 'lib/rubylisp/cons_cell.rb', line 198 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
#car ⇒ Object (readonly)
Returns the value of attribute car.
5 6 7 |
# File 'lib/rubylisp/cons_cell.rb', line 5 def car @car end |
#cdr ⇒ Object (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
176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/rubylisp/cons_cell.rb', line 176 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
7 8 9 10 |
# File 'lib/rubylisp/cons_cell.rb', line 7 def self.cons(a=nil, b=nil) b = nil if b.pair? && b.empty? ConsCell.new(a, b) end |
Instance Method Details
#each(&block) ⇒ Object
165 166 167 168 169 170 171 172 173 174 |
# File 'lib/rubylisp/cons_cell.rb', line 165 def each &block return if empty? c = self if self.length > 0 until c.nil? yield c.car c = c.cdr end end end |
#empty? ⇒ Boolean
42 43 44 |
# File 'lib/rubylisp/cons_cell.rb', line 42 def empty? @car.nil? && @cdr.nil? end |
#eq?(other) ⇒ Boolean
106 107 108 109 |
# File 'lib/rubylisp/cons_cell.rb', line 106 def eq?(other) return true if empty? && (other.nil? || (other.pair? && other.empty?)) other.pair? && self == other end |
#equal?(other) ⇒ Boolean
116 117 118 119 120 |
# File 'lib/rubylisp/cons_cell.rb', line 116 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
111 112 113 114 |
# File 'lib/rubylisp/cons_cell.rb', line 111 def eqv?(other) return true if empty? && (other.nil? || (other.pair? && other.empty?)) other.pair? && self == other end |
#evaluate(env) ⇒ Object
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 |
# File 'lib/rubylisp/cons_cell.rb', line 248 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
276 277 278 279 280 281 |
# File 'lib/rubylisp/cons_cell.rb', line 276 def evaluate_each(env) return nil if empty? result = @car.evaluate(env) return result if @cdr.nil? @cdr.evaluate_each(env) end |
#flatten ⇒ Object
313 314 315 316 317 318 319 320 321 322 323 324 325 |
# File 'lib/rubylisp/cons_cell.rb', line 313 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 |
#inner_eval(env) ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
# File 'lib/rubylisp/cons_cell.rb', line 225 def inner_eval(env) func = @car.evaluate(env) return Lisp::Debug.process_error("There is no function or macro named #{@car}", env) if func.nil? env.current_code.unshift(self.print_string()) if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive Lisp::Debug.log_eval(self, env) unless Lisp::Debug.eval_in_debug_repl if !Lisp::Debug.target_env.nil? && env == Lisp::Debug.target_env.previous Lisp::Debug.target_env = nil Lisp::Debug.debug_repl(env) elsif Lisp::Debug.single_step || (func.function? && Lisp::Debug.on_entry.include?(func.name)) Lisp::Debug.debug_repl(env) end end result = func.apply_to(@cdr, env) env.current_code.shift() if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive Lisp::Debug.log_result(result, env) result end |
#last ⇒ Object
301 302 303 304 305 306 307 |
# File 'lib/rubylisp/cons_cell.rb', line 301 def last c = self while !c.cdr.nil? && c.cdr.pair? do c = c.cdr end c end |
#length ⇒ Object
283 284 285 286 287 |
# File 'lib/rubylisp/cons_cell.rb', line 283 def length return 0 if empty? return 1 if @cdr.nil? return 1 + @cdr.length end |
#lisp_object? ⇒ Boolean
25 26 27 |
# File 'lib/rubylisp/cons_cell.rb', line 25 def lisp_object? true end |
#nth(n) ⇒ Object
206 207 208 209 210 |
# File 'lib/rubylisp/cons_cell.rb', line 206 def nth(n) c = self n.times {|i| c = c.cdr} c.car end |
#nth_tail(n) ⇒ Object
212 213 214 215 216 |
# File 'lib/rubylisp/cons_cell.rb', line 212 def nth_tail(n) c = self n.times {|i| c = c.cdr} c end |
#objc_object_or_nil(obj) ⇒ Object
218 219 220 221 |
# File 'lib/rubylisp/cons_cell.rb', line 218 def objc_object_or_nil(obj) return nil unless obj.object? return obj.value end |
#print_ary(a) ⇒ Object
309 310 311 |
# File 'lib/rubylisp/cons_cell.rb', line 309 def print_ary(a) (0...a.length).map {|i| puts (a[i].nil? ? "nil" : a[i])} end |
#print_string ⇒ Object
145 146 147 148 149 150 151 152 |
# File 'lib/rubylisp/cons_cell.rb', line 145 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
141 142 143 |
# File 'lib/rubylisp/cons_cell.rb', line 141 def print_string_helper @cdr.nil? ? "#{@car.print_string}" : "#{@car.print_string} #{@cdr.print_string_helper}" end |
#quoted ⇒ Object
297 298 299 |
# File 'lib/rubylisp/cons_cell.rb', line 297 def quoted Lisp::ConsCell.array_to_list([Symbol.named("quote"), self]) end |
#set_car!(d) ⇒ Object
21 22 23 |
# File 'lib/rubylisp/cons_cell.rb', line 21 def set_car!(d) @car = d end |
#set_cdr!(d) ⇒ Object
29 30 31 |
# File 'lib/rubylisp/cons_cell.rb', line 29 def set_cdr!(d) @cdr = d end |
#set_nth!(n, d) ⇒ Object
34 35 36 37 38 39 |
# File 'lib/rubylisp/cons_cell.rb', line 34 def set_nth!(n, d) return nil if empty? c = self n.times {|i| c = c.cdr} c.set_car!(d) end |
#to_a ⇒ Object
154 155 156 157 158 159 160 161 162 163 |
# File 'lib/rubylisp/cons_cell.rb', line 154 def to_a a = [] return a if empty? c = self until c.nil? a << c.car c = c.cdr end a end |
#to_s ⇒ Object
132 133 134 135 136 137 138 139 |
# File 'lib/rubylisp/cons_cell.rb', line 132 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
126 127 128 129 130 |
# File 'lib/rubylisp/cons_cell.rb', line 126 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
189 190 191 192 193 194 195 196 |
# File 'lib/rubylisp/cons_cell.rb', line 189 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 |
#type ⇒ Object
122 123 124 |
# File 'lib/rubylisp/cons_cell.rb', line 122 def type :pair end |
#value ⇒ Object
17 18 19 |
# File 'lib/rubylisp/cons_cell.rb', line 17 def value self end |