rubylisp 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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)