ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/microscheme/init.scm
Revision: 1.28
Committed: Wed Dec 2 12:16:24 2015 UTC (8 years, 6 months ago) by root
Branch: MAIN
Changes since 1.27: +1 -0 lines
Log Message:
*** empty log message ***

File Contents

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