ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/microscheme/init.scm
Revision: 1.24
Committed: Tue Dec 1 05:55:29 2015 UTC (8 years, 6 months ago) by root
Branch: MAIN
Changes since 1.23: +34 -79 lines
Log Message:
*** empty log message ***

File Contents

# Content
1 ; Initialization file for TinySCHEME 1.41
2
3 (gc-verbose #t)
4
5 ;;;; Utility to ease macro creation
6 (define (macro-expand form)
7 ((eval (get-closure-code (eval (car form)))) form))
8
9 (define (macro-expand-all form)
10 (if (macro? form)
11 (macro-expand-all (macro-expand form))
12 form))
13
14 (define *compile-hook* macro-expand-all)
15
16
17 (macro (unless form)
18 `(if (not ,(cadr form)) (begin ,@(cddr form))))
19
20 (macro (when form)
21 `(if ,(cadr form) (begin ,@(cddr form))))
22
23 ; DEFINE-MACRO Contributed by Andy Gaynor
24 (macro (define-macro dform)
25 (if (symbol? (cadr dform))
26 `(macro ,@(cdr dform))
27 (let ((form (gensym)))
28 `(macro (,(caadr dform) ,form)
29 (apply (lambda ,(cdadr dform) ,@(cddr dform)) (cdr ,form))))))
30
31 ; Utilities for math. Notice that inexact->exact is primitive,
32 ; but exact->inexact is not.
33 (define exact? integer?)
34 (define exact-integer? integer?)
35 (define (inexact? x) (and (real? x) (not (integer? x))))
36 (define (exact->inexact n) (* n 1.0))
37 (define exact inexact->exact)
38 (define inexact exact->inexact)
39 (define (even? n) (= (remainder n 2) 0))
40 (define (odd? n) (not (= (remainder n 2) 0)))
41 (define (zero? n) (= n 0))
42 (define (positive? n) (> n 0))
43 (define (negative? n) (< n 0))
44 (define complex? number?)
45 (define rational? real?)
46 (define (abs n) (if (>= n 0) n (- n)))
47 (define (<> n1 n2) (not (= n1 n2)))
48 (define (square n) (* n n))
49 ;; missing: numerator denominator rationalize exact-integer-sqrt
50
51 ; min and max must return inexact if any arg is inexact
52 (define (max . lst)
53 (foldr (lambda (a b)
54 (if (> a b)
55 (if (exact? b) a (exact->inexact a))
56 (if (exact? a) b (exact->inexact b))))
57 (car lst) (cdr lst)))
58 (define (min . lst)
59 (foldr (lambda (a b)
60 (if (< a b)
61 (if (exact? b) a (exact->inexact a))
62 (if (exact? a) b (exact->inexact b))))
63 (car lst) (cdr lst)))
64
65 (define (succ x) (+ x 1))
66 (define (pred x) (- x 1))
67 (define gcd
68 (lambda a
69 (if (null? a)
70 0
71 (let ((aa (abs (car a)))
72 (bb (abs (cadr a))))
73 (if (= bb 0)
74 aa
75 (gcd bb (remainder aa bb)))))))
76 (define lcm
77 (lambda a
78 (if (null? a)
79 1
80 (let ((aa (abs (car a)))
81 (bb (abs (cadr a))))
82 (if (or (= aa 0) (= bb 0))
83 0
84 (abs (* (quotient aa (gcd aa bb)) bb)))))))
85
86
87 (define (string . charlist)
88 (list->string charlist))
89
90 (define (list->string charlist)
91 (let* ((len (length charlist))
92 (newstr (make-string len))
93 (fill-string!
94 (lambda (str i len charlist)
95 (if (= i len)
96 str
97 (begin (string-set! str i (car charlist))
98 (fill-string! str (+ i 1) len (cdr charlist)))))))
99 (fill-string! newstr 0 len charlist)))
100
101 (define (string-fill! s e)
102 (let ((n (string-length s)))
103 (let loop ((i 0))
104 (if (= i n)
105 s
106 (begin (string-set! s i e) (loop (succ i)))))))
107
108 (define (string->list s)
109 (let loop ((n (pred (string-length s))) (l '()))
110 (if (= n -1)
111 l
112 (loop (pred n) (cons (string-ref s n) l)))))
113
114 ;TODO string-upcase
115 ;TODO string-downcase
116 ;TODO string-foldcase
117 ;TODO string-copy!
118 ;TODO string-fill!
119
120 (define substring string-copy)
121
122 (define (string->anyatom str pred)
123 (let* ((a (string->atom str)))
124 (if (pred a) a
125 (error "string->xxx: not a xxx" a))))
126
127 (define (string->number str . base)
128 (let ((n (string->atom str (if (null? base) 10 (car base)))))
129 (if (number? n) n #f)))
130
131 (define (anyatom->string n pred)
132 (if (pred n)
133 (atom->string n)
134 (error "xxx->string: not a xxx" n)))
135
136 (define (number->string n . base)
137 (atom->string n (if (null? base) 10 (car base))))
138
139
140 (define (char-cmp? cmp a b)
141 (cmp (char->integer a) (char->integer b)))
142 (define (char-ci-cmp? cmp a b)
143 (cmp (char->integer (char-downcase a)) (char->integer (char-downcase b))))
144
145 (define (char=? a b) (char-cmp? = a b))
146 (define (char<? a b) (char-cmp? < a b))
147 (define (char>? a b) (char-cmp? > a b))
148 (define (char<=? a b) (char-cmp? <= a b))
149 (define (char>=? a b) (char-cmp? >= a b))
150
151 (define (char-ci=? a b) (char-ci-cmp? = a b))
152 (define (char-ci<? a b) (char-ci-cmp? < a b))
153 (define (char-ci>? a b) (char-ci-cmp? > a b))
154 (define (char-ci<=? a b) (char-ci-cmp? <= a b))
155 (define (char-ci>=? a b) (char-ci-cmp? >= a b))
156
157 (define (digit-value ch)
158 (if (and (char<=? #\0 ch) (char<=? ch #\9))
159 (- (char->integer ch) (char->integer #\0))
160 #f))
161
162 (define char-foldcase char-downcase)
163
164 ; Note the trick of returning (cmp x y)
165 (define (string-cmp? chcmp cmp a b)
166 (let ((na (string-length a)) (nb (string-length b)))
167 (let loop ((i 0))
168 (cond
169 ((= i na)
170 (if (= i nb) (cmp 0 0) (cmp 0 1)))
171 ((= i nb)
172 (cmp 1 0))
173 ((chcmp = (string-ref a i) (string-ref b i))
174 (loop (succ i)))
175 (else
176 (chcmp cmp (string-ref a i) (string-ref b i)))))))
177
178
179 (define (string=? a b) (string-cmp? char-cmp? = a b))
180 (define (string<? a b) (string-cmp? char-cmp? < a b))
181 (define (string>? a b) (string-cmp? char-cmp? > a b))
182 (define (string<=? a b) (string-cmp? char-cmp? <= a b))
183 (define (string>=? a b) (string-cmp? char-cmp? >= a b))
184
185 (define (string-ci=? a b) (string-cmp? char-ci-cmp? = a b))
186 (define (string-ci<? a b) (string-cmp? char-ci-cmp? < a b))
187 (define (string-ci>? a b) (string-cmp? char-ci-cmp? > a b))
188 (define (string-ci<=? a b) (string-cmp? char-ci-cmp? <= a b))
189 (define (string-ci>=? a b) (string-cmp? char-ci-cmp? >= a b))
190
191 (define (list . x) x)
192
193 (define (foldr f x lst)
194 (if (null? lst)
195 x
196 (foldr f (f x (car lst)) (cdr lst))))
197
198 (define (unzip1-with-cdr . lists)
199 (unzip1-with-cdr-iterative lists '() '()))
200
201 (define (unzip1-with-cdr-iterative lists cars cdrs)
202 (if (null? lists)
203 (cons cars cdrs)
204 (let ((car1 (caar lists))
205 (cdr1 (cdar lists)))
206 (unzip1-with-cdr-iterative
207 (cdr lists)
208 (append cars (list car1))
209 (append cdrs (list cdr1))))))
210
211 (define (map proc . lists)
212 (if (null? lists)
213 (apply proc)
214 (if (null? (car lists))
215 '()
216 (let* ((unz (apply unzip1-with-cdr lists))
217 (cars (car unz))
218 (cdrs (cdr unz)))
219 (cons (apply proc cars) (apply map (cons proc cdrs)))))))
220
221 (define (for-each proc . lists)
222 (if (null? lists)
223 (apply proc)
224 (if (null? (car lists))
225 #t
226 (let* ((unz (apply unzip1-with-cdr lists))
227 (cars (car unz))
228 (cdrs (cdr unz)))
229 (apply proc cars) (apply map (cons proc cdrs))))))
230
231 (define (make-list k . fill) (vector->list (vector k (car fill))))
232
233 (define (list-copy l) (vector->list (list->vector l)))
234
235 (define (list-tail x k)
236 (if (zero? k)
237 x
238 (list-tail (cdr x) (- k 1))))
239
240 (define (list-ref x k)
241 (car (list-tail x k)))
242
243 (define (last-pair x)
244 (if (pair? (cdr x))
245 (last-pair (cdr x))
246 x))
247
248 (define (head stream) (car stream))
249
250 (define (tail stream) (force (cdr stream)))
251
252 (define (vector-equal? x y)
253 (and (vector? x) (vector? y) (= (vector-length x) (vector-length y))
254 (let ((n (vector-length x)))
255 (let loop ((i 0))
256 (if (= i n)
257 #t
258 (and (equal? (vector-ref x i) (vector-ref y i))
259 (loop (succ i))))))))
260
261 (define (list->vector x)
262 (apply vector x))
263
264 ;TODO vector-fill! v e start end
265 (define (vector-fill! v e)
266 (let ((n (vector-length v)))
267 (let loop ((i 0))
268 (if (= i n)
269 v
270 (begin (vector-set! v i e) (loop (succ i)))))))
271
272 (define (vector->list v)
273 (let loop ((n (pred (vector-length v))) (l '()))
274 (if (= n -1)
275 l
276 (loop (pred n) (cons (vector-ref v n) l)))))
277
278 ;TODO vector->string vector start end
279
280 (define (string->vector . args)
281 (list->vector (string->list (apply string-copy args))))
282
283 ;TODO vector-copy v s e
284 ;TODO vector-copy! to at v s e
285
286 (define (vector-append hd . tl)
287 (if (null? tl)
288 hd
289 (list->vector (append (hd (vector->list (vector-append tl)))))))
290
291 ;; The following quasiquote macro is due to Eric S. Tiedemann.
292 ;; Copyright 1988 by Eric S. Tiedemann; all rights reserved.
293 ;;
294 ;; Subsequently modified to handle vectors: D. Souflis
295
296 (macro
297 quasiquote
298 (lambda (l)
299 (define (mcons f l r)
300 (if (and (pair? r)
301 (eq? (car r) 'quote)
302 (eq? (car (cdr r)) (cdr f))
303 (pair? l)
304 (eq? (car l) 'quote)
305 (eq? (car (cdr l)) (car f)))
306 (if (or (procedure? f) (number? f) (string? f))
307 f
308 (list 'quote f))
309 (if (eqv? l vector)
310 (apply l (eval r))
311 (list 'cons l r)
312 )))
313 (define (mappend f l r)
314 (if (or (null? (cdr f))
315 (and (pair? r)
316 (eq? (car r) 'quote)
317 (eq? (car (cdr r)) '())))
318 l
319 (list 'append l r)))
320 (define (foo level form)
321 (cond ((not (pair? form))
322 (if (or (procedure? form) (number? form) (string? form))
323 form
324 (list 'quote form))
325 )
326 ((eq? 'quasiquote (car form))
327 (mcons form ''quasiquote (foo (+ level 1) (cdr form))))
328 (#t (if (zero? level)
329 (cond ((eq? (car form) 'unquote) (car (cdr form)))
330 ((eq? (car form) 'unquote-splicing)
331 (error "Unquote-splicing wasn't in a list:"
332 form))
333 ((and (pair? (car form))
334 (eq? (car (car form)) 'unquote-splicing))
335 (mappend form (car (cdr (car form)))
336 (foo level (cdr form))))
337 (#t (mcons form (foo level (car form))
338 (foo level (cdr form)))))
339 (cond ((eq? (car form) 'unquote)
340 (mcons form ''unquote (foo (- level 1)
341 (cdr form))))
342 ((eq? (car form) 'unquote-splicing)
343 (mcons form ''unquote-splicing
344 (foo (- level 1) (cdr form))))
345 (#t (mcons form (foo level (car form))
346 (foo level (cdr form)))))))))
347 (foo 0 (car (cdr l)))))
348
349 ;;;;;Helper for the dynamic-wind definition. By Tom Breton (Tehom)
350 (define (shared-tail x y)
351 (let ((len-x (length x))
352 (len-y (length y)))
353 (define (shared-tail-helper x y)
354 (if
355 (eq? x y)
356 x
357 (shared-tail-helper (cdr x) (cdr y))))
358
359 (cond
360 ((> len-x len-y)
361 (shared-tail-helper
362 (list-tail x (- len-x len-y))
363 y))
364 ((< len-x len-y)
365 (shared-tail-helper
366 x
367 (list-tail y (- len-y len-x))))
368 (#t (shared-tail-helper x y)))))
369
370 ;;;;;Dynamic-wind by Tom Breton (Tehom)
371
372 ;;Guarded because we must only eval this once, because doing so
373 ;;redefines call/cc in terms of old call/cc
374 (unless (defined? 'dynamic-wind)
375 (let
376 ;;These functions are defined in the context of a private list of
377 ;;pairs of before/after procs.
378 ( (*active-windings* '())
379 ;;We'll define some functions into the larger environment, so
380 ;;we need to know it.
381 (outer-env (current-environment)))
382
383 ;;Poor-man's structure operations
384 (define before-func car)
385 (define after-func cdr)
386 (define make-winding cons)
387
388 ;;Manage active windings
389 (define (activate-winding! new)
390 ((before-func new))
391 (set! *active-windings* (cons new *active-windings*)))
392 (define (deactivate-top-winding!)
393 (let ((old-top (car *active-windings*)))
394 ;;Remove it from the list first so it's not active during its
395 ;;own exit.
396 (set! *active-windings* (cdr *active-windings*))
397 ((after-func old-top))))
398
399 (define (set-active-windings! new-ws)
400 (unless (eq? new-ws *active-windings*)
401 (let ((shared (shared-tail new-ws *active-windings*)))
402
403 ;;Define the looping functions.
404 ;;Exit the old list. Do deeper ones last. Don't do
405 ;;any shared ones.
406 (define (pop-many)
407 (unless (eq? *active-windings* shared)
408 (deactivate-top-winding!)
409 (pop-many)))
410 ;;Enter the new list. Do deeper ones first so that the
411 ;;deeper windings will already be active. Don't do any
412 ;;shared ones.
413 (define (push-many new-ws)
414 (unless (eq? new-ws shared)
415 (push-many (cdr new-ws))
416 (activate-winding! (car new-ws))))
417
418 ;;Do it.
419 (pop-many)
420 (push-many new-ws))))
421
422 ;;The definitions themselves.
423 (eval
424 `(define call-with-current-continuation
425 ;;It internally uses the built-in call/cc, so capture it.
426 ,(let ((old-c/cc call-with-current-continuation))
427 (lambda (func)
428 ;;Use old call/cc to get the continuation.
429 (old-c/cc
430 (lambda (continuation)
431 ;;Call func with not the continuation itself
432 ;;but a procedure that adjusts the active
433 ;;windings to what they were when we made
434 ;;this, and only then calls the
435 ;;continuation.
436 (func
437 (let ((current-ws *active-windings*))
438 (lambda (x)
439 (set-active-windings! current-ws)
440 (continuation x)))))))))
441 outer-env)
442 ;;We can't just say "define (dynamic-wind before thunk after)"
443 ;;because the lambda it's defined to lives in this environment,
444 ;;not in the global environment.
445 (eval
446 `(define dynamic-wind
447 ,(lambda (before thunk after)
448 ;;Make a new winding
449 (activate-winding! (make-winding before after))
450 (let ((result (thunk)))
451 ;;Get rid of the new winding.
452 (deactivate-top-winding!)
453 ;;The return value is that of thunk.
454 result)))
455 outer-env)))
456
457 (define call/cc call-with-current-continuation)
458
459 (define (symbol=? hd . tl)
460 (if (null? tl)
461 #t
462 (and (symbol? hd) (eq? hd (car tl)) (symbol=? (cdr tl)))))
463
464 (define (boolean=? hd . tl)
465 (if (null? tl)
466 #t
467 (and (boolean? hd) (eq? hd (car tl)) (boolean=? (cdr tl)))))
468
469 ;;;;; atom? and equal? written by a.k
470
471 ;;;; atom?
472 (define (atom? x)
473 (not (pair? x)))
474
475 ;;;; equal?
476 (define (equal? x y)
477 (cond
478 ((pair? x)
479 (and (pair? y)
480 (equal? (car x) (car y))
481 (equal? (cdr x) (cdr y))))
482 ((vector? x)
483 (and (vector? y) (vector-equal? x y)))
484 ((string? x)
485 (and (string? y) (string=? x y)))
486 (else (eqv? x y))))
487
488 ;;;; (do ((var init inc) ...) (endtest result ...) body ...)
489 ;;
490 (macro do
491 (lambda (do-macro)
492 (apply (lambda (do vars endtest . body)
493 (let ((do-loop (gensym)))
494 `(letrec ((,do-loop
495 (lambda ,(map (lambda (x)
496 (if (pair? x) (car x) x))
497 `,vars)
498 (if ,(car endtest)
499 (begin ,@(cdr endtest))
500 (begin
501 ,@body
502 (,do-loop
503 ,@(map (lambda (x)
504 (cond
505 ((not (pair? x)) x)
506 ((< (length x) 3) (car x))
507 (else (car (cdr (cdr x))))))
508 `,vars)))))))
509 (,do-loop
510 ,@(map (lambda (x)
511 (if (and (pair? x) (cdr x))
512 (car (cdr x))
513 '()))
514 `,vars)))))
515 do-macro)))
516
517 ;;;; generic-member
518 (define (generic-member cmp obj lst)
519 (cond
520 ((null? lst) #f)
521 ((cmp obj (car lst)) lst)
522 (else (generic-member cmp obj (cdr lst)))))
523
524 (define (memq obj lst)
525 (generic-member eq? obj lst))
526 (define (memv obj lst)
527 (generic-member eqv? obj lst))
528 (define (member obj lst)
529 (generic-member equal? obj lst))
530
531 ;;;; generic-assoc
532 (define (generic-assoc cmp obj alst)
533 (cond
534 ((null? alst) #f)
535 ((cmp obj (caar alst)) (car alst))
536 (else (generic-assoc cmp obj (cdr alst)))))
537
538 (define (assq obj alst)
539 (generic-assoc eq? obj alst))
540 (define (assv obj alst)
541 (generic-assoc eqv? obj alst))
542 (define (assoc obj alst)
543 (generic-assoc equal? obj alst))
544
545 (define (acons x y z) (cons (cons x y) z))
546
547 ;;;; Handy for imperative programs
548 ;;;; Used as: (define-with-return (foo x y) .... (return z) ...)
549 (macro (define-with-return form)
550 `(define ,(cadr form)
551 (call/cc (lambda (return) ,@(cddr form)))))
552
553 ;;;; Simple exception handling
554 ;
555 ; Exceptions are caught as follows:
556 ;
557 ; (catch (do-something to-recover and-return meaningful-value)
558 ; (if-something goes-wrong)
559 ; (with-these calls))
560 ;
561 ; "Catch" establishes a scope spanning multiple call-frames
562 ; until another "catch" is encountered.
563 ;
564 ; Exceptions are thrown with:
565 ;
566 ; (throw "message")
567 ;
568 ; If used outside a (catch ...), reverts to (error "message)
569
570 (define *handlers* (list))
571
572 (define (push-handler proc)
573 (set! *handlers* (cons proc *handlers*)))
574
575 (define (pop-handler)
576 (let ((h (car *handlers*)))
577 (set! *handlers* (cdr *handlers*))
578 h))
579
580 (define (more-handlers?)
581 (pair? *handlers*))
582
583 (define (throw . x)
584 (if (more-handlers?)
585 (apply (pop-handler))
586 (apply error x)))
587
588 ; catch handler thunk
589 (macro (catch form)
590 (let ((label (gensym)))
591 `(call/cc (lambda (exit)
592 (push-handler (lambda () (exit ,(cadr form))))
593 (let ((,label (begin ,@(cddr form))))
594 (pop-handler)
595 ,label)))))
596
597 (define *error-hook* throw)
598
599 ; same as above, r7rs
600 (define (with-exception-handler handler thunk)
601 (catch (handler) (thunk)))
602
603 (define (raise-continuable x)
604 (if (more-handlers?)
605 ((pop-handler) x)
606 (error x)))
607
608 (define (raise x)
609 (raise-continuable x)
610 (error "raise: exception handler returned"))
611
612 ;(with-exception-handler
613 ; (lambda () (display (list "xerror")))
614 ; (lambda () (begin (display ("aaa") (raise 5)))))
615
616 ;TODO: a lot more is missing, and it doesn't work
617
618 ;;;;; Definition of MAKE-ENVIRONMENT, to be used with two-argument EVAL
619
620 (macro (make-environment form)
621 `(apply (lambda ()
622 ,@(cdr form)
623 (current-environment))))
624
625 (define-macro (eval-polymorphic x . envl)
626 (display envl)
627 (let* ((env (if (null? envl) (current-environment) (eval (car envl))))
628 (xval (eval x env)))
629 (if (closure? xval)
630 (make-closure (get-closure-code xval) env)
631 xval)))
632
633 ; Redefine this if you install another package infrastructure
634 ; Also redefine 'package'
635 (define *colon-hook* eval)
636
637 ;;;;; I/O
638
639 (define (input-output-port? p)
640 (and (input-port? p) (output-port? p)))
641
642 (define (close-port p)
643 (cond
644 ((input-output-port? p) (close-input-port (close-output-port p)))
645 ((input-port? p) (close-input-port p))
646 ((output-port? p) (close-output-port p))
647 (else (throw "Not a port" p))))
648
649 (define (call-with-input-file s p)
650 (let ((inport (open-input-file s)))
651 (if (eq? inport #f)
652 #f
653 (let ((res (p inport)))
654 (close-input-port inport)
655 res))))
656
657 (define (call-with-output-file s p)
658 (let ((outport (open-output-file s)))
659 (if (eq? outport #f)
660 #f
661 (let ((res (p outport)))
662 (close-output-port outport)
663 res))))
664
665 (define (with-input-from-file s p)
666 (let ((inport (open-input-file s)))
667 (if (eq? inport #f)
668 #f
669 (let ((prev-inport (current-input-port)))
670 (set-input-port inport)
671 (let ((res (p)))
672 (close-input-port inport)
673 (set-input-port prev-inport)
674 res)))))
675
676 (define (with-output-to-file s p)
677 (let ((outport (open-output-file s)))
678 (if (eq? outport #f)
679 #f
680 (let ((prev-outport (current-output-port)))
681 (set-output-port outport)
682 (let ((res (p)))
683 (close-output-port outport)
684 (set-output-port prev-outport)
685 res)))))
686
687 (define (with-input-output-from-to-files si so p)
688 (let ((inport (open-input-file si))
689 (outport (open-input-file so)))
690 (if (not (and inport outport))
691 (begin
692 (close-input-port inport)
693 (close-output-port outport)
694 #f)
695 (let ((prev-inport (current-input-port))
696 (prev-outport (current-output-port)))
697 (set-input-port inport)
698 (set-output-port outport)
699 (let ((res (p)))
700 (close-input-port inport)
701 (close-output-port outport)
702 (set-input-port prev-inport)
703 (set-output-port prev-outport)
704 res)))))
705
706 ; Random number generator (maximum cycle)
707 (define *seed* 1)
708 (define (random-next)
709 (let* ((a 16807) (m 2147483647) (q (quotient m a)) (r (modulo m a)))
710 (set! *seed*
711 (- (* a (- *seed*
712 (* (quotient *seed* q) q)))
713 (* (quotient *seed* q) r)))
714 (if (< *seed* 0) (set! *seed* (+ *seed* m)))
715 *seed*))
716
717 ;; SRFI-0
718 ;; COND-EXPAND
719 ;; Implemented as a macro
720 (define *features* '(srfi-0))
721
722 (define-macro (cond-expand . cond-action-list)
723 (cond-expand-runtime cond-action-list))
724
725 (define (cond-expand-runtime cond-action-list)
726 (if (null? cond-action-list)
727 #t
728 (if (cond-eval (caar cond-action-list))
729 `(begin ,@(cdar cond-action-list))
730 (cond-expand-runtime (cdr cond-action-list)))))
731
732 (define (cond-eval-and cond-list)
733 (foldr (lambda (x y) (and (cond-eval x) (cond-eval y))) #t cond-list))
734
735 (define (cond-eval-or cond-list)
736 (foldr (lambda (x y) (or (cond-eval x) (cond-eval y))) #f cond-list))
737
738 (define (cond-eval condition)
739 (cond
740 ((symbol? condition)
741 (if (member condition *features*) #t #f))
742 ((eq? condition #t) #t)
743 ((eq? condition #f) #f)
744 (else (case (car condition)
745 ((and) (cond-eval-and (cdr condition)))
746 ((or) (cond-eval-or (cdr condition)))
747 ((not) (if (not (null? (cddr condition)))
748 (error "cond-expand : 'not' takes 1 argument")
749 (not (cond-eval (cadr condition)))))
750 (else (error "cond-expand : unknown operator" (car condition)))))))
751
752 ; compatibility functions added by schmorp@schmorp.de
753 (macro (defmacro dform)
754 (let ((name (cadr dform)) (formals (caddr dform)) (body (cdddr dform)))
755 `(define-macro (,name . ,formals) ,@body)))
756
757 ;; r7rs
758 ; sring-map, vector-map, string-for-each, vector-for-each
759 ; bytevectors
760
761 ;; srfi-1
762
763 (define (check-arg pred val caller)
764 (let lp ((val val))
765 (if (pred val) val (lp (error "Bad argument" val pred caller)))))
766
767 ; Some macros and functions that the SRFI 1 reference implementation
768 ; requires that it does not define and are not part of R5RS.
769
770 (define-macro let-optionals
771 (lambda (input names . code)
772 (let ((input-left (gensym)))
773 `(let ((,input-left ,input))
774 ,(let next ((names names))
775 (if (null? names)
776 `(begin ,@code)
777 `(let ((,input-left (if (null? ,input-left)
778 '()
779 (cdr ,input-left)))
780 (,(caar names) (if (null? ,input-left)
781 ,(cadar names)
782 (car ,input-left))))
783 ,(next (cdr names)))))))))
784
785 (define-macro receive
786 (lambda (names values . code)
787 `(call-with-values (lambda () ,values)
788 (lambda ,names ,@code))))
789
790
791 (define (:optional data default)
792 (if (null? data)
793 default
794 (car data)))
795
796 (load "srfi-1.scm")
797
798 ;(load "srfi-55.scm")
799
800 ;(register-extension '(srfi 1) (lamba () (load "srfi-1.scm")))
801 ;(register-extension '(srfi 23) (lamba () ())) ; error builtin
802 ;(register-extension '(srfi 55) (lamba () ())) ; always available
803
804 ;; end of init
805
806 ;(load "test.scm")
807
808 ;; macros-by-example
809
810 (define append!
811 (lambda args
812 (cond ((null? args) '())
813 ((null? (cdr args)) (car args))
814 ((null? (car args)) (apply comlist:nconc (cdr args)))
815 (else
816 (set-cdr! (last-pair (car args))
817 (apply comlist:nconc (cdr args)))
818 (car args)))))
819
820 (define (some pred lst . rest)
821 (cond ((null? rest)
822 (let mapf ((lst lst))
823 (and (not (null? lst))
824 (or (pred (car lst)) (mapf (cdr lst))))))
825 (else (let mapf ((lst lst) (rest rest))
826 (and (not (null? lst))
827 (or (apply pred (car lst) (map car rest))
828 (mapf (cdr lst) (map cdr rest))))))))
829
830 (define (every pred lst . rest)
831 (cond ((null? rest)
832 (let mapf ((lst lst))
833 (or (null? lst)
834 (and (pred (car lst)) (mapf (cdr lst))))))
835 (else (let mapf ((lst lst) (rest rest))
836 (or (null? lst)
837 (and (apply pred (car lst) (map car rest))
838 (mapf (cdr lst) (map cdr rest))))))))
839
840 (load "mbe.scm")
841
842 (load "test.scm")
843
844 (gc-verbose #f)