rubymotionlisp 0.2.2 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|