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