rubymotionlisp 0.2.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +129 -2
- data/lib/rubylisp/atom.rb +25 -6
- data/lib/rubylisp/boolean.rb +9 -6
- data/lib/rubylisp/builtins.rb +33 -0
- data/lib/rubylisp/character.rb +14 -275
- data/lib/rubylisp/class_object.rb +56 -0
- data/lib/rubylisp/cons_cell.rb +50 -20
- data/lib/rubylisp/environment.rb +27 -0
- data/lib/rubylisp/environment_frame.rb +24 -6
- data/lib/rubylisp/eof_object.rb +26 -0
- data/lib/rubylisp/exception.rb +61 -61
- data/lib/rubylisp/ext.rb +32 -6
- data/lib/rubylisp/ffi_new.rb +2 -1
- data/lib/rubylisp/ffi_send.rb +15 -5
- data/lib/rubylisp/frame.rb +5 -164
- data/lib/rubylisp/function.rb +4 -3
- data/lib/rubylisp/macro.rb +13 -8
- data/lib/rubylisp/{object.rb → native_object.rb} +0 -15
- data/lib/rubylisp/number.rb +5 -0
- data/lib/rubylisp/parser.rb +81 -52
- data/lib/rubylisp/port.rb +27 -0
- data/lib/rubylisp/prim_alist.rb +115 -0
- data/lib/rubylisp/prim_assignment.rb +61 -0
- data/lib/rubylisp/prim_character.rb +273 -0
- data/lib/rubylisp/{ffi_class.rb → prim_class_object.rb} +16 -69
- data/lib/rubylisp/prim_environment.rb +203 -0
- data/lib/rubylisp/prim_equivalence.rb +93 -0
- data/lib/rubylisp/prim_frame.rb +166 -0
- data/lib/rubylisp/prim_io.rb +266 -0
- data/lib/rubylisp/prim_list_support.rb +496 -0
- data/lib/rubylisp/{logical.rb → prim_logical.rb} +9 -14
- data/lib/rubylisp/prim_math.rb +397 -0
- data/lib/rubylisp/prim_native_object.rb +21 -0
- data/lib/rubylisp/prim_relational.rb +42 -0
- data/lib/rubylisp/{special_forms.rb → prim_special_forms.rb} +97 -84
- data/lib/rubylisp/prim_string.rb +792 -0
- data/lib/rubylisp/prim_system.rb +55 -0
- data/lib/rubylisp/prim_type_checks.rb +58 -0
- data/lib/rubylisp/prim_vector.rb +497 -0
- data/lib/rubylisp/primitive.rb +51 -6
- data/lib/rubylisp/string.rb +4 -803
- data/lib/rubylisp/symbol.rb +0 -1
- data/lib/rubylisp/tokenizer.rb +160 -136
- data/lib/rubylisp/vector.rb +10 -31
- data/lib/rubymotion/debug.rb +40 -0
- data/lib/rubymotion/require-fix.rb +1 -0
- data/lib/rubymotionlisp.rb +4 -0
- metadata +28 -17
- data/lib/rubylisp/alist.rb +0 -230
- data/lib/rubylisp/assignment.rb +0 -65
- data/lib/rubylisp/equivalence.rb +0 -118
- data/lib/rubylisp/io.rb +0 -74
- data/lib/rubylisp/list_support.rb +0 -526
- data/lib/rubylisp/math.rb +0 -405
- data/lib/rubylisp/motion_builtins.rb +0 -31
- data/lib/rubylisp/relational.rb +0 -46
- data/lib/rubylisp/system.rb +0 -20
- data/lib/rubylisp/testing.rb +0 -136
- data/lib/rubylisp/type_checks.rb +0 -60
data/lib/rubylisp/cons_cell.rb
CHANGED
@@ -5,6 +5,7 @@ module Lisp
|
|
5
5
|
attr_reader :car, :cdr
|
6
6
|
|
7
7
|
def self.cons(a=nil, b=nil)
|
8
|
+
b = nil if b.pair? && b.empty?
|
8
9
|
ConsCell.new(a, b)
|
9
10
|
end
|
10
11
|
|
@@ -31,8 +32,9 @@ module Lisp
|
|
31
32
|
|
32
33
|
|
33
34
|
def set_nth!(n, d)
|
35
|
+
return nil if empty?
|
34
36
|
c = self
|
35
|
-
|
37
|
+
n.times {|i| c = c.cdr}
|
36
38
|
c.set_car!(d)
|
37
39
|
end
|
38
40
|
|
@@ -93,10 +95,6 @@ module Lisp
|
|
93
95
|
true
|
94
96
|
end
|
95
97
|
|
96
|
-
def alist?
|
97
|
-
false
|
98
|
-
end
|
99
|
-
|
100
98
|
def frame?
|
101
99
|
false
|
102
100
|
end
|
@@ -104,10 +102,21 @@ module Lisp
|
|
104
102
|
def vector?
|
105
103
|
false
|
106
104
|
end
|
105
|
+
|
106
|
+
def eq?(other)
|
107
|
+
return true if empty? && (other.nil? || (other.pair? && other.empty?))
|
108
|
+
other.pair? && self == other
|
109
|
+
end
|
110
|
+
|
111
|
+
def eqv?(other)
|
112
|
+
return true if empty? && (other.nil? || (other.pair? && other.empty?))
|
113
|
+
other.pair? && self == other
|
114
|
+
end
|
107
115
|
|
108
|
-
def
|
109
|
-
return
|
110
|
-
|
116
|
+
def equal?(other)
|
117
|
+
return true if empty? && (other.nil? || (other.pair? && other.empty?))
|
118
|
+
return false unless other.pair?
|
119
|
+
@car.equal?(other.car) && @cdr.equal?(other.cdr)
|
111
120
|
end
|
112
121
|
|
113
122
|
def type
|
@@ -124,7 +133,7 @@ module Lisp
|
|
124
133
|
return "()" if self.empty?
|
125
134
|
return "'#{@cdr.car.to_s}" if @car.symbol? && @car.name == "quote"
|
126
135
|
return "{#{@cdr.to_s_helper}}" if @car.symbol? && @car.name == "make-frame"
|
127
|
-
return "
|
136
|
+
return "#(#{@cdr.to_s_helper})" if @car.symbol? && @car.name == "make-vector"
|
128
137
|
return "(#{@car.to_s} . #{@cdr.to_s})" if !@cdr.nil? && !@cdr.pair?
|
129
138
|
return "(#{self.to_s_helper})"
|
130
139
|
end
|
@@ -137,22 +146,24 @@ module Lisp
|
|
137
146
|
return "()" if self.empty?
|
138
147
|
return "'#{@cdr.car.print_string}" if @car.symbol? && @car.name == "quote"
|
139
148
|
return "{#{@cdr.print_string_helper}}" if @car.symbol? && @car.name == "make-frame"
|
140
|
-
return "
|
149
|
+
return "#(#{@cdr.print_string_helper})" if @car.symbol? && @car.name == "make-vector"
|
141
150
|
return "(#{@car.print_string} . #{@cdr.print_string})" if !@cdr.nil? && !@cdr.pair?
|
142
151
|
return "(#{self.print_string_helper})"
|
143
152
|
end
|
144
153
|
|
145
154
|
def to_a
|
146
155
|
a = []
|
156
|
+
return a if empty?
|
147
157
|
c = self
|
148
158
|
until c.nil?
|
149
|
-
a << c.car
|
159
|
+
a << c.car
|
150
160
|
c = c.cdr
|
151
161
|
end
|
152
162
|
a
|
153
163
|
end
|
154
164
|
|
155
165
|
def each &block
|
166
|
+
return if empty?
|
156
167
|
c = self
|
157
168
|
if self.length > 0
|
158
169
|
until c.nil?
|
@@ -163,11 +174,11 @@ module Lisp
|
|
163
174
|
end
|
164
175
|
|
165
176
|
def self.array_to_list(cells, tail=nil)
|
166
|
-
return
|
177
|
+
return cons() if cells.empty? && tail.nil?
|
167
178
|
head = ConsCell.new
|
168
179
|
last_cell = head
|
169
|
-
cells.each do |
|
170
|
-
new_cell = self.cons(
|
180
|
+
(0...cells.length).each do |i|
|
181
|
+
new_cell = self.cons(cells[i], nil)
|
171
182
|
last_cell.set_cdr!(new_cell)
|
172
183
|
last_cell = new_cell
|
173
184
|
end
|
@@ -193,13 +204,13 @@ module Lisp
|
|
193
204
|
|
194
205
|
def nth(n)
|
195
206
|
c = self
|
196
|
-
|
207
|
+
n.times {|i| c = c.cdr}
|
197
208
|
c.car
|
198
209
|
end
|
199
210
|
|
200
211
|
def nth_tail(n)
|
201
212
|
c = self
|
202
|
-
|
213
|
+
n.times {|i| c = c.cdr}
|
203
214
|
c
|
204
215
|
end
|
205
216
|
|
@@ -225,6 +236,7 @@ module Lisp
|
|
225
236
|
Lisp::Debug.debug_repl(env)
|
226
237
|
end
|
227
238
|
end
|
239
|
+
|
228
240
|
result = func.apply_to(@cdr, env)
|
229
241
|
env.current_code.shift() if !Lisp::Debug.eval_in_debug_repl && Lisp::Debug.interactive
|
230
242
|
Lisp::Debug.log_result(result, env)
|
@@ -236,8 +248,8 @@ module Lisp
|
|
236
248
|
return self if empty?
|
237
249
|
sexpr = if @car.symbol?
|
238
250
|
key = @car
|
239
|
-
frame = nth(
|
240
|
-
value = nth(
|
251
|
+
frame = nth(1)
|
252
|
+
value = nth(2)
|
241
253
|
|
242
254
|
s = key.name
|
243
255
|
if s.end_with?(":")
|
@@ -246,6 +258,10 @@ module Lisp
|
|
246
258
|
ConsCell.array_to_list([Symbol.named("set-slot!"), frame, Symbol.named(s[0..-2]), value])
|
247
259
|
elsif s.end_with?(":?")
|
248
260
|
ConsCell.array_to_list([Symbol.named("has-slot?"), frame, Symbol.named(s[0..-2])])
|
261
|
+
elsif s.end_with?(":>")
|
262
|
+
ConsCell.array_to_list([Symbol.named("send"), frame, Symbol.named(s[0..-2])] << self.cdddr)
|
263
|
+
elsif s.end_with?(":^")
|
264
|
+
ConsCell.array_to_list([Symbol.named("send-super"), frame, Symbol.named(s[0..-2])] << self.cdddr)
|
249
265
|
else
|
250
266
|
self
|
251
267
|
end
|
@@ -256,6 +272,7 @@ module Lisp
|
|
256
272
|
end
|
257
273
|
|
258
274
|
def evaluate_each(env)
|
275
|
+
return nil if empty?
|
259
276
|
result = @car.evaluate(env)
|
260
277
|
return result if @cdr.nil?
|
261
278
|
@cdr.evaluate_each(env)
|
@@ -287,9 +304,22 @@ module Lisp
|
|
287
304
|
c
|
288
305
|
end
|
289
306
|
|
307
|
+
def print_ary(a)
|
308
|
+
(0...a.length).map {|i| puts (a[i].nil? ? "nil" : a[i])}
|
309
|
+
end
|
310
|
+
|
290
311
|
def flatten
|
291
|
-
ary =
|
292
|
-
|
312
|
+
ary = []
|
313
|
+
to_a.each do |s|
|
314
|
+
if s.nil?
|
315
|
+
ary << nil
|
316
|
+
elsif s.list?
|
317
|
+
s.to_a.each {|e| ary << e}
|
318
|
+
else
|
319
|
+
ary << s
|
320
|
+
end
|
321
|
+
end
|
322
|
+
ConsCell.array_to_list(ary)
|
293
323
|
end
|
294
324
|
|
295
325
|
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Lisp
|
2
|
+
|
3
|
+
class Environment < Atom
|
4
|
+
|
5
|
+
def self.with_value(e)
|
6
|
+
self.new(e)
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize(e)
|
10
|
+
@value = e
|
11
|
+
end
|
12
|
+
|
13
|
+
def environment?
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def equal?(other)
|
18
|
+
other.environment? && @value == other.value
|
19
|
+
end
|
20
|
+
|
21
|
+
def type
|
22
|
+
:environment
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -2,21 +2,25 @@ module Lisp
|
|
2
2
|
|
3
3
|
class EnvironmentFrame
|
4
4
|
|
5
|
-
attr_accessor :frame, :current_code, :previous
|
5
|
+
attr_accessor :frame, :current_code, :previous, :name
|
6
|
+
attr_reader :parent
|
6
7
|
|
7
8
|
def self.global
|
8
|
-
@@global_frame ||= EnvironmentFrame.new(nil)
|
9
|
+
@@global_frame ||= EnvironmentFrame.new(nil, "GLOBAL")
|
9
10
|
@@global_frame
|
10
11
|
end
|
11
12
|
|
12
|
-
def self.extending(parent, f=nil)
|
13
|
+
def self.extending(parent, name, f=nil)
|
13
14
|
f ||= parent.frame if parent && parent.has_frame?
|
14
|
-
self.new(parent, f)
|
15
|
+
e = self.new(parent, name, f)
|
16
|
+
TopLevelEnvironments[name] = e if parent.nil? || parent == self.global
|
17
|
+
e
|
15
18
|
end
|
16
19
|
|
17
|
-
def initialize(parent, f=nil)
|
20
|
+
def initialize(parent, name, f=nil)
|
18
21
|
@bindings = []
|
19
22
|
@parent = parent
|
23
|
+
@name = name
|
20
24
|
@frame = f
|
21
25
|
@current_code = []
|
22
26
|
end
|
@@ -27,6 +31,14 @@ module Lisp
|
|
27
31
|
|
28
32
|
# Bindings following parent env frame pointer
|
29
33
|
|
34
|
+
def bound_names
|
35
|
+
@bindings.map {|b| b.symbol}
|
36
|
+
end
|
37
|
+
|
38
|
+
def bound_values
|
39
|
+
@bindings.map {|b| b.value}
|
40
|
+
end
|
41
|
+
|
30
42
|
def is_name_bound?(str)
|
31
43
|
if !@frame && @frame.has_slot?(Lisp:Symbol.named("#{str}:", true))
|
32
44
|
return true
|
@@ -38,6 +50,11 @@ module Lisp
|
|
38
50
|
return @parent.is_name_bound?(str)
|
39
51
|
end
|
40
52
|
|
53
|
+
def name_bound_locally?(str)
|
54
|
+
binding = @bindings.detect {|b| b.symbol.name == str}
|
55
|
+
!binding.nil?
|
56
|
+
end
|
57
|
+
|
41
58
|
def binding_for(symbol)
|
42
59
|
binding = @bindings.detect {|b| b.symbol.name == symbol.name}
|
43
60
|
return binding unless binding.nil?
|
@@ -152,8 +169,9 @@ module Lisp
|
|
152
169
|
1 + @previous.depth
|
153
170
|
end
|
154
171
|
end
|
155
|
-
|
172
|
+
|
156
173
|
end
|
157
174
|
|
175
|
+
TopLevelEnvironments = {}
|
158
176
|
|
159
177
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Lisp
|
2
|
+
|
3
|
+
class EofObject < Atom
|
4
|
+
|
5
|
+
def self.instance
|
6
|
+
@instance ||= self.new()
|
7
|
+
end
|
8
|
+
|
9
|
+
def initialize()
|
10
|
+
end
|
11
|
+
|
12
|
+
def type
|
13
|
+
:eof_object
|
14
|
+
end
|
15
|
+
|
16
|
+
def eof_object?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_s
|
21
|
+
"<EOF>"
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/rubylisp/exception.rb
CHANGED
@@ -3,81 +3,81 @@ module Lisp
|
|
3
3
|
class Exception
|
4
4
|
|
5
5
|
def self.register
|
6
|
-
Primitive.register("raise") {|args, env| Lisp::Exception::raise_impl(args, env) }
|
7
|
-
Primitive.register("reraise") {|args, env| Lisp::Exception::reraise_impl(args, env) }
|
8
|
-
Primitive.register("try") {|args, env| Lisp::Exception::try_impl(args, env) }
|
9
|
-
Primitive.register("reraise") {|args, env| Lisp::Exception::reraise_impl(args, env) }
|
10
|
-
Primitive.register("resume") {|args, env| Lisp::Exception::resume_impl(args, env) }
|
11
|
-
Primitive.register("restart") {|args, env| Lisp::Exception::restart_impl(args, env) }
|
6
|
+
# Primitive.register("raise") {|args, env| Lisp::Exception::raise_impl(args, env) }
|
7
|
+
# Primitive.register("reraise") {|args, env| Lisp::Exception::reraise_impl(args, env) }
|
8
|
+
# Primitive.register("try") {|args, env| Lisp::Exception::try_impl(args, env) }
|
9
|
+
# Primitive.register("reraise") {|args, env| Lisp::Exception::reraise_impl(args, env) }
|
10
|
+
# Primitive.register("resume") {|args, env| Lisp::Exception::resume_impl(args, env) }
|
11
|
+
# Primitive.register("restart") {|args, env| Lisp::Exception::restart_impl(args, env) }
|
12
12
|
end
|
13
13
|
|
14
14
|
|
15
|
-
def handler_or_nil(handlers, exception_name)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.do_exception(name, with_message, args, env)
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
15
|
+
# def handler_or_nil(handlers, exception_name)
|
16
|
+
# handlers.each do |handler_pair|
|
17
|
+
# exceptions = handler_pair.car
|
18
|
+
# if exceptions.eq(exception_name) || (exceptions.pair? && exceptions.include?(exception_name))
|
19
|
+
# handler_pair.cdr
|
20
|
+
# else
|
21
|
+
# nil
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
|
26
|
+
# def self.do_exception(name, with_message, args, env)
|
27
|
+
# frame = env
|
28
|
+
# while !frame.nil?
|
29
|
+
# handlers = frame.value_of(Symbol.named("__handlers__"))
|
30
|
+
# unless handlers.nil?
|
31
|
+
# handler = handler_or_nil(handlers, for: name)
|
32
|
+
# unless handler.nil?
|
33
|
+
# handler.apply_to_without_evaluating(args, frame)
|
34
|
+
# break
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# frame = frame.parent
|
38
|
+
# if frame.nil?
|
39
|
+
# exception_message = message.empty? ? "" : ": #{message}"
|
40
|
+
# return Lisp::Debug.process_error("Unhandled Exception: #{exception_name}#{exception_message}", env)
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
# end
|
44
44
|
|
45
45
|
def self.raise_impl(args, env)
|
46
|
-
return Lisp::Debug.process_error("'raise' requires at least one argument.", env) unless args.length > 0
|
47
|
-
exception_name = args.car.evaluate(env)
|
48
|
-
return Lisp::Debug.process_error("'raise' requires an exception name as it's first argument.", env) unless exception_name.string? || class_name.symbol?
|
46
|
+
# return Lisp::Debug.process_error("'raise' requires at least one argument.", env) unless args.length > 0
|
47
|
+
# exception_name = args.car.evaluate(env)
|
48
|
+
# return Lisp::Debug.process_error("'raise' requires an exception name as it's first argument.", env) unless exception_name.string? || class_name.symbol?
|
49
49
|
|
50
|
-
message = ""
|
51
|
-
if args.length > 1
|
52
|
-
|
53
|
-
|
54
|
-
end
|
50
|
+
# message = ""
|
51
|
+
# if args.length > 1
|
52
|
+
# message = args.cadr.evaluate(env)
|
53
|
+
# return Lisp::Debug.process_error("The message parameter to 'raise' must be a string.", env) unless message.string?
|
54
|
+
# end
|
55
55
|
|
56
|
-
handler_args = args.length > 2 ? Lisp::ConsCell.array_to_list(args.cdr.to_a.collect {|a| a.evaluate(env)}) : Lisp::ConsCell.new
|
56
|
+
# handler_args = args.length > 2 ? Lisp::ConsCell.array_to_list(args.cdr.to_a.collect {|a| a.evaluate(env)}) : Lisp::ConsCell.new
|
57
57
|
end
|
58
58
|
|
59
59
|
|
60
60
|
def self.try_impl(args, env)
|
61
|
-
raw_handlers = args.car
|
62
|
-
body = args.cdr
|
61
|
+
# raw_handlers = args.car
|
62
|
+
# body = args.cdr
|
63
63
|
|
64
|
-
return Lisp::Debug.process_error("Exception handlers must be a list.", env) unless raw_handlers.list?
|
65
|
-
return Lisp::Debug.process_error("Exception handlers must be a list of pairs.", env) unless raw_handlers.all? {|h| h.list?}
|
66
|
-
return Lisp::Debug.process_error("Exception clause must be a symbol/string or a list of symbol/string.", env) unless raw_handlers.all? do |h|
|
67
|
-
|
68
|
-
|
69
|
-
end
|
64
|
+
# return Lisp::Debug.process_error("Exception handlers must be a list.", env) unless raw_handlers.list?
|
65
|
+
# return Lisp::Debug.process_error("Exception handlers must be a list of pairs.", env) unless raw_handlers.all? {|h| h.list?}
|
66
|
+
# return Lisp::Debug.process_error("Exception clause must be a symbol/string or a list of symbol/string.", env) unless raw_handlers.all? do |h|
|
67
|
+
# ex = h.car
|
68
|
+
# ex.symbol? || ex.string? || (ex.list? && ex.all? {|h2| h2.symbol? || h2.string?})
|
69
|
+
# end
|
70
70
|
|
71
|
-
array_of_handlers = raw_handlers.to_a.collect do |h|
|
72
|
-
|
73
|
-
|
74
|
-
return Lisp::Debug.process_error("Exception handler has to be a function.", env) unless f.function?
|
75
|
-
|
76
|
-
end
|
77
|
-
handlers = Lisp::ConsCell.array_to_list(array_of_handlers)
|
78
|
-
env.bind_locally(Symbol.named("__handlers__"), handlers)
|
71
|
+
# array_of_handlers = raw_handlers.to_a.collect do |h|
|
72
|
+
# ex = h.car
|
73
|
+
# f = h.cadr.evaluate(env)
|
74
|
+
# return Lisp::Debug.process_error("Exception handler has to be a function.", env) unless f.function?
|
75
|
+
# Lisp::ConsCell.cons(ex, f)
|
76
|
+
# end
|
77
|
+
# handlers = Lisp::ConsCell.array_to_list(array_of_handlers)
|
78
|
+
# env.bind_locally(Symbol.named("__handlers__"), handlers)
|
79
79
|
|
80
|
-
body.evaluate_each(env)
|
80
|
+
# body.evaluate_each(env)
|
81
81
|
end
|
82
82
|
|
83
83
|
|
data/lib/rubylisp/ext.rb
CHANGED
@@ -5,15 +5,29 @@ class NilClass
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def false?
|
8
|
-
|
8
|
+
false
|
9
9
|
end
|
10
10
|
|
11
11
|
def to_s
|
12
12
|
"()"
|
13
13
|
end
|
14
14
|
|
15
|
+
|
16
|
+
def to_ary
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
|
21
|
+
def eqv?(other)
|
22
|
+
other.nil? || (other.pair? && other.empty?)
|
23
|
+
end
|
24
|
+
|
15
25
|
def eq?(other)
|
16
|
-
other.nil?
|
26
|
+
other.nil? || (other.pair? && other.empty?)
|
27
|
+
end
|
28
|
+
|
29
|
+
def equal?(other)
|
30
|
+
other.nil? || (other.pair? && other.empty?)
|
17
31
|
end
|
18
32
|
|
19
33
|
def print_string
|
@@ -84,14 +98,25 @@ class NilClass
|
|
84
98
|
true
|
85
99
|
end
|
86
100
|
|
101
|
+
def vector?
|
102
|
+
false
|
103
|
+
end
|
104
|
+
|
105
|
+
def environment?
|
106
|
+
false
|
107
|
+
end
|
108
|
+
|
87
109
|
def method_missing(name, *args, &block)
|
88
|
-
|
110
|
+
is_list_walk = name[0] == ?c && name[-1] == ?r && (name[1..-2].chars.all? {|e| "ad".include?(e)})
|
111
|
+
if is_list_walk
|
89
112
|
nil
|
90
113
|
else
|
114
|
+
#puts "nil#method_missing name: #{name} args #{args}"
|
115
|
+
#puts caller
|
91
116
|
super
|
92
117
|
end
|
93
118
|
end
|
94
|
-
|
119
|
+
|
95
120
|
def primitive?
|
96
121
|
false
|
97
122
|
end
|
@@ -112,8 +137,9 @@ class NilClass
|
|
112
137
|
true
|
113
138
|
end
|
114
139
|
|
115
|
-
|
116
|
-
|
140
|
+
def flatten
|
141
|
+
nil
|
142
|
+
end
|
117
143
|
end
|
118
144
|
|
119
145
|
|
data/lib/rubylisp/ffi_new.rb
CHANGED
@@ -4,14 +4,15 @@ module Lisp
|
|
4
4
|
|
5
5
|
def initialize(name)
|
6
6
|
@value = name
|
7
|
-
@klass = Object.const_get(name)
|
8
7
|
end
|
9
8
|
|
10
9
|
def apply_to(args, env)
|
10
|
+
@klass = Object.const_get(@value)
|
11
11
|
NativeObject.with_value(@klass.new)
|
12
12
|
end
|
13
13
|
|
14
14
|
def apply_to_without_evaluating(args, env)
|
15
|
+
@klass = Object.const_get(@value)
|
15
16
|
NativeObject.with_value(@klass.new)
|
16
17
|
end
|
17
18
|
|
data/lib/rubylisp/ffi_send.rb
CHANGED
@@ -10,7 +10,9 @@ module Lisp
|
|
10
10
|
apply_to_without_evaluating(Lisp::ConsCell.array_to_list(args.to_a.map {|a| a.evaluate(env)}), env)
|
11
11
|
end
|
12
12
|
|
13
|
+
# convert a rubymotion arg to a lisp arg
|
13
14
|
def convert_value(value)
|
15
|
+
#puts "convert_value(#{value.to_s})\n"
|
14
16
|
case value.class.name
|
15
17
|
when "Fixnum", "Float"
|
16
18
|
Lisp::Number.with_value(value)
|
@@ -30,11 +32,17 @@ module Lisp
|
|
30
32
|
end
|
31
33
|
|
32
34
|
|
35
|
+
# convert a lisp arg to a rubymotion arg
|
33
36
|
def process_arg(a, env)
|
37
|
+
#puts "process_arg(#{a.to_s})"
|
34
38
|
if a.function?
|
35
|
-
|
36
|
-
|
37
|
-
|
39
|
+
#puts "function arg"
|
40
|
+
proc do #|*args|
|
41
|
+
#puts "Proc argument invoked"
|
42
|
+
# arg_list = args.empty? ? nil : Lisp::ConsCell.array_to_list(args.collect {|arg| convert_value(arg) })
|
43
|
+
# puts "Applying #{@a.to_s} to #{arg_list}"
|
44
|
+
|
45
|
+
a.apply_to(nil, env)
|
38
46
|
end
|
39
47
|
elsif a.list?
|
40
48
|
a.to_a.map {|i| process_arg(i, env)}
|
@@ -49,6 +57,8 @@ module Lisp
|
|
49
57
|
return Lisp::Debug.process_error("Send target of '#{@value}' evaluated to nil.", env) if target.nil?
|
50
58
|
return Lisp::Debug.process_error("Target of an FFI send of '#{@value}' must be a wrapped ObjC object, was #{target}", env) unless target.object?
|
51
59
|
|
60
|
+
# puts "Sending #{@value} to #{target.to_s} with raw args #{args}"
|
61
|
+
|
52
62
|
arguments = args.cdr.nil? ? [] : args.cdr.to_a.map {|a| process_arg(a, env)}
|
53
63
|
result = nil
|
54
64
|
|
@@ -56,11 +66,11 @@ module Lisp
|
|
56
66
|
result = if arguments[-1].instance_of?(Proc)
|
57
67
|
target.value.send(@value, *(arguments[0..-2]), &arguments[-1])
|
58
68
|
else
|
59
|
-
#
|
69
|
+
# puts "Sending #{@value} to #{target} with processed args #{arguments}"
|
60
70
|
target.value.send(@value, *arguments)
|
61
71
|
end
|
62
72
|
rescue Exception => e
|
63
|
-
return Lisp::Debug.process_error("Exception sending #{@value}
|
73
|
+
return Lisp::Debug.process_error("Exception sending #{@value} - #{e.name}", env)
|
64
74
|
end
|
65
75
|
|
66
76
|
convert_value(result)
|