;; Copyright (C) 2006 Dan Muresan ;; ;; This file is part of cpscm (http://www.omnigia.com/scheme/cpscm/home). ;; ;; cpscm is free software; you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation; either version 2 of the License, or ;; (at your option) any later version. ;; ;; cpscm is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with cpscm; if not, write to the Free Software ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (require-library 'danm/scheme-util) (import danm/scheme-util) (require-extension (srfi 60)) (module r5rs-bootstrap (r5rs-bootstrap-defs) (define (num->cxr-def i n) (define num (map (cut char=? <> #\1) (string->list (string-pad (number->string i 2) n #\0)))) (define (bool->x x) (if x #\d #\a)) `(define (,(string->symbol (s+ "c" (list->string (map bool->x num)) "r")) x) ,(fold-right (lambda (e last) `(,(string->symbol (string #\c (bool->x e) #\r)) ,last)) 'x num))) ;; Generates definitions for caar, cadr etc. (define (cxr-defs max) (append-ec (: n 2 (+ max 1)) (map (cut num->cxr-def <> n) (iota (arithmetic-shift 1 n))))) (define (r5rs-bootstrap-defs) `( ,@(cxr-defs 4) (define (not x) (if x #f #t)) ;; TODO: No complex numbers for now (define (real-part x) x) (define (imag-part x) 0) (define (magnitude x) x) (define (angle x) 0) (define (expt x y) (exp (* y (log x)))) (define (char-numeric? c) (and (char<=? #\0 c) (char<=? c #\9))) ;; TODO: only ASCII supported (define (char-upper-case? c) (and (char<=? #\A c) (char<=? c #\Z))) (define (char-lower-case? c) (and (char<=? #\a c) (char<=? c #\z))) (define (char-alphabetic? c) (and (char-upper-case? c) (char-lower-case? c))) (define (char-ci? c1 c2) (char>? (char-upcase c1) (char-upcase c2))) (define (char-ci>=? c1 c2) (char>=? (char-upcase c1) (char-upcase c2))) (define (char-ci=? c1 c2) (char=? (char-upcase c1) (char-upcase c2))) (define (list . l) l) (define (length l) (define (loop l res) (if (null? l) res (loop (cdr l) (+ res 1)))) (loop l 0)) (define (list? l) (if (null? l) #t (if (pair? l) (list? (cdr l)) #f))) (define (list-tail x k) (if (zero? k) x (list-tail (cdr x) (- k 1)))) (define (list-ref list k) (car (list-tail x k))) (define (reverse l) (define (loop l res) (if (null? l) res (loop (cdr l) (cons (car l) res)))) (loop l '())) (define (append . ls) (define (spill l res) (if (null? l) res (spill (cdr l) (cons (car l) res)))) (define (loop ls res) (if (null? ls) (reverse! res) (loop (cdr ls) (spill (car ls) res)))) (loop ls '())) ;; SRFI-1 stuff used in bootstrap (define append! append) ;; TODO: optimize (define (append-reverse rev-head tail) ;; TODO: optimize (append (reverse rev-head) tail)) (define append-reverse! append-reverse) (define (reverse! l) (reverse l)) ;; TODO: optimize (define (find-tail pred l) (define (lp l) (and (not (null? l)) (if (pred (car l)) l (lp (cdr l))))) (lp l)) (define (find pred list) (cond ((find-tail pred list) => car) (else #f))) (define (map f l) (define (loop l res) (if (null? l) (reverse! res) (loop (cdr l) (cons (f (car l)) res)))) (loop l '())) (define (for-each f l) (define (loop l) (if (null? l) #t (begin (f (car l)) (loop (cdr l))))) (loop l)) (define (assoc x lis . maybe-=) (let ((e (if (null? maybe-=) equal? (car maybe-=)))) (find (lambda (entry) (e x (car entry))) lis))) (define (assq x l) (assoc x l eq?)) (define (assv x l) (assoc x l eqv?)) (define (member x lis . maybe-=) (let ((e (if (null? maybe-=) equal? (car maybe-=)))) (find-tail (lambda (y) (e x y)) lis))) (define (memq x l) (member x l eq?)) (define (memv x l) (member x l eqv?)) (define (max x . l) (if (null? l) x (let ((y (car l))) (apply max (if (> x y) x y) (cdr l))))) (define (min x . l) (if (null? l) x (let ((y (car l))) (apply max (if (< x y) x y) (cdr l))))) (define (vector->list v) (define n (vector-length v)) (define (loop i res) (if (< i 0) res (loop (- i 1) (cons (vector-ref v i) res)))) (loop (- n 1) '())) (define (list->vector l) (define n (length l)) (define v #f) (define (loop i l) (if (= i n) v (begin (vector-set! v i (car l)) (loop (+ i 1) (cdr l))))) (set! v (make-vector n)) (loop 0 l)) (define (vector . l) (list->vector l)) (define (vector-fill! v x) (define n (vector-length v)) (let loop ((i 0)) (if (= i n) #t (begin (vector-set! v i x) (loop (+ i 1)))))) (define (string . l) (list->string l)) (define (string-fill! v x) (define n (string-length v)) (let loop ((i 0)) (if (= i n) #t (begin (string-set! v i x) (loop (+ i 1)))))) (define (string->list s) (let loop ((i (- (string-length s) 1)) (l '())) (if (= i -1) l (loop (- i 1) (cons (string-ref s i) l))))) (define (string-copy s) (substring s 0 (string-length s))) (define call/cc call-with-current-continuation) (define write-char display) (define (with-output-to-port p thunk) (let ((oldp (current-output-port))) (current-output-port p) (let ((res (thunk))) (current-output-port oldp) res))) )) )