rubylisp 0.1.1 → 0.2.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.
data/lib/rubylisp/io.rb CHANGED
@@ -13,9 +13,9 @@ module Lisp
13
13
 
14
14
 
15
15
  def self.load_impl(args, env)
16
- raise "'load' requires 1 argument." if args.empty?
16
+ return Lisp::Debug.process_error("'load' requires 1 argument.", env) if args.empty?
17
17
  fname = args.car.evaluate(env)
18
- raise "'load' requires a string argument." unless fname.string?
18
+ return Lisp::Debug.process_error("'load' requires a string argument.", env) unless fname.string?
19
19
  filename = fname.value.end_with?(".lsp") ? fname.value : "#{fname.value}.lsp"
20
20
  File.open(filename) do |f|
21
21
  contents = f.read()
@@ -26,9 +26,9 @@ module Lisp
26
26
 
27
27
 
28
28
  def self.load_library_impl(args, env)
29
- raise "'load-library' requires 1 argument." if args.empty?
29
+ return Lisp::Debug.process_error("'load-library' requires 1 argument.", env) if args.empty?
30
30
  library_name = args.car.evaluate(env)
31
- raise "'load-library' requires a string or symbol argument." unless library_name.string? || library_name.symbol?
31
+ return Lisp::Debug.process_error("'load-library' requires a string or symbol argument.", env) unless library_name.string? || library_name.symbol?
32
32
  Dir.chdir(File.join(App.documents_path, "libraries", "#{library_name}.lib")) do |d|
33
33
  if File.exists?("load.lsp")
34
34
  File.open("load.lsp") do |f|
@@ -49,9 +49,9 @@ module Lisp
49
49
 
50
50
 
51
51
  def self.load_project_impl(args, env)
52
- raise "'load-project' requires 1 argument." if args.empty?
52
+ return Lisp::Debug.process_error("'load-project' requires 1 argument.", env) if args.empty?
53
53
  project_name = args.car.evaluate(env)
54
- raise "'load-project' requires a string or symbol argument." unless project_name.string? || project_name.symbol?
54
+ return Lisp::Debug.process_error("'load-project' requires a string or symbol argument.", env) unless project_name.string? || project_name.symbol?
55
55
  Dir.chdir(File.join(App.documents_path, "projects", "#{project_name}.prj")) do |d|
56
56
  if File.exists?("load.lsp")
57
57
  File.open("load.lsp") do |f|
@@ -59,7 +59,7 @@ module Lisp
59
59
 
60
60
 
61
61
  def self.cons_impl(args, env)
62
- raise "cons requires two arguments." unless args.length == 2
62
+ return Lisp::Debug.process_error("cons requires two arguments.", env) unless args.length == 2
63
63
  left = args.car.evaluate(env)
64
64
  right = args.cadr.evaluate(env)
65
65
  Lisp::ConsCell.cons(left, right)
@@ -85,9 +85,9 @@ module Lisp
85
85
 
86
86
 
87
87
  def self.make_list_impl(args, env)
88
- raise "consmake-list requires one or two arguments." unless args.length == 1 || args.length == 2
88
+ return Lisp::Debug.process_error("consmake-list requires one or two arguments.", env) unless args.length == 1 || args.length == 2
89
89
  arg1 = args.car.evaluate(env)
90
- raise "make-list requires an integer for it's first argument, received: #{args.car}" unless arg1.integer?
90
+ return Lisp::Debug.process_error("make-list requires an integer for it's first argument, received: #{args.car}", env) unless arg1.integer?
91
91
  count = arg1.value
92
92
  val = if args.length == 1
93
93
  nil
@@ -101,16 +101,16 @@ module Lisp
101
101
 
102
102
 
103
103
  def self.iota_impl(args, env)
104
- raise "iota requires at least one argument." unless args.length > 0
104
+ return Lisp::Debug.process_error("iota requires at least one argument.", env) unless args.length > 0
105
105
  arg1 = args.car.evaluate(env)
106
- raise "iota requires an positive integer for it's first argument, received: #{args.car}" unless arg1.integer? && arg1.positive?
106
+ return Lisp::Debug.process_error("iota requires an positive integer for it's first argument, received: #{args.car}", env) unless arg1.integer? && arg1.positive?
107
107
  count = arg1.value
108
108
 
109
109
  start = if args.length < 2
110
110
  0
111
111
  else
112
112
  arg2 = args.cadr.evaluate(env)
113
- raise "iota requires an number for it's second argument, received: #{args.cadr}" unless arg2.number?
113
+ return Lisp::Debug.process_error("iota requires an number for it's second argument, received: #{args.cadr}", env) unless arg2.number?
114
114
  arg2.value
115
115
  end
116
116
 
@@ -118,7 +118,7 @@ module Lisp
118
118
  1
119
119
  else
120
120
  arg3 = args.caddr.evaluate(env)
121
- raise "iota requires an number for it's third argument, received: #{args.caddr}" unless arg3.number?
121
+ return Lisp::Debug.process_error("iota requires an number for it's third argument, received: #{args.caddr}", env) unless arg3.number?
122
122
  arg3.value
123
123
  end
124
124
 
@@ -140,22 +140,22 @@ module Lisp
140
140
  # in support of all the CxR functions
141
141
  def self.ad_impl(args, env, f)
142
142
  l = args.car.evaluate(env)
143
- raise "list required." unless l.list?
143
+ return Lisp::Debug.process_error("list required.", env) unless l.list?
144
144
  l.send(f)
145
145
  end
146
146
 
147
147
 
148
148
  def self.first_impl(args, env)
149
149
  l = args.car.evaluate(env)
150
- raise "rest requires a list or vector." unless l.list? || l.vector?
151
- raise "list index out of bounds" unless l.length >= 1
150
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
151
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 1
152
152
  l.nth(1)
153
153
  end
154
154
 
155
155
 
156
156
  def self.rest_impl(args, env)
157
157
  l = args.car.evaluate(env)
158
- raise "rest requires a list or vector." unless l.list? || l.vector?
158
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
159
159
  if l.list?
160
160
  l.cdr
161
161
  else
@@ -166,82 +166,82 @@ module Lisp
166
166
 
167
167
  def self.second_impl(args, env)
168
168
  l = args.car.evaluate(env)
169
- raise "rest requires a list or vector." unless l.list? || l.vector?
170
- raise "list index out of bounds" unless l.length >= 2
169
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
170
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 2
171
171
  l.nth(2)
172
172
  end
173
173
 
174
174
  def self.third_impl(args, env)
175
175
  l = args.car.evaluate(env)
176
- raise "rest requires a list or vector." unless l.list? || l.vector?
177
- raise "list index out of bounds" unless l.length >= 3
176
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
177
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 3
178
178
  l.nth(3)
179
179
  end
180
180
 
181
181
 
182
182
  def self.fourth_impl(args, env)
183
183
  l = args.car.evaluate(env)
184
- raise "rest requires a list or vector." unless l.list? || l.vector?
185
- raise "list index out of bounds" unless l.length >= 4
184
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
185
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 4
186
186
  l.nth(4)
187
187
  end
188
188
 
189
189
 
190
190
  def self.fifth_impl(args, env)
191
191
  l = args.car.evaluate(env)
192
- raise "rest requires a list or vector." unless l.list? || l.vector?
193
- raise "list index out of bounds" unless l.length >= 5
192
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
193
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 5
194
194
  l.nth(5)
195
195
  end
196
196
 
197
197
 
198
198
  def self.sixth_impl(args, env)
199
199
  l = args.car.evaluate(env)
200
- raise "rest requires a list or vector." unless l.list? || l.vector?
201
- raise "list index out of bounds" unless l.length >= 6
200
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
201
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 6
202
202
  l.nth(6)
203
203
  end
204
204
 
205
205
 
206
206
  def self.seventh_impl(args, env)
207
207
  l = args.car.evaluate(env)
208
- raise "rest requires a list or vector." unless l.list? || l.vector?
209
- raise "list index out of bounds" unless l.length >= 7
208
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
209
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 7
210
210
  l.nth(7)
211
211
  end
212
212
 
213
213
 
214
214
  def self.eighth_impl(args, env)
215
215
  l = args.car.evaluate(env)
216
- raise "rest requires a list or vector." unless l.list? || l.vector?
217
- raise "list index out of bounds" unless l.length >= 8
216
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
217
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 8
218
218
  l.nth(8)
219
219
  end
220
220
 
221
221
 
222
222
  def self.ninth_impl(args, env)
223
223
  l = args.car.evaluate(env)
224
- raise "rest requires a list or vector." unless l.list? || l.vector?
225
- raise "list index out of bounds" unless l.length >= 9
224
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
225
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 9
226
226
  l.nth(9)
227
227
  end
228
228
 
229
229
 
230
230
  def self.tenth_impl(args, env)
231
231
  l = args.car.evaluate(env)
232
- raise "rest requires a list or vector." unless l.list? || l.vector?
233
- raise "list index out of bounds" unless l.length >= 10
232
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
233
+ return Lisp::Debug.process_error("list index out of bounds", env) unless l.length >= 10
234
234
  l.nth(10)
235
235
  end
236
236
 
237
237
 
238
238
  def self.nth_impl(args, env)
239
- raise "nth requires 2 arguments" unless args.length == 2
239
+ return Lisp::Debug.process_error("nth requires 2 arguments", env) unless args.length == 2
240
240
  n = args.car.evaluate(env)
241
- raise "The first argument of nth has to be an number." unless n.number?
242
- raise "The first argument of nth has to be positive." unless n.value > 0
241
+ return Lisp::Debug.process_error("The first argument of nth has to be an number.", env) unless n.number?
242
+ return Lisp::Debug.process_error("The first argument of nth has to be positive.", env) unless n.value > 0
243
243
  l = args.cadr.evaluate(env)
244
- raise "rest requires a list or vector." unless l.list? || l.vector?
244
+ return Lisp::Debug.process_error("rest requires a list or vector.", env) unless l.list? || l.vector?
245
245
  l.nth(n.value)
246
246
  end
247
247
 
@@ -256,78 +256,77 @@ module Lisp
256
256
 
257
257
 
258
258
  def self.sublist_impl(args, env)
259
- raise "sublist requires 3 arguments" unless args.length == 3
259
+ return Lisp::Debug.process_error("sublist requires 3 arguments", env) unless args.length == 3
260
260
  l = args.car.evaluate(env)
261
- raise "sublist requires it's first argument to be a list or vector, but received #{args.car}" unless l.list? || l.vector?
261
+ return Lisp::Debug.process_error("sublist requires it's first argument to be a list or vector, but received #{args.car}", env) unless l.list? || l.vector?
262
262
  st = args.cadr.evaluate(env)
263
- raise "sublist requires it's second argument to be a positive integer, but received #{args.cadr}" unless st.number? && st.positive?
264
- raise "sublist requires it's second argument to be <= the list length" unless st.value <= l.length
263
+ return Lisp::Debug.process_error("sublist requires it's second argument to be a positive integer, but received #{args.cadr}", env) unless st.number? && st.positive?
264
+ return Lisp::Debug.process_error("sublist requires it's second argument to be <= the list length", env) unless st.value <= l.length
265
265
  en = args.caddr.evaluate(env)
266
- raise "sublist requires it's third argument to be a positive integer, but received #{args.caddr}" unless en.number? && en.positive?
267
- raise "sublist requires it's third argument to be <= the list length" unless en.value <= l.length
268
- raise "sublist requires it's second argument to be <= the third argument" unless st.value <= en.value
266
+ return Lisp::Debug.process_error("sublist requires it's third argument to be a positive integer, but received #{args.caddr}", env) unless en.number? && en.positive?
267
+ return Lisp::Debug.process_error("sublist requires it's third argument to be <= the list length", env) unless en.value <= l.length
268
+ return Lisp::Debug.process_error("sublist requires it's second argument to be <= the third argument", env) unless st.value <= en.value
269
269
  make_same_kind_as(l, l.to_a[(st.value - 1)...en.value])
270
270
  end
271
271
 
272
272
 
273
273
  def self.list_head_impl(args, env)
274
- raise "list_head requires 2 arguments" unless args.length == 2
274
+ return Lisp::Debug.process_error("list_head requires 2 arguments", env) unless args.length == 2
275
275
  l = args.car.evaluate(env)
276
- raise "list_head requires it's first argument to be a list, but received #{args.car}" unless l.list?
276
+ return Lisp::Debug.process_error("list_head requires it's first argument to be a list, but received #{args.car}", env) unless l.list?
277
277
  k = args.cadr.evaluate(env)
278
- raise "list_head requires it's second argument to be a positive integer, but received #{args.cadr}" unless k.number? && k.positive?
279
- raise "list_head requires it's second argument to be <= the list length" unless k.value <= l.length
278
+ return Lisp::Debug.process_error("list_head requires it's second argument to be a positive integer, but received #{args.cadr}", env) unless k.number? && k.positive?
279
+ return Lisp::Debug.process_error("list_head requires it's second argument to be <= the list length", env) unless k.value <= l.length
280
280
  Lisp::ConsCell.array_to_list(l.to_a[0...k.value])
281
281
  end
282
282
 
283
283
 
284
284
  def self.take_impl(args, env)
285
- raise "take requires 2 arguments" unless args.length == 2
285
+ return Lisp::Debug.process_error("take requires 2 arguments", env) unless args.length == 2
286
286
  k = args.car.evaluate(env)
287
- raise "take requires it's first argument to be an integer >= 0, but received #{args.car}" unless k.number? && !k.negative?
287
+ return Lisp::Debug.process_error("take requires it's first argument to be an integer >= 0, but received #{args.car}", env) unless k.number? && !k.negative?
288
288
  l = args.cadr.evaluate(env)
289
- raise "take requires it's second argument to be a list or vector, but received #{args.cadr}" unless l.list? || l.vector?
290
- raise "take requires it's first argument to be <= the list length" unless k.value <= l.length
291
- puts l
289
+ return Lisp::Debug.process_error("take requires it's second argument to be a list or vector, but received #{args.cadr}", env) unless l.list? || l.vector?
290
+ return Lisp::Debug.process_error("take requires it's first argument to be <= the list length", env) unless k.value <= l.length
292
291
  make_same_kind_as(l, l.to_a[0...k.value])
293
292
  end
294
293
 
295
294
 
296
295
  def self.list_tail_impl(args, env)
297
- raise "list_head requires 2 arguments" unless args.length == 2
296
+ return Lisp::Debug.process_error("list_head requires 2 arguments", env) unless args.length == 2
298
297
  l = args.car.evaluate(env)
299
- raise "list_head requires it's first argument to be a list, but received #{args.car}" unless l.list?
298
+ return Lisp::Debug.process_error("list_head requires it's first argument to be a list, but received #{args.car}", env) unless l.list?
300
299
  k = args.cadr.evaluate(env)
301
- raise "list_head requires it's second argument to be a positive integer, but received #{args.cadr}" unless k.number? && k.positive?
302
- raise "list_head requires it's second argument to be <= the list length" unless k.value <= l.length
300
+ return Lisp::Debug.process_error("list_head requires it's second argument to be a positive integer, but received #{args.cadr}", env) unless k.number? && k.positive?
301
+ return Lisp::Debug.process_error("list_head requires it's second argument to be <= the list length", env) unless k.value <= l.length
303
302
  l.nth_tail(k.value + 1)
304
303
  end
305
304
 
306
305
 
307
306
  def self.drop_impl(args, env)
308
- raise "drop requires 2 arguments" unless args.length == 2
307
+ return Lisp::Debug.process_error("drop requires 2 arguments", env) unless args.length == 2
309
308
  k = args.car.evaluate(env)
310
- raise "drop requires it's first argument to be an integer >= 0, but received #{args.car}" unless k.number? && !k.negative?
309
+ return Lisp::Debug.process_error("drop requires it's first argument to be an integer >= 0, but received #{args.car}", env) unless k.number? && !k.negative?
311
310
  l = args.cadr.evaluate(env)
312
- raise "drop requires it's second argument to be a list or vector, but received #{args.cadr}" unless l.list? || l.vector?
313
- raise "drop requires it's first argument to be <= the list length" unless k.value <= l.length
311
+ return Lisp::Debug.process_error("drop requires it's second argument to be a list or vector, but received #{args.cadr}", env) unless l.list? || l.vector?
312
+ return Lisp::Debug.process_error("drop requires it's first argument to be <= the list length", env) unless k.value <= l.length
314
313
  l.nth_tail(k.value + 1)
315
314
  end
316
315
 
317
316
 
318
317
  def self.last_pair_impl(args, env)
319
- raise "last_pair requires 1 arguments" unless args.length == 1
318
+ return Lisp::Debug.process_error("last_pair requires 1 arguments", env) unless args.length == 1
320
319
  l = args.car.evaluate(env)
321
- raise "last_pair requires it's argument to be a list, but received #{args.car}" unless l.list?
320
+ return Lisp::Debug.process_error("last_pair requires it's argument to be a list, but received #{args.car}", env) unless l.list?
322
321
  l.last
323
322
  end
324
323
 
325
324
 
326
325
  def self.memq_impl(args, env)
327
- raise "memq requires 2 arguments but received #{args.length}." unless args.length == 2
326
+ return Lisp::Debug.process_error("memq requires 2 arguments but received #{args.length}.", env) unless args.length == 2
328
327
  item = args.car.evaluate(env)
329
328
  collection = args.cadr.evaluate(env)
330
- raise "memq requires a list as it's second argument." unless collection.list?
329
+ return Lisp::Debug.process_error("memq requires a list as it's second argument.", env) unless collection.list?
331
330
  collection.length.times do |i|
332
331
  if Lisp::Equivalence.eq_check(item, collection.nth(i + 1)).value
333
332
  return collection.nth_tail(i + 1)
@@ -338,10 +337,10 @@ module Lisp
338
337
 
339
338
 
340
339
  def self.memv_impl(args, env)
341
- raise "memv requires 2 arguments but received #{args.length}." unless args.length == 2
340
+ return Lisp::Debug.process_error("memv requires 2 arguments but received #{args.length}.", env) unless args.length == 2
342
341
  item = args.car.evaluate(env)
343
342
  collection = args.cadr.evaluate(env)
344
- raise "memv requires a list as it's second argument." unless collection.list?
343
+ return Lisp::Debug.process_error("memv requires a list as it's second argument.", env) unless collection.list?
345
344
  collection.length.times do |i|
346
345
  if Lisp::Equivalence.eqv_check(item, collection.nth(i + 1)).value
347
346
  return collection.nth_tail(i + 1)
@@ -352,10 +351,10 @@ module Lisp
352
351
 
353
352
 
354
353
  def self.member_impl(args, env)
355
- raise "member requires 2 arguments but received #{args.length}." unless args.length == 2
354
+ return Lisp::Debug.process_error("member requires 2 arguments but received #{args.length}.", env) unless args.length == 2
356
355
  item = args.car.evaluate(env)
357
356
  collection = args.cadr.evaluate(env)
358
- raise "member requires a list as it's second argument." unless collection.list?
357
+ return Lisp::Debug.process_error("member requires a list as it's second argument.", env) unless collection.list?
359
358
  collection.length.times do |i|
360
359
  if Lisp::Equivalence.equal_check(item, collection.nth(i + 1)).value
361
360
  return collection.nth_tail(i + 1)
@@ -366,33 +365,33 @@ module Lisp
366
365
 
367
366
 
368
367
  def self.filter_impl(args, env)
369
- raise "filter requires 2 arguments but received #{args.length}." unless args.length == 2
368
+ return Lisp::Debug.process_error("filter requires 2 arguments but received #{args.length}.", env) unless args.length == 2
370
369
  f = args.car.evaluate(env)
371
- raise "filter requires a function as it's first argument but received #{args.car}." unless f.function? || f.primitive?
370
+ return Lisp::Debug.process_error("filter requires a function as it's first argument but received #{args.car}.", env) unless f.function? || f.primitive?
372
371
  collection = args.cadr.evaluate(env)
373
- raise "filter requires a list or vector as it's second argument but received #{args.cadr}." unless collection.list? || collection.vector?
372
+ return Lisp::Debug.process_error("filter requires a list or vector as it's second argument but received #{args.cadr}.", env) unless collection.list? || collection.vector?
374
373
  results = collection.to_a.select {|item| f.apply_to_without_evaluating(Lisp::ConsCell.cons(item, nil), env).value }
375
374
  make_same_kind_as(collection, results)
376
375
  end
377
376
 
378
377
 
379
378
  def self.remove_impl(args, env)
380
- raise "remove requires 2 arguments but received #{args.length}." unless args.length == 2
379
+ return Lisp::Debug.process_error("remove requires 2 arguments but received #{args.length}.", env) unless args.length == 2
381
380
  f = args.car.evaluate(env)
382
- raise "remove requires a function as it's first argument but received #{args.car}." unless f.function? || f.primitive?
381
+ return Lisp::Debug.process_error("remove requires a function as it's first argument but received #{args.car}.", env) unless f.function? || f.primitive?
383
382
  collection = args.cadr.evaluate(env)
384
- raise "remove requires a list or vector as it's second argument but received #{args.cadr}." unless collection.list? || collection.vector?
383
+ return Lisp::Debug.process_error("remove requires a list or vector as it's second argument but received #{args.cadr}.", env) unless collection.list? || collection.vector?
385
384
  results = collection.to_a.reject {|item| f.apply_to_without_evaluating(Lisp::ConsCell.cons(item, nil), env).value }
386
385
  make_same_kind_as(collection, results)
387
386
  end
388
387
 
389
388
 
390
389
  def self.partition_impl(args, env)
391
- raise "partition requires 2 arguments but received #{args.length}." unless args.length == 2
390
+ return Lisp::Debug.process_error("partition requires 2 arguments but received #{args.length}.", env) unless args.length == 2
392
391
  f = args.car.evaluate(env)
393
- raise "partition requires a function as it's first argument." unless f.function? || f.primitive?
392
+ return Lisp::Debug.process_error("partition requires a function as it's first argument.", env) unless f.function? || f.primitive?
394
393
  collection = args.cadr.evaluate(env)
395
- raise "partition requires a list as it's second argument." unless collection.list? | collection.vector?
394
+ return Lisp::Debug.process_error("partition requires a list as it's second argument.", env) unless collection.list? | collection.vector?
396
395
  results = collection.to_a.partition {|item| f.apply_to_without_evaluating(Lisp::ConsCell.cons(item, nil), env).value }
397
396
  matches = make_same_kind_as(collection, results[0])
398
397
  non_matches = make_same_kind_as(collection, results[1])
@@ -401,11 +400,11 @@ module Lisp
401
400
 
402
401
 
403
402
  def self.map_impl(args, env)
404
- raise "map requires at least 2 arguments but received #{args.length}." if args.length < 2
403
+ return Lisp::Debug.process_error("map requires at least 2 arguments but received #{args.length}.", env) if args.length < 2
405
404
  f = args.car.evaluate(env)
406
- raise "map requires a function as it's first argument but received #{args.car}." unless f.function? || f.primitive?
405
+ return Lisp::Debug.process_error("map requires a function as it's first argument but received #{args.car}.", env) unless f.function? || f.primitive?
407
406
  collections = args.cdr.to_a.collect {|a| a.evaluate(env)}
408
- raise "all requires all subsequent arguments to be lists or vectors" unless collections.all? {|l| l.list? || l.vector?}
407
+ return Lisp::Debug.process_error("all requires all subsequent arguments to be lists or vectors", env) unless collections.all? {|l| l.list? || l.vector?}
409
408
  all_vectors = collections.all? {|i| i.vector?}
410
409
  lists = collections.collect {|l| l.to_a }
411
410
 
@@ -430,12 +429,12 @@ module Lisp
430
429
 
431
430
 
432
431
  def self.reduce_left_impl(args, env)
433
- raise "reduce requires 3 arguments but received #{args.length}." unless args.length == 3
432
+ return Lisp::Debug.process_error("reduce requires 3 arguments but received #{args.length}.", env) unless args.length == 3
434
433
  f = args.car.evaluate(env)
435
- raise "map requires a function as it's first argument but received #{args.car}." unless f.function? || f.primitive?
434
+ return Lisp::Debug.process_error("map requires a function as it's first argument but received #{args.car}.", env) unless f.function? || f.primitive?
436
435
  initial = args.cadr.evaluate(env)
437
436
  collection = args.caddr.evaluate(env)
438
- raise "reduce requires a list or vector as it's third argument but received #{args.caddr}." unless collection.list? || collection.vector?
437
+ return Lisp::Debug.process_error("reduce requires a list or vector as it's third argument but received #{args.caddr}.", env) unless collection.list? || collection.vector?
439
438
  return initial if collection.empty?
440
439
  return collection.nth(1) if collection.length == 1
441
440
  result = collection.to_a.inject do |acc, item|
@@ -446,11 +445,11 @@ module Lisp
446
445
 
447
446
 
448
447
  def self.any_impl(args, env)
449
- raise "any requires at least two arguments" unless args.length >= 2
448
+ return Lisp::Debug.process_error("any requires at least two arguments", env) unless args.length >= 2
450
449
  p = args.car.evaluate(env)
451
- raise "any requires a function as it's first argument" unless p.function? || p.primitive?
450
+ return Lisp::Debug.process_error("any requires a function as it's first argument", env) unless p.function? || p.primitive?
452
451
  lists = args.cdr.to_a.collect {|a| a.evaluate(env)}
453
- raise "any requires all subsequent arguments to be lists or vectors" unless lists.all? {|l| l.list? || l.vector?}
452
+ return Lisp::Debug.process_error("any requires all subsequent arguments to be lists or vectors", env) unless lists.all? {|l| l.list? || l.vector?}
454
453
 
455
454
  while true
456
455
  cars = lists.collect {|l| l.nth(1)}
@@ -463,11 +462,11 @@ module Lisp
463
462
 
464
463
 
465
464
  def self.every_impl(args, env)
466
- raise "all requires at least two arguments" unless args.length >= 2
465
+ return Lisp::Debug.process_error("all requires at least two arguments", env) unless args.length >= 2
467
466
  p = args.car.evaluate(env)
468
- raise "all requires a function as it's first argument" unless p.function? || p.primitive?
467
+ return Lisp::Debug.process_error("all requires a function as it's first argument", env) unless p.function? || p.primitive?
469
468
  lists = args.cdr.to_a.collect {|a| a.evaluate(env)}
470
- raise "all requires all subsequent arguments to be lists or vectors" unless lists.all? {|l| l.list? || l.vector?}
469
+ return Lisp::Debug.process_error("all requires all subsequent arguments to be lists or vectors", env) unless lists.all? {|l| l.list? || l.vector?}
471
470
 
472
471
  while true
473
472
  cars = lists.collect {|l| l.nth(1)}
@@ -480,17 +479,17 @@ module Lisp
480
479
 
481
480
 
482
481
  def self.reverse_impl(args, env)
483
- raise "reverse requires a single argument." unless args.length == 1
482
+ return Lisp::Debug.process_error("reverse requires a single argument.", env) unless args.length == 1
484
483
  l = args.car.evaluate(env)
485
- raise "reverse requires a list or vector" unless l.list? || l.vector?
484
+ return Lisp::Debug.process_error("reverse requires a list or vector", env) unless l.list? || l.vector?
486
485
  make_same_kind_as(l, l.to_a.reverse)
487
486
  end
488
487
 
489
488
 
490
489
  def self.append_impl(args, env)
491
- raise "append requires at least 1 argument." unless args.length >= 1
490
+ return Lisp::Debug.process_error("append requires at least 1 argument.", env) unless args.length >= 1
492
491
  l = args.map {|i| i.evaluate(env)}
493
- raise "append requires lists or vectors" unless l.all? {|i| i.list? || i.vector?}
492
+ return Lisp::Debug.process_error("append requires lists or vectors", env) unless l.all? {|i| i.list? || i.vector?}
494
493
  all_vectors = l.all? {|i| i.vector?}
495
494
  new_items = []
496
495
  l.each do |sublist|
@@ -506,9 +505,9 @@ module Lisp
506
505
 
507
506
 
508
507
  def self.appendbang_impl(args, env)
509
- raise "append! requires at least 1 argument." unless args.length >= 1
508
+ return Lisp::Debug.process_error("append! requires at least 1 argument.", env) unless args.length >= 1
510
509
  arg_array = args.to_a.map {|i| i.evaluate(env)}
511
- raise "append! requires lists" unless arg_array.all? {|i| i.list?}
510
+ return Lisp::Debug.process_error("append! requires lists", env) unless arg_array.all? {|i| i.list?}
512
511
  (0...(arg_array.length-1)). each do |i|
513
512
  arg_array[i].last.set_cdr!(arg_array[i+1])
514
513
  end
@@ -517,9 +516,9 @@ module Lisp
517
516
 
518
517
 
519
518
  def self.flatten_impl(args, env)
520
- raise "flatten requires 1 argument." unless args.length != 1
519
+ return Lisp::Debug.process_error("flatten requires 1 argument.", env) unless args.length != 1
521
520
  l = args.car.evaluate(env)
522
- raise "flatten requires a list argument" unless l.list?
521
+ return Lisp::Debug.process_error("flatten requires a list argument", env) unless l.list?
523
522
  l.flatten
524
523
  end
525
524
 
@@ -18,19 +18,19 @@ module Lisp
18
18
 
19
19
 
20
20
  def self.or_impl(args, env)
21
- raise "or needs at least 2 arguments" unless args.length > 1
21
+ return Lisp::Debug.process_error("or needs at least 2 arguments", env) unless args.length > 1
22
22
  value = !!args.inject(false) {|acc, item| acc || item.evaluate(env).value}
23
23
  return Lisp::Boolean.with_value(value)
24
24
  end
25
25
 
26
26
  def self.and_impl(args, env)
27
- raise "and needs at least 2 arguments" unless args.length > 1
27
+ return Lisp::Debug.process_error("and needs at least 2 arguments", env) unless args.length > 1
28
28
  value = !!args.inject(true) {|acc, item| acc && item.evaluate(env).value}
29
29
  return Lisp::Boolean.with_value(value)
30
30
  end
31
31
 
32
32
  def self.not_impl(args, env)
33
- raise "not needs a single argument" unless args.length == 1
33
+ return Lisp::Debug.process_error("not needs a single argument", env) unless args.length == 1
34
34
  return Lisp::Boolean.with_value(!(args.car.evaluate(env).value))
35
35
  end
36
36
 
@@ -33,9 +33,11 @@ module Lisp
33
33
 
34
34
  def expand(parameters, env, should_eval)
35
35
  if @var_args
36
- raise "#{@name} expected at least #{@required_argument_count} parameters, received #{parameters.length}." if parameters.length < @required_argument_count
36
+ return Lisp::Debug.process_error("#{@name} expected at least
37
+ ##{@required_argument_count} parameters, received #{parameters.length}.", env) if parameters.length < @required_argument_count
37
38
  else
38
- raise "#{@name} expected #{@required_argument_count} parameters, received #{parameters.length}." unless parameters.length == @required_argument_count
39
+ return Lisp::Debug.process_error("#{@name} expected
40
+ ##{@required_argument_count} parameters, received #{parameters.length}.", env) unless parameters.length == @required_argument_count
39
41
  end
40
42
 
41
43
  local_env = EnvironmentFrame.extending(@env, env.frame)