* boot-9.scm (call-with-deprecation): New procedure.
[bpt/guile.git] / ice-9 / boot-9.scm
1 ;;; installed-scm-file
2
3 ;;;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4 ;;;;
5 ;;;; This program is free software; you can redistribute it and/or modify
6 ;;;; it under the terms of the GNU General Public License as published by
7 ;;;; the Free Software Foundation; either version 2, or (at your option)
8 ;;;; any later version.
9 ;;;;
10 ;;;; This program is distributed in the hope that it will be useful,
11 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ;;;; GNU General Public License for more details.
14 ;;;;
15 ;;;; You should have received a copy of the GNU General Public License
16 ;;;; along with this software; see the file COPYING. If not, write to
17 ;;;; the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 ;;;; Boston, MA 02111-1307 USA
19 ;;;;
20 \f
21
22 ;;; This file is the first thing loaded into Guile. It adds many mundane
23 ;;; definitions and a few that are interesting.
24 ;;;
25 ;;; The module system (hence the hierarchical namespace) are defined in this
26 ;;; file.
27 ;;;
28
29 \f
30 ;;; {Features}
31 ;;
32
33 (define (provide sym)
34 (if (not (memq sym *features*))
35 (set! *features* (cons sym *features*))))
36
37 ;;; Return #t iff FEATURE is available to this Guile interpreter.
38 ;;; In SLIB, provided? also checks to see if the module is available.
39 ;;; We should do that too, but don't.
40 (define (provided? feature)
41 (and (memq feature *features*) #t))
42
43 ;;; presumably deprecated.
44 (define feature? provided?)
45
46 ;;; let format alias simple-format until the more complete version is loaded
47 (define format simple-format)
48
49 \f
50 ;;; {R4RS compliance}
51
52 (primitive-load-path "ice-9/r4rs.scm")
53
54 \f
55 ;;; {Simple Debugging Tools}
56 ;;
57
58
59 ;; peek takes any number of arguments, writes them to the
60 ;; current ouput port, and returns the last argument.
61 ;; It is handy to wrap around an expression to look at
62 ;; a value each time is evaluated, e.g.:
63 ;;
64 ;; (+ 10 (troublesome-fn))
65 ;; => (+ 10 (pk 'troublesome-fn-returned (troublesome-fn)))
66 ;;
67
68 (define (peek . stuff)
69 (newline)
70 (display ";;; ")
71 (write stuff)
72 (newline)
73 (car (last-pair stuff)))
74
75 (define pk peek)
76
77 (define (warn . stuff)
78 (with-output-to-port (current-error-port)
79 (lambda ()
80 (newline)
81 (display ";;; WARNING ")
82 (display stuff)
83 (newline)
84 (car (last-pair stuff)))))
85
86 \f
87 ;;; {Trivial Functions}
88 ;;;
89
90 (define (identity x) x)
91 (define (1+ n) (+ n 1))
92 (define (-1+ n) (+ n -1))
93 (define 1- -1+)
94 (define return-it noop)
95 (define (and=> value procedure) (and value (procedure value)))
96 (define (make-hash-table k) (make-vector k '()))
97
98 ;;; apply-to-args is functionally redunant with apply and, worse,
99 ;;; is less general than apply since it only takes two arguments.
100 ;;;
101 ;;; On the other hand, apply-to-args is a syntacticly convenient way to
102 ;;; perform binding in many circumstances when the "let" family of
103 ;;; of forms don't cut it. E.g.:
104 ;;;
105 ;;; (apply-to-args (return-3d-mouse-coords)
106 ;;; (lambda (x y z)
107 ;;; ...))
108 ;;;
109
110 (define (apply-to-args args fn) (apply fn args))
111
112 \f
113 ;;; {Deprecation}
114 ;;;
115
116 (define call-with-deprecation
117 (let ((issued-warnings (make-hash-table 13)))
118 (lambda (msg thunk)
119 (cond ((not (hashv-ref issued-warnings msg #f))
120 (display ";;; " (current-error-port))
121 (display msg (current-error-port))
122 (newline (current-error-port))
123 (hashv-set! issued-warnings msg #t)))
124 (thunk))))
125
126 (define (id x)
127 (call-with-deprecation "`id' is deprecated. Use `identity' instead."
128 (lambda ()
129 (identity x))))
130
131 \f
132 ;;; {Integer Math}
133 ;;;
134
135 (define (ipow-by-squaring x k acc proc)
136 (cond ((zero? k) acc)
137 ((= 1 k) (proc acc x))
138 (else (ipow-by-squaring (proc x x)
139 (quotient k 2)
140 (if (even? k) acc (proc acc x))
141 proc))))
142
143 (define string-character-length string-length)
144
145
146
147 ;; A convenience function for combining flag bits. Like logior, but
148 ;; handles the cases of 0 and 1 arguments.
149 ;;
150 (define (flags . args)
151 (cond
152 ((null? args) 0)
153 ((null? (cdr args)) (car args))
154 (else (apply logior args))))
155
156 \f
157 ;;; {Symbol Properties}
158 ;;;
159
160 (define (symbol-property sym prop)
161 (let ((pair (assoc prop (symbol-pref sym))))
162 (and pair (cdr pair))))
163
164 (define (set-symbol-property! sym prop val)
165 (let ((pair (assoc prop (symbol-pref sym))))
166 (if pair
167 (set-cdr! pair val)
168 (symbol-pset! sym (acons prop val (symbol-pref sym))))))
169
170 (define (symbol-property-remove! sym prop)
171 (let ((pair (assoc prop (symbol-pref sym))))
172 (if pair
173 (symbol-pset! sym (delq! pair (symbol-pref sym))))))
174
175 ;;; {General Properties}
176
177 ;; This is a more modern interface to properties. It will replace all
178 ;; other property-like things eventually.
179
180 (define (make-object-property)
181 (let ((prop (primitive-make-property #f)))
182 (make-procedure-with-setter
183 (lambda (obj) (primitive-property-ref prop obj))
184 (lambda (obj val) (primitive-property-set! prop obj val)))))
185
186 \f
187
188 ;;; {Arrays}
189 ;;;
190
191 (if (provided? 'array)
192 (primitive-load-path "ice-9/arrays.scm"))
193
194 \f
195 ;;; {Keywords}
196 ;;;
197
198 (define (symbol->keyword symbol)
199 (make-keyword-from-dash-symbol (symbol-append '- symbol)))
200
201 (define (keyword->symbol kw)
202 (let ((sym (symbol->string (keyword-dash-symbol kw))))
203 (string->symbol (substring sym 1 (string-length sym)))))
204
205 (define (kw-arg-ref args kw)
206 (let ((rem (member kw args)))
207 (and rem (pair? (cdr rem)) (cadr rem))))
208
209 \f
210
211 ;;; {Structs}
212
213 (define (struct-layout s)
214 (struct-ref (struct-vtable s) vtable-index-layout))
215
216 \f
217
218 ;;; Environments
219
220 (define the-environment
221 (procedure->syntax
222 (lambda (x e)
223 e)))
224
225 (define the-root-environment (the-environment))
226
227 (define (environment-module env)
228 (let ((closure (and (pair? env) (car (last-pair env)))))
229 (and closure (procedure-property closure 'module))))
230
231 \f
232 ;;; {Records}
233 ;;;
234
235 ;; Printing records: by default, records are printed as
236 ;;
237 ;; #<type-name field1: val1 field2: val2 ...>
238 ;;
239 ;; You can change that by giving a custom printing function to
240 ;; MAKE-RECORD-TYPE (after the list of field symbols). This function
241 ;; will be called like
242 ;;
243 ;; (<printer> object port)
244 ;;
245 ;; It should print OBJECT to PORT.
246
247 (define (inherit-print-state old-port new-port)
248 (if (get-print-state old-port)
249 (port-with-print-state new-port (get-print-state old-port))
250 new-port))
251
252 ;; 0: type-name, 1: fields
253 (define record-type-vtable
254 (make-vtable-vtable "prpr" 0
255 (lambda (s p)
256 (cond ((eq? s record-type-vtable)
257 (display "#<record-type-vtable>" p))
258 (else
259 (display "#<record-type " p)
260 (display (record-type-name s) p)
261 (display ">" p))))))
262
263 (define (record-type? obj)
264 (and (struct? obj) (eq? record-type-vtable (struct-vtable obj))))
265
266 (define (make-record-type type-name fields . opt)
267 (let ((printer-fn (and (pair? opt) (car opt))))
268 (let ((struct (make-struct record-type-vtable 0
269 (make-struct-layout
270 (apply string-append
271 (map (lambda (f) "pw") fields)))
272 (or printer-fn
273 (lambda (s p)
274 (display "#<" p)
275 (display type-name p)
276 (let loop ((fields fields)
277 (off 0))
278 (cond
279 ((not (null? fields))
280 (display " " p)
281 (display (car fields) p)
282 (display ": " p)
283 (display (struct-ref s off) p)
284 (loop (cdr fields) (+ 1 off)))))
285 (display ">" p)))
286 type-name
287 (copy-tree fields))))
288 ;; Temporary solution: Associate a name to the record type descriptor
289 ;; so that the object system can create a wrapper class for it.
290 (set-struct-vtable-name! struct (if (symbol? type-name)
291 type-name
292 (string->symbol type-name)))
293 struct)))
294
295 (define (record-type-name obj)
296 (if (record-type? obj)
297 (struct-ref obj vtable-offset-user)
298 (error 'not-a-record-type obj)))
299
300 (define (record-type-fields obj)
301 (if (record-type? obj)
302 (struct-ref obj (+ 1 vtable-offset-user))
303 (error 'not-a-record-type obj)))
304
305 (define (record-constructor rtd . opt)
306 (let ((field-names (if (pair? opt) (car opt) (record-type-fields rtd))))
307 (local-eval `(lambda ,field-names
308 (make-struct ',rtd 0 ,@(map (lambda (f)
309 (if (memq f field-names)
310 f
311 #f))
312 (record-type-fields rtd))))
313 the-root-environment)))
314
315 (define (record-predicate rtd)
316 (lambda (obj) (and (struct? obj) (eq? rtd (struct-vtable obj)))))
317
318 (define (record-accessor rtd field-name)
319 (let* ((pos (list-index (record-type-fields rtd) field-name)))
320 (if (not pos)
321 (error 'no-such-field field-name))
322 (local-eval `(lambda (obj)
323 (and (eq? ',rtd (record-type-descriptor obj))
324 (struct-ref obj ,pos)))
325 the-root-environment)))
326
327 (define (record-modifier rtd field-name)
328 (let* ((pos (list-index (record-type-fields rtd) field-name)))
329 (if (not pos)
330 (error 'no-such-field field-name))
331 (local-eval `(lambda (obj val)
332 (and (eq? ',rtd (record-type-descriptor obj))
333 (struct-set! obj ,pos val)))
334 the-root-environment)))
335
336
337 (define (record? obj)
338 (and (struct? obj) (record-type? (struct-vtable obj))))
339
340 (define (record-type-descriptor obj)
341 (if (struct? obj)
342 (struct-vtable obj)
343 (error 'not-a-record obj)))
344
345 (provide 'record)
346
347 \f
348 ;;; {Booleans}
349 ;;;
350
351 (define (->bool x) (not (not x)))
352
353 \f
354 ;;; {Symbols}
355 ;;;
356
357 (define (symbol-append . args)
358 (string->symbol (apply string-append (map symbol->string args))))
359
360 (define (list->symbol . args)
361 (string->symbol (apply list->string args)))
362
363 (define (symbol . args)
364 (string->symbol (apply string args)))
365
366 \f
367 ;;; {Lists}
368 ;;;
369
370 (define (list-index l k)
371 (let loop ((n 0)
372 (l l))
373 (and (not (null? l))
374 (if (eq? (car l) k)
375 n
376 (loop (+ n 1) (cdr l))))))
377
378 (define (make-list n . init)
379 (if (pair? init) (set! init (car init)))
380 (let loop ((answer '())
381 (n n))
382 (if (<= n 0)
383 answer
384 (loop (cons init answer) (- n 1)))))
385
386 \f
387 ;;; {and-map and or-map}
388 ;;;
389 ;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...)
390 ;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...)
391 ;;;
392
393 ;; and-map f l
394 ;;
395 ;; Apply f to successive elements of l until exhaustion or f returns #f.
396 ;; If returning early, return #f. Otherwise, return the last value returned
397 ;; by f. If f has never been called because l is empty, return #t.
398 ;;
399 (define (and-map f lst)
400 (let loop ((result #t)
401 (l lst))
402 (and result
403 (or (and (null? l)
404 result)
405 (loop (f (car l)) (cdr l))))))
406
407 ;; or-map f l
408 ;;
409 ;; Apply f to successive elements of l until exhaustion or while f returns #f.
410 ;; If returning early, return the return value of f.
411 ;;
412 (define (or-map f lst)
413 (let loop ((result #f)
414 (l lst))
415 (or result
416 (and (not (null? l))
417 (loop (f (car l)) (cdr l))))))
418
419 \f
420
421 (if (provided? 'posix)
422 (primitive-load-path "ice-9/posix.scm"))
423
424 (if (provided? 'socket)
425 (primitive-load-path "ice-9/networking.scm"))
426
427 (define file-exists?
428 (if (provided? 'posix)
429 (lambda (str)
430 (access? str F_OK))
431 (lambda (str)
432 (let ((port (catch 'system-error (lambda () (open-file str OPEN_READ))
433 (lambda args #f))))
434 (if port (begin (close-port port) #t)
435 #f)))))
436
437 (define file-is-directory?
438 (if (provided? 'posix)
439 (lambda (str)
440 (eq? (stat:type (stat str)) 'directory))
441 (lambda (str)
442 (let ((port (catch 'system-error
443 (lambda () (open-file (string-append str "/.")
444 OPEN_READ))
445 (lambda args #f))))
446 (if port (begin (close-port port) #t)
447 #f)))))
448
449 (define (has-suffix? str suffix)
450 (let ((sufl (string-length suffix))
451 (sl (string-length str)))
452 (and (> sl sufl)
453 (string=? (substring str (- sl sufl) sl) suffix))))
454
455 \f
456 ;;; {Error Handling}
457 ;;;
458
459 (define (error . args)
460 (save-stack)
461 (if (null? args)
462 (scm-error 'misc-error #f "?" #f #f)
463 (let loop ((msg "~A")
464 (rest (cdr args)))
465 (if (not (null? rest))
466 (loop (string-append msg " ~S")
467 (cdr rest))
468 (scm-error 'misc-error #f msg args #f)))))
469
470 ;; bad-throw is the hook that is called upon a throw to a an unhandled
471 ;; key (unless the throw has four arguments, in which case
472 ;; it's usually interpreted as an error throw.)
473 ;; If the key has a default handler (a throw-handler-default property),
474 ;; it is applied to the throw.
475 ;;
476 (define (bad-throw key . args)
477 (let ((default (symbol-property key 'throw-handler-default)))
478 (or (and default (apply default key args))
479 (apply error "unhandled-exception:" key args))))
480
481 \f
482
483 (define (tm:sec obj) (vector-ref obj 0))
484 (define (tm:min obj) (vector-ref obj 1))
485 (define (tm:hour obj) (vector-ref obj 2))
486 (define (tm:mday obj) (vector-ref obj 3))
487 (define (tm:mon obj) (vector-ref obj 4))
488 (define (tm:year obj) (vector-ref obj 5))
489 (define (tm:wday obj) (vector-ref obj 6))
490 (define (tm:yday obj) (vector-ref obj 7))
491 (define (tm:isdst obj) (vector-ref obj 8))
492 (define (tm:gmtoff obj) (vector-ref obj 9))
493 (define (tm:zone obj) (vector-ref obj 10))
494
495 (define (set-tm:sec obj val) (vector-set! obj 0 val))
496 (define (set-tm:min obj val) (vector-set! obj 1 val))
497 (define (set-tm:hour obj val) (vector-set! obj 2 val))
498 (define (set-tm:mday obj val) (vector-set! obj 3 val))
499 (define (set-tm:mon obj val) (vector-set! obj 4 val))
500 (define (set-tm:year obj val) (vector-set! obj 5 val))
501 (define (set-tm:wday obj val) (vector-set! obj 6 val))
502 (define (set-tm:yday obj val) (vector-set! obj 7 val))
503 (define (set-tm:isdst obj val) (vector-set! obj 8 val))
504 (define (set-tm:gmtoff obj val) (vector-set! obj 9 val))
505 (define (set-tm:zone obj val) (vector-set! obj 10 val))
506
507 (define (tms:clock obj) (vector-ref obj 0))
508 (define (tms:utime obj) (vector-ref obj 1))
509 (define (tms:stime obj) (vector-ref obj 2))
510 (define (tms:cutime obj) (vector-ref obj 3))
511 (define (tms:cstime obj) (vector-ref obj 4))
512
513 (define (file-position . args) (apply ftell args))
514 (define (file-set-position . args) (apply fseek args))
515
516 (define (move->fdes fd/port fd)
517 (cond ((integer? fd/port)
518 (dup->fdes fd/port fd)
519 (close fd/port)
520 fd)
521 (else
522 (primitive-move->fdes fd/port fd)
523 (set-port-revealed! fd/port 1)
524 fd/port)))
525
526 (define (release-port-handle port)
527 (let ((revealed (port-revealed port)))
528 (if (> revealed 0)
529 (set-port-revealed! port (- revealed 1)))))
530
531 (define (dup->port port/fd mode . maybe-fd)
532 (let ((port (fdopen (apply dup->fdes port/fd maybe-fd)
533 mode)))
534 (if (pair? maybe-fd)
535 (set-port-revealed! port 1))
536 port))
537
538 (define (dup->inport port/fd . maybe-fd)
539 (apply dup->port port/fd "r" maybe-fd))
540
541 (define (dup->outport port/fd . maybe-fd)
542 (apply dup->port port/fd "w" maybe-fd))
543
544 (define (dup port/fd . maybe-fd)
545 (if (integer? port/fd)
546 (apply dup->fdes port/fd maybe-fd)
547 (apply dup->port port/fd (port-mode port/fd) maybe-fd)))
548
549 (define (duplicate-port port modes)
550 (dup->port port modes))
551
552 (define (fdes->inport fdes)
553 (let loop ((rest-ports (fdes->ports fdes)))
554 (cond ((null? rest-ports)
555 (let ((result (fdopen fdes "r")))
556 (set-port-revealed! result 1)
557 result))
558 ((input-port? (car rest-ports))
559 (set-port-revealed! (car rest-ports)
560 (+ (port-revealed (car rest-ports)) 1))
561 (car rest-ports))
562 (else
563 (loop (cdr rest-ports))))))
564
565 (define (fdes->outport fdes)
566 (let loop ((rest-ports (fdes->ports fdes)))
567 (cond ((null? rest-ports)
568 (let ((result (fdopen fdes "w")))
569 (set-port-revealed! result 1)
570 result))
571 ((output-port? (car rest-ports))
572 (set-port-revealed! (car rest-ports)
573 (+ (port-revealed (car rest-ports)) 1))
574 (car rest-ports))
575 (else
576 (loop (cdr rest-ports))))))
577
578 (define (port->fdes port)
579 (set-port-revealed! port (+ (port-revealed port) 1))
580 (fileno port))
581
582 (define (setenv name value)
583 (if value
584 (putenv (string-append name "=" value))
585 (putenv name)))
586
587 \f
588 ;;; {Load Paths}
589 ;;;
590
591 ;;; Here for backward compatability
592 ;;
593 (define scheme-file-suffix (lambda () ".scm"))
594
595 (define (in-vicinity vicinity file)
596 (let ((tail (let ((len (string-length vicinity)))
597 (if (zero? len)
598 #f
599 (string-ref vicinity (- len 1))))))
600 (string-append vicinity
601 (if (or (not tail)
602 (eq? tail #\/))
603 ""
604 "/")
605 file)))
606
607 \f
608 ;;; {Help for scm_shell}
609 ;;; The argument-processing code used by Guile-based shells generates
610 ;;; Scheme code based on the argument list. This page contains help
611 ;;; functions for the code it generates.
612
613 (define (command-line) (program-arguments))
614
615 ;; This is mostly for the internal use of the code generated by
616 ;; scm_compile_shell_switches.
617 (define (load-user-init)
618 (let* ((home (or (getenv "HOME")
619 (false-if-exception (passwd:dir (getpwuid (getuid))))
620 "/")) ;; fallback for cygwin etc.
621 (init-file (in-vicinity home ".guile")))
622 (if (file-exists? init-file)
623 (primitive-load init-file))))
624
625 \f
626 ;;; {Loading by paths}
627
628 ;;; Load a Scheme source file named NAME, searching for it in the
629 ;;; directories listed in %load-path, and applying each of the file
630 ;;; name extensions listed in %load-extensions.
631 (define (load-from-path name)
632 (start-stack 'load-stack
633 (primitive-load-path name)))
634
635
636 \f
637 ;;; {Transcendental Functions}
638 ;;;
639 ;;; Derived from "Transcen.scm", Complex trancendental functions for SCM.
640 ;;; Written by Jerry D. Hedden, (C) FSF.
641 ;;; See the file `COPYING' for terms applying to this program.
642 ;;;
643
644 (define (exp z)
645 (if (real? z) ($exp z)
646 (make-polar ($exp (real-part z)) (imag-part z))))
647
648 (define (log z)
649 (if (and (real? z) (>= z 0))
650 ($log z)
651 (make-rectangular ($log (magnitude z)) (angle z))))
652
653 (define (sqrt z)
654 (if (real? z)
655 (if (negative? z) (make-rectangular 0 ($sqrt (- z)))
656 ($sqrt z))
657 (make-polar ($sqrt (magnitude z)) (/ (angle z) 2))))
658
659 (define expt
660 (let ((integer-expt integer-expt))
661 (lambda (z1 z2)
662 (cond ((integer? z2)
663 (if (>= z2 0)
664 (integer-expt z1 z2)
665 (/ 1 (integer-expt z1 (- z2)))))
666 ((and (real? z2) (real? z1) (>= z1 0))
667 ($expt z1 z2))
668 (else
669 (exp (* z2 (log z1))))))))
670
671 (define (sinh z)
672 (if (real? z) ($sinh z)
673 (let ((x (real-part z)) (y (imag-part z)))
674 (make-rectangular (* ($sinh x) ($cos y))
675 (* ($cosh x) ($sin y))))))
676 (define (cosh z)
677 (if (real? z) ($cosh z)
678 (let ((x (real-part z)) (y (imag-part z)))
679 (make-rectangular (* ($cosh x) ($cos y))
680 (* ($sinh x) ($sin y))))))
681 (define (tanh z)
682 (if (real? z) ($tanh z)
683 (let* ((x (* 2 (real-part z)))
684 (y (* 2 (imag-part z)))
685 (w (+ ($cosh x) ($cos y))))
686 (make-rectangular (/ ($sinh x) w) (/ ($sin y) w)))))
687
688 (define (asinh z)
689 (if (real? z) ($asinh z)
690 (log (+ z (sqrt (+ (* z z) 1))))))
691
692 (define (acosh z)
693 (if (and (real? z) (>= z 1))
694 ($acosh z)
695 (log (+ z (sqrt (- (* z z) 1))))))
696
697 (define (atanh z)
698 (if (and (real? z) (> z -1) (< z 1))
699 ($atanh z)
700 (/ (log (/ (+ 1 z) (- 1 z))) 2)))
701
702 (define (sin z)
703 (if (real? z) ($sin z)
704 (let ((x (real-part z)) (y (imag-part z)))
705 (make-rectangular (* ($sin x) ($cosh y))
706 (* ($cos x) ($sinh y))))))
707 (define (cos z)
708 (if (real? z) ($cos z)
709 (let ((x (real-part z)) (y (imag-part z)))
710 (make-rectangular (* ($cos x) ($cosh y))
711 (- (* ($sin x) ($sinh y)))))))
712 (define (tan z)
713 (if (real? z) ($tan z)
714 (let* ((x (* 2 (real-part z)))
715 (y (* 2 (imag-part z)))
716 (w (+ ($cos x) ($cosh y))))
717 (make-rectangular (/ ($sin x) w) (/ ($sinh y) w)))))
718
719 (define (asin z)
720 (if (and (real? z) (>= z -1) (<= z 1))
721 ($asin z)
722 (* -i (asinh (* +i z)))))
723
724 (define (acos z)
725 (if (and (real? z) (>= z -1) (<= z 1))
726 ($acos z)
727 (+ (/ (angle -1) 2) (* +i (asinh (* +i z))))))
728
729 (define (atan z . y)
730 (if (null? y)
731 (if (real? z) ($atan z)
732 (/ (log (/ (- +i z) (+ +i z))) +2i))
733 ($atan2 z (car y))))
734
735 (define (log10 arg)
736 (/ (log arg) (log 10)))
737
738 \f
739
740 ;;; {Reader Extensions}
741 ;;;
742
743 ;;; Reader code for various "#c" forms.
744 ;;;
745
746 (read-hash-extend #\' (lambda (c port)
747 (read port)))
748 (read-hash-extend #\. (lambda (c port)
749 (eval (read port) (interaction-environment))))
750
751 \f
752 ;;; {Command Line Options}
753 ;;;
754
755 (define (get-option argv kw-opts kw-args return)
756 (cond
757 ((null? argv)
758 (return #f #f argv))
759
760 ((or (not (eq? #\- (string-ref (car argv) 0)))
761 (eq? (string-length (car argv)) 1))
762 (return 'normal-arg (car argv) (cdr argv)))
763
764 ((eq? #\- (string-ref (car argv) 1))
765 (let* ((kw-arg-pos (or (string-index (car argv) #\=)
766 (string-length (car argv))))
767 (kw (symbol->keyword (substring (car argv) 2 kw-arg-pos)))
768 (kw-opt? (member kw kw-opts))
769 (kw-arg? (member kw kw-args))
770 (arg (or (and (not (eq? kw-arg-pos (string-length (car argv))))
771 (substring (car argv)
772 (+ kw-arg-pos 1)
773 (string-length (car argv))))
774 (and kw-arg?
775 (begin (set! argv (cdr argv)) (car argv))))))
776 (if (or kw-opt? kw-arg?)
777 (return kw arg (cdr argv))
778 (return 'usage-error kw (cdr argv)))))
779
780 (else
781 (let* ((char (substring (car argv) 1 2))
782 (kw (symbol->keyword char)))
783 (cond
784
785 ((member kw kw-opts)
786 (let* ((rest-car (substring (car argv) 2 (string-length (car argv))))
787 (new-argv (if (= 0 (string-length rest-car))
788 (cdr argv)
789 (cons (string-append "-" rest-car) (cdr argv)))))
790 (return kw #f new-argv)))
791
792 ((member kw kw-args)
793 (let* ((rest-car (substring (car argv) 2 (string-length (car argv))))
794 (arg (if (= 0 (string-length rest-car))
795 (cadr argv)
796 rest-car))
797 (new-argv (if (= 0 (string-length rest-car))
798 (cddr argv)
799 (cdr argv))))
800 (return kw arg new-argv)))
801
802 (else (return 'usage-error kw argv)))))))
803
804 (define (for-next-option proc argv kw-opts kw-args)
805 (let loop ((argv argv))
806 (get-option argv kw-opts kw-args
807 (lambda (opt opt-arg argv)
808 (and opt (proc opt opt-arg argv loop))))))
809
810 (define (display-usage-report kw-desc)
811 (for-each
812 (lambda (kw)
813 (or (eq? (car kw) #t)
814 (eq? (car kw) 'else)
815 (let* ((opt-desc kw)
816 (help (cadr opt-desc))
817 (opts (car opt-desc))
818 (opts-proper (if (string? (car opts)) (cdr opts) opts))
819 (arg-name (if (string? (car opts))
820 (string-append "<" (car opts) ">")
821 ""))
822 (left-part (string-append
823 (with-output-to-string
824 (lambda ()
825 (map (lambda (x) (display (keyword-symbol x)) (display " "))
826 opts-proper)))
827 arg-name))
828 (middle-part (if (and (< (string-length left-part) 30)
829 (< (string-length help) 40))
830 (make-string (- 30 (string-length left-part)) #\ )
831 "\n\t")))
832 (display left-part)
833 (display middle-part)
834 (display help)
835 (newline))))
836 kw-desc))
837
838
839
840 (define (transform-usage-lambda cases)
841 (let* ((raw-usage (delq! 'else (map car cases)))
842 (usage-sans-specials (map (lambda (x)
843 (or (and (not (list? x)) x)
844 (and (symbol? (car x)) #t)
845 (and (boolean? (car x)) #t)
846 x))
847 raw-usage))
848 (usage-desc (delq! #t usage-sans-specials))
849 (kw-desc (map car usage-desc))
850 (kw-opts (apply append (map (lambda (x) (and (not (string? (car x))) x)) kw-desc)))
851 (kw-args (apply append (map (lambda (x) (and (string? (car x)) (cdr x))) kw-desc)))
852 (transmogrified-cases (map (lambda (case)
853 (cons (let ((opts (car case)))
854 (if (or (boolean? opts) (eq? 'else opts))
855 opts
856 (cond
857 ((symbol? (car opts)) opts)
858 ((boolean? (car opts)) opts)
859 ((string? (caar opts)) (cdar opts))
860 (else (car opts)))))
861 (cdr case)))
862 cases)))
863 `(let ((%display-usage (lambda () (display-usage-report ',usage-desc))))
864 (lambda (%argv)
865 (let %next-arg ((%argv %argv))
866 (get-option %argv
867 ',kw-opts
868 ',kw-args
869 (lambda (%opt %arg %new-argv)
870 (case %opt
871 ,@ transmogrified-cases))))))))
872
873
874 \f
875
876 ;;; {Low Level Modules}
877 ;;;
878 ;;; These are the low level data structures for modules.
879 ;;;
880 ;;; !!! warning: The interface to lazy binder procedures is going
881 ;;; to be changed in an incompatible way to permit all the basic
882 ;;; module ops to be virtualized.
883 ;;;
884 ;;; (make-module size use-list lazy-binding-proc) => module
885 ;;; module-{obarray,uses,binder}[|-set!]
886 ;;; (module? obj) => [#t|#f]
887 ;;; (module-locally-bound? module symbol) => [#t|#f]
888 ;;; (module-bound? module symbol) => [#t|#f]
889 ;;; (module-symbol-locally-interned? module symbol) => [#t|#f]
890 ;;; (module-symbol-interned? module symbol) => [#t|#f]
891 ;;; (module-local-variable module symbol) => [#<variable ...> | #f]
892 ;;; (module-variable module symbol) => [#<variable ...> | #f]
893 ;;; (module-symbol-binding module symbol opt-value)
894 ;;; => [ <obj> | opt-value | an error occurs ]
895 ;;; (module-make-local-var! module symbol) => #<variable...>
896 ;;; (module-add! module symbol var) => unspecified
897 ;;; (module-remove! module symbol) => unspecified
898 ;;; (module-for-each proc module) => unspecified
899 ;;; (make-scm-module) => module ; a lazy copy of the symhash module
900 ;;; (set-current-module module) => unspecified
901 ;;; (current-module) => #<module...>
902 ;;;
903 ;;;
904
905 \f
906 ;;; {Printing Modules}
907 ;; This is how modules are printed. You can re-define it.
908 ;; (Redefining is actually more complicated than simply redefining
909 ;; %print-module because that would only change the binding and not
910 ;; the value stored in the vtable that determines how record are
911 ;; printed. Sigh.)
912
913 (define (%print-module mod port) ; unused args: depth length style table)
914 (display "#<" port)
915 (display (or (module-kind mod) "module") port)
916 (let ((name (module-name mod)))
917 (if name
918 (begin
919 (display " " port)
920 (display name port))))
921 (display " " port)
922 (display (number->string (object-address mod) 16) port)
923 (display ">" port))
924
925 ;; module-type
926 ;;
927 ;; A module is characterized by an obarray in which local symbols
928 ;; are interned, a list of modules, "uses", from which non-local
929 ;; bindings can be inherited, and an optional lazy-binder which
930 ;; is a (CLOSURE module symbol) which, as a last resort, can provide
931 ;; bindings that would otherwise not be found locally in the module.
932 ;;
933 ;; NOTE: If you change here, you also need to change libguile/modules.h.
934 ;;
935 (define module-type
936 (make-record-type 'module
937 '(obarray uses binder eval-closure transformer name kind
938 observers weak-observers observer-id)
939 %print-module))
940
941 ;; make-module &opt size uses binder
942 ;;
943 ;; Create a new module, perhaps with a particular size of obarray,
944 ;; initial uses list, or binding procedure.
945 ;;
946 (define make-module
947 (lambda args
948
949 (define (parse-arg index default)
950 (if (> (length args) index)
951 (list-ref args index)
952 default))
953
954 (if (> (length args) 3)
955 (error "Too many args to make-module." args))
956
957 (let ((size (parse-arg 0 1021))
958 (uses (parse-arg 1 '()))
959 (binder (parse-arg 2 #f)))
960
961 (if (not (integer? size))
962 (error "Illegal size to make-module." size))
963 (if (not (and (list? uses)
964 (and-map module? uses)))
965 (error "Incorrect use list." uses))
966 (if (and binder (not (procedure? binder)))
967 (error
968 "Lazy-binder expected to be a procedure or #f." binder))
969
970 (let ((module (module-constructor (make-vector size '())
971 uses binder #f #f #f #f
972 '()
973 (make-weak-value-hash-table 31)
974 0)))
975
976 ;; We can't pass this as an argument to module-constructor,
977 ;; because we need it to close over a pointer to the module
978 ;; itself.
979 (set-module-eval-closure! module (standard-eval-closure module))
980
981 module))))
982
983 (define module-constructor (record-constructor module-type))
984 (define module-obarray (record-accessor module-type 'obarray))
985 (define set-module-obarray! (record-modifier module-type 'obarray))
986 (define module-uses (record-accessor module-type 'uses))
987 (define set-module-uses! (record-modifier module-type 'uses))
988 (define module-binder (record-accessor module-type 'binder))
989 (define set-module-binder! (record-modifier module-type 'binder))
990
991 ;; NOTE: This binding is used in libguile/modules.c.
992 (define module-eval-closure (record-accessor module-type 'eval-closure))
993
994 (define module-transformer (record-accessor module-type 'transformer))
995 (define set-module-transformer! (record-modifier module-type 'transformer))
996 (define module-name (record-accessor module-type 'name))
997 (define set-module-name! (record-modifier module-type 'name))
998 (define module-kind (record-accessor module-type 'kind))
999 (define set-module-kind! (record-modifier module-type 'kind))
1000 (define module-observers (record-accessor module-type 'observers))
1001 (define set-module-observers! (record-modifier module-type 'observers))
1002 (define module-weak-observers (record-accessor module-type 'weak-observers))
1003 (define module-observer-id (record-accessor module-type 'observer-id))
1004 (define set-module-observer-id! (record-modifier module-type 'observer-id))
1005 (define module? (record-predicate module-type))
1006
1007 (define set-module-eval-closure!
1008 (let ((setter (record-modifier module-type 'eval-closure)))
1009 (lambda (module closure)
1010 (setter module closure)
1011 ;; Make it possible to lookup the module from the environment.
1012 ;; This implementation is correct since an eval closure can belong
1013 ;; to maximally one module.
1014 (set-procedure-property! closure 'module module))))
1015
1016 ;;; This procedure is depreated
1017 ;;;
1018 (define eval-in-module eval)
1019
1020 \f
1021 ;;; {Observer protocol}
1022 ;;;
1023
1024 (define (module-observe module proc)
1025 (set-module-observers! module (cons proc (module-observers module)))
1026 (cons module proc))
1027
1028 (define (module-observe-weak module proc)
1029 (let ((id (module-observer-id module)))
1030 (hash-set! (module-weak-observers module) id proc)
1031 (set-module-observer-id! module (+ 1 id))
1032 (cons module id)))
1033
1034 (define (module-unobserve token)
1035 (let ((module (car token))
1036 (id (cdr token)))
1037 (if (integer? id)
1038 (hash-remove! (module-weak-observers module) id)
1039 (set-module-observers! module (delq1! id (module-observers module)))))
1040 *unspecified*)
1041
1042 (define (module-modified m)
1043 (for-each (lambda (proc) (proc m)) (module-observers m))
1044 (hash-fold (lambda (id proc res) (proc m)) #f (module-weak-observers m)))
1045
1046 \f
1047 ;;; {Module Searching in General}
1048 ;;;
1049 ;;; We sometimes want to look for properties of a symbol
1050 ;;; just within the obarray of one module. If the property
1051 ;;; holds, then it is said to hold ``locally'' as in, ``The symbol
1052 ;;; DISPLAY is locally rebound in the module `safe-guile'.''
1053 ;;;
1054 ;;;
1055 ;;; Other times, we want to test for a symbol property in the obarray
1056 ;;; of M and, if it is not found there, try each of the modules in the
1057 ;;; uses list of M. This is the normal way of testing for some
1058 ;;; property, so we state these properties without qualification as
1059 ;;; in: ``The symbol 'fnord is interned in module M because it is
1060 ;;; interned locally in module M2 which is a member of the uses list
1061 ;;; of M.''
1062 ;;;
1063
1064 ;; module-search fn m
1065 ;;
1066 ;; return the first non-#f result of FN applied to M and then to
1067 ;; the modules in the uses of m, and so on recursively. If all applications
1068 ;; return #f, then so does this function.
1069 ;;
1070 (define (module-search fn m v)
1071 (define (loop pos)
1072 (and (pair? pos)
1073 (or (module-search fn (car pos) v)
1074 (loop (cdr pos)))))
1075 (or (fn m v)
1076 (loop (module-uses m))))
1077
1078
1079 ;;; {Is a symbol bound in a module?}
1080 ;;;
1081 ;;; Symbol S in Module M is bound if S is interned in M and if the binding
1082 ;;; of S in M has been set to some well-defined value.
1083 ;;;
1084
1085 ;; module-locally-bound? module symbol
1086 ;;
1087 ;; Is a symbol bound (interned and defined) locally in a given module?
1088 ;;
1089 (define (module-locally-bound? m v)
1090 (let ((var (module-local-variable m v)))
1091 (and var
1092 (variable-bound? var))))
1093
1094 ;; module-bound? module symbol
1095 ;;
1096 ;; Is a symbol bound (interned and defined) anywhere in a given module
1097 ;; or its uses?
1098 ;;
1099 (define (module-bound? m v)
1100 (module-search module-locally-bound? m v))
1101
1102 ;;; {Is a symbol interned in a module?}
1103 ;;;
1104 ;;; Symbol S in Module M is interned if S occurs in
1105 ;;; of S in M has been set to some well-defined value.
1106 ;;;
1107 ;;; It is possible to intern a symbol in a module without providing
1108 ;;; an initial binding for the corresponding variable. This is done
1109 ;;; with:
1110 ;;; (module-add! module symbol (make-undefined-variable))
1111 ;;;
1112 ;;; In that case, the symbol is interned in the module, but not
1113 ;;; bound there. The unbound symbol shadows any binding for that
1114 ;;; symbol that might otherwise be inherited from a member of the uses list.
1115 ;;;
1116
1117 (define (module-obarray-get-handle ob key)
1118 ((if (symbol? key) hashq-get-handle hash-get-handle) ob key))
1119
1120 (define (module-obarray-ref ob key)
1121 ((if (symbol? key) hashq-ref hash-ref) ob key))
1122
1123 (define (module-obarray-set! ob key val)
1124 ((if (symbol? key) hashq-set! hash-set!) ob key val))
1125
1126 (define (module-obarray-remove! ob key)
1127 ((if (symbol? key) hashq-remove! hash-remove!) ob key))
1128
1129 ;; module-symbol-locally-interned? module symbol
1130 ;;
1131 ;; is a symbol interned (not neccessarily defined) locally in a given module
1132 ;; or its uses? Interned symbols shadow inherited bindings even if
1133 ;; they are not themselves bound to a defined value.
1134 ;;
1135 (define (module-symbol-locally-interned? m v)
1136 (not (not (module-obarray-get-handle (module-obarray m) v))))
1137
1138 ;; module-symbol-interned? module symbol
1139 ;;
1140 ;; is a symbol interned (not neccessarily defined) anywhere in a given module
1141 ;; or its uses? Interned symbols shadow inherited bindings even if
1142 ;; they are not themselves bound to a defined value.
1143 ;;
1144 (define (module-symbol-interned? m v)
1145 (module-search module-symbol-locally-interned? m v))
1146
1147
1148 ;;; {Mapping modules x symbols --> variables}
1149 ;;;
1150
1151 ;; module-local-variable module symbol
1152 ;; return the local variable associated with a MODULE and SYMBOL.
1153 ;;
1154 ;;; This function is very important. It is the only function that can
1155 ;;; return a variable from a module other than the mutators that store
1156 ;;; new variables in modules. Therefore, this function is the location
1157 ;;; of the "lazy binder" hack.
1158 ;;;
1159 ;;; If symbol is defined in MODULE, and if the definition binds symbol
1160 ;;; to a variable, return that variable object.
1161 ;;;
1162 ;;; If the symbols is not found at first, but the module has a lazy binder,
1163 ;;; then try the binder.
1164 ;;;
1165 ;;; If the symbol is not found at all, return #f.
1166 ;;;
1167 (define (module-local-variable m v)
1168 ; (caddr
1169 ; (list m v
1170 (let ((b (module-obarray-ref (module-obarray m) v)))
1171 (or (and (variable? b) b)
1172 (and (module-binder m)
1173 ((module-binder m) m v #f)))))
1174 ;))
1175
1176 ;; module-variable module symbol
1177 ;;
1178 ;; like module-local-variable, except search the uses in the
1179 ;; case V is not found in M.
1180 ;;
1181 ;; NOTE: This function is superseded with C code (see modules.c)
1182 ;;; when using the standard eval closure.
1183 ;;
1184 (define (module-variable m v)
1185 (module-search module-local-variable m v))
1186
1187
1188 ;;; {Mapping modules x symbols --> bindings}
1189 ;;;
1190 ;;; These are similar to the mapping to variables, except that the
1191 ;;; variable is dereferenced.
1192 ;;;
1193
1194 ;; module-symbol-binding module symbol opt-value
1195 ;;
1196 ;; return the binding of a variable specified by name within
1197 ;; a given module, signalling an error if the variable is unbound.
1198 ;; If the OPT-VALUE is passed, then instead of signalling an error,
1199 ;; return OPT-VALUE.
1200 ;;
1201 (define (module-symbol-local-binding m v . opt-val)
1202 (let ((var (module-local-variable m v)))
1203 (if var
1204 (variable-ref var)
1205 (if (not (null? opt-val))
1206 (car opt-val)
1207 (error "Locally unbound variable." v)))))
1208
1209 ;; module-symbol-binding module symbol opt-value
1210 ;;
1211 ;; return the binding of a variable specified by name within
1212 ;; a given module, signalling an error if the variable is unbound.
1213 ;; If the OPT-VALUE is passed, then instead of signalling an error,
1214 ;; return OPT-VALUE.
1215 ;;
1216 (define (module-symbol-binding m v . opt-val)
1217 (let ((var (module-variable m v)))
1218 (if var
1219 (variable-ref var)
1220 (if (not (null? opt-val))
1221 (car opt-val)
1222 (error "Unbound variable." v)))))
1223
1224
1225 \f
1226 ;;; {Adding Variables to Modules}
1227 ;;;
1228 ;;;
1229
1230
1231 ;; module-make-local-var! module symbol
1232 ;;
1233 ;; ensure a variable for V in the local namespace of M.
1234 ;; If no variable was already there, then create a new and uninitialzied
1235 ;; variable.
1236 ;;
1237 (define (module-make-local-var! m v)
1238 (or (let ((b (module-obarray-ref (module-obarray m) v)))
1239 (and (variable? b)
1240 (begin
1241 (module-modified m)
1242 b)))
1243 (and (module-binder m)
1244 ((module-binder m) m v #t))
1245 (begin
1246 (let ((answer (make-undefined-variable v)))
1247 (module-obarray-set! (module-obarray m) v answer)
1248 (module-modified m)
1249 answer))))
1250
1251 ;; module-add! module symbol var
1252 ;;
1253 ;; ensure a particular variable for V in the local namespace of M.
1254 ;;
1255 (define (module-add! m v var)
1256 (if (not (variable? var))
1257 (error "Bad variable to module-add!" var))
1258 (module-obarray-set! (module-obarray m) v var)
1259 (module-modified m))
1260
1261 ;; module-remove!
1262 ;;
1263 ;; make sure that a symbol is undefined in the local namespace of M.
1264 ;;
1265 (define (module-remove! m v)
1266 (module-obarray-remove! (module-obarray m) v)
1267 (module-modified m))
1268
1269 (define (module-clear! m)
1270 (vector-fill! (module-obarray m) '())
1271 (module-modified m))
1272
1273 ;; MODULE-FOR-EACH -- exported
1274 ;;
1275 ;; Call PROC on each symbol in MODULE, with arguments of (SYMBOL VARIABLE).
1276 ;;
1277 (define (module-for-each proc module)
1278 (let ((obarray (module-obarray module)))
1279 (do ((index 0 (+ index 1))
1280 (end (vector-length obarray)))
1281 ((= index end))
1282 (for-each
1283 (lambda (bucket)
1284 (proc (car bucket) (cdr bucket)))
1285 (vector-ref obarray index)))))
1286
1287
1288 (define (module-map proc module)
1289 (let* ((obarray (module-obarray module))
1290 (end (vector-length obarray)))
1291
1292 (let loop ((i 0)
1293 (answer '()))
1294 (if (= i end)
1295 answer
1296 (loop (+ 1 i)
1297 (append!
1298 (map (lambda (bucket)
1299 (proc (car bucket) (cdr bucket)))
1300 (vector-ref obarray i))
1301 answer))))))
1302 \f
1303
1304 ;;; {Low Level Bootstrapping}
1305 ;;;
1306
1307 ;; make-root-module
1308
1309 ;; A root module uses the symhash table (the system's privileged
1310 ;; obarray). Being inside a root module is like using SCM without
1311 ;; any module system.
1312 ;;
1313
1314
1315 (define (root-module-closure m s define?)
1316 (let ((bi (builtin-variable s)))
1317 (and bi
1318 (or define? (variable-bound? bi))
1319 (begin
1320 (module-add! m s bi)
1321 bi))))
1322
1323 (define (make-root-module)
1324 (make-module 1019 '() root-module-closure))
1325
1326
1327 ;; make-scm-module
1328
1329 ;; An scm module is a module into which the lazy binder copies
1330 ;; variable bindings from the system symhash table. The mapping is
1331 ;; one way only; newly introduced bindings in an scm module are not
1332 ;; copied back into the system symhash table (and can be used to override
1333 ;; bindings from the symhash table).
1334 ;;
1335
1336 (define (scm-module-closure m s define?)
1337 (let ((bi (builtin-variable s)))
1338 (and bi
1339 (variable-bound? bi)
1340 (begin
1341 (module-add! m s bi)
1342 bi))))
1343
1344 (define (make-scm-module)
1345 (make-module 1019 '() scm-module-closure))
1346
1347
1348
1349 ;; the-module
1350 ;;
1351 ;; NOTE: This binding is used in libguile/modules.c.
1352 ;;
1353 (define the-module (make-fluid))
1354
1355 ;; scm:eval-transformer
1356 ;;
1357 ;;(define scm:eval-transformer (make-fluid)) ; initialized in eval.c.
1358
1359 ;; set-current-module module
1360 ;;
1361 ;; set the current module as viewed by the normalizer.
1362 ;;
1363 ;; NOTE: This binding is used in libguile/modules.c.
1364 ;;
1365 (define (set-current-module m)
1366 (fluid-set! the-module m)
1367 (if m
1368 (begin
1369 ;; *top-level-lookup-closure* is now deprecated
1370 (fluid-set! *top-level-lookup-closure*
1371 (module-eval-closure (fluid-ref the-module)))
1372 (fluid-set! scm:eval-transformer (module-transformer (fluid-ref the-module))))
1373 (fluid-set! *top-level-lookup-closure* #f)))
1374
1375
1376 ;; current-module
1377 ;;
1378 ;; return the current module as viewed by the normalizer.
1379 ;;
1380 (define (current-module) (fluid-ref the-module))
1381 \f
1382 ;;; {Module-based Loading}
1383 ;;;
1384
1385 (define (save-module-excursion thunk)
1386 (let ((inner-module (current-module))
1387 (outer-module #f))
1388 (dynamic-wind (lambda ()
1389 (set! outer-module (current-module))
1390 (set-current-module inner-module)
1391 (set! inner-module #f))
1392 thunk
1393 (lambda ()
1394 (set! inner-module (current-module))
1395 (set-current-module outer-module)
1396 (set! outer-module #f)))))
1397
1398 (define basic-load load)
1399
1400 (define (load-module filename)
1401 (save-module-excursion
1402 (lambda ()
1403 (let ((oldname (and (current-load-port)
1404 (port-filename (current-load-port)))))
1405 (basic-load (if (and oldname
1406 (> (string-length filename) 0)
1407 (not (char=? (string-ref filename 0) #\/))
1408 (not (string=? (dirname oldname) ".")))
1409 (string-append (dirname oldname) "/" filename)
1410 filename))))))
1411
1412
1413 \f
1414 ;;; {MODULE-REF -- exported}
1415 ;;
1416 ;; Returns the value of a variable called NAME in MODULE or any of its
1417 ;; used modules. If there is no such variable, then if the optional third
1418 ;; argument DEFAULT is present, it is returned; otherwise an error is signaled.
1419 ;;
1420 (define (module-ref module name . rest)
1421 (let ((variable (module-variable module name)))
1422 (if (and variable (variable-bound? variable))
1423 (variable-ref variable)
1424 (if (null? rest)
1425 (error "No variable named" name 'in module)
1426 (car rest) ; default value
1427 ))))
1428
1429 ;; MODULE-SET! -- exported
1430 ;;
1431 ;; Sets the variable called NAME in MODULE (or in a module that MODULE uses)
1432 ;; to VALUE; if there is no such variable, an error is signaled.
1433 ;;
1434 (define (module-set! module name value)
1435 (let ((variable (module-variable module name)))
1436 (if variable
1437 (variable-set! variable value)
1438 (error "No variable named" name 'in module))))
1439
1440 ;; MODULE-DEFINE! -- exported
1441 ;;
1442 ;; Sets the variable called NAME in MODULE to VALUE; if there is no such
1443 ;; variable, it is added first.
1444 ;;
1445 (define (module-define! module name value)
1446 (let ((variable (module-local-variable module name)))
1447 (if variable
1448 (begin
1449 (variable-set! variable value)
1450 (module-modified module))
1451 (module-add! module name (make-variable value name)))))
1452
1453 ;; MODULE-DEFINED? -- exported
1454 ;;
1455 ;; Return #t iff NAME is defined in MODULE (or in a module that MODULE
1456 ;; uses)
1457 ;;
1458 (define (module-defined? module name)
1459 (let ((variable (module-variable module name)))
1460 (and variable (variable-bound? variable))))
1461
1462 ;; MODULE-USE! module interface
1463 ;;
1464 ;; Add INTERFACE to the list of interfaces used by MODULE.
1465 ;;
1466 (define (module-use! module interface)
1467 (set-module-uses! module
1468 (cons interface (delq! interface (module-uses module))))
1469 (module-modified module))
1470
1471 \f
1472 ;;; {Recursive Namespaces}
1473 ;;;
1474 ;;;
1475 ;;; A hierarchical namespace emerges if we consider some module to be
1476 ;;; root, and variables bound to modules as nested namespaces.
1477 ;;;
1478 ;;; The routines in this file manage variable names in hierarchical namespace.
1479 ;;; Each variable name is a list of elements, looked up in successively nested
1480 ;;; modules.
1481 ;;;
1482 ;;; (nested-ref some-root-module '(foo bar baz))
1483 ;;; => <value of a variable named baz in the module bound to bar in
1484 ;;; the module bound to foo in some-root-module>
1485 ;;;
1486 ;;;
1487 ;;; There are:
1488 ;;;
1489 ;;; ;; a-root is a module
1490 ;;; ;; name is a list of symbols
1491 ;;;
1492 ;;; nested-ref a-root name
1493 ;;; nested-set! a-root name val
1494 ;;; nested-define! a-root name val
1495 ;;; nested-remove! a-root name
1496 ;;;
1497 ;;;
1498 ;;; (current-module) is a natural choice for a-root so for convenience there are
1499 ;;; also:
1500 ;;;
1501 ;;; local-ref name == nested-ref (current-module) name
1502 ;;; local-set! name val == nested-set! (current-module) name val
1503 ;;; local-define! name val == nested-define! (current-module) name val
1504 ;;; local-remove! name == nested-remove! (current-module) name
1505 ;;;
1506
1507
1508 (define (nested-ref root names)
1509 (let loop ((cur root)
1510 (elts names))
1511 (cond
1512 ((null? elts) cur)
1513 ((not (module? cur)) #f)
1514 (else (loop (module-ref cur (car elts) #f) (cdr elts))))))
1515
1516 (define (nested-set! root names val)
1517 (let loop ((cur root)
1518 (elts names))
1519 (if (null? (cdr elts))
1520 (module-set! cur (car elts) val)
1521 (loop (module-ref cur (car elts)) (cdr elts)))))
1522
1523 (define (nested-define! root names val)
1524 (let loop ((cur root)
1525 (elts names))
1526 (if (null? (cdr elts))
1527 (module-define! cur (car elts) val)
1528 (loop (module-ref cur (car elts)) (cdr elts)))))
1529
1530 (define (nested-remove! root names)
1531 (let loop ((cur root)
1532 (elts names))
1533 (if (null? (cdr elts))
1534 (module-remove! cur (car elts))
1535 (loop (module-ref cur (car elts)) (cdr elts)))))
1536
1537 (define (local-ref names) (nested-ref (current-module) names))
1538 (define (local-set! names val) (nested-set! (current-module) names val))
1539 (define (local-define names val) (nested-define! (current-module) names val))
1540 (define (local-remove names) (nested-remove! (current-module) names))
1541
1542
1543 \f
1544 ;;; {The (app) module}
1545 ;;;
1546 ;;; The root of conventionally named objects not directly in the top level.
1547 ;;;
1548 ;;; (app modules)
1549 ;;; (app modules guile)
1550 ;;;
1551 ;;; The directory of all modules and the standard root module.
1552 ;;;
1553
1554 (define (module-public-interface m)
1555 (module-ref m '%module-public-interface #f))
1556 (define (set-module-public-interface! m i)
1557 (module-define! m '%module-public-interface i))
1558 (define (set-system-module! m s)
1559 (set-procedure-property! (module-eval-closure m) 'system-module s))
1560 (define the-root-module (make-root-module))
1561 (define the-scm-module (make-scm-module))
1562 (set-module-public-interface! the-root-module the-scm-module)
1563 (set-module-name! the-root-module '(guile))
1564 (set-module-name! the-scm-module '(guile))
1565 (set-module-kind! the-scm-module 'interface)
1566 (for-each set-system-module! (list the-root-module the-scm-module) '(#t #t))
1567
1568 (set-current-module the-root-module)
1569
1570 (define app (make-module 31))
1571 (local-define '(app modules) (make-module 31))
1572 (local-define '(app modules guile) the-root-module)
1573
1574 ;; (define-special-value '(app modules new-ws) (lambda () (make-scm-module)))
1575
1576 (define (try-load-module name)
1577 (or (try-module-linked name)
1578 (try-module-autoload name)
1579 (try-module-dynamic-link name)))
1580
1581 ;; NOTE: This binding is used in libguile/modules.c.
1582 ;;
1583 (define (resolve-module name . maybe-autoload)
1584 (let ((full-name (append '(app modules) name)))
1585 (let ((already (local-ref full-name)))
1586 (if already
1587 ;; The module already exists...
1588 (if (and (or (null? maybe-autoload) (car maybe-autoload))
1589 (not (module-ref already '%module-public-interface #f)))
1590 ;; ...but we are told to load and it doesn't contain source, so
1591 (begin
1592 (try-load-module name)
1593 already)
1594 ;; simply return it.
1595 already)
1596 (begin
1597 ;; Try to autoload it if we are told so
1598 (if (or (null? maybe-autoload) (car maybe-autoload))
1599 (try-load-module name))
1600 ;; Get/create it.
1601 (make-modules-in (current-module) full-name))))))
1602
1603 (define (beautify-user-module! module)
1604 (let ((interface (module-public-interface module)))
1605 (if (or (not interface)
1606 (eq? interface module))
1607 (let ((interface (make-module 31)))
1608 (set-module-name! interface (module-name module))
1609 (set-module-kind! interface 'interface)
1610 (set-module-public-interface! module interface))))
1611 (if (and (not (memq the-scm-module (module-uses module)))
1612 (not (eq? module the-root-module)))
1613 (set-module-uses! module (append (module-uses module) (list the-scm-module)))))
1614
1615 (define (purify-module! module)
1616 "Removes bindings in MODULE which are inherited from the (guile) module."
1617 (let ((use-list (module-uses module)))
1618 (if (and (pair? use-list)
1619 (eq? (car (last-pair use-list)) the-scm-module))
1620 (set-module-uses! module (reverse (cdr (reverse use-list)))))))
1621
1622 ;; NOTE: This binding is used in libguile/modules.c.
1623 ;;
1624 (define (make-modules-in module name)
1625 (if (null? name)
1626 module
1627 (cond
1628 ((module-ref module (car name) #f)
1629 => (lambda (m) (make-modules-in m (cdr name))))
1630 (else (let ((m (make-module 31)))
1631 (set-module-kind! m 'directory)
1632 (set-module-name! m (append (or (module-name module)
1633 '())
1634 (list (car name))))
1635 (module-define! module (car name) m)
1636 (make-modules-in m (cdr name)))))))
1637
1638 (define (resolve-interface name)
1639 (let ((module (resolve-module name)))
1640 (and module (module-public-interface module))))
1641
1642
1643 (define %autoloader-developer-mode #t)
1644
1645 (define (process-define-module args)
1646 (let* ((module-id (car args))
1647 (module (resolve-module module-id #f))
1648 (kws (cdr args)))
1649 (beautify-user-module! module)
1650 (let loop ((kws kws)
1651 (reversed-interfaces '())
1652 (exports '()))
1653 (if (null? kws)
1654 (begin
1655 (for-each (lambda (interface)
1656 (module-use! module interface))
1657 reversed-interfaces)
1658 (module-export! module exports))
1659 (let ((keyword (if (keyword? (car kws))
1660 (keyword->symbol (car kws))
1661 (and (symbol? (car kws))
1662 (let ((s (symbol->string (car kws))))
1663 (and (eq? (string-ref s 0) #\:)
1664 (string->symbol (substring s 1))))))))
1665 (case keyword
1666 ((use-module use-syntax)
1667 (if (not (pair? (cdr kws)))
1668 (error "unrecognized defmodule argument" kws))
1669 (let* ((used-name (cadr kws))
1670 (used-module (resolve-module used-name)))
1671 (if (not (module-ref used-module
1672 '%module-public-interface
1673 #f))
1674 (begin
1675 ((if %autoloader-developer-mode warn error)
1676 "no code for module" (module-name used-module))
1677 (beautify-user-module! used-module)))
1678 (let ((interface (module-public-interface used-module)))
1679 (if (not interface)
1680 (error "missing interface for use-module"
1681 used-module))
1682 (if (eq? keyword 'use-syntax)
1683 (set-module-transformer!
1684 module
1685 (module-ref interface (car (last-pair used-name))
1686 #f)))
1687 (loop (cddr kws)
1688 (cons interface reversed-interfaces)
1689 exports))))
1690 ((autoload)
1691 (if (not (and (pair? (cdr kws)) (pair? (cddr kws))))
1692 (error "unrecognized defmodule argument" kws))
1693 (loop (cdddr kws)
1694 (cons (make-autoload-interface module
1695 (cadr kws)
1696 (caddr kws))
1697 reversed-interfaces)
1698 exports))
1699 ((no-backtrace)
1700 (set-system-module! module #t)
1701 (loop (cdr kws) reversed-interfaces exports))
1702 ((pure)
1703 (purify-module! module)
1704 (loop (cdr kws) reversed-interfaces exports))
1705 ((export)
1706 (if (not (pair? (cdr kws)))
1707 (error "unrecognized defmodule argument" kws))
1708 (loop (cddr kws)
1709 reversed-interfaces
1710 (append (cadr kws) exports)))
1711 (else
1712 (error "unrecognized defmodule argument" kws))))))
1713 (set-current-module module)
1714 module))
1715
1716 ;;; {Autoload}
1717
1718 (define (make-autoload-interface module name bindings)
1719 (let ((b (lambda (a sym definep)
1720 (and (memq sym bindings)
1721 (let ((i (module-public-interface (resolve-module name))))
1722 (if (not i)
1723 (error "missing interface for module" name))
1724 ;; Replace autoload-interface with interface
1725 (set-car! (memq a (module-uses module)) i)
1726 (module-local-variable i sym))))))
1727 (module-constructor #() '() b #f #f name 'autoload
1728 '() (make-weak-value-hash-table 31) 0)))
1729
1730 \f
1731 ;;; {Autoloading modules}
1732
1733 (define autoloads-in-progress '())
1734
1735 (define (try-module-autoload module-name)
1736 (let* ((reverse-name (reverse module-name))
1737 (name (symbol->string (car reverse-name)))
1738 (dir-hint-module-name (reverse (cdr reverse-name)))
1739 (dir-hint (apply string-append
1740 (map (lambda (elt)
1741 (string-append (symbol->string elt) "/"))
1742 dir-hint-module-name))))
1743 (resolve-module dir-hint-module-name #f)
1744 (and (not (autoload-done-or-in-progress? dir-hint name))
1745 (let ((didit #f))
1746 (dynamic-wind
1747 (lambda () (autoload-in-progress! dir-hint name))
1748 (lambda ()
1749 (let ((full (%search-load-path (in-vicinity dir-hint name))))
1750 (if full
1751 (begin
1752 (save-module-excursion (lambda () (primitive-load full)))
1753 (set! didit #t)))))
1754 (lambda () (set-autoloaded! dir-hint name didit)))
1755 didit))))
1756
1757 \f
1758 ;;; Dynamic linking of modules
1759
1760 ;; Initializing a module that is written in C is a two step process.
1761 ;; First the module's `module init' function is called. This function
1762 ;; is expected to call `scm_register_module_xxx' to register the `real
1763 ;; init' function. Later, when the module is referenced for the first
1764 ;; time, this real init function is called in the right context. See
1765 ;; gtcltk-lib/gtcltk-module.c for an example.
1766 ;;
1767 ;; The code for the module can be in a regular shared library (so that
1768 ;; the `module init' function will be called when libguile is
1769 ;; initialized). Or it can be dynamically linked.
1770 ;;
1771 ;; You can safely call `scm_register_module_xxx' before libguile
1772 ;; itself is initialized. You could call it from an C++ constructor
1773 ;; of a static object, for example.
1774 ;;
1775 ;; To make your Guile extension into a dynamic linkable module, follow
1776 ;; these easy steps:
1777 ;;
1778 ;; - Find a name for your module, like (ice-9 gtcltk)
1779 ;; - Write a function with a name like
1780 ;;
1781 ;; scm_init_ice_9_gtcltk_module
1782 ;;
1783 ;; This is your `module init' function. It should call
1784 ;;
1785 ;; scm_register_module_xxx ("ice-9 gtcltk", scm_init_gtcltk);
1786 ;;
1787 ;; "ice-9 gtcltk" is the C version of the module name. Slashes are
1788 ;; replaced by spaces, the rest is untouched. `scm_init_gtcltk' is
1789 ;; the real init function that executes the usual initializations
1790 ;; like making new smobs, etc.
1791 ;;
1792 ;; - Make a shared library with your code and a name like
1793 ;;
1794 ;; ice-9/libgtcltk.so
1795 ;;
1796 ;; and put it somewhere in %load-path.
1797 ;;
1798 ;; - Then you can simply write `:use-module (ice-9 gtcltk)' and it
1799 ;; will be linked automatically.
1800 ;;
1801 ;; This is all very experimental.
1802
1803 (define (split-c-module-name str)
1804 (let loop ((rev '())
1805 (start 0)
1806 (pos 0)
1807 (end (string-length str)))
1808 (cond
1809 ((= pos end)
1810 (reverse (cons (string->symbol (substring str start pos)) rev)))
1811 ((eq? (string-ref str pos) #\space)
1812 (loop (cons (string->symbol (substring str start pos)) rev)
1813 (+ pos 1)
1814 (+ pos 1)
1815 end))
1816 (else
1817 (loop rev start (+ pos 1) end)))))
1818
1819 (define (convert-c-registered-modules dynobj)
1820 (let ((res (map (lambda (c)
1821 (list (split-c-module-name (car c)) (cdr c) dynobj))
1822 (c-registered-modules))))
1823 (c-clear-registered-modules)
1824 res))
1825
1826 (define registered-modules '())
1827
1828 (define (register-modules dynobj)
1829 (set! registered-modules
1830 (append! (convert-c-registered-modules dynobj)
1831 registered-modules)))
1832
1833 (define (warn-autoload-deprecation modname)
1834 (display
1835 ";;; Autoloading of compiled code modules is deprecated.\n"
1836 (current-error-port))
1837 (display
1838 ";;; Write a Scheme file instead that uses `dynamic-link' directly.\n"
1839 (current-error-port))
1840 (format (current-error-port)
1841 ";;; (You just tried to autoload module ~S.)\n" modname))
1842
1843 (define (init-dynamic-module modname)
1844 ;; Register any linked modules which has been registered on the C level
1845 (register-modules #f)
1846 (or-map (lambda (modinfo)
1847 (if (equal? (car modinfo) modname)
1848 (begin
1849 (warn-autoload-deprecation modname)
1850 (set! registered-modules (delq! modinfo registered-modules))
1851 (let ((mod (resolve-module modname #f)))
1852 (save-module-excursion
1853 (lambda ()
1854 (set-current-module mod)
1855 (set-module-public-interface! mod mod)
1856 (dynamic-call (cadr modinfo) (caddr modinfo))
1857 ))
1858 #t))
1859 #f))
1860 registered-modules))
1861
1862 (define (dynamic-maybe-call name dynobj)
1863 (catch #t ; could use false-if-exception here
1864 (lambda ()
1865 (dynamic-call name dynobj))
1866 (lambda args
1867 #f)))
1868
1869 (define (dynamic-maybe-link filename)
1870 (catch #t ; could use false-if-exception here
1871 (lambda ()
1872 (dynamic-link filename))
1873 (lambda args
1874 #f)))
1875
1876 (define (find-and-link-dynamic-module module-name)
1877 (define (make-init-name mod-name)
1878 (string-append "scm_init"
1879 (list->string (map (lambda (c)
1880 (if (or (char-alphabetic? c)
1881 (char-numeric? c))
1882 c
1883 #\_))
1884 (string->list mod-name)))
1885 "_module"))
1886
1887 ;; Put the subdirectory for this module in the car of SUBDIR-AND-LIBNAME,
1888 ;; and the `libname' (the name of the module prepended by `lib') in the cdr
1889 ;; field. For example, if MODULE-NAME is the list (inet tcp-ip udp), then
1890 ;; SUBDIR-AND-LIBNAME will be the pair ("inet/tcp-ip" . "libudp").
1891 (let ((subdir-and-libname
1892 (let loop ((dirs "")
1893 (syms module-name))
1894 (if (null? (cdr syms))
1895 (cons dirs (string-append "lib" (symbol->string (car syms))))
1896 (loop (string-append dirs (symbol->string (car syms)) "/")
1897 (cdr syms)))))
1898 (init (make-init-name (apply string-append
1899 (map (lambda (s)
1900 (string-append "_"
1901 (symbol->string s)))
1902 module-name)))))
1903 (let ((subdir (car subdir-and-libname))
1904 (libname (cdr subdir-and-libname)))
1905
1906 ;; Now look in each dir in %LOAD-PATH for `subdir/libfoo.la'. If that
1907 ;; file exists, fetch the dlname from that file and attempt to link
1908 ;; against it. If `subdir/libfoo.la' does not exist, or does not seem
1909 ;; to name any shared library, look for `subdir/libfoo.so' instead and
1910 ;; link against that.
1911 (let check-dirs ((dir-list %load-path))
1912 (if (null? dir-list)
1913 #f
1914 (let* ((dir (in-vicinity (car dir-list) subdir))
1915 (sharlib-full
1916 (or (try-using-libtool-name dir libname)
1917 (try-using-sharlib-name dir libname))))
1918 (if (and sharlib-full (file-exists? sharlib-full))
1919 (link-dynamic-module sharlib-full init)
1920 (check-dirs (cdr dir-list)))))))))
1921
1922 (define (try-using-libtool-name libdir libname)
1923 (let ((libtool-filename (in-vicinity libdir
1924 (string-append libname ".la"))))
1925 (and (file-exists? libtool-filename)
1926 libtool-filename)))
1927
1928 (define (try-using-sharlib-name libdir libname)
1929 (in-vicinity libdir (string-append libname ".so")))
1930
1931 (define (link-dynamic-module filename initname)
1932 ;; Register any linked modules which has been registered on the C level
1933 (register-modules #f)
1934 (let ((dynobj (dynamic-link filename)))
1935 (dynamic-call initname dynobj)
1936 (register-modules dynobj)))
1937
1938 (define (try-module-linked module-name)
1939 (init-dynamic-module module-name))
1940
1941 (define (try-module-dynamic-link module-name)
1942 (and (find-and-link-dynamic-module module-name)
1943 (init-dynamic-module module-name)))
1944
1945
1946
1947 (define autoloads-done '((guile . guile)))
1948
1949 (define (autoload-done-or-in-progress? p m)
1950 (let ((n (cons p m)))
1951 (->bool (or (member n autoloads-done)
1952 (member n autoloads-in-progress)))))
1953
1954 (define (autoload-done! p m)
1955 (let ((n (cons p m)))
1956 (set! autoloads-in-progress
1957 (delete! n autoloads-in-progress))
1958 (or (member n autoloads-done)
1959 (set! autoloads-done (cons n autoloads-done)))))
1960
1961 (define (autoload-in-progress! p m)
1962 (let ((n (cons p m)))
1963 (set! autoloads-done
1964 (delete! n autoloads-done))
1965 (set! autoloads-in-progress (cons n autoloads-in-progress))))
1966
1967 (define (set-autoloaded! p m done?)
1968 (if done?
1969 (autoload-done! p m)
1970 (let ((n (cons p m)))
1971 (set! autoloads-done (delete! n autoloads-done))
1972 (set! autoloads-in-progress (delete! n autoloads-in-progress)))))
1973
1974
1975
1976 \f
1977 ;; {EVAL-CASE}
1978 ;;
1979 ;; (eval-case ((situation*) forms)* (else forms)?)
1980 ;;
1981 ;; Evaluate certain code based on the situation that eval-case is used
1982 ;; in. The only defined situation right now is `load-toplevel' which
1983 ;; triggers for code evaluated at the top-level, for example from the
1984 ;; REPL or when loading a file.
1985
1986 (define eval-case
1987 (procedure->memoizing-macro
1988 (lambda (exp env)
1989 (define (toplevel-env? env)
1990 (or (not (pair? env)) (not (pair? (car env)))))
1991 (define (syntax)
1992 (error "syntax error in eval-case"))
1993 (let loop ((clauses (cdr exp)))
1994 (cond
1995 ((null? clauses)
1996 #f)
1997 ((not (list? (car clauses)))
1998 (syntax))
1999 ((eq? 'else (caar clauses))
2000 (or (null? (cdr clauses))
2001 (syntax))
2002 (cons 'begin (cdar clauses)))
2003 ((not (list? (caar clauses)))
2004 (syntax))
2005 ((and (toplevel-env? env)
2006 (memq 'load-toplevel (caar clauses)))
2007 (cons 'begin (cdar clauses)))
2008 (else
2009 (loop (cdr clauses))))))))
2010
2011 \f
2012 ;;; {Macros}
2013 ;;;
2014
2015 (define (primitive-macro? m)
2016 (and (macro? m)
2017 (not (macro-transformer m))))
2018
2019 ;;; {Defmacros}
2020 ;;;
2021 (define macro-table (make-weak-key-hash-table 523))
2022 (define xformer-table (make-weak-key-hash-table 523))
2023
2024 (define (defmacro? m) (hashq-ref macro-table m))
2025 (define (assert-defmacro?! m) (hashq-set! macro-table m #t))
2026 (define (defmacro-transformer m) (hashq-ref xformer-table m))
2027 (define (set-defmacro-transformer! m t) (hashq-set! xformer-table m t))
2028
2029 (define defmacro:transformer
2030 (lambda (f)
2031 (let* ((xform (lambda (exp env)
2032 (copy-tree (apply f (cdr exp)))))
2033 (a (procedure->memoizing-macro xform)))
2034 (assert-defmacro?! a)
2035 (set-defmacro-transformer! a f)
2036 a)))
2037
2038
2039 (define defmacro
2040 (let ((defmacro-transformer
2041 (lambda (name parms . body)
2042 (let ((transformer `(lambda ,parms ,@body)))
2043 `(eval-case
2044 ((load-toplevel)
2045 (define ,name (defmacro:transformer ,transformer)))
2046 (else
2047 (error "defmacro can only be used at the top level")))))))
2048 (defmacro:transformer defmacro-transformer)))
2049
2050 (define defmacro:syntax-transformer
2051 (lambda (f)
2052 (procedure->syntax
2053 (lambda (exp env)
2054 (copy-tree (apply f (cdr exp)))))))
2055
2056
2057 ;; XXX - should the definition of the car really be looked up in the
2058 ;; current module?
2059
2060 (define (macroexpand-1 e)
2061 (cond
2062 ((pair? e) (let* ((a (car e))
2063 (val (and (symbol? a) (local-ref (list a)))))
2064 (if (defmacro? val)
2065 (apply (defmacro-transformer val) (cdr e))
2066 e)))
2067 (#t e)))
2068
2069 (define (macroexpand e)
2070 (cond
2071 ((pair? e) (let* ((a (car e))
2072 (val (and (symbol? a) (local-ref (list a)))))
2073 (if (defmacro? val)
2074 (macroexpand (apply (defmacro-transformer val) (cdr e)))
2075 e)))
2076 (#t e)))
2077
2078 (provide 'defmacro)
2079
2080 \f
2081
2082 ;;; {Run-time options}
2083
2084 (define define-option-interface
2085 (let* ((option-name car)
2086 (option-value cadr)
2087 (option-documentation caddr)
2088
2089 (print-option (lambda (option)
2090 (display (option-name option))
2091 (if (< (string-length
2092 (symbol->string (option-name option)))
2093 8)
2094 (display #\tab))
2095 (display #\tab)
2096 (display (option-value option))
2097 (display #\tab)
2098 (display (option-documentation option))
2099 (newline)))
2100
2101 ;; Below follow the macros defining the run-time option interfaces.
2102
2103 (make-options (lambda (interface)
2104 `(lambda args
2105 (cond ((null? args) (,interface))
2106 ((list? (car args))
2107 (,interface (car args)) (,interface))
2108 (else (for-each ,print-option
2109 (,interface #t)))))))
2110
2111 (make-enable (lambda (interface)
2112 `(lambda flags
2113 (,interface (append flags (,interface)))
2114 (,interface))))
2115
2116 (make-disable (lambda (interface)
2117 `(lambda flags
2118 (let ((options (,interface)))
2119 (for-each (lambda (flag)
2120 (set! options (delq! flag options)))
2121 flags)
2122 (,interface options)
2123 (,interface)))))
2124
2125 (make-set! (lambda (interface)
2126 `((name exp)
2127 (,'quasiquote
2128 (begin (,interface (append (,interface)
2129 (list '(,'unquote name)
2130 (,'unquote exp))))
2131 (,interface)))))))
2132 (procedure->macro
2133 (lambda (exp env)
2134 (cons 'begin
2135 (let* ((option-group (cadr exp))
2136 (interface (car option-group)))
2137 (append (map (lambda (name constructor)
2138 `(define ,name
2139 ,(constructor interface)))
2140 (cadr option-group)
2141 (list make-options
2142 make-enable
2143 make-disable))
2144 (map (lambda (name constructor)
2145 `(defmacro ,name
2146 ,@(constructor interface)))
2147 (caddr option-group)
2148 (list make-set!)))))))))
2149
2150 (define-option-interface
2151 (eval-options-interface
2152 (eval-options eval-enable eval-disable)
2153 (eval-set!)))
2154
2155 (define-option-interface
2156 (debug-options-interface
2157 (debug-options debug-enable debug-disable)
2158 (debug-set!)))
2159
2160 (define-option-interface
2161 (evaluator-traps-interface
2162 (traps trap-enable trap-disable)
2163 (trap-set!)))
2164
2165 (define-option-interface
2166 (read-options-interface
2167 (read-options read-enable read-disable)
2168 (read-set!)))
2169
2170 (define-option-interface
2171 (print-options-interface
2172 (print-options print-enable print-disable)
2173 (print-set!)))
2174
2175 \f
2176
2177 ;;; {Running Repls}
2178 ;;;
2179
2180 (define (repl read evaler print)
2181 (let loop ((source (read (current-input-port))))
2182 (print (evaler source))
2183 (loop (read (current-input-port)))))
2184
2185 ;; A provisional repl that acts like the SCM repl:
2186 ;;
2187 (define scm-repl-silent #f)
2188 (define (assert-repl-silence v) (set! scm-repl-silent v))
2189
2190 (define *unspecified* (if #f #f))
2191 (define (unspecified? v) (eq? v *unspecified*))
2192
2193 (define scm-repl-print-unspecified #f)
2194 (define (assert-repl-print-unspecified v) (set! scm-repl-print-unspecified v))
2195
2196 (define scm-repl-verbose #f)
2197 (define (assert-repl-verbosity v) (set! scm-repl-verbose v))
2198
2199 (define scm-repl-prompt "guile> ")
2200
2201 (define (set-repl-prompt! v) (set! scm-repl-prompt v))
2202
2203 (define (default-lazy-handler key . args)
2204 (save-stack lazy-handler-dispatch)
2205 (apply throw key args))
2206
2207 (define enter-frame-handler default-lazy-handler)
2208 (define apply-frame-handler default-lazy-handler)
2209 (define exit-frame-handler default-lazy-handler)
2210
2211 (define (lazy-handler-dispatch key . args)
2212 (case key
2213 ((apply-frame)
2214 (apply apply-frame-handler key args))
2215 ((exit-frame)
2216 (apply exit-frame-handler key args))
2217 ((enter-frame)
2218 (apply enter-frame-handler key args))
2219 (else
2220 (apply default-lazy-handler key args))))
2221
2222 (define abort-hook (make-hook))
2223
2224 ;; these definitions are used if running a script.
2225 ;; otherwise redefined in error-catching-loop.
2226 (define (set-batch-mode?! arg) #t)
2227 (define (batch-mode?) #t)
2228
2229 (define (error-catching-loop thunk)
2230 (let ((status #f)
2231 (interactive #t))
2232 (define (loop first)
2233 (let ((next
2234 (catch #t
2235
2236 (lambda ()
2237 (lazy-catch #t
2238 (lambda ()
2239 (dynamic-wind
2240 (lambda () (unmask-signals))
2241 (lambda ()
2242 (with-traps
2243 (lambda ()
2244 (first)
2245
2246 ;; This line is needed because mark
2247 ;; doesn't do closures quite right.
2248 ;; Unreferenced locals should be
2249 ;; collected.
2250 ;;
2251 (set! first #f)
2252 (let loop ((v (thunk)))
2253 (loop (thunk)))
2254 #f)))
2255 (lambda () (mask-signals))))
2256
2257 lazy-handler-dispatch))
2258
2259 (lambda (key . args)
2260 (case key
2261 ((quit)
2262 (set! status args)
2263 #f)
2264
2265 ((switch-repl)
2266 (apply throw 'switch-repl args))
2267
2268 ((abort)
2269 ;; This is one of the closures that require
2270 ;; (set! first #f) above
2271 ;;
2272 (lambda ()
2273 (run-hook abort-hook)
2274 (force-output (current-output-port))
2275 (display "ABORT: " (current-error-port))
2276 (write args (current-error-port))
2277 (newline (current-error-port))
2278 (if interactive
2279 (begin
2280 (if (and
2281 (not has-shown-debugger-hint?)
2282 (not (memq 'backtrace
2283 (debug-options-interface)))
2284 (stack? (fluid-ref the-last-stack)))
2285 (begin
2286 (newline (current-error-port))
2287 (display
2288 "Type \"(backtrace)\" to get more information or \"(debug)\" to enter the debugger.\n"
2289 (current-error-port))
2290 (set! has-shown-debugger-hint? #t)))
2291 (force-output (current-error-port)))
2292 (begin
2293 (primitive-exit 1)))
2294 (set! stack-saved? #f)))
2295
2296 (else
2297 ;; This is the other cons-leak closure...
2298 (lambda ()
2299 (cond ((= (length args) 4)
2300 (apply handle-system-error key args))
2301 (else
2302 (apply bad-throw key args))))))))))
2303 (if next (loop next) status)))
2304 (set! set-batch-mode?! (lambda (arg)
2305 (cond (arg
2306 (set! interactive #f)
2307 (restore-signals))
2308 (#t
2309 (error "sorry, not implemented")))))
2310 (set! batch-mode? (lambda () (not interactive)))
2311 (loop (lambda () #t))))
2312
2313 ;;(define the-last-stack (make-fluid)) Defined by scm_init_backtrace ()
2314 (define before-signal-stack (make-fluid))
2315 (define stack-saved? #f)
2316
2317 (define (save-stack . narrowing)
2318 (or stack-saved?
2319 (cond ((not (memq 'debug (debug-options-interface)))
2320 (fluid-set! the-last-stack #f)
2321 (set! stack-saved? #t))
2322 (else
2323 (fluid-set!
2324 the-last-stack
2325 (case (stack-id #t)
2326 ((repl-stack)
2327 (apply make-stack #t save-stack primitive-eval #t 0 narrowing))
2328 ((load-stack)
2329 (apply make-stack #t save-stack 0 #t 0 narrowing))
2330 ((tk-stack)
2331 (apply make-stack #t save-stack tk-stack-mark #t 0 narrowing))
2332 ((#t)
2333 (apply make-stack #t save-stack 0 1 narrowing))
2334 (else
2335 (let ((id (stack-id #t)))
2336 (and (procedure? id)
2337 (apply make-stack #t save-stack id #t 0 narrowing))))))
2338 (set! stack-saved? #t)))))
2339
2340 (define before-error-hook (make-hook))
2341 (define after-error-hook (make-hook))
2342 (define before-backtrace-hook (make-hook))
2343 (define after-backtrace-hook (make-hook))
2344
2345 (define has-shown-debugger-hint? #f)
2346
2347 (define (handle-system-error key . args)
2348 (let ((cep (current-error-port)))
2349 (cond ((not (stack? (fluid-ref the-last-stack))))
2350 ((memq 'backtrace (debug-options-interface))
2351 (run-hook before-backtrace-hook)
2352 (newline cep)
2353 (display "Backtrace:\n")
2354 (display-backtrace (fluid-ref the-last-stack) cep)
2355 (newline cep)
2356 (run-hook after-backtrace-hook)))
2357 (run-hook before-error-hook)
2358 (apply display-error (fluid-ref the-last-stack) cep args)
2359 (run-hook after-error-hook)
2360 (force-output cep)
2361 (throw 'abort key)))
2362
2363 (define (quit . args)
2364 (apply throw 'quit args))
2365
2366 (define exit quit)
2367
2368 ;;(define has-shown-backtrace-hint? #f) Defined by scm_init_backtrace ()
2369
2370 ;; Replaced by C code:
2371 ;;(define (backtrace)
2372 ;; (if (fluid-ref the-last-stack)
2373 ;; (begin
2374 ;; (newline)
2375 ;; (display-backtrace (fluid-ref the-last-stack) (current-output-port))
2376 ;; (newline)
2377 ;; (if (and (not has-shown-backtrace-hint?)
2378 ;; (not (memq 'backtrace (debug-options-interface))))
2379 ;; (begin
2380 ;; (display
2381 ;;"Type \"(debug-enable 'backtrace)\" if you would like a backtrace
2382 ;;automatically if an error occurs in the future.\n")
2383 ;; (set! has-shown-backtrace-hint? #t))))
2384 ;; (display "No backtrace available.\n")))
2385
2386 (define (error-catching-repl r e p)
2387 (error-catching-loop (lambda () (p (e (r))))))
2388
2389 (define (gc-run-time)
2390 (cdr (assq 'gc-time-taken (gc-stats))))
2391
2392 (define before-read-hook (make-hook))
2393 (define after-read-hook (make-hook))
2394 (define before-eval-hook (make-hook 1))
2395 (define after-eval-hook (make-hook 1))
2396 (define before-print-hook (make-hook 1))
2397 (define after-print-hook (make-hook 1))
2398
2399 ;;; The default repl-reader function. We may override this if we've
2400 ;;; the readline library.
2401 (define repl-reader
2402 (lambda (prompt)
2403 (display prompt)
2404 (force-output)
2405 (run-hook before-read-hook)
2406 (read (current-input-port))))
2407
2408 (define (scm-style-repl)
2409
2410 (letrec (
2411 (start-gc-rt #f)
2412 (start-rt #f)
2413 (repl-report-start-timing (lambda ()
2414 (set! start-gc-rt (gc-run-time))
2415 (set! start-rt (get-internal-run-time))))
2416 (repl-report (lambda ()
2417 (display ";;; ")
2418 (display (inexact->exact
2419 (* 1000 (/ (- (get-internal-run-time) start-rt)
2420 internal-time-units-per-second))))
2421 (display " msec (")
2422 (display (inexact->exact
2423 (* 1000 (/ (- (gc-run-time) start-gc-rt)
2424 internal-time-units-per-second))))
2425 (display " msec in gc)\n")))
2426
2427 (consume-trailing-whitespace
2428 (lambda ()
2429 (let ((ch (peek-char)))
2430 (cond
2431 ((eof-object? ch))
2432 ((or (char=? ch #\space) (char=? ch #\tab))
2433 (read-char)
2434 (consume-trailing-whitespace))
2435 ((char=? ch #\newline)
2436 (read-char))))))
2437 (-read (lambda ()
2438 (let ((val
2439 (let ((prompt (cond ((string? scm-repl-prompt)
2440 scm-repl-prompt)
2441 ((thunk? scm-repl-prompt)
2442 (scm-repl-prompt))
2443 (scm-repl-prompt "> ")
2444 (else ""))))
2445 (repl-reader prompt))))
2446
2447 ;; As described in R4RS, the READ procedure updates the
2448 ;; port to point to the first character past the end of
2449 ;; the external representation of the object. This
2450 ;; means that it doesn't consume the newline typically
2451 ;; found after an expression. This means that, when
2452 ;; debugging Guile with GDB, GDB gets the newline, which
2453 ;; it often interprets as a "continue" command, making
2454 ;; breakpoints kind of useless. So, consume any
2455 ;; trailing newline here, as well as any whitespace
2456 ;; before it.
2457 ;; But not if EOF, for control-D.
2458 (if (not (eof-object? val))
2459 (consume-trailing-whitespace))
2460 (run-hook after-read-hook)
2461 (if (eof-object? val)
2462 (begin
2463 (repl-report-start-timing)
2464 (if scm-repl-verbose
2465 (begin
2466 (newline)
2467 (display ";;; EOF -- quitting")
2468 (newline)))
2469 (quit 0)))
2470 val)))
2471
2472 (-eval (lambda (sourc)
2473 (repl-report-start-timing)
2474 (run-hook before-eval-hook sourc)
2475 (let ((val (start-stack 'repl-stack
2476 ;; If you change this procedure
2477 ;; (primitive-eval), please also
2478 ;; modify the repl-stack case in
2479 ;; save-stack so that stack cutting
2480 ;; continues to work.
2481 (primitive-eval sourc))))
2482 (run-hook after-eval-hook sourc)
2483 val)))
2484
2485
2486 (-print (let ((maybe-print (lambda (result)
2487 (if (or scm-repl-print-unspecified
2488 (not (unspecified? result)))
2489 (begin
2490 (write result)
2491 (newline))))))
2492 (lambda (result)
2493 (if (not scm-repl-silent)
2494 (begin
2495 (run-hook before-print-hook result)
2496 (maybe-print result)
2497 (run-hook after-print-hook result)
2498 (if scm-repl-verbose
2499 (repl-report))
2500 (force-output))))))
2501
2502 (-quit (lambda (args)
2503 (if scm-repl-verbose
2504 (begin
2505 (display ";;; QUIT executed, repl exitting")
2506 (newline)
2507 (repl-report)))
2508 args))
2509
2510 (-abort (lambda ()
2511 (if scm-repl-verbose
2512 (begin
2513 (display ";;; ABORT executed.")
2514 (newline)
2515 (repl-report)))
2516 (repl -read -eval -print))))
2517
2518 (let ((status (error-catching-repl -read
2519 -eval
2520 -print)))
2521 (-quit status))))
2522
2523
2524 \f
2525 ;;; {IOTA functions: generating lists of numbers}
2526
2527 (define (iota n)
2528 (let loop ((count (1- n)) (result '()))
2529 (if (< count 0) result
2530 (loop (1- count) (cons count result)))))
2531
2532 \f
2533 ;;; {While}
2534 ;;;
2535 ;;; with `continue' and `break'.
2536 ;;;
2537
2538 (defmacro while (cond . body)
2539 `(letrec ((continue (lambda () (or (not ,cond) (begin (begin ,@ body) (continue)))))
2540 (break (lambda val (apply throw 'break val))))
2541 (catch 'break
2542 (lambda () (continue))
2543 (lambda v (cadr v)))))
2544
2545 ;;; {collect}
2546 ;;;
2547 ;;; Similar to `begin' but returns a list of the results of all constituent
2548 ;;; forms instead of the result of the last form.
2549 ;;; (The definition relies on the current left-to-right
2550 ;;; order of evaluation of operands in applications.)
2551
2552 (defmacro collect forms
2553 (cons 'list forms))
2554
2555 ;;; {with-fluids}
2556
2557 ;; with-fluids is a convenience wrapper for the builtin procedure
2558 ;; `with-fluids*'. The syntax is just like `let':
2559 ;;
2560 ;; (with-fluids ((fluid val)
2561 ;; ...)
2562 ;; body)
2563
2564 (defmacro with-fluids (bindings . body)
2565 `(with-fluids* (list ,@(map car bindings)) (list ,@(map cadr bindings))
2566 (lambda () ,@body)))
2567
2568 \f
2569
2570 ;;; {Macros}
2571 ;;;
2572
2573 ;; actually....hobbit might be able to hack these with a little
2574 ;; coaxing
2575 ;;
2576
2577 (defmacro define-macro (first . rest)
2578 (let ((name (if (symbol? first) first (car first)))
2579 (transformer
2580 (if (symbol? first)
2581 (car rest)
2582 `(lambda ,(cdr first) ,@rest))))
2583 `(eval-case
2584 ((load-toplevel)
2585 (define ,name (defmacro:transformer ,transformer)))
2586 (else
2587 (error "define-macro can only be used at the top level")))))
2588
2589
2590 (defmacro define-syntax-macro (first . rest)
2591 (let ((name (if (symbol? first) first (car first)))
2592 (transformer
2593 (if (symbol? first)
2594 (car rest)
2595 `(lambda ,(cdr first) ,@rest))))
2596 `(eval-case
2597 ((load-toplevel)
2598 (define ,name (defmacro:syntax-transformer ,transformer)))
2599 (else
2600 (error "define-syntax-macro can only be used at the top level")))))
2601
2602 \f
2603 ;;; {Module System Macros}
2604 ;;;
2605
2606 (defmacro define-module args
2607 `(eval-case
2608 ((load-toplevel)
2609 (process-define-module ',args))
2610 (else
2611 (error "define-module can only be used at the top level"))))
2612
2613 ;; the guts of the use-modules macro. add the interfaces of the named
2614 ;; modules to the use-list of the current module, in order
2615 (define (process-use-modules module-names)
2616 (for-each (lambda (module-name)
2617 (let ((mod-iface (resolve-interface module-name)))
2618 (or mod-iface
2619 (error "no such module" module-name))
2620 (module-use! (current-module) mod-iface)))
2621 (reverse module-names)))
2622
2623 (defmacro use-modules modules
2624 `(eval-case
2625 ((load-toplevel)
2626 (process-use-modules ',modules))
2627 (else
2628 (error "use-modules can only be used at the top level"))))
2629
2630 (defmacro use-syntax (spec)
2631 `(eval-case
2632 ((load-toplevel)
2633 ,@(if (pair? spec)
2634 `((process-use-modules ',(list spec))
2635 (set-module-transformer! (current-module)
2636 ,(car (last-pair spec))))
2637 `((set-module-transformer! (current-module) ,spec)))
2638 (fluid-set! scm:eval-transformer (module-transformer (current-module))))
2639 (else
2640 (error "use-modules can only be used at the top level"))))
2641
2642 (define define-private define)
2643
2644 (defmacro define-public args
2645 (define (syntax)
2646 (error "bad syntax" (list 'define-public args)))
2647 (define (defined-name n)
2648 (cond
2649 ((symbol? n) n)
2650 ((pair? n) (defined-name (car n)))
2651 (else (syntax))))
2652 (cond
2653 ((null? args)
2654 (syntax))
2655 (#t
2656 (let ((name (defined-name (car args))))
2657 `(begin
2658 (eval-case ((load-toplevel) (export ,name)))
2659 (define-private ,@args))))))
2660
2661 (defmacro defmacro-public args
2662 (define (syntax)
2663 (error "bad syntax" (list 'defmacro-public args)))
2664 (define (defined-name n)
2665 (cond
2666 ((symbol? n) n)
2667 (else (syntax))))
2668 (cond
2669 ((null? args)
2670 (syntax))
2671 (#t
2672 (let ((name (defined-name (car args))))
2673 `(begin
2674 (eval-case ((load-toplevel) (export ,name)))
2675 (defmacro ,@args))))))
2676
2677 (define (module-export! m names)
2678 (let ((public-i (module-public-interface m)))
2679 (for-each (lambda (name)
2680 ;; Make sure there is a local variable:
2681 (module-define! m name (module-ref m name #f))
2682 ;; Make sure that local is exported:
2683 (module-add! public-i name (module-variable m name)))
2684 names)))
2685
2686 (defmacro export names
2687 `(eval-case
2688 ((load-toplevel)
2689 (module-export! (current-module) ',names))
2690 (else
2691 (error "export can only be used at the top level"))))
2692
2693 (define export-syntax export)
2694
2695
2696 (define load load-module)
2697
2698
2699 \f
2700
2701 ;;; {Load emacs interface support if emacs option is given.}
2702
2703 (define (named-module-use! user usee)
2704 (module-use! (resolve-module user) (resolve-module usee)))
2705
2706 (define (load-emacs-interface)
2707 (if (memq 'debug-extensions *features*)
2708 (debug-enable 'backtrace))
2709 (named-module-use! '(guile-user) '(ice-9 emacs)))
2710
2711 \f
2712
2713 (define using-readline?
2714 (let ((using-readline? (make-fluid)))
2715 (make-procedure-with-setter
2716 (lambda () (fluid-ref using-readline?))
2717 (lambda (v) (fluid-set! using-readline? v)))))
2718
2719 (define (top-repl)
2720
2721 ;; Load emacs interface support if emacs option is given.
2722 (if (and (module-defined? the-root-module 'use-emacs-interface)
2723 (module-ref the-root-module 'use-emacs-interface))
2724 (load-emacs-interface))
2725
2726 ;; Place the user in the guile-user module.
2727 (process-define-module
2728 '((guile-user)
2729 :use-module (guile) ;so that bindings will be checked here first
2730 :use-module (ice-9 session)
2731 :use-module (ice-9 debug)
2732 :autoload (ice-9 debugger) (debug))) ;load debugger on demand
2733 (if (memq 'threads *features*)
2734 (named-module-use! '(guile-user) '(ice-9 threads)))
2735 (if (memq 'regex *features*)
2736 (named-module-use! '(guile-user) '(ice-9 regex)))
2737
2738 (let ((old-handlers #f)
2739 (signals (if (provided? 'posix)
2740 `((,SIGINT . "User interrupt")
2741 (,SIGFPE . "Arithmetic error")
2742 (,SIGBUS . "Bad memory access (bus error)")
2743 (,SIGSEGV .
2744 "Bad memory access (Segmentation violation)"))
2745 '())))
2746
2747 (dynamic-wind
2748
2749 ;; call at entry
2750 (lambda ()
2751 (let ((make-handler (lambda (msg)
2752 (lambda (sig)
2753 ;; Make a backup copy of the stack
2754 (fluid-set! before-signal-stack
2755 (fluid-ref the-last-stack))
2756 (save-stack %deliver-signals)
2757 (scm-error 'signal
2758 #f
2759 msg
2760 #f
2761 (list sig))))))
2762 (set! old-handlers
2763 (map (lambda (sig-msg)
2764 (sigaction (car sig-msg)
2765 (make-handler (cdr sig-msg))))
2766 signals))))
2767
2768 ;; the protected thunk.
2769 (lambda ()
2770 (let ((status (scm-style-repl)))
2771 (run-hook exit-hook)
2772 status))
2773
2774 ;; call at exit.
2775 (lambda ()
2776 (map (lambda (sig-msg old-handler)
2777 (if (not (car old-handler))
2778 ;; restore original C handler.
2779 (sigaction (car sig-msg) #f)
2780 ;; restore Scheme handler, SIG_IGN or SIG_DFL.
2781 (sigaction (car sig-msg)
2782 (car old-handler)
2783 (cdr old-handler))))
2784 signals old-handlers)))))
2785
2786 (defmacro false-if-exception (expr)
2787 `(catch #t (lambda () ,expr)
2788 (lambda args #f)))
2789
2790 ;;; This hook is run at the very end of an interactive session.
2791 ;;;
2792 (define exit-hook (make-hook))
2793
2794 \f
2795 (define-module (guile))
2796
2797 (append! %load-path (cons "." '()))
2798