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