init.scm 23 KB

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