Merge remote-tracking branch 'origin/stable-2.0'
[bpt/guile.git] / module / ice-9 / boot-9.scm
1 ;;; -*- mode: scheme; coding: utf-8; -*-
2
3 ;;;; Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 ;;;; 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
5 ;;;; Free Software Foundation, Inc.
6 ;;;;
7 ;;;; This library is free software; you can redistribute it and/or
8 ;;;; modify it under the terms of the GNU Lesser General Public
9 ;;;; License as published by the Free Software Foundation; either
10 ;;;; version 3 of the License, or (at your option) any later version.
11 ;;;;
12 ;;;; This library is distributed in the hope that it will be useful,
13 ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;;;; Lesser General Public License for more details.
16 ;;;;
17 ;;;; You should have received a copy of the GNU Lesser General Public
18 ;;;; License along with this library; if not, write to the Free Software
19 ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 ;;;;
21
22 \f
23
24 ;;; Commentary:
25
26 ;;; This file is the first thing loaded into Guile. It adds many mundane
27 ;;; definitions and a few that are interesting.
28 ;;;
29 ;;; The module system (hence the hierarchical namespace) are defined in this
30 ;;; file.
31 ;;;
32
33 ;;; Code:
34
35 \f
36
37 ;; Before compiling, make sure any symbols are resolved in the (guile)
38 ;; module, the primary location of those symbols, rather than in
39 ;; (guile-user), the default module that we compile in.
40
41 (eval-when (compile)
42 (set-current-module (resolve-module '(guile))))
43
44 \f
45
46 ;;; {Error handling}
47 ;;;
48
49 ;; Define delimited continuation operators, and implement catch and throw in
50 ;; terms of them.
51
52 (define make-prompt-tag
53 (lambda* (#:optional (stem "prompt"))
54 ;; The only property that prompt tags need have is uniqueness in the
55 ;; sense of eq?. A one-element list will serve nicely.
56 (list stem)))
57
58 (define default-prompt-tag
59 ;; Redefined later to be a parameter.
60 (let ((%default-prompt-tag (make-prompt-tag)))
61 (lambda ()
62 %default-prompt-tag)))
63
64 (define (call-with-prompt tag thunk handler)
65 (@prompt tag (thunk) handler))
66 (define (abort-to-prompt tag . args)
67 (@abort tag args))
68
69
70 ;; Define catch and with-throw-handler, using some common helper routines and a
71 ;; shared fluid. Hide the helpers in a lexical contour.
72
73 (define with-throw-handler #f)
74 (let ()
75 (define (default-exception-handler k . args)
76 (cond
77 ((eq? k 'quit)
78 (primitive-exit (cond
79 ((not (pair? args)) 0)
80 ((integer? (car args)) (car args))
81 ((not (car args)) 1)
82 (else 0))))
83 (else
84 (format (current-error-port) "guile: uncaught throw to ~a: ~a\n" k args)
85 (primitive-exit 1))))
86
87 (define %running-exception-handlers (make-fluid '()))
88 (define %exception-handler (make-fluid default-exception-handler))
89
90 (define (default-throw-handler prompt-tag catch-k)
91 (let ((prev (fluid-ref %exception-handler)))
92 (lambda (thrown-k . args)
93 (if (or (eq? thrown-k catch-k) (eqv? catch-k #t))
94 (apply abort-to-prompt prompt-tag thrown-k args)
95 (apply prev thrown-k args)))))
96
97 (define (custom-throw-handler prompt-tag catch-k pre)
98 (let ((prev (fluid-ref %exception-handler)))
99 (lambda (thrown-k . args)
100 (if (or (eq? thrown-k catch-k) (eqv? catch-k #t))
101 (let ((running (fluid-ref %running-exception-handlers)))
102 (with-fluids ((%running-exception-handlers (cons pre running)))
103 (if (not (memq pre running))
104 (apply pre thrown-k args))
105 ;; fall through
106 (if prompt-tag
107 (apply abort-to-prompt prompt-tag thrown-k args)
108 (apply prev thrown-k args))))
109 (apply prev thrown-k args)))))
110
111 (set! catch
112 (lambda* (k thunk handler #:optional pre-unwind-handler)
113 "Invoke @var{thunk} in the dynamic context of @var{handler} for
114 exceptions matching @var{key}. If thunk throws to the symbol
115 @var{key}, then @var{handler} is invoked this way:
116 @lisp
117 (handler key args ...)
118 @end lisp
119
120 @var{key} is a symbol or @code{#t}.
121
122 @var{thunk} takes no arguments. If @var{thunk} returns
123 normally, that is the return value of @code{catch}.
124
125 Handler is invoked outside the scope of its own @code{catch}.
126 If @var{handler} again throws to the same key, a new handler
127 from further up the call chain is invoked.
128
129 If the key is @code{#t}, then a throw to @emph{any} symbol will
130 match this call to @code{catch}.
131
132 If a @var{pre-unwind-handler} is given and @var{thunk} throws
133 an exception that matches @var{key}, Guile calls the
134 @var{pre-unwind-handler} before unwinding the dynamic state and
135 invoking the main @var{handler}. @var{pre-unwind-handler} should
136 be a procedure with the same signature as @var{handler}, that
137 is @code{(lambda (key . args))}. It is typically used to save
138 the stack at the point where the exception occurred, but can also
139 query other parts of the dynamic state at that point, such as
140 fluid values.
141
142 A @var{pre-unwind-handler} can exit either normally or non-locally.
143 If it exits normally, Guile unwinds the stack and dynamic context
144 and then calls the normal (third argument) handler. If it exits
145 non-locally, that exit determines the continuation."
146 (if (not (or (symbol? k) (eqv? k #t)))
147 (scm-error 'wrong-type-arg "catch"
148 "Wrong type argument in position ~a: ~a"
149 (list 1 k) (list k)))
150 (let ((tag (make-prompt-tag "catch")))
151 (call-with-prompt
152 tag
153 (lambda ()
154 (with-fluids
155 ((%exception-handler
156 (if pre-unwind-handler
157 (custom-throw-handler tag k pre-unwind-handler)
158 (default-throw-handler tag k))))
159 (thunk)))
160 (lambda (cont k . args)
161 (apply handler k args))))))
162
163 (set! with-throw-handler
164 (lambda (k thunk pre-unwind-handler)
165 "Add @var{handler} to the dynamic context as a throw handler
166 for key @var{k}, then invoke @var{thunk}."
167 (if (not (or (symbol? k) (eqv? k #t)))
168 (scm-error 'wrong-type-arg "with-throw-handler"
169 "Wrong type argument in position ~a: ~a"
170 (list 1 k) (list k)))
171 (with-fluids ((%exception-handler
172 (custom-throw-handler #f k pre-unwind-handler)))
173 (thunk))))
174
175 (set! throw
176 (lambda (key . args)
177 "Invoke the catch form matching @var{key}, passing @var{args} to the
178 @var{handler}.
179
180 @var{key} is a symbol. It will match catches of the same symbol or of @code{#t}.
181
182 If there is no handler at all, Guile prints an error and then exits."
183 (if (not (symbol? key))
184 ((fluid-ref %exception-handler) 'wrong-type-arg "throw"
185 "Wrong type argument in position ~a: ~a" (list 1 key) (list key))
186 (apply (fluid-ref %exception-handler) key args)))))
187
188
189 \f
190
191 ;;; {Language primitives}
192 ;;;
193
194 ;; These are are the procedural wrappers around the primitives of
195 ;; Guile's language: @apply, @call-with-current-continuation, etc.
196 ;;
197 ;; Usually, a call to a primitive is compiled specially. The compiler
198 ;; knows about all these kinds of expressions. But the primitives may
199 ;; be referenced not only as operators, but as values as well. These
200 ;; stub procedures are the "values" of apply, dynamic-wind, and other
201 ;; such primitives.
202 ;;
203 (define (apply fun . args)
204 (@apply fun (apply:nconc2last args)))
205 (define (call-with-current-continuation proc)
206 (@call-with-current-continuation proc))
207 (define (call-with-values producer consumer)
208 (@call-with-values producer consumer))
209 (define (dynamic-wind in thunk out)
210 "All three arguments must be 0-argument procedures.
211 Guard @var{in} is called, then @var{thunk}, then
212 guard @var{out}.
213
214 If, any time during the execution of @var{thunk}, the
215 continuation of the @code{dynamic_wind} expression is escaped
216 non-locally, @var{out} is called. If the continuation of
217 the dynamic-wind is re-entered, @var{in} is called. Thus
218 @var{in} and @var{out} may be called any number of
219 times.
220 @lisp
221 (define x 'normal-binding)
222 @result{} x
223 (define a-cont
224 (call-with-current-continuation
225 (lambda (escape)
226 (let ((old-x x))
227 (dynamic-wind
228 ;; in-guard:
229 ;;
230 (lambda () (set! x 'special-binding))
231
232 ;; thunk
233 ;;
234 (lambda () (display x) (newline)
235 (call-with-current-continuation escape)
236 (display x) (newline)
237 x)
238
239 ;; out-guard:
240 ;;
241 (lambda () (set! x old-x)))))))
242
243 ;; Prints:
244 special-binding
245 ;; Evaluates to:
246 @result{} a-cont
247 x
248 @result{} normal-binding
249 (a-cont #f)
250 ;; Prints:
251 special-binding
252 ;; Evaluates to:
253 @result{} a-cont ;; the value of the (define a-cont...)
254 x
255 @result{} normal-binding
256 a-cont
257 @result{} special-binding
258 @end lisp"
259 (@dynamic-wind in (thunk) out))
260
261 \f
262
263 ;;; {Low-Level Port Code}
264 ;;;
265
266 ;; These are used to request the proper mode to open files in.
267 ;;
268 (define OPEN_READ "r")
269 (define OPEN_WRITE "w")
270 (define OPEN_BOTH "r+")
271
272 (define *null-device* "/dev/null")
273
274 (define (open-input-file str)
275 "Takes a string naming an existing file and returns an input port
276 capable of delivering characters from the file. If the file
277 cannot be opened, an error is signalled."
278 (open-file str OPEN_READ))
279
280 (define (open-output-file str)
281 "Takes a string naming an output file to be created and returns an
282 output port capable of writing characters to a new file by that
283 name. If the file cannot be opened, an error is signalled. If a
284 file with the given name already exists, the effect is unspecified."
285 (open-file str OPEN_WRITE))
286
287 (define (open-io-file str)
288 "Open file with name STR for both input and output."
289 (open-file str OPEN_BOTH))
290
291 \f
292
293 ;;; {Simple Debugging Tools}
294 ;;;
295
296 ;; peek takes any number of arguments, writes them to the
297 ;; current ouput port, and returns the last argument.
298 ;; It is handy to wrap around an expression to look at
299 ;; a value each time is evaluated, e.g.:
300 ;;
301 ;; (+ 10 (troublesome-fn))
302 ;; => (+ 10 (pk 'troublesome-fn-returned (troublesome-fn)))
303 ;;
304
305 (define (peek . stuff)
306 (newline)
307 (display ";;; ")
308 (write stuff)
309 (newline)
310 (car (last-pair stuff)))
311
312 (define pk peek)
313
314 ;; Temporary definition; replaced later.
315 (define current-warning-port current-error-port)
316
317 (define (warn . stuff)
318 (newline (current-warning-port))
319 (display ";;; WARNING " (current-warning-port))
320 (display stuff (current-warning-port))
321 (newline (current-warning-port))
322 (car (last-pair stuff)))
323
324 \f
325
326 ;;; {Features}
327 ;;;
328
329 (define (provide sym)
330 (if (not (memq sym *features*))
331 (set! *features* (cons sym *features*))))
332
333 ;; Return #t iff FEATURE is available to this Guile interpreter. In SLIB,
334 ;; provided? also checks to see if the module is available. We should do that
335 ;; too, but don't.
336
337 (define (provided? feature)
338 (and (memq feature *features*) #t))
339
340 \f
341
342 ;;; {Structs}
343 ;;;
344
345 (define (make-struct/no-tail vtable . args)
346 (apply make-struct vtable 0 args))
347
348 \f
349
350 ;;; Boot versions of `map' and `for-each', enough to get the expander
351 ;;; running.
352 ;;;
353 (define map
354 (case-lambda
355 ((f l)
356 (let map1 ((l l))
357 (if (null? l)
358 '()
359 (cons (f (car l)) (map1 (cdr l))))))
360 ((f l1 l2)
361 (let map2 ((l1 l1) (l2 l2))
362 (if (null? l1)
363 '()
364 (cons (f (car l1) (car l2))
365 (map2 (cdr l1) (cdr l2))))))
366 ((f l1 . rest)
367 (let lp ((l1 l1) (rest rest))
368 (if (null? l1)
369 '()
370 (cons (apply f (car l1) (map car rest))
371 (lp (cdr l1) (map cdr rest))))))))
372
373 (define for-each
374 (case-lambda
375 ((f l)
376 (let for-each1 ((l l))
377 (if (pair? l)
378 (begin
379 (f (car l))
380 (for-each1 (cdr l))))))
381 ((f l1 l2)
382 (let for-each2 ((l1 l1) (l2 l2))
383 (if (pair? l1)
384 (begin
385 (f (car l1) (car l2))
386 (for-each2 (cdr l1) (cdr l2))))))
387 ((f l1 . rest)
388 (let lp ((l1 l1) (rest rest))
389 (if (pair? l1)
390 (begin
391 (apply f (car l1) (map car rest))
392 (lp (cdr l1) (map cdr rest))))))))
393
394 ;;; {and-map and or-map}
395 ;;;
396 ;;; (and-map fn lst) is like (and (fn (car lst)) (fn (cadr lst)) (fn...) ...)
397 ;;; (or-map fn lst) is like (or (fn (car lst)) (fn (cadr lst)) (fn...) ...)
398 ;;;
399
400 ;; and-map f l
401 ;;
402 ;; Apply f to successive elements of l until exhaustion or f returns #f.
403 ;; If returning early, return #f. Otherwise, return the last value returned
404 ;; by f. If f has never been called because l is empty, return #t.
405 ;;
406 (define (and-map f lst)
407 (let loop ((result #t)
408 (l lst))
409 (and result
410 (or (and (null? l)
411 result)
412 (loop (f (car l)) (cdr l))))))
413
414 ;; or-map f l
415 ;;
416 ;; Apply f to successive elements of l until exhaustion or while f returns #f.
417 ;; If returning early, return the return value of f.
418 ;;
419 (define (or-map f lst)
420 (let loop ((result #f)
421 (l lst))
422 (or result
423 (and (not (null? l))
424 (loop (f (car l)) (cdr l))))))
425
426 \f
427
428 ;; let format alias simple-format until the more complete version is loaded
429
430 (define format simple-format)
431
432 ;; this is scheme wrapping the C code so the final pred call is a tail call,
433 ;; per SRFI-13 spec
434 (define string-any
435 (lambda* (char_pred s #:optional (start 0) (end (string-length s)))
436 (if (and (procedure? char_pred)
437 (> end start)
438 (<= end (string-length s))) ;; let c-code handle range error
439 (or (string-any-c-code char_pred s start (1- end))
440 (char_pred (string-ref s (1- end))))
441 (string-any-c-code char_pred s start end))))
442
443 ;; this is scheme wrapping the C code so the final pred call is a tail call,
444 ;; per SRFI-13 spec
445 (define string-every
446 (lambda* (char_pred s #:optional (start 0) (end (string-length s)))
447 (if (and (procedure? char_pred)
448 (> end start)
449 (<= end (string-length s))) ;; let c-code handle range error
450 (and (string-every-c-code char_pred s start (1- end))
451 (char_pred (string-ref s (1- end))))
452 (string-every-c-code char_pred s start end))))
453
454 ;; A variant of string-fill! that we keep for compatability
455 ;;
456 (define (substring-fill! str start end fill)
457 (string-fill! str fill start end))
458
459 \f
460
461 ;; Define a minimal stub of the module API for psyntax, before modules
462 ;; have booted.
463 (define (module-name x)
464 '(guile))
465 (define (module-add! module sym var)
466 (hashq-set! (%get-pre-modules-obarray) sym var))
467 (define (module-define! module sym val)
468 (let ((v (hashq-ref (%get-pre-modules-obarray) sym)))
469 (if v
470 (variable-set! v val)
471 (module-add! (current-module) sym (make-variable val)))))
472 (define (module-ref module sym)
473 (let ((v (module-variable module sym)))
474 (if v (variable-ref v) (error "badness!" (pk module) (pk sym)))))
475 (define (resolve-module . args)
476 #f)
477
478 ;; API provided by psyntax
479 (define syntax-violation #f)
480 (define datum->syntax #f)
481 (define syntax->datum #f)
482 (define syntax-source #f)
483 (define identifier? #f)
484 (define generate-temporaries #f)
485 (define bound-identifier=? #f)
486 (define free-identifier=? #f)
487
488 ;; $sc-dispatch is an implementation detail of psyntax. It is used by
489 ;; expanded macros, to dispatch an input against a set of patterns.
490 (define $sc-dispatch #f)
491
492 ;; Load it up!
493 (primitive-load-path "ice-9/psyntax-pp")
494 ;; The binding for `macroexpand' has now been overridden, making psyntax the
495 ;; expander now.
496
497 (define-syntax and
498 (syntax-rules ()
499 ((_) #t)
500 ((_ x) x)
501 ((_ x y ...) (if x (and y ...) #f))))
502
503 (define-syntax or
504 (syntax-rules ()
505 ((_) #f)
506 ((_ x) x)
507 ((_ x y ...) (let ((t x)) (if t t (or y ...))))))
508
509 (include-from-path "ice-9/quasisyntax")
510
511 (define-syntax-rule (when test stmt stmt* ...)
512 (if test (begin stmt stmt* ...)))
513
514 (define-syntax-rule (unless test stmt stmt* ...)
515 (if (not test) (begin stmt stmt* ...)))
516
517 (define-syntax cond
518 (lambda (whole-expr)
519 (define (fold f seed xs)
520 (let loop ((xs xs) (seed seed))
521 (if (null? xs) seed
522 (loop (cdr xs) (f (car xs) seed)))))
523 (define (reverse-map f xs)
524 (fold (lambda (x seed) (cons (f x) seed))
525 '() xs))
526 (syntax-case whole-expr ()
527 ((_ clause clauses ...)
528 #`(begin
529 #,@(fold (lambda (clause-builder tail)
530 (clause-builder tail))
531 #'()
532 (reverse-map
533 (lambda (clause)
534 (define* (bad-clause #:optional (msg "invalid clause"))
535 (syntax-violation 'cond msg whole-expr clause))
536 (syntax-case clause (=> else)
537 ((else e e* ...)
538 (lambda (tail)
539 (if (null? tail)
540 #'((begin e e* ...))
541 (bad-clause "else must be the last clause"))))
542 ((else . _) (bad-clause))
543 ((test => receiver)
544 (lambda (tail)
545 #`((let ((t test))
546 (if t
547 (receiver t)
548 #,@tail)))))
549 ((test => receiver ...)
550 (bad-clause "wrong number of receiver expressions"))
551 ((generator guard => receiver)
552 (lambda (tail)
553 #`((call-with-values (lambda () generator)
554 (lambda vals
555 (if (apply guard vals)
556 (apply receiver vals)
557 #,@tail))))))
558 ((generator guard => receiver ...)
559 (bad-clause "wrong number of receiver expressions"))
560 ((test)
561 (lambda (tail)
562 #`((let ((t test))
563 (if t t #,@tail)))))
564 ((test e e* ...)
565 (lambda (tail)
566 #`((if test
567 (begin e e* ...)
568 #,@tail))))
569 (_ (bad-clause))))
570 #'(clause clauses ...))))))))
571
572 (define-syntax case
573 (lambda (whole-expr)
574 (define (fold f seed xs)
575 (let loop ((xs xs) (seed seed))
576 (if (null? xs) seed
577 (loop (cdr xs) (f (car xs) seed)))))
578 (define (fold2 f a b xs)
579 (let loop ((xs xs) (a a) (b b))
580 (if (null? xs) (values a b)
581 (call-with-values
582 (lambda () (f (car xs) a b))
583 (lambda (a b)
584 (loop (cdr xs) a b))))))
585 (define (reverse-map-with-seed f seed xs)
586 (fold2 (lambda (x ys seed)
587 (call-with-values
588 (lambda () (f x seed))
589 (lambda (y seed)
590 (values (cons y ys) seed))))
591 '() seed xs))
592 (syntax-case whole-expr ()
593 ((_ expr clause clauses ...)
594 (with-syntax ((key #'key))
595 #`(let ((key expr))
596 #,@(fold
597 (lambda (clause-builder tail)
598 (clause-builder tail))
599 #'()
600 (reverse-map-with-seed
601 (lambda (clause seen)
602 (define* (bad-clause #:optional (msg "invalid clause"))
603 (syntax-violation 'case msg whole-expr clause))
604 (syntax-case clause ()
605 ((test . rest)
606 (with-syntax
607 ((clause-expr
608 (syntax-case #'rest (=>)
609 ((=> receiver) #'(receiver key))
610 ((=> receiver ...)
611 (bad-clause
612 "wrong number of receiver expressions"))
613 ((e e* ...) #'(begin e e* ...))
614 (_ (bad-clause)))))
615 (syntax-case #'test (else)
616 ((datums ...)
617 (let ((seen
618 (fold
619 (lambda (datum seen)
620 (define (warn-datum type)
621 ((@ (system base message)
622 warning)
623 type
624 (append (source-properties datum)
625 (source-properties
626 (syntax->datum #'test)))
627 datum
628 (syntax->datum clause)
629 (syntax->datum whole-expr)))
630 (if (memv datum seen)
631 (warn-datum 'duplicate-case-datum))
632 (if (or (pair? datum)
633 (array? datum)
634 (generalized-vector? datum))
635 (warn-datum 'bad-case-datum))
636 (cons datum seen))
637 seen
638 (map syntax->datum #'(datums ...)))))
639 (values (lambda (tail)
640 #`((if (memv key '(datums ...))
641 clause-expr
642 #,@tail)))
643 seen)))
644 (else (values (lambda (tail)
645 (if (null? tail)
646 #'(clause-expr)
647 (bad-clause
648 "else must be the last clause")))
649 seen))
650 (_ (bad-clause)))))
651 (_ (bad-clause))))
652 '() #'(clause clauses ...)))))))))
653
654 (define-syntax do
655 (syntax-rules ()
656 ((do ((var init step ...) ...)
657 (test expr ...)
658 command ...)
659 (letrec
660 ((loop
661 (lambda (var ...)
662 (if test
663 (begin
664 (if #f #f)
665 expr ...)
666 (begin
667 command
668 ...
669 (loop (do "step" var step ...)
670 ...))))))
671 (loop init ...)))
672 ((do "step" x)
673 x)
674 ((do "step" x y)
675 y)))
676
677 (define-syntax-rule (delay exp)
678 (make-promise (lambda () exp)))
679
680 (define-syntax current-source-location
681 (lambda (x)
682 (syntax-case x ()
683 ((_)
684 (with-syntax ((s (datum->syntax x (syntax-source x))))
685 #''s)))))
686
687 ;; We provide this accessor out of convenience. current-line and
688 ;; current-column aren't so interesting, because they distort what they
689 ;; are measuring; better to use syntax-source from a macro.
690 ;;
691 (define-syntax current-filename
692 (lambda (x)
693 "A macro that expands to the current filename: the filename that
694 the (current-filename) form appears in. Expands to #f if this
695 information is unavailable."
696 (false-if-exception
697 (canonicalize-path (assq-ref (syntax-source x) 'filename)))))
698
699 (define-syntax-rule (define-once sym val)
700 (define sym
701 (if (module-locally-bound? (current-module) 'sym) sym val)))
702
703 ;;; The real versions of `map' and `for-each', with cycle detection, and
704 ;;; that use reverse! instead of recursion in the case of `map'.
705 ;;;
706 (define map
707 (case-lambda
708 ((f l)
709 (let map1 ((hare l) (tortoise l) (move? #f) (out '()))
710 (if (pair? hare)
711 (if move?
712 (if (eq? tortoise hare)
713 (scm-error 'wrong-type-arg "map" "Circular list: ~S"
714 (list l) #f)
715 (map1 (cdr hare) (cdr tortoise) #f
716 (cons (f (car hare)) out)))
717 (map1 (cdr hare) tortoise #t
718 (cons (f (car hare)) out)))
719 (if (null? hare)
720 (reverse! out)
721 (scm-error 'wrong-type-arg "map" "Not a list: ~S"
722 (list l) #f)))))
723
724 ((f l1 l2)
725 (let map2 ((h1 l1) (h2 l2) (t1 l1) (t2 l2) (move? #f) (out '()))
726 (cond
727 ((pair? h1)
728 (cond
729 ((not (pair? h2))
730 (scm-error 'wrong-type-arg "map"
731 (if (list? h2)
732 "List of wrong length: ~S"
733 "Not a list: ~S")
734 (list l2) #f))
735 ((not move?)
736 (map2 (cdr h1) (cdr h2) t1 t2 #t
737 (cons (f (car h1) (car h2)) out)))
738 ((eq? t1 h1)
739 (scm-error 'wrong-type-arg "map" "Circular list: ~S"
740 (list l1) #f))
741 ((eq? t2 h2)
742 (scm-error 'wrong-type-arg "map" "Circular list: ~S"
743 (list l2) #f))
744 (else
745 (map2 (cdr h1) (cdr h2) (cdr t1) (cdr t2) #f
746 (cons (f (car h1) (car h2)) out)))))
747
748 ((and (null? h1) (null? h2))
749 (reverse! out))
750
751 ((null? h1)
752 (scm-error 'wrong-type-arg "map"
753 (if (list? h2)
754 "List of wrong length: ~S"
755 "Not a list: ~S")
756 (list l2) #f))
757 (else
758 (scm-error 'wrong-type-arg "map"
759 "Not a list: ~S"
760 (list l1) #f)))))
761
762 ((f l1 . rest)
763 (let ((len (length l1)))
764 (let mapn ((rest rest))
765 (or (null? rest)
766 (if (= (length (car rest)) len)
767 (mapn (cdr rest))
768 (scm-error 'wrong-type-arg "map" "List of wrong length: ~S"
769 (list (car rest)) #f)))))
770 (let mapn ((l1 l1) (rest rest) (out '()))
771 (if (null? l1)
772 (reverse! out)
773 (mapn (cdr l1) (map cdr rest)
774 (cons (apply f (car l1) (map car rest)) out)))))))
775
776 (define map-in-order map)
777
778 (define for-each
779 (case-lambda
780 ((f l)
781 (let for-each1 ((hare l) (tortoise l) (move? #f))
782 (if (pair? hare)
783 (if move?
784 (if (eq? tortoise hare)
785 (scm-error 'wrong-type-arg "for-each" "Circular list: ~S"
786 (list l) #f)
787 (begin
788 (f (car hare))
789 (for-each1 (cdr hare) (cdr tortoise) #f)))
790 (begin
791 (f (car hare))
792 (for-each1 (cdr hare) tortoise #t)))
793
794 (if (not (null? hare))
795 (scm-error 'wrong-type-arg "for-each" "Not a list: ~S"
796 (list l) #f)))))
797
798 ((f l1 l2)
799 (let for-each2 ((h1 l1) (h2 l2) (t1 l1) (t2 l2) (move? #f))
800 (cond
801 ((and (pair? h1) (pair? h2))
802 (cond
803 ((not move?)
804 (f (car h1) (car h2))
805 (for-each2 (cdr h1) (cdr h2) t1 t2 #t))
806 ((eq? t1 h1)
807 (scm-error 'wrong-type-arg "for-each" "Circular list: ~S"
808 (list l1) #f))
809 ((eq? t2 h2)
810 (scm-error 'wrong-type-arg "for-each" "Circular list: ~S"
811 (list l2) #f))
812 (else
813 (f (car h1) (car h2))
814 (for-each2 (cdr h1) (cdr h2) (cdr t1) (cdr t2) #f))))
815
816 ((if (null? h1)
817 (or (null? h2) (pair? h2))
818 (and (pair? h1) (null? h2)))
819 (if #f #f))
820
821 ((list? h1)
822 (scm-error 'wrong-type-arg "for-each" "Unexpected tail: ~S"
823 (list h2) #f))
824 (else
825 (scm-error 'wrong-type-arg "for-each" "Unexpected tail: ~S"
826 (list h1) #f)))))
827
828 ((f l1 . rest)
829 (let ((len (length l1)))
830 (let for-eachn ((rest rest))
831 (or (null? rest)
832 (if (= (length (car rest)) len)
833 (for-eachn (cdr rest))
834 (scm-error 'wrong-type-arg "for-each" "List of wrong length: ~S"
835 (list (car rest)) #f)))))
836
837 (let for-eachn ((l1 l1) (rest rest))
838 (if (pair? l1)
839 (begin
840 (apply f (car l1) (map car rest))
841 (for-eachn (cdr l1) (map cdr rest))))))))
842
843
844 \f
845
846 ;;;
847 ;;; Extensible exception printing.
848 ;;;
849
850 (define set-exception-printer! #f)
851 ;; There is already a definition of print-exception from backtrace.c
852 ;; that we will override.
853
854 (let ((exception-printers '()))
855 (define (print-location frame port)
856 (let ((source (and=> frame frame-source)))
857 ;; source := (addr . (filename . (line . column)))
858 (if source
859 (let ((filename (or (cadr source) "<unnamed port>"))
860 (line (caddr source))
861 (col (cdddr source)))
862 (format port "~a:~a:~a: " filename (1+ line) col))
863 (format port "ERROR: "))))
864
865 (set! set-exception-printer!
866 (lambda (key proc)
867 (set! exception-printers (acons key proc exception-printers))))
868
869 (set! print-exception
870 (lambda (port frame key args)
871 (define (default-printer)
872 (format port "Throw to key `~a' with args `~s'." key args))
873
874 (if frame
875 (let ((proc (frame-procedure frame)))
876 (print-location frame port)
877 (format port "In procedure ~a:\n"
878 (or (false-if-exception (procedure-name proc))
879 proc))))
880
881 (print-location frame port)
882 (catch #t
883 (lambda ()
884 (let ((printer (assq-ref exception-printers key)))
885 (if printer
886 (printer port key args default-printer)
887 (default-printer))))
888 (lambda (k . args)
889 (format port "Error while printing exception.")))
890 (newline port)
891 (force-output port))))
892
893 ;;;
894 ;;; Printers for those keys thrown by Guile.
895 ;;;
896 (let ()
897 (define (scm-error-printer port key args default-printer)
898 ;; Abuse case-lambda as a pattern matcher, given that we don't have
899 ;; ice-9 match at this point.
900 (apply (case-lambda
901 ((subr msg args . rest)
902 (if subr
903 (format port "In procedure ~a: " subr))
904 (apply format port msg (or args '())))
905 (_ (default-printer)))
906 args))
907
908 (define (syntax-error-printer port key args default-printer)
909 (apply (case-lambda
910 ((who what where form subform . extra)
911 (format port "Syntax error:\n")
912 (if where
913 (let ((file (or (assq-ref where 'filename) "unknown file"))
914 (line (and=> (assq-ref where 'line) 1+))
915 (col (assq-ref where 'column)))
916 (format port "~a:~a:~a: " file line col))
917 (format port "unknown location: "))
918 (if who
919 (format port "~a: " who))
920 (format port "~a" what)
921 (if subform
922 (format port " in subform ~s of ~s" subform form)
923 (if form
924 (format port " in form ~s" form))))
925 (_ (default-printer)))
926 args))
927
928 (define (getaddrinfo-error-printer port key args default-printer)
929 (format port "In procedure getaddrinfo: ~a" (gai-strerror (car args))))
930
931 (set-exception-printer! 'goops-error scm-error-printer)
932 (set-exception-printer! 'host-not-found scm-error-printer)
933 (set-exception-printer! 'keyword-argument-error scm-error-printer)
934 (set-exception-printer! 'misc-error scm-error-printer)
935 (set-exception-printer! 'no-data scm-error-printer)
936 (set-exception-printer! 'no-recovery scm-error-printer)
937 (set-exception-printer! 'null-pointer-error scm-error-printer)
938 (set-exception-printer! 'out-of-range scm-error-printer)
939 (set-exception-printer! 'program-error scm-error-printer)
940 (set-exception-printer! 'read-error scm-error-printer)
941 (set-exception-printer! 'regular-expression-syntax scm-error-printer)
942 (set-exception-printer! 'signal scm-error-printer)
943 (set-exception-printer! 'stack-overflow scm-error-printer)
944 (set-exception-printer! 'system-error scm-error-printer)
945 (set-exception-printer! 'try-again scm-error-printer)
946 (set-exception-printer! 'unbound-variable scm-error-printer)
947 (set-exception-printer! 'wrong-number-of-args scm-error-printer)
948 (set-exception-printer! 'wrong-type-arg scm-error-printer)
949
950 (set-exception-printer! 'syntax-error syntax-error-printer)
951
952 (set-exception-printer! 'getaddrinfo-error getaddrinfo-error-printer))
953
954
955 \f
956
957 ;;; {Defmacros}
958 ;;;
959
960 (define-syntax define-macro
961 (lambda (x)
962 "Define a defmacro."
963 (syntax-case x ()
964 ((_ (macro . args) doc body1 body ...)
965 (string? (syntax->datum #'doc))
966 #'(define-macro macro doc (lambda args body1 body ...)))
967 ((_ (macro . args) body ...)
968 #'(define-macro macro #f (lambda args body ...)))
969 ((_ macro doc transformer)
970 (or (string? (syntax->datum #'doc))
971 (not (syntax->datum #'doc)))
972 #'(define-syntax macro
973 (lambda (y)
974 doc
975 #((macro-type . defmacro)
976 (defmacro-args args))
977 (syntax-case y ()
978 ((_ . args)
979 (let ((v (syntax->datum #'args)))
980 (datum->syntax y (apply transformer v)))))))))))
981
982 (define-syntax defmacro
983 (lambda (x)
984 "Define a defmacro, with the old lispy defun syntax."
985 (syntax-case x ()
986 ((_ macro args doc body1 body ...)
987 (string? (syntax->datum #'doc))
988 #'(define-macro macro doc (lambda args body1 body ...)))
989 ((_ macro args body ...)
990 #'(define-macro macro #f (lambda args body ...))))))
991
992 (provide 'defmacro)
993
994 \f
995
996 ;;; {Deprecation}
997 ;;;
998
999 (define-syntax begin-deprecated
1000 (lambda (x)
1001 (syntax-case x ()
1002 ((_ form form* ...)
1003 (if (include-deprecated-features)
1004 #'(begin form form* ...)
1005 #'(begin))))))
1006
1007 \f
1008
1009 ;;; {Trivial Functions}
1010 ;;;
1011
1012 (define (identity x) x)
1013
1014 (define (compose proc . rest)
1015 "Compose PROC with the procedures in REST, such that the last one in
1016 REST is applied first and PROC last, and return the resulting procedure.
1017 The given procedures must have compatible arity."
1018 (if (null? rest)
1019 proc
1020 (let ((g (apply compose rest)))
1021 (lambda args
1022 (call-with-values (lambda () (apply g args)) proc)))))
1023
1024 (define (negate proc)
1025 "Return a procedure with the same arity as PROC that returns the `not'
1026 of PROC's result."
1027 (lambda args
1028 (not (apply proc args))))
1029
1030 (define (const value)
1031 "Return a procedure that accepts any number of arguments and returns
1032 VALUE."
1033 (lambda _
1034 value))
1035
1036 (define (and=> value procedure) (and value (procedure value)))
1037 (define call/cc call-with-current-continuation)
1038
1039 (define-syntax-rule (false-if-exception expr)
1040 (catch #t
1041 (lambda () expr)
1042 (lambda (k . args) #f)))
1043
1044 \f
1045
1046 ;;; {General Properties}
1047 ;;;
1048
1049 ;; Properties are a lispy way to associate random info with random objects.
1050 ;; Traditionally properties are implemented as an alist or a plist actually
1051 ;; pertaining to the object in question.
1052 ;;
1053 ;; These "object properties" have the advantage that they can be associated with
1054 ;; any object, even if the object has no plist. Object properties are good when
1055 ;; you are extending pre-existing objects in unexpected ways. They also present
1056 ;; a pleasing, uniform procedure-with-setter interface. But if you have a data
1057 ;; type that always has properties, it's often still best to store those
1058 ;; properties within the object itself.
1059
1060 (define (make-object-property)
1061 ;; Weak tables are thread-safe.
1062 (let ((prop (make-weak-key-hash-table)))
1063 (make-procedure-with-setter
1064 (lambda (obj) (hashq-ref prop obj))
1065 (lambda (obj val) (hashq-set! prop obj val)))))
1066
1067
1068 \f
1069
1070 ;;; {Symbol Properties}
1071 ;;;
1072
1073 ;;; Symbol properties are something you see in old Lisp code. In most current
1074 ;;; Guile code, symbols are not used as a data structure -- they are used as
1075 ;;; keys into other data structures.
1076
1077 (define (symbol-property sym prop)
1078 (let ((pair (assoc prop (symbol-pref sym))))
1079 (and pair (cdr pair))))
1080
1081 (define (set-symbol-property! sym prop val)
1082 (let ((pair (assoc prop (symbol-pref sym))))
1083 (if pair
1084 (set-cdr! pair val)
1085 (symbol-pset! sym (acons prop val (symbol-pref sym))))))
1086
1087 (define (symbol-property-remove! sym prop)
1088 (let ((pair (assoc prop (symbol-pref sym))))
1089 (if pair
1090 (symbol-pset! sym (delq! pair (symbol-pref sym))))))
1091
1092 \f
1093
1094 ;;; {Arrays}
1095 ;;;
1096
1097 (define (array-shape a)
1098 (map (lambda (ind) (if (number? ind) (list 0 (+ -1 ind)) ind))
1099 (array-dimensions a)))
1100
1101 \f
1102
1103 ;;; {Keywords}
1104 ;;;
1105
1106 ;;; It's much better if you can use lambda* / define*, of course.
1107
1108 (define (kw-arg-ref args kw)
1109 (let ((rem (member kw args)))
1110 (and rem (pair? (cdr rem)) (cadr rem))))
1111
1112 \f
1113
1114 ;;; {Structs}
1115 ;;;
1116
1117 (define (struct-layout s)
1118 (struct-ref (struct-vtable s) vtable-index-layout))
1119
1120 \f
1121
1122 ;;; {Records}
1123 ;;;
1124
1125 ;; Printing records: by default, records are printed as
1126 ;;
1127 ;; #<type-name field1: val1 field2: val2 ...>
1128 ;;
1129 ;; You can change that by giving a custom printing function to
1130 ;; MAKE-RECORD-TYPE (after the list of field symbols). This function
1131 ;; will be called like
1132 ;;
1133 ;; (<printer> object port)
1134 ;;
1135 ;; It should print OBJECT to PORT.
1136
1137 (define (inherit-print-state old-port new-port)
1138 (if (get-print-state old-port)
1139 (port-with-print-state new-port (get-print-state old-port))
1140 new-port))
1141
1142 ;; 0: type-name, 1: fields, 2: constructor
1143 (define record-type-vtable
1144 (let ((s (make-vtable (string-append standard-vtable-fields "prprpw")
1145 (lambda (s p)
1146 (display "#<record-type " p)
1147 (display (record-type-name s) p)
1148 (display ">" p)))))
1149 (set-struct-vtable-name! s 'record-type)
1150 s))
1151
1152 (define (record-type? obj)
1153 (and (struct? obj) (eq? record-type-vtable (struct-vtable obj))))
1154
1155 (define* (make-record-type type-name fields #:optional printer)
1156 ;; Pre-generate constructors for nfields < 20.
1157 (define-syntax make-constructor
1158 (lambda (x)
1159 (define *max-static-argument-count* 20)
1160 (define (make-formals n)
1161 (let lp ((i 0))
1162 (if (< i n)
1163 (cons (datum->syntax
1164 x
1165 (string->symbol
1166 (string (integer->char (+ (char->integer #\a) i)))))
1167 (lp (1+ i)))
1168 '())))
1169 (syntax-case x ()
1170 ((_ rtd exp) (not (identifier? #'exp))
1171 #'(let ((n exp))
1172 (make-constructor rtd n)))
1173 ((_ rtd nfields)
1174 #`(case nfields
1175 #,@(let lp ((n 0))
1176 (if (< n *max-static-argument-count*)
1177 (cons (with-syntax (((formal ...) (make-formals n))
1178 (n n))
1179 #'((n)
1180 (lambda (formal ...)
1181 (make-struct rtd 0 formal ...))))
1182 (lp (1+ n)))
1183 '()))
1184 (else
1185 (lambda args
1186 (if (= (length args) nfields)
1187 (apply make-struct rtd 0 args)
1188 (scm-error 'wrong-number-of-args
1189 (format #f "make-~a" type-name)
1190 "Wrong number of arguments" '() #f)))))))))
1191
1192 (define (default-record-printer s p)
1193 (display "#<" p)
1194 (display (record-type-name (record-type-descriptor s)) p)
1195 (let loop ((fields (record-type-fields (record-type-descriptor s)))
1196 (off 0))
1197 (cond
1198 ((not (null? fields))
1199 (display " " p)
1200 (display (car fields) p)
1201 (display ": " p)
1202 (display (struct-ref s off) p)
1203 (loop (cdr fields) (+ 1 off)))))
1204 (display ">" p))
1205
1206 (let ((rtd (make-struct record-type-vtable 0
1207 (make-struct-layout
1208 (apply string-append
1209 (map (lambda (f) "pw") fields)))
1210 (or printer default-record-printer)
1211 type-name
1212 (copy-tree fields))))
1213 (struct-set! rtd (+ vtable-offset-user 2)
1214 (make-constructor rtd (length fields)))
1215 ;; Temporary solution: Associate a name to the record type descriptor
1216 ;; so that the object system can create a wrapper class for it.
1217 (set-struct-vtable-name! rtd (if (symbol? type-name)
1218 type-name
1219 (string->symbol type-name)))
1220 rtd))
1221
1222 (define (record-type-name obj)
1223 (if (record-type? obj)
1224 (struct-ref obj vtable-offset-user)
1225 (error 'not-a-record-type obj)))
1226
1227 (define (record-type-fields obj)
1228 (if (record-type? obj)
1229 (struct-ref obj (+ 1 vtable-offset-user))
1230 (error 'not-a-record-type obj)))
1231
1232 (define* (record-constructor rtd #:optional field-names)
1233 (if (not field-names)
1234 (struct-ref rtd (+ 2 vtable-offset-user))
1235 (primitive-eval
1236 `(lambda ,field-names
1237 (make-struct ',rtd 0 ,@(map (lambda (f)
1238 (if (memq f field-names)
1239 f
1240 #f))
1241 (record-type-fields rtd)))))))
1242
1243 (define (record-predicate rtd)
1244 (lambda (obj) (and (struct? obj) (eq? rtd (struct-vtable obj)))))
1245
1246 (define (%record-type-error rtd obj) ;; private helper
1247 (or (eq? rtd (record-type-descriptor obj))
1248 (scm-error 'wrong-type-arg "%record-type-check"
1249 "Wrong type record (want `~S'): ~S"
1250 (list (record-type-name rtd) obj)
1251 #f)))
1252
1253 (define (record-accessor rtd field-name)
1254 (let ((pos (list-index (record-type-fields rtd) field-name)))
1255 (if (not pos)
1256 (error 'no-such-field field-name))
1257 (lambda (obj)
1258 (if (eq? (struct-vtable obj) rtd)
1259 (struct-ref obj pos)
1260 (%record-type-error rtd obj)))))
1261
1262 (define (record-modifier rtd field-name)
1263 (let ((pos (list-index (record-type-fields rtd) field-name)))
1264 (if (not pos)
1265 (error 'no-such-field field-name))
1266 (lambda (obj val)
1267 (if (eq? (struct-vtable obj) rtd)
1268 (struct-set! obj pos val)
1269 (%record-type-error rtd obj)))))
1270
1271 (define (record? obj)
1272 (and (struct? obj) (record-type? (struct-vtable obj))))
1273
1274 (define (record-type-descriptor obj)
1275 (if (struct? obj)
1276 (struct-vtable obj)
1277 (error 'not-a-record obj)))
1278
1279 (provide 'record)
1280
1281
1282 \f
1283 ;;; {Parameters}
1284 ;;;
1285
1286 (define <parameter>
1287 ;; Three fields: the procedure itself, the fluid, and the converter.
1288 (make-struct <applicable-struct-vtable> 0 'pwprpr))
1289 (set-struct-vtable-name! <parameter> '<parameter>)
1290
1291 (define* (make-parameter init #:optional (conv (lambda (x) x)))
1292 (let ((fluid (make-fluid (conv init))))
1293 (make-struct <parameter> 0
1294 (case-lambda
1295 (() (fluid-ref fluid))
1296 ((x) (let ((prev (fluid-ref fluid)))
1297 (fluid-set! fluid (conv x))
1298 prev)))
1299 fluid conv)))
1300
1301 (define (parameter? x)
1302 (and (struct? x) (eq? (struct-vtable x) <parameter>)))
1303
1304 (define (parameter-fluid p)
1305 (if (parameter? p)
1306 (struct-ref p 1)
1307 (scm-error 'wrong-type-arg "parameter-fluid"
1308 "Not a parameter: ~S" (list p) #f)))
1309
1310 (define (parameter-converter p)
1311 (if (parameter? p)
1312 (struct-ref p 2)
1313 (scm-error 'wrong-type-arg "parameter-fluid"
1314 "Not a parameter: ~S" (list p) #f)))
1315
1316 (define-syntax parameterize
1317 (lambda (x)
1318 (syntax-case x ()
1319 ((_ ((param value) ...) body body* ...)
1320 (with-syntax (((p ...) (generate-temporaries #'(param ...))))
1321 #'(let ((p param) ...)
1322 (if (not (parameter? p))
1323 (scm-error 'wrong-type-arg "parameterize"
1324 "Not a parameter: ~S" (list p) #f))
1325 ...
1326 (with-fluids (((struct-ref p 1) ((struct-ref p 2) value))
1327 ...)
1328 body body* ...)))))))
1329
1330 \f
1331
1332 ;;; Once parameters have booted, define the default prompt tag as being
1333 ;;; a parameter.
1334 ;;;
1335
1336 (set! default-prompt-tag (make-parameter (default-prompt-tag)))
1337
1338 \f
1339
1340 ;;; Current ports as parameters.
1341 ;;;
1342
1343 (let ((fluid->parameter
1344 (lambda (fluid conv)
1345 (make-struct <parameter> 0
1346 (case-lambda
1347 (() (fluid-ref fluid))
1348 ((x) (let ((prev (fluid-ref fluid)))
1349 (fluid-set! fluid (conv x))
1350 prev)))
1351 fluid conv))))
1352 (define-syntax-rule (port-parameterize! binding fluid predicate msg)
1353 (begin
1354 (set! binding (fluid->parameter (module-ref (current-module) 'fluid)
1355 (lambda (x)
1356 (if (predicate x) x
1357 (error msg x)))))
1358 (hashq-remove! (%get-pre-modules-obarray) 'fluid)))
1359
1360 (port-parameterize! current-input-port %current-input-port-fluid
1361 input-port? "expected an input port")
1362 (port-parameterize! current-output-port %current-output-port-fluid
1363 output-port? "expected an output port")
1364 (port-parameterize! current-error-port %current-error-port-fluid
1365 output-port? "expected an output port"))
1366
1367 \f
1368
1369 ;;; {Warnings}
1370 ;;;
1371
1372 (define current-warning-port
1373 (make-parameter (current-error-port)
1374 (lambda (x)
1375 (if (output-port? x)
1376 x
1377 (error "expected an output port" x)))))
1378
1379 \f
1380
1381 ;;; {High-Level Port Routines}
1382 ;;;
1383
1384 (define (call-with-input-file str proc)
1385 "PROC should be a procedure of one argument, and STR should be a
1386 string naming a file. The file must already exist. These procedures
1387 call PROC with one argument: the port obtained by opening the named file
1388 for input or output. If the file cannot be opened, an error is
1389 signalled. If the procedure returns, then the port is closed
1390 automatically and the values yielded by the procedure are returned. If
1391 the procedure does not return, then the port will not be closed
1392 automatically unless it is possible to prove that the port will never
1393 again be used for a read or write operation."
1394 (let ((p (open-input-file str)))
1395 (call-with-values
1396 (lambda () (proc p))
1397 (lambda vals
1398 (close-input-port p)
1399 (apply values vals)))))
1400
1401 (define (call-with-output-file str proc)
1402 "PROC should be a procedure of one argument, and STR should be a
1403 string naming a file. The behaviour is unspecified if the file
1404 already exists. These procedures call PROC
1405 with one argument: the port obtained by opening the named file for
1406 input or output. If the file cannot be opened, an error is
1407 signalled. If the procedure returns, then the port is closed
1408 automatically and the values yielded by the procedure are returned.
1409 If the procedure does not return, then the port will not be closed
1410 automatically unless it is possible to prove that the port will
1411 never again be used for a read or write operation."
1412 (let ((p (open-output-file str)))
1413 (call-with-values
1414 (lambda () (proc p))
1415 (lambda vals
1416 (close-output-port p)
1417 (apply values vals)))))
1418
1419 (define (with-input-from-port port thunk)
1420 (parameterize ((current-input-port port))
1421 (thunk)))
1422
1423 (define (with-output-to-port port thunk)
1424 (parameterize ((current-output-port port))
1425 (thunk)))
1426
1427 (define (with-error-to-port port thunk)
1428 (parameterize ((current-error-port port))
1429 (thunk)))
1430
1431 (define (with-input-from-file file thunk)
1432 "THUNK must be a procedure of no arguments, and FILE must be a
1433 string naming a file. The file must already exist. The file is opened for
1434 input, an input port connected to it is made
1435 the default value returned by `current-input-port',
1436 and the THUNK is called with no arguments.
1437 When the THUNK returns, the port is closed and the previous
1438 default is restored. Returns the values yielded by THUNK. If an
1439 escape procedure is used to escape from the continuation of these
1440 procedures, their behavior is implementation dependent."
1441 (call-with-input-file file
1442 (lambda (p) (with-input-from-port p thunk))))
1443
1444 (define (with-output-to-file file thunk)
1445 "THUNK must be a procedure of no arguments, and FILE must be a
1446 string naming a file. The effect is unspecified if the file already exists.
1447 The file is opened for output, an output port connected to it is made
1448 the default value returned by `current-output-port',
1449 and the THUNK is called with no arguments.
1450 When the THUNK returns, the port is closed and the previous
1451 default is restored. Returns the values yielded by THUNK. If an
1452 escape procedure is used to escape from the continuation of these
1453 procedures, their behavior is implementation dependent."
1454 (call-with-output-file file
1455 (lambda (p) (with-output-to-port p thunk))))
1456
1457 (define (with-error-to-file file thunk)
1458 "THUNK must be a procedure of no arguments, and FILE must be a
1459 string naming a file. The effect is unspecified if the file already exists.
1460 The file is opened for output, an output port connected to it is made
1461 the default value returned by `current-error-port',
1462 and the THUNK is called with no arguments.
1463 When the THUNK returns, the port is closed and the previous
1464 default is restored. Returns the values yielded by THUNK. If an
1465 escape procedure is used to escape from the continuation of these
1466 procedures, their behavior is implementation dependent."
1467 (call-with-output-file file
1468 (lambda (p) (with-error-to-port p thunk))))
1469
1470 (define (call-with-input-string string proc)
1471 "Calls the one-argument procedure @var{proc} with a newly created
1472 input port from which @var{string}'s contents may be read. The value
1473 yielded by the @var{proc} is returned."
1474 (proc (open-input-string string)))
1475
1476 (define (with-input-from-string string thunk)
1477 "THUNK must be a procedure of no arguments.
1478 The test of STRING is opened for
1479 input, an input port connected to it is made,
1480 and the THUNK is called with no arguments.
1481 When the THUNK returns, the port is closed.
1482 Returns the values yielded by THUNK. If an
1483 escape procedure is used to escape from the continuation of these
1484 procedures, their behavior is implementation dependent."
1485 (call-with-input-string string
1486 (lambda (p) (with-input-from-port p thunk))))
1487
1488 (define (call-with-output-string proc)
1489 "Calls the one-argument procedure @var{proc} with a newly created output
1490 port. When the function returns, the string composed of the characters
1491 written into the port is returned."
1492 (let ((port (open-output-string)))
1493 (proc port)
1494 (get-output-string port)))
1495
1496 (define (with-output-to-string thunk)
1497 "Calls THUNK and returns its output as a string."
1498 (call-with-output-string
1499 (lambda (p) (with-output-to-port p thunk))))
1500
1501 (define (with-error-to-string thunk)
1502 "Calls THUNK and returns its error output as a string."
1503 (call-with-output-string
1504 (lambda (p) (with-error-to-port p thunk))))
1505
1506 (define the-eof-object (call-with-input-string "" (lambda (p) (read-char p))))
1507
1508 \f
1509
1510 ;;; {Booleans}
1511 ;;;
1512
1513 (define (->bool x) (not (not x)))
1514
1515 \f
1516
1517 ;;; {Symbols}
1518 ;;;
1519
1520 (define (symbol-append . args)
1521 (string->symbol (apply string-append (map symbol->string args))))
1522
1523 (define (list->symbol . args)
1524 (string->symbol (apply list->string args)))
1525
1526 (define (symbol . args)
1527 (string->symbol (apply string args)))
1528
1529 \f
1530
1531 ;;; {Lists}
1532 ;;;
1533
1534 (define (list-index l k)
1535 (let loop ((n 0)
1536 (l l))
1537 (and (not (null? l))
1538 (if (eq? (car l) k)
1539 n
1540 (loop (+ n 1) (cdr l))))))
1541
1542 \f
1543
1544 ;; Load `posix.scm' even when not (provided? 'posix) so that we get the
1545 ;; `stat' accessors.
1546 (primitive-load-path "ice-9/posix")
1547
1548 (if (provided? 'socket)
1549 (primitive-load-path "ice-9/networking"))
1550
1551 ;; For reference, Emacs file-exists-p uses stat in this same way.
1552 (define file-exists?
1553 (if (provided? 'posix)
1554 (lambda (str)
1555 (->bool (stat str #f)))
1556 (lambda (str)
1557 (let ((port (catch 'system-error (lambda () (open-input-file str))
1558 (lambda args #f))))
1559 (if port (begin (close-port port) #t)
1560 #f)))))
1561
1562 (define file-is-directory?
1563 (if (provided? 'posix)
1564 (lambda (str)
1565 (eq? (stat:type (stat str)) 'directory))
1566 (lambda (str)
1567 (let ((port (catch 'system-error
1568 (lambda ()
1569 (open-input-file (string-append str "/.")))
1570 (lambda args #f))))
1571 (if port (begin (close-port port) #t)
1572 #f)))))
1573
1574 (define (system-error-errno args)
1575 (if (eq? (car args) 'system-error)
1576 (car (list-ref args 4))
1577 #f))
1578
1579 \f
1580
1581 ;;; {Error Handling}
1582 ;;;
1583
1584 (define error
1585 (case-lambda
1586 (()
1587 (scm-error 'misc-error #f "?" #f #f))
1588 ((message . args)
1589 (let ((msg (string-join (cons "~A" (make-list (length args) "~S")))))
1590 (scm-error 'misc-error #f msg (cons message args) #f)))))
1591
1592 \f
1593
1594 ;;; {Time Structures}
1595 ;;;
1596
1597 (define (tm:sec obj) (vector-ref obj 0))
1598 (define (tm:min obj) (vector-ref obj 1))
1599 (define (tm:hour obj) (vector-ref obj 2))
1600 (define (tm:mday obj) (vector-ref obj 3))
1601 (define (tm:mon obj) (vector-ref obj 4))
1602 (define (tm:year obj) (vector-ref obj 5))
1603 (define (tm:wday obj) (vector-ref obj 6))
1604 (define (tm:yday obj) (vector-ref obj 7))
1605 (define (tm:isdst obj) (vector-ref obj 8))
1606 (define (tm:gmtoff obj) (vector-ref obj 9))
1607 (define (tm:zone obj) (vector-ref obj 10))
1608
1609 (define (set-tm:sec obj val) (vector-set! obj 0 val))
1610 (define (set-tm:min obj val) (vector-set! obj 1 val))
1611 (define (set-tm:hour obj val) (vector-set! obj 2 val))
1612 (define (set-tm:mday obj val) (vector-set! obj 3 val))
1613 (define (set-tm:mon obj val) (vector-set! obj 4 val))
1614 (define (set-tm:year obj val) (vector-set! obj 5 val))
1615 (define (set-tm:wday obj val) (vector-set! obj 6 val))
1616 (define (set-tm:yday obj val) (vector-set! obj 7 val))
1617 (define (set-tm:isdst obj val) (vector-set! obj 8 val))
1618 (define (set-tm:gmtoff obj val) (vector-set! obj 9 val))
1619 (define (set-tm:zone obj val) (vector-set! obj 10 val))
1620
1621 (define (tms:clock obj) (vector-ref obj 0))
1622 (define (tms:utime obj) (vector-ref obj 1))
1623 (define (tms:stime obj) (vector-ref obj 2))
1624 (define (tms:cutime obj) (vector-ref obj 3))
1625 (define (tms:cstime obj) (vector-ref obj 4))
1626
1627 \f
1628
1629 ;;; {File Descriptors and Ports}
1630 ;;;
1631
1632 (define file-position ftell)
1633 (define* (file-set-position port offset #:optional (whence SEEK_SET))
1634 (seek port offset whence))
1635
1636 (define (move->fdes fd/port fd)
1637 (cond ((integer? fd/port)
1638 (dup->fdes fd/port fd)
1639 (close fd/port)
1640 fd)
1641 (else
1642 (primitive-move->fdes fd/port fd)
1643 (set-port-revealed! fd/port 1)
1644 fd/port)))
1645
1646 (define (release-port-handle port)
1647 (let ((revealed (port-revealed port)))
1648 (if (> revealed 0)
1649 (set-port-revealed! port (- revealed 1)))))
1650
1651 (define dup->port
1652 (case-lambda
1653 ((port/fd mode)
1654 (fdopen (dup->fdes port/fd) mode))
1655 ((port/fd mode new-fd)
1656 (let ((port (fdopen (dup->fdes port/fd new-fd) mode)))
1657 (set-port-revealed! port 1)
1658 port))))
1659
1660 (define dup->inport
1661 (case-lambda
1662 ((port/fd)
1663 (dup->port port/fd "r"))
1664 ((port/fd new-fd)
1665 (dup->port port/fd "r" new-fd))))
1666
1667 (define dup->outport
1668 (case-lambda
1669 ((port/fd)
1670 (dup->port port/fd "w"))
1671 ((port/fd new-fd)
1672 (dup->port port/fd "w" new-fd))))
1673
1674 (define dup
1675 (case-lambda
1676 ((port/fd)
1677 (if (integer? port/fd)
1678 (dup->fdes port/fd)
1679 (dup->port port/fd (port-mode port/fd))))
1680 ((port/fd new-fd)
1681 (if (integer? port/fd)
1682 (dup->fdes port/fd new-fd)
1683 (dup->port port/fd (port-mode port/fd) new-fd)))))
1684
1685 (define (duplicate-port port modes)
1686 (dup->port port modes))
1687
1688 (define (fdes->inport fdes)
1689 (let loop ((rest-ports (fdes->ports fdes)))
1690 (cond ((null? rest-ports)
1691 (let ((result (fdopen fdes "r")))
1692 (set-port-revealed! result 1)
1693 result))
1694 ((input-port? (car rest-ports))
1695 (set-port-revealed! (car rest-ports)
1696 (+ (port-revealed (car rest-ports)) 1))
1697 (car rest-ports))
1698 (else
1699 (loop (cdr rest-ports))))))
1700
1701 (define (fdes->outport fdes)
1702 (let loop ((rest-ports (fdes->ports fdes)))
1703 (cond ((null? rest-ports)
1704 (let ((result (fdopen fdes "w")))
1705 (set-port-revealed! result 1)
1706 result))
1707 ((output-port? (car rest-ports))
1708 (set-port-revealed! (car rest-ports)
1709 (+ (port-revealed (car rest-ports)) 1))
1710 (car rest-ports))
1711 (else
1712 (loop (cdr rest-ports))))))
1713
1714 (define (port->fdes port)
1715 (set-port-revealed! port (+ (port-revealed port) 1))
1716 (fileno port))
1717
1718 (define (setenv name value)
1719 (if value
1720 (putenv (string-append name "=" value))
1721 (putenv name)))
1722
1723 (define (unsetenv name)
1724 "Remove the entry for NAME from the environment."
1725 (putenv name))
1726
1727 \f
1728
1729 ;;; {Load Paths}
1730 ;;;
1731
1732 (define (in-vicinity vicinity file)
1733 (let ((tail (let ((len (string-length vicinity)))
1734 (if (zero? len)
1735 #f
1736 (string-ref vicinity (- len 1))))))
1737 (string-append vicinity
1738 (if (or (not tail)
1739 (eq? tail #\/))
1740 ""
1741 "/")
1742 file)))
1743
1744 \f
1745
1746 ;;; {Help for scm_shell}
1747 ;;;
1748 ;;; The argument-processing code used by Guile-based shells generates
1749 ;;; Scheme code based on the argument list. This page contains help
1750 ;;; functions for the code it generates.
1751 ;;;
1752
1753 (define (command-line) (program-arguments))
1754
1755 ;; This is mostly for the internal use of the code generated by
1756 ;; scm_compile_shell_switches.
1757
1758 (define (load-user-init)
1759 (let* ((home (or (getenv "HOME")
1760 (false-if-exception (passwd:dir (getpwuid (getuid))))
1761 "/")) ;; fallback for cygwin etc.
1762 (init-file (in-vicinity home ".guile")))
1763 (if (file-exists? init-file)
1764 (primitive-load init-file))))
1765
1766 \f
1767
1768 ;;; {The interpreter stack}
1769 ;;;
1770
1771 ;; %stacks defined in stacks.c
1772 (define (%start-stack tag thunk)
1773 (let ((prompt-tag (make-prompt-tag "start-stack")))
1774 (call-with-prompt
1775 prompt-tag
1776 (lambda ()
1777 (with-fluids ((%stacks (acons tag prompt-tag
1778 (or (fluid-ref %stacks) '()))))
1779 (thunk)))
1780 (lambda (k . args)
1781 (%start-stack tag (lambda () (apply k args)))))))
1782
1783 (define-syntax-rule (start-stack tag exp)
1784 (%start-stack tag (lambda () exp)))
1785
1786 \f
1787
1788 ;;; {Loading by paths}
1789 ;;;
1790
1791 ;;; Load a Scheme source file named NAME, searching for it in the
1792 ;;; directories listed in %load-path, and applying each of the file
1793 ;;; name extensions listed in %load-extensions.
1794 (define (load-from-path name)
1795 (start-stack 'load-stack
1796 (primitive-load-path name)))
1797
1798 (define-syntax-rule (add-to-load-path elt)
1799 "Add ELT to Guile's load path, at compile-time and at run-time."
1800 (eval-when (compile load eval)
1801 (set! %load-path (cons elt %load-path))))
1802
1803 (define %load-verbosely #f)
1804 (define (assert-load-verbosity v) (set! %load-verbosely v))
1805
1806 (define (%load-announce file)
1807 (if %load-verbosely
1808 (with-output-to-port (current-warning-port)
1809 (lambda ()
1810 (display ";;; ")
1811 (display "loading ")
1812 (display file)
1813 (newline)
1814 (force-output)))))
1815
1816 (set! %load-hook %load-announce)
1817
1818 \f
1819
1820 ;;; {Reader Extensions}
1821 ;;;
1822 ;;; Reader code for various "#c" forms.
1823 ;;;
1824
1825 (define read-eval? (make-fluid #f))
1826 (read-hash-extend #\.
1827 (lambda (c port)
1828 (if (fluid-ref read-eval?)
1829 (eval (read port) (interaction-environment))
1830 (error
1831 "#. read expansion found and read-eval? is #f."))))
1832
1833 \f
1834
1835 ;;; {Low Level Modules}
1836 ;;;
1837 ;;; These are the low level data structures for modules.
1838 ;;;
1839 ;;; Every module object is of the type 'module-type', which is a record
1840 ;;; consisting of the following members:
1841 ;;;
1842 ;;; - eval-closure: A deprecated field, to be removed in Guile 2.2.
1843 ;;;
1844 ;;; - obarray: a hash table that maps symbols to variable objects. In this
1845 ;;; hash table, the definitions are found that are local to the module (that
1846 ;;; is, not imported from other modules). When looking up bindings in the
1847 ;;; module, this hash table is searched first.
1848 ;;;
1849 ;;; - binder: either #f or a function taking a module and a symbol argument.
1850 ;;; If it is a function it is called after the obarray has been
1851 ;;; unsuccessfully searched for a binding. It then can provide bindings
1852 ;;; that would otherwise not be found locally in the module.
1853 ;;;
1854 ;;; - uses: a list of modules from which non-local bindings can be inherited.
1855 ;;; These modules are the third place queried for bindings after the obarray
1856 ;;; has been unsuccessfully searched and the binder function did not deliver
1857 ;;; a result either.
1858 ;;;
1859 ;;; - transformer: either #f or a function taking a scheme expression as
1860 ;;; delivered by read. If it is a function, it will be called to perform
1861 ;;; syntax transformations (e. g. makro expansion) on the given scheme
1862 ;;; expression. The output of the transformer function will then be passed
1863 ;;; to Guile's internal memoizer. This means that the output must be valid
1864 ;;; scheme code. The only exception is, that the output may make use of the
1865 ;;; syntax extensions provided to identify the modules that a binding
1866 ;;; belongs to.
1867 ;;;
1868 ;;; - name: the name of the module. This is used for all kinds of printing
1869 ;;; outputs. In certain places the module name also serves as a way of
1870 ;;; identification. When adding a module to the uses list of another
1871 ;;; module, it is made sure that the new uses list will not contain two
1872 ;;; modules of the same name.
1873 ;;;
1874 ;;; - kind: classification of the kind of module. The value is (currently?)
1875 ;;; only used for printing. It has no influence on how a module is treated.
1876 ;;; Currently the following values are used when setting the module kind:
1877 ;;; 'module, 'directory, 'interface, 'custom-interface. If no explicit kind
1878 ;;; is set, it defaults to 'module.
1879 ;;;
1880 ;;; - duplicates-handlers: a list of procedures that get called to make a
1881 ;;; choice between two duplicate bindings when name clashes occur. See the
1882 ;;; `duplicate-handlers' global variable below.
1883 ;;;
1884 ;;; - observers: a list of procedures that get called when the module is
1885 ;;; modified.
1886 ;;;
1887 ;;; - weak-observers: a weak-key hash table of procedures that get called
1888 ;;; when the module is modified. See `module-observe-weak' for details.
1889 ;;;
1890 ;;; In addition, the module may (must?) contain a binding for
1891 ;;; `%module-public-interface'. This variable should be bound to a module
1892 ;;; representing the exported interface of a module. See the
1893 ;;; `module-public-interface' and `module-export!' procedures.
1894 ;;;
1895 ;;; !!! warning: The interface to lazy binder procedures is going
1896 ;;; to be changed in an incompatible way to permit all the basic
1897 ;;; module ops to be virtualized.
1898 ;;;
1899 ;;; (make-module size use-list lazy-binding-proc) => module
1900 ;;; module-{obarray,uses,binder}[|-set!]
1901 ;;; (module? obj) => [#t|#f]
1902 ;;; (module-locally-bound? module symbol) => [#t|#f]
1903 ;;; (module-bound? module symbol) => [#t|#f]
1904 ;;; (module-symbol-locally-interned? module symbol) => [#t|#f]
1905 ;;; (module-symbol-interned? module symbol) => [#t|#f]
1906 ;;; (module-local-variable module symbol) => [#<variable ...> | #f]
1907 ;;; (module-variable module symbol) => [#<variable ...> | #f]
1908 ;;; (module-symbol-binding module symbol opt-value)
1909 ;;; => [ <obj> | opt-value | an error occurs ]
1910 ;;; (module-make-local-var! module symbol) => #<variable...>
1911 ;;; (module-add! module symbol var) => unspecified
1912 ;;; (module-remove! module symbol) => unspecified
1913 ;;; (module-for-each proc module) => unspecified
1914 ;;; (make-scm-module) => module ; a lazy copy of the symhash module
1915 ;;; (set-current-module module) => unspecified
1916 ;;; (current-module) => #<module...>
1917 ;;;
1918 ;;;
1919
1920 \f
1921
1922 ;;; {Printing Modules}
1923 ;;;
1924
1925 ;; This is how modules are printed. You can re-define it.
1926 (define (%print-module mod port)
1927 (display "#<" port)
1928 (display (or (module-kind mod) "module") port)
1929 (display " " port)
1930 (display (module-name mod) port)
1931 (display " " port)
1932 (display (number->string (object-address mod) 16) port)
1933 (display ">" port))
1934
1935 (letrec-syntax
1936 ;; Locally extend the syntax to allow record accessors to be defined at
1937 ;; compile-time. Cache the rtd locally to the constructor, the getters and
1938 ;; the setters, in order to allow for redefinition of the record type; not
1939 ;; relevant in the case of modules, but perhaps if we make this public, it
1940 ;; could matter.
1941
1942 ((define-record-type
1943 (lambda (x)
1944 (define (make-id scope . fragments)
1945 (datum->syntax scope
1946 (apply symbol-append
1947 (map (lambda (x)
1948 (if (symbol? x) x (syntax->datum x)))
1949 fragments))))
1950
1951 (define (getter rtd type-name field slot)
1952 #`(define #,(make-id rtd type-name '- field)
1953 (let ((rtd #,rtd))
1954 (lambda (#,type-name)
1955 (if (eq? (struct-vtable #,type-name) rtd)
1956 (struct-ref #,type-name #,slot)
1957 (%record-type-error rtd #,type-name))))))
1958
1959 (define (setter rtd type-name field slot)
1960 #`(define #,(make-id rtd 'set- type-name '- field '!)
1961 (let ((rtd #,rtd))
1962 (lambda (#,type-name val)
1963 (if (eq? (struct-vtable #,type-name) rtd)
1964 (struct-set! #,type-name #,slot val)
1965 (%record-type-error rtd #,type-name))))))
1966
1967 (define (accessors rtd type-name fields n exp)
1968 (syntax-case fields ()
1969 (() exp)
1970 (((field #:no-accessors) field* ...) (identifier? #'field)
1971 (accessors rtd type-name #'(field* ...) (1+ n)
1972 exp))
1973 (((field #:no-setter) field* ...) (identifier? #'field)
1974 (accessors rtd type-name #'(field* ...) (1+ n)
1975 #`(begin #,exp
1976 #,(getter rtd type-name #'field n))))
1977 (((field #:no-getter) field* ...) (identifier? #'field)
1978 (accessors rtd type-name #'(field* ...) (1+ n)
1979 #`(begin #,exp
1980 #,(setter rtd type-name #'field n))))
1981 ((field field* ...) (identifier? #'field)
1982 (accessors rtd type-name #'(field* ...) (1+ n)
1983 #`(begin #,exp
1984 #,(getter rtd type-name #'field n)
1985 #,(setter rtd type-name #'field n))))))
1986
1987 (define (predicate rtd type-name fields exp)
1988 (accessors
1989 rtd type-name fields 0
1990 #`(begin
1991 #,exp
1992 (define (#,(make-id rtd type-name '?) obj)
1993 (and (struct? obj) (eq? (struct-vtable obj) #,rtd))))))
1994
1995 (define (field-list fields)
1996 (syntax-case fields ()
1997 (() '())
1998 (((f . opts) . rest) (identifier? #'f)
1999 (cons #'f (field-list #'rest)))
2000 ((f . rest) (identifier? #'f)
2001 (cons #'f (field-list #'rest)))))
2002
2003 (define (constructor rtd type-name fields exp)
2004 (let ((ctor (make-id rtd type-name '-constructor))
2005 (args (field-list fields)))
2006 (predicate rtd type-name fields
2007 #`(begin #,exp
2008 (define #,ctor
2009 (let ((rtd #,rtd))
2010 (lambda #,args
2011 (make-struct rtd 0 #,@args))))
2012 (struct-set! #,rtd (+ vtable-offset-user 2)
2013 #,ctor)))))
2014
2015 (define (type type-name printer fields)
2016 (define (make-layout)
2017 (let lp ((fields fields) (slots '()))
2018 (syntax-case fields ()
2019 (() (datum->syntax #'here
2020 (make-struct-layout
2021 (apply string-append slots))))
2022 ((_ . rest) (lp #'rest (cons "pw" slots))))))
2023
2024 (let ((rtd (make-id type-name type-name '-type)))
2025 (constructor rtd type-name fields
2026 #`(begin
2027 (define #,rtd
2028 (make-struct record-type-vtable 0
2029 '#,(make-layout)
2030 #,printer
2031 '#,type-name
2032 '#,(field-list fields)))
2033 (set-struct-vtable-name! #,rtd '#,type-name)))))
2034
2035 (syntax-case x ()
2036 ((_ type-name printer (field ...))
2037 (type #'type-name #'printer #'(field ...)))))))
2038
2039 ;; module-type
2040 ;;
2041 ;; A module is characterized by an obarray in which local symbols
2042 ;; are interned, a list of modules, "uses", from which non-local
2043 ;; bindings can be inherited, and an optional lazy-binder which
2044 ;; is a (CLOSURE module symbol) which, as a last resort, can provide
2045 ;; bindings that would otherwise not be found locally in the module.
2046 ;;
2047 ;; NOTE: If you change the set of fields or their order, you also need to
2048 ;; change the constants in libguile/modules.h.
2049 ;;
2050 ;; NOTE: The getter `module-transfomer' is defined libguile/modules.c.
2051 ;; NOTE: The getter `module-name' is defined later, due to boot reasons.
2052 ;; NOTE: The getter `module-public-interface' is used in libguile/modules.c.
2053 ;;
2054 (define-record-type module
2055 (lambda (obj port) (%print-module obj port))
2056 (obarray
2057 uses
2058 binder
2059 eval-closure
2060 (transformer #:no-getter)
2061 (name #:no-getter)
2062 kind
2063 duplicates-handlers
2064 (import-obarray #:no-setter)
2065 observers
2066 (weak-observers #:no-setter)
2067 version
2068 submodules
2069 submodule-binder
2070 public-interface
2071 filename)))
2072
2073
2074 ;; make-module &opt size uses binder
2075 ;;
2076 ;; Create a new module, perhaps with a particular size of obarray,
2077 ;; initial uses list, or binding procedure.
2078 ;;
2079 (define* (make-module #:optional (size 31) (uses '()) (binder #f))
2080 (if (not (integer? size))
2081 (error "Illegal size to make-module." size))
2082 (if (not (and (list? uses)
2083 (and-map module? uses)))
2084 (error "Incorrect use list." uses))
2085 (if (and binder (not (procedure? binder)))
2086 (error
2087 "Lazy-binder expected to be a procedure or #f." binder))
2088
2089 (module-constructor (make-hash-table size)
2090 uses binder #f macroexpand
2091 #f #f #f
2092 (make-hash-table)
2093 '()
2094 (make-weak-key-hash-table 31) #f
2095 (make-hash-table 7) #f #f #f))
2096
2097
2098 \f
2099
2100 ;;; {Observer protocol}
2101 ;;;
2102
2103 (define (module-observe module proc)
2104 (set-module-observers! module (cons proc (module-observers module)))
2105 (cons module proc))
2106
2107 (define* (module-observe-weak module observer-id #:optional (proc observer-id))
2108 ;; Register PROC as an observer of MODULE under name OBSERVER-ID (which can
2109 ;; be any Scheme object). PROC is invoked and passed MODULE any time
2110 ;; MODULE is modified. PROC gets unregistered when OBSERVER-ID gets GC'd
2111 ;; (thus, it is never unregistered if OBSERVER-ID is an immediate value,
2112 ;; for instance).
2113
2114 ;; The two-argument version is kept for backward compatibility: when called
2115 ;; with two arguments, the observer gets unregistered when closure PROC
2116 ;; gets GC'd (making it impossible to use an anonymous lambda for PROC).
2117 (hashq-set! (module-weak-observers module) observer-id proc))
2118
2119 (define (module-unobserve token)
2120 (let ((module (car token))
2121 (id (cdr token)))
2122 (if (integer? id)
2123 (hash-remove! (module-weak-observers module) id)
2124 (set-module-observers! module (delq1! id (module-observers module)))))
2125 *unspecified*)
2126
2127 (define module-defer-observers #f)
2128 (define module-defer-observers-mutex (make-mutex 'recursive))
2129 (define module-defer-observers-table (make-hash-table))
2130
2131 (define (module-modified m)
2132 (if module-defer-observers
2133 (hash-set! module-defer-observers-table m #t)
2134 (module-call-observers m)))
2135
2136 ;;; This function can be used to delay calls to observers so that they
2137 ;;; can be called once only in the face of massive updating of modules.
2138 ;;;
2139 (define (call-with-deferred-observers thunk)
2140 (dynamic-wind
2141 (lambda ()
2142 (lock-mutex module-defer-observers-mutex)
2143 (set! module-defer-observers #t))
2144 thunk
2145 (lambda ()
2146 (set! module-defer-observers #f)
2147 (hash-for-each (lambda (m dummy)
2148 (module-call-observers m))
2149 module-defer-observers-table)
2150 (hash-clear! module-defer-observers-table)
2151 (unlock-mutex module-defer-observers-mutex))))
2152
2153 (define (module-call-observers m)
2154 (for-each (lambda (proc) (proc m)) (module-observers m))
2155
2156 ;; We assume that weak observers don't (un)register themselves as they are
2157 ;; called since this would preclude proper iteration over the hash table
2158 ;; elements.
2159 (hash-for-each (lambda (id proc) (proc m)) (module-weak-observers m)))
2160
2161 \f
2162
2163 ;;; {Module Searching in General}
2164 ;;;
2165 ;;; We sometimes want to look for properties of a symbol
2166 ;;; just within the obarray of one module. If the property
2167 ;;; holds, then it is said to hold ``locally'' as in, ``The symbol
2168 ;;; DISPLAY is locally rebound in the module `safe-guile'.''
2169 ;;;
2170 ;;;
2171 ;;; Other times, we want to test for a symbol property in the obarray
2172 ;;; of M and, if it is not found there, try each of the modules in the
2173 ;;; uses list of M. This is the normal way of testing for some
2174 ;;; property, so we state these properties without qualification as
2175 ;;; in: ``The symbol 'fnord is interned in module M because it is
2176 ;;; interned locally in module M2 which is a member of the uses list
2177 ;;; of M.''
2178 ;;;
2179
2180 ;; module-search fn m
2181 ;;
2182 ;; return the first non-#f result of FN applied to M and then to
2183 ;; the modules in the uses of m, and so on recursively. If all applications
2184 ;; return #f, then so does this function.
2185 ;;
2186 (define (module-search fn m v)
2187 (define (loop pos)
2188 (and (pair? pos)
2189 (or (module-search fn (car pos) v)
2190 (loop (cdr pos)))))
2191 (or (fn m v)
2192 (loop (module-uses m))))
2193
2194
2195 ;;; {Is a symbol bound in a module?}
2196 ;;;
2197 ;;; Symbol S in Module M is bound if S is interned in M and if the binding
2198 ;;; of S in M has been set to some well-defined value.
2199 ;;;
2200
2201 ;; module-locally-bound? module symbol
2202 ;;
2203 ;; Is a symbol bound (interned and defined) locally in a given module?
2204 ;;
2205 (define (module-locally-bound? m v)
2206 (let ((var (module-local-variable m v)))
2207 (and var
2208 (variable-bound? var))))
2209
2210 ;; module-bound? module symbol
2211 ;;
2212 ;; Is a symbol bound (interned and defined) anywhere in a given module
2213 ;; or its uses?
2214 ;;
2215 (define (module-bound? m v)
2216 (let ((var (module-variable m v)))
2217 (and var
2218 (variable-bound? var))))
2219
2220 ;;; {Is a symbol interned in a module?}
2221 ;;;
2222 ;;; Symbol S in Module M is interned if S occurs in
2223 ;;; of S in M has been set to some well-defined value.
2224 ;;;
2225 ;;; It is possible to intern a symbol in a module without providing
2226 ;;; an initial binding for the corresponding variable. This is done
2227 ;;; with:
2228 ;;; (module-add! module symbol (make-undefined-variable))
2229 ;;;
2230 ;;; In that case, the symbol is interned in the module, but not
2231 ;;; bound there. The unbound symbol shadows any binding for that
2232 ;;; symbol that might otherwise be inherited from a member of the uses list.
2233 ;;;
2234
2235 (define (module-obarray-get-handle ob key)
2236 ((if (symbol? key) hashq-get-handle hash-get-handle) ob key))
2237
2238 (define (module-obarray-ref ob key)
2239 ((if (symbol? key) hashq-ref hash-ref) ob key))
2240
2241 (define (module-obarray-set! ob key val)
2242 ((if (symbol? key) hashq-set! hash-set!) ob key val))
2243
2244 (define (module-obarray-remove! ob key)
2245 ((if (symbol? key) hashq-remove! hash-remove!) ob key))
2246
2247 ;; module-symbol-locally-interned? module symbol
2248 ;;
2249 ;; is a symbol interned (not neccessarily defined) locally in a given module
2250 ;; or its uses? Interned symbols shadow inherited bindings even if
2251 ;; they are not themselves bound to a defined value.
2252 ;;
2253 (define (module-symbol-locally-interned? m v)
2254 (not (not (module-obarray-get-handle (module-obarray m) v))))
2255
2256 ;; module-symbol-interned? module symbol
2257 ;;
2258 ;; is a symbol interned (not neccessarily defined) anywhere in a given module
2259 ;; or its uses? Interned symbols shadow inherited bindings even if
2260 ;; they are not themselves bound to a defined value.
2261 ;;
2262 (define (module-symbol-interned? m v)
2263 (module-search module-symbol-locally-interned? m v))
2264
2265
2266 ;;; {Mapping modules x symbols --> variables}
2267 ;;;
2268
2269 ;; module-local-variable module symbol
2270 ;; return the local variable associated with a MODULE and SYMBOL.
2271 ;;
2272 ;;; This function is very important. It is the only function that can
2273 ;;; return a variable from a module other than the mutators that store
2274 ;;; new variables in modules. Therefore, this function is the location
2275 ;;; of the "lazy binder" hack.
2276 ;;;
2277 ;;; If symbol is defined in MODULE, and if the definition binds symbol
2278 ;;; to a variable, return that variable object.
2279 ;;;
2280 ;;; If the symbols is not found at first, but the module has a lazy binder,
2281 ;;; then try the binder.
2282 ;;;
2283 ;;; If the symbol is not found at all, return #f.
2284 ;;;
2285 ;;; (This is now written in C, see `modules.c'.)
2286 ;;;
2287
2288 ;;; {Mapping modules x symbols --> bindings}
2289 ;;;
2290 ;;; These are similar to the mapping to variables, except that the
2291 ;;; variable is dereferenced.
2292 ;;;
2293
2294 ;; module-symbol-binding module symbol opt-value
2295 ;;
2296 ;; return the binding of a variable specified by name within
2297 ;; a given module, signalling an error if the variable is unbound.
2298 ;; If the OPT-VALUE is passed, then instead of signalling an error,
2299 ;; return OPT-VALUE.
2300 ;;
2301 (define (module-symbol-local-binding m v . opt-val)
2302 (let ((var (module-local-variable m v)))
2303 (if (and var (variable-bound? var))
2304 (variable-ref var)
2305 (if (not (null? opt-val))
2306 (car opt-val)
2307 (error "Locally unbound variable." v)))))
2308
2309 ;; module-symbol-binding module symbol opt-value
2310 ;;
2311 ;; return the binding of a variable specified by name within
2312 ;; a given module, signalling an error if the variable is unbound.
2313 ;; If the OPT-VALUE is passed, then instead of signalling an error,
2314 ;; return OPT-VALUE.
2315 ;;
2316 (define (module-symbol-binding m v . opt-val)
2317 (let ((var (module-variable m v)))
2318 (if (and var (variable-bound? var))
2319 (variable-ref var)
2320 (if (not (null? opt-val))
2321 (car opt-val)
2322 (error "Unbound variable." v)))))
2323
2324
2325 \f
2326
2327 ;;; {Adding Variables to Modules}
2328 ;;;
2329
2330 ;; module-make-local-var! module symbol
2331 ;;
2332 ;; ensure a variable for V in the local namespace of M.
2333 ;; If no variable was already there, then create a new and uninitialzied
2334 ;; variable.
2335 ;;
2336 ;; This function is used in modules.c.
2337 ;;
2338 (define (module-make-local-var! m v)
2339 (or (let ((b (module-obarray-ref (module-obarray m) v)))
2340 (and (variable? b)
2341 (begin
2342 ;; Mark as modified since this function is called when
2343 ;; the standard eval closure defines a binding
2344 (module-modified m)
2345 b)))
2346
2347 ;; Create a new local variable.
2348 (let ((local-var (make-undefined-variable)))
2349 (module-add! m v local-var)
2350 local-var)))
2351
2352 ;; module-ensure-local-variable! module symbol
2353 ;;
2354 ;; Ensure that there is a local variable in MODULE for SYMBOL. If
2355 ;; there is no binding for SYMBOL, create a new uninitialized
2356 ;; variable. Return the local variable.
2357 ;;
2358 (define (module-ensure-local-variable! module symbol)
2359 (or (module-local-variable module symbol)
2360 (let ((var (make-undefined-variable)))
2361 (module-add! module symbol var)
2362 var)))
2363
2364 ;; module-add! module symbol var
2365 ;;
2366 ;; ensure a particular variable for V in the local namespace of M.
2367 ;;
2368 (define (module-add! m v var)
2369 (if (not (variable? var))
2370 (error "Bad variable to module-add!" var))
2371 (module-obarray-set! (module-obarray m) v var)
2372 (module-modified m))
2373
2374 ;; module-remove!
2375 ;;
2376 ;; make sure that a symbol is undefined in the local namespace of M.
2377 ;;
2378 (define (module-remove! m v)
2379 (module-obarray-remove! (module-obarray m) v)
2380 (module-modified m))
2381
2382 (define (module-clear! m)
2383 (hash-clear! (module-obarray m))
2384 (module-modified m))
2385
2386 ;; MODULE-FOR-EACH -- exported
2387 ;;
2388 ;; Call PROC on each symbol in MODULE, with arguments of (SYMBOL VARIABLE).
2389 ;;
2390 (define (module-for-each proc module)
2391 (hash-for-each proc (module-obarray module)))
2392
2393 (define (module-map proc module)
2394 (hash-map->list proc (module-obarray module)))
2395
2396 ;; Submodules
2397 ;;
2398 ;; Modules exist in a separate namespace from values, because you generally do
2399 ;; not want the name of a submodule, which you might not even use, to collide
2400 ;; with local variables that happen to be named the same as the submodule.
2401 ;;
2402 (define (module-ref-submodule module name)
2403 (or (hashq-ref (module-submodules module) name)
2404 (and (module-submodule-binder module)
2405 ((module-submodule-binder module) module name))))
2406
2407 (define (module-define-submodule! module name submodule)
2408 (hashq-set! (module-submodules module) name submodule))
2409
2410 \f
2411
2412 ;;; {Module-based Loading}
2413 ;;;
2414
2415 (define (save-module-excursion thunk)
2416 (let ((inner-module (current-module))
2417 (outer-module #f))
2418 (dynamic-wind (lambda ()
2419 (set! outer-module (current-module))
2420 (set-current-module inner-module)
2421 (set! inner-module #f))
2422 thunk
2423 (lambda ()
2424 (set! inner-module (current-module))
2425 (set-current-module outer-module)
2426 (set! outer-module #f)))))
2427
2428 \f
2429
2430 ;;; {MODULE-REF -- exported}
2431 ;;;
2432
2433 ;; Returns the value of a variable called NAME in MODULE or any of its
2434 ;; used modules. If there is no such variable, then if the optional third
2435 ;; argument DEFAULT is present, it is returned; otherwise an error is signaled.
2436 ;;
2437 (define (module-ref module name . rest)
2438 (let ((variable (module-variable module name)))
2439 (if (and variable (variable-bound? variable))
2440 (variable-ref variable)
2441 (if (null? rest)
2442 (error "No variable named" name 'in module)
2443 (car rest) ; default value
2444 ))))
2445
2446 ;; MODULE-SET! -- exported
2447 ;;
2448 ;; Sets the variable called NAME in MODULE (or in a module that MODULE uses)
2449 ;; to VALUE; if there is no such variable, an error is signaled.
2450 ;;
2451 (define (module-set! module name value)
2452 (let ((variable (module-variable module name)))
2453 (if variable
2454 (variable-set! variable value)
2455 (error "No variable named" name 'in module))))
2456
2457 ;; MODULE-DEFINE! -- exported
2458 ;;
2459 ;; Sets the variable called NAME in MODULE to VALUE; if there is no such
2460 ;; variable, it is added first.
2461 ;;
2462 (define (module-define! module name value)
2463 (let ((variable (module-local-variable module name)))
2464 (if variable
2465 (begin
2466 (variable-set! variable value)
2467 (module-modified module))
2468 (let ((variable (make-variable value)))
2469 (module-add! module name variable)))))
2470
2471 ;; MODULE-DEFINED? -- exported
2472 ;;
2473 ;; Return #t iff NAME is defined in MODULE (or in a module that MODULE
2474 ;; uses)
2475 ;;
2476 (define (module-defined? module name)
2477 (let ((variable (module-variable module name)))
2478 (and variable (variable-bound? variable))))
2479
2480 ;; MODULE-USE! module interface
2481 ;;
2482 ;; Add INTERFACE to the list of interfaces used by MODULE.
2483 ;;
2484 (define (module-use! module interface)
2485 (if (not (or (eq? module interface)
2486 (memq interface (module-uses module))))
2487 (begin
2488 ;; Newly used modules must be appended rather than consed, so that
2489 ;; `module-variable' traverses the use list starting from the first
2490 ;; used module.
2491 (set-module-uses! module (append (module-uses module)
2492 (list interface)))
2493 (hash-clear! (module-import-obarray module))
2494 (module-modified module))))
2495
2496 ;; MODULE-USE-INTERFACES! module interfaces
2497 ;;
2498 ;; Same as MODULE-USE!, but only notifies module observers after all
2499 ;; interfaces are added to the inports list.
2500 ;;
2501 (define (module-use-interfaces! module interfaces)
2502 (let* ((cur (module-uses module))
2503 (new (let lp ((in interfaces) (out '()))
2504 (if (null? in)
2505 (reverse out)
2506 (lp (cdr in)
2507 (let ((iface (car in)))
2508 (if (or (memq iface cur) (memq iface out))
2509 out
2510 (cons iface out))))))))
2511 (set-module-uses! module (append cur new))
2512 (hash-clear! (module-import-obarray module))
2513 (module-modified module)))
2514
2515 \f
2516
2517 ;;; {Recursive Namespaces}
2518 ;;;
2519 ;;; A hierarchical namespace emerges if we consider some module to be
2520 ;;; root, and submodules of that module to be nested namespaces.
2521 ;;;
2522 ;;; The routines here manage variable names in hierarchical namespace.
2523 ;;; Each variable name is a list of elements, looked up in successively nested
2524 ;;; modules.
2525 ;;;
2526 ;;; (nested-ref some-root-module '(foo bar baz))
2527 ;;; => <value of a variable named baz in the submodule bar of
2528 ;;; the submodule foo of some-root-module>
2529 ;;;
2530 ;;;
2531 ;;; There are:
2532 ;;;
2533 ;;; ;; a-root is a module
2534 ;;; ;; name is a list of symbols
2535 ;;;
2536 ;;; nested-ref a-root name
2537 ;;; nested-set! a-root name val
2538 ;;; nested-define! a-root name val
2539 ;;; nested-remove! a-root name
2540 ;;;
2541 ;;; These functions manipulate values in namespaces. For referencing the
2542 ;;; namespaces themselves, use the following:
2543 ;;;
2544 ;;; nested-ref-module a-root name
2545 ;;; nested-define-module! a-root name mod
2546 ;;;
2547 ;;; (current-module) is a natural choice for a root so for convenience there are
2548 ;;; also:
2549 ;;;
2550 ;;; local-ref name == nested-ref (current-module) name
2551 ;;; local-set! name val == nested-set! (current-module) name val
2552 ;;; local-define name val == nested-define! (current-module) name val
2553 ;;; local-remove name == nested-remove! (current-module) name
2554 ;;; local-ref-module name == nested-ref-module (current-module) name
2555 ;;; local-define-module! name m == nested-define-module! (current-module) name m
2556 ;;;
2557
2558
2559 (define (nested-ref root names)
2560 (if (null? names)
2561 root
2562 (let loop ((cur root)
2563 (head (car names))
2564 (tail (cdr names)))
2565 (if (null? tail)
2566 (module-ref cur head #f)
2567 (let ((cur (module-ref-submodule cur head)))
2568 (and cur
2569 (loop cur (car tail) (cdr tail))))))))
2570
2571 (define (nested-set! root names val)
2572 (let loop ((cur root)
2573 (head (car names))
2574 (tail (cdr names)))
2575 (if (null? tail)
2576 (module-set! cur head val)
2577 (let ((cur (module-ref-submodule cur head)))
2578 (if (not cur)
2579 (error "failed to resolve module" names)
2580 (loop cur (car tail) (cdr tail)))))))
2581
2582 (define (nested-define! root names val)
2583 (let loop ((cur root)
2584 (head (car names))
2585 (tail (cdr names)))
2586 (if (null? tail)
2587 (module-define! cur head val)
2588 (let ((cur (module-ref-submodule cur head)))
2589 (if (not cur)
2590 (error "failed to resolve module" names)
2591 (loop cur (car tail) (cdr tail)))))))
2592
2593 (define (nested-remove! root names)
2594 (let loop ((cur root)
2595 (head (car names))
2596 (tail (cdr names)))
2597 (if (null? tail)
2598 (module-remove! cur head)
2599 (let ((cur (module-ref-submodule cur head)))
2600 (if (not cur)
2601 (error "failed to resolve module" names)
2602 (loop cur (car tail) (cdr tail)))))))
2603
2604
2605 (define (nested-ref-module root names)
2606 (let loop ((cur root)
2607 (names names))
2608 (if (null? names)
2609 cur
2610 (let ((cur (module-ref-submodule cur (car names))))
2611 (and cur
2612 (loop cur (cdr names)))))))
2613
2614 (define (nested-define-module! root names module)
2615 (if (null? names)
2616 (error "can't redefine root module" root module)
2617 (let loop ((cur root)
2618 (head (car names))
2619 (tail (cdr names)))
2620 (if (null? tail)
2621 (module-define-submodule! cur head module)
2622 (let ((cur (or (module-ref-submodule cur head)
2623 (let ((m (make-module 31)))
2624 (set-module-kind! m 'directory)
2625 (set-module-name! m (append (module-name cur)
2626 (list head)))
2627 (module-define-submodule! cur head m)
2628 m))))
2629 (loop cur (car tail) (cdr tail)))))))
2630
2631
2632 (define (local-ref names)
2633 (nested-ref (current-module) names))
2634
2635 (define (local-set! names val)
2636 (nested-set! (current-module) names val))
2637
2638 (define (local-define names val)
2639 (nested-define! (current-module) names val))
2640
2641 (define (local-remove names)
2642 (nested-remove! (current-module) names))
2643
2644 (define (local-ref-module names)
2645 (nested-ref-module (current-module) names))
2646
2647 (define (local-define-module names mod)
2648 (nested-define-module! (current-module) names mod))
2649
2650
2651
2652 \f
2653
2654 ;;; {The (guile) module}
2655 ;;;
2656 ;;; The standard module, which has the core Guile bindings. Also called the
2657 ;;; "root module", as it is imported by many other modules, but it is not
2658 ;;; necessarily the root of anything; and indeed, the module named '() might be
2659 ;;; better thought of as a root.
2660 ;;;
2661
2662 ;; The root module uses the pre-modules-obarray as its obarray. This
2663 ;; special obarray accumulates all bindings that have been established
2664 ;; before the module system is fully booted.
2665 ;;
2666 ;; (The obarray continues to be used by code that has been closed over
2667 ;; before the module system has been booted.)
2668 ;;
2669 (define the-root-module
2670 (let ((m (make-module 0)))
2671 (set-module-obarray! m (%get-pre-modules-obarray))
2672 (set-module-name! m '(guile))
2673 m))
2674
2675 ;; The root interface is a module that uses the same obarray as the
2676 ;; root module. It does not allow new definitions, tho.
2677 ;;
2678 (define the-scm-module
2679 (let ((m (make-module 0)))
2680 (set-module-obarray! m (%get-pre-modules-obarray))
2681 (set-module-name! m '(guile))
2682 (set-module-kind! m 'interface)
2683
2684 ;; In Guile 1.8 and earlier M was its own public interface.
2685 (set-module-public-interface! m m)
2686
2687 m))
2688
2689 (set-module-public-interface! the-root-module the-scm-module)
2690
2691 \f
2692
2693 ;; Now that we have a root module, even though modules aren't fully booted,
2694 ;; expand the definition of resolve-module.
2695 ;;
2696 (define (resolve-module name . args)
2697 (if (equal? name '(guile))
2698 the-root-module
2699 (error "unexpected module to resolve during module boot" name)))
2700
2701 ;; Cheat. These bindings are needed by modules.c, but we don't want
2702 ;; to move their real definition here because that would be unnatural.
2703 ;;
2704 (define define-module* #f)
2705 (define process-use-modules #f)
2706 (define module-export! #f)
2707 (define default-duplicate-binding-procedures #f)
2708
2709 ;; This boots the module system. All bindings needed by modules.c
2710 ;; must have been defined by now.
2711 ;;
2712 (set-current-module the-root-module)
2713
2714
2715 \f
2716
2717 ;; Now that modules are booted, give module-name its final definition.
2718 ;;
2719 (define module-name
2720 (let ((accessor (record-accessor module-type 'name)))
2721 (lambda (mod)
2722 (or (accessor mod)
2723 (let ((name (list (gensym))))
2724 ;; Name MOD and bind it in the module root so that it's visible to
2725 ;; `resolve-module'. This is important as `psyntax' stores module
2726 ;; names and relies on being able to `resolve-module' them.
2727 (set-module-name! mod name)
2728 (nested-define-module! (resolve-module '() #f) name mod)
2729 (accessor mod))))))
2730
2731 (define (make-modules-in module name)
2732 (or (nested-ref-module module name)
2733 (let ((m (make-module 31)))
2734 (set-module-kind! m 'directory)
2735 (set-module-name! m (append (module-name module) name))
2736 (nested-define-module! module name m)
2737 m)))
2738
2739 (define (beautify-user-module! module)
2740 (let ((interface (module-public-interface module)))
2741 (if (or (not interface)
2742 (eq? interface module))
2743 (let ((interface (make-module 31)))
2744 (set-module-name! interface (module-name module))
2745 (set-module-version! interface (module-version module))
2746 (set-module-kind! interface 'interface)
2747 (set-module-public-interface! module interface))))
2748 (if (and (not (memq the-scm-module (module-uses module)))
2749 (not (eq? module the-root-module)))
2750 ;; Import the default set of bindings (from the SCM module) in MODULE.
2751 (module-use! module the-scm-module)))
2752
2753 (define (version-matches? version-ref target)
2754 (define (sub-versions-match? v-refs t)
2755 (define (sub-version-matches? v-ref t)
2756 (let ((matches? (lambda (v) (sub-version-matches? v t))))
2757 (cond
2758 ((number? v-ref) (eqv? v-ref t))
2759 ((list? v-ref)
2760 (case (car v-ref)
2761 ((>=) (>= t (cadr v-ref)))
2762 ((<=) (<= t (cadr v-ref)))
2763 ((and) (and-map matches? (cdr v-ref)))
2764 ((or) (or-map matches? (cdr v-ref)))
2765 ((not) (not (matches? (cadr v-ref))))
2766 (else (error "Invalid sub-version reference" v-ref))))
2767 (else (error "Invalid sub-version reference" v-ref)))))
2768 (or (null? v-refs)
2769 (and (not (null? t))
2770 (sub-version-matches? (car v-refs) (car t))
2771 (sub-versions-match? (cdr v-refs) (cdr t)))))
2772
2773 (let ((matches? (lambda (v) (version-matches? v target))))
2774 (or (null? version-ref)
2775 (case (car version-ref)
2776 ((and) (and-map matches? (cdr version-ref)))
2777 ((or) (or-map matches? (cdr version-ref)))
2778 ((not) (not (matches? (cadr version-ref))))
2779 (else (sub-versions-match? version-ref target))))))
2780
2781 (define (make-fresh-user-module)
2782 (let ((m (make-module)))
2783 (beautify-user-module! m)
2784 m))
2785
2786 ;; NOTE: This binding is used in libguile/modules.c.
2787 ;;
2788 (define resolve-module
2789 (let ((root (make-module)))
2790 (set-module-name! root '())
2791 ;; Define the-root-module as '(guile).
2792 (module-define-submodule! root 'guile the-root-module)
2793
2794 (lambda* (name #:optional (autoload #t) (version #f) #:key (ensure #t))
2795 (let ((already (nested-ref-module root name)))
2796 (cond
2797 ((and already
2798 (or (not autoload) (module-public-interface already)))
2799 ;; A hit, a palpable hit.
2800 (if (and version
2801 (not (version-matches? version (module-version already))))
2802 (error "incompatible module version already loaded" name))
2803 already)
2804 (autoload
2805 ;; Try to autoload the module, and recurse.
2806 (try-load-module name version)
2807 (resolve-module name #f #:ensure ensure))
2808 (else
2809 ;; No module found (or if one was, it had no public interface), and
2810 ;; we're not autoloading. Make an empty module if #:ensure is true.
2811 (or already
2812 (and ensure
2813 (make-modules-in root name)))))))))
2814
2815
2816 (define (try-load-module name version)
2817 (try-module-autoload name version))
2818
2819 (define (reload-module m)
2820 "Revisit the source file corresponding to the module @var{m}."
2821 (let ((f (module-filename m)))
2822 (if f
2823 (save-module-excursion
2824 (lambda ()
2825 ;; Re-set the initial environment, as in try-module-autoload.
2826 (set-current-module (make-fresh-user-module))
2827 (primitive-load-path f)
2828 m))
2829 ;; Though we could guess, we *should* know it.
2830 (error "unknown file name for module" m))))
2831
2832 (define (purify-module! module)
2833 "Removes bindings in MODULE which are inherited from the (guile) module."
2834 (let ((use-list (module-uses module)))
2835 (if (and (pair? use-list)
2836 (eq? (car (last-pair use-list)) the-scm-module))
2837 (set-module-uses! module (reverse (cdr (reverse use-list)))))))
2838
2839 ;; Return a module that is an interface to the module designated by
2840 ;; NAME.
2841 ;;
2842 ;; `resolve-interface' takes four keyword arguments:
2843 ;;
2844 ;; #:select SELECTION
2845 ;;
2846 ;; SELECTION is a list of binding-specs to be imported; A binding-spec
2847 ;; is either a symbol or a pair of symbols (ORIG . SEEN), where ORIG
2848 ;; is the name in the used module and SEEN is the name in the using
2849 ;; module. Note that SEEN is also passed through RENAMER, below. The
2850 ;; default is to select all bindings. If you specify no selection but
2851 ;; a renamer, only the bindings that already exist in the used module
2852 ;; are made available in the interface. Bindings that are added later
2853 ;; are not picked up.
2854 ;;
2855 ;; #:hide BINDINGS
2856 ;;
2857 ;; BINDINGS is a list of bindings which should not be imported.
2858 ;;
2859 ;; #:prefix PREFIX
2860 ;;
2861 ;; PREFIX is a symbol that will be appended to each exported name.
2862 ;; The default is to not perform any renaming.
2863 ;;
2864 ;; #:renamer RENAMER
2865 ;;
2866 ;; RENAMER is a procedure that takes a symbol and returns its new
2867 ;; name. The default is not perform any renaming.
2868 ;;
2869 ;; Signal "no code for module" error if module name is not resolvable
2870 ;; or its public interface is not available. Signal "no binding"
2871 ;; error if selected binding does not exist in the used module.
2872 ;;
2873 (define* (resolve-interface name #:key
2874 (select #f)
2875 (hide '())
2876 (prefix #f)
2877 (renamer (if prefix
2878 (symbol-prefix-proc prefix)
2879 identity))
2880 version)
2881 (let* ((module (resolve-module name #t version #:ensure #f))
2882 (public-i (and module (module-public-interface module))))
2883 (and (or (not module) (not public-i))
2884 (error "no code for module" name))
2885 (if (and (not select) (null? hide) (eq? renamer identity))
2886 public-i
2887 (let ((selection (or select (module-map (lambda (sym var) sym)
2888 public-i)))
2889 (custom-i (make-module 31)))
2890 (set-module-kind! custom-i 'custom-interface)
2891 (set-module-name! custom-i name)
2892 ;; XXX - should use a lazy binder so that changes to the
2893 ;; used module are picked up automatically.
2894 (for-each (lambda (bspec)
2895 (let* ((direct? (symbol? bspec))
2896 (orig (if direct? bspec (car bspec)))
2897 (seen (if direct? bspec (cdr bspec)))
2898 (var (or (module-local-variable public-i orig)
2899 (module-local-variable module orig)
2900 (error
2901 ;; fixme: format manually for now
2902 (simple-format
2903 #f "no binding `~A' in module ~A"
2904 orig name)))))
2905 (if (memq orig hide)
2906 (set! hide (delq! orig hide))
2907 (module-add! custom-i
2908 (renamer seen)
2909 var))))
2910 selection)
2911 ;; Check that we are not hiding bindings which don't exist
2912 (for-each (lambda (binding)
2913 (if (not (module-local-variable public-i binding))
2914 (error
2915 (simple-format
2916 #f "no binding `~A' to hide in module ~A"
2917 binding name))))
2918 hide)
2919 custom-i))))
2920
2921 (define (symbol-prefix-proc prefix)
2922 (lambda (symbol)
2923 (symbol-append prefix symbol)))
2924
2925 ;; This function is called from "modules.c". If you change it, be
2926 ;; sure to update "modules.c" as well.
2927
2928 (define* (define-module* name
2929 #:key filename pure version (duplicates '())
2930 (imports '()) (exports '()) (replacements '())
2931 (re-exports '()) (autoloads '()) transformer)
2932 (define (list-of pred l)
2933 (or (null? l)
2934 (and (pair? l) (pred (car l)) (list-of pred (cdr l)))))
2935 (define (valid-export? x)
2936 (or (symbol? x) (and (pair? x) (symbol? (car x)) (symbol? (cdr x)))))
2937 (define (valid-autoload? x)
2938 (and (pair? x) (list-of symbol? (car x)) (list-of symbol? (cdr x))))
2939
2940 (define (resolve-imports imports)
2941 (define (resolve-import import-spec)
2942 (if (list? import-spec)
2943 (apply resolve-interface import-spec)
2944 (error "unexpected use-module specification" import-spec)))
2945 (let lp ((imports imports) (out '()))
2946 (cond
2947 ((null? imports) (reverse! out))
2948 ((pair? imports)
2949 (lp (cdr imports)
2950 (cons (resolve-import (car imports)) out)))
2951 (else (error "unexpected tail of imports list" imports)))))
2952
2953 ;; We could add a #:no-check arg, set by the define-module macro, if
2954 ;; these checks are taking too much time.
2955 ;;
2956 (let ((module (resolve-module name #f)))
2957 (beautify-user-module! module)
2958 (if filename
2959 (set-module-filename! module filename))
2960 (if pure
2961 (purify-module! module))
2962 (if version
2963 (begin
2964 (if (not (list-of integer? version))
2965 (error "expected list of integers for version"))
2966 (set-module-version! module version)
2967 (set-module-version! (module-public-interface module) version)))
2968 (let ((imports (resolve-imports imports)))
2969 (call-with-deferred-observers
2970 (lambda ()
2971 (if (pair? imports)
2972 (module-use-interfaces! module imports))
2973 (if (list-of valid-export? exports)
2974 (if (pair? exports)
2975 (module-export! module exports))
2976 (error "expected exports to be a list of symbols or symbol pairs"))
2977 (if (list-of valid-export? replacements)
2978 (if (pair? replacements)
2979 (module-replace! module replacements))
2980 (error "expected replacements to be a list of symbols or symbol pairs"))
2981 (if (list-of valid-export? re-exports)
2982 (if (pair? re-exports)
2983 (module-re-export! module re-exports))
2984 (error "expected re-exports to be a list of symbols or symbol pairs"))
2985 ;; FIXME
2986 (if (not (null? autoloads))
2987 (apply module-autoload! module autoloads))
2988 ;; Wait until modules have been loaded to resolve duplicates
2989 ;; handlers.
2990 (if (pair? duplicates)
2991 (let ((handlers (lookup-duplicates-handlers duplicates)))
2992 (set-module-duplicates-handlers! module handlers))))))
2993
2994 (if transformer
2995 (if (and (pair? transformer) (list-of symbol? transformer))
2996 (let ((iface (resolve-interface transformer))
2997 (sym (car (last-pair transformer))))
2998 (set-module-transformer! module (module-ref iface sym)))
2999 (error "expected transformer to be a module name" transformer)))
3000
3001 (run-hook module-defined-hook module)
3002 module))
3003
3004 ;; `module-defined-hook' is a hook that is run whenever a new module
3005 ;; is defined. Its members are called with one argument, the new
3006 ;; module.
3007 (define module-defined-hook (make-hook 1))
3008
3009 \f
3010
3011 ;;; {Autoload}
3012 ;;;
3013
3014 (define (make-autoload-interface module name bindings)
3015 (let ((b (lambda (a sym definep)
3016 (and (memq sym bindings)
3017 (let ((i (module-public-interface (resolve-module name))))
3018 (if (not i)
3019 (error "missing interface for module" name))
3020 (let ((autoload (memq a (module-uses module))))
3021 ;; Replace autoload-interface with actual interface if
3022 ;; that has not happened yet.
3023 (if (pair? autoload)
3024 (set-car! autoload i)))
3025 (module-local-variable i sym))))))
3026 (module-constructor (make-hash-table 0) '() b #f #f name 'autoload #f
3027 (make-hash-table 0) '() (make-weak-value-hash-table 31) #f
3028 (make-hash-table 0) #f #f #f)))
3029
3030 (define (module-autoload! module . args)
3031 "Have @var{module} automatically load the module named @var{name} when one
3032 of the symbols listed in @var{bindings} is looked up. @var{args} should be a
3033 list of module-name/binding-list pairs, e.g., as in @code{(module-autoload!
3034 module '(ice-9 q) '(make-q q-length))}."
3035 (let loop ((args args))
3036 (cond ((null? args)
3037 #t)
3038 ((null? (cdr args))
3039 (error "invalid name+binding autoload list" args))
3040 (else
3041 (let ((name (car args))
3042 (bindings (cadr args)))
3043 (module-use! module (make-autoload-interface module
3044 name bindings))
3045 (loop (cddr args)))))))
3046
3047
3048 \f
3049
3050 ;;; {Autoloading modules}
3051 ;;;
3052
3053 (define autoloads-in-progress '())
3054
3055 ;; This function is called from "modules.c". If you change it, be
3056 ;; sure to update "modules.c" as well.
3057
3058 (define* (try-module-autoload module-name #:optional version)
3059 (let* ((reverse-name (reverse module-name))
3060 (name (symbol->string (car reverse-name)))
3061 (dir-hint-module-name (reverse (cdr reverse-name)))
3062 (dir-hint (apply string-append
3063 (map (lambda (elt)
3064 (string-append (symbol->string elt) "/"))
3065 dir-hint-module-name))))
3066 (resolve-module dir-hint-module-name #f)
3067 (and (not (autoload-done-or-in-progress? dir-hint name))
3068 (let ((didit #f))
3069 (dynamic-wind
3070 (lambda () (autoload-in-progress! dir-hint name))
3071 (lambda ()
3072 (with-fluids ((current-reader #f))
3073 (save-module-excursion
3074 (lambda ()
3075 ;; The initial environment when loading a module is a fresh
3076 ;; user module.
3077 (set-current-module (make-fresh-user-module))
3078 ;; Here we could allow some other search strategy (other than
3079 ;; primitive-load-path), for example using versions encoded
3080 ;; into the file system -- but then we would have to figure
3081 ;; out how to locate the compiled file, do auto-compilation,
3082 ;; etc. Punt for now, and don't use versions when locating
3083 ;; the file.
3084 (primitive-load-path (in-vicinity dir-hint name) #f)
3085 (set! didit #t)))))
3086 (lambda () (set-autoloaded! dir-hint name didit)))
3087 didit))))
3088
3089 \f
3090
3091 ;;; {Dynamic linking of modules}
3092 ;;;
3093
3094 (define autoloads-done '((guile . guile)))
3095
3096 (define (autoload-done-or-in-progress? p m)
3097 (let ((n (cons p m)))
3098 (->bool (or (member n autoloads-done)
3099 (member n autoloads-in-progress)))))
3100
3101 (define (autoload-done! p m)
3102 (let ((n (cons p m)))
3103 (set! autoloads-in-progress
3104 (delete! n autoloads-in-progress))
3105 (or (member n autoloads-done)
3106 (set! autoloads-done (cons n autoloads-done)))))
3107
3108 (define (autoload-in-progress! p m)
3109 (let ((n (cons p m)))
3110 (set! autoloads-done
3111 (delete! n autoloads-done))
3112 (set! autoloads-in-progress (cons n autoloads-in-progress))))
3113
3114 (define (set-autoloaded! p m done?)
3115 (if done?
3116 (autoload-done! p m)
3117 (let ((n (cons p m)))
3118 (set! autoloads-done (delete! n autoloads-done))
3119 (set! autoloads-in-progress (delete! n autoloads-in-progress)))))
3120
3121 \f
3122
3123 ;;; {Run-time options}
3124 ;;;
3125
3126 (define-syntax define-option-interface
3127 (syntax-rules ()
3128 ((_ (interface (options enable disable) (option-set!)))
3129 (begin
3130 (define options
3131 (case-lambda
3132 (() (interface))
3133 ((arg)
3134 (if (list? arg)
3135 (begin (interface arg) (interface))
3136 (for-each
3137 (lambda (option)
3138 (apply (lambda (name value documentation)
3139 (display name)
3140 (let ((len (string-length (symbol->string name))))
3141 (when (< len 16)
3142 (display #\tab)
3143 (when (< len 8)
3144 (display #\tab))))
3145 (display #\tab)
3146 (display value)
3147 (display #\tab)
3148 (display documentation)
3149 (newline))
3150 option))
3151 (interface #t))))))
3152 (define (enable . flags)
3153 (interface (append flags (interface)))
3154 (interface))
3155 (define (disable . flags)
3156 (let ((options (interface)))
3157 (for-each (lambda (flag) (set! options (delq! flag options)))
3158 flags)
3159 (interface options)
3160 (interface)))
3161 (define-syntax-rule (option-set! opt val)
3162 (eval-when (eval load compile expand)
3163 (options (append (options) (list 'opt val)))))))))
3164
3165 (define-option-interface
3166 (debug-options-interface
3167 (debug-options debug-enable debug-disable)
3168 (debug-set!)))
3169
3170 (define-option-interface
3171 (read-options-interface
3172 (read-options read-enable read-disable)
3173 (read-set!)))
3174
3175 (define-option-interface
3176 (print-options-interface
3177 (print-options print-enable print-disable)
3178 (print-set!)))
3179
3180 \f
3181
3182 ;;; {The Unspecified Value}
3183 ;;;
3184 ;;; Currently Guile represents unspecified values via one particular value,
3185 ;;; which may be obtained by evaluating (if #f #f). It would be nice in the
3186 ;;; future if we could replace this with a return of 0 values, though.
3187 ;;;
3188
3189 (define-syntax *unspecified*
3190 (identifier-syntax (if #f #f)))
3191
3192 (define (unspecified? v) (eq? v *unspecified*))
3193
3194
3195 \f
3196
3197 ;;; {Running Repls}
3198 ;;;
3199
3200 (define *repl-stack* (make-fluid '()))
3201
3202 ;; Programs can call `batch-mode?' to see if they are running as part of a
3203 ;; script or if they are running interactively. REPL implementations ensure that
3204 ;; `batch-mode?' returns #f during their extent.
3205 ;;
3206 (define (batch-mode?)
3207 (null? (fluid-ref *repl-stack*)))
3208
3209 ;; Programs can re-enter batch mode, for example after a fork, by calling
3210 ;; `ensure-batch-mode!'. It's not a great interface, though; it would be better
3211 ;; to abort to the outermost prompt, and call a thunk there.
3212 ;;
3213 (define (ensure-batch-mode!)
3214 (set! batch-mode? (lambda () #t)))
3215
3216 (define (quit . args)
3217 (apply throw 'quit args))
3218
3219 (define exit quit)
3220
3221 (define (gc-run-time)
3222 (cdr (assq 'gc-time-taken (gc-stats))))
3223
3224 (define abort-hook (make-hook))
3225 (define before-error-hook (make-hook))
3226 (define after-error-hook (make-hook))
3227 (define before-backtrace-hook (make-hook))
3228 (define after-backtrace-hook (make-hook))
3229
3230 (define before-read-hook (make-hook))
3231 (define after-read-hook (make-hook))
3232 (define before-eval-hook (make-hook 1))
3233 (define after-eval-hook (make-hook 1))
3234 (define before-print-hook (make-hook 1))
3235 (define after-print-hook (make-hook 1))
3236
3237 ;;; This hook is run at the very end of an interactive session.
3238 ;;;
3239 (define exit-hook (make-hook))
3240
3241 ;;; The default repl-reader function. We may override this if we've
3242 ;;; the readline library.
3243 (define repl-reader
3244 (lambda* (prompt #:optional (reader (fluid-ref current-reader)))
3245 (if (not (char-ready?))
3246 (begin
3247 (display (if (string? prompt) prompt (prompt)))
3248 ;; An interesting situation. The printer resets the column to
3249 ;; 0 by printing a newline, but we then advance it by printing
3250 ;; the prompt. However the port-column of the output port
3251 ;; does not typically correspond with the actual column on the
3252 ;; screen, because the input is echoed back! Since the
3253 ;; input is line-buffered and thus ends with a newline, the
3254 ;; output will really start on column zero. So, here we zero
3255 ;; it out. See bug 9664.
3256 ;;
3257 ;; Note that for similar reasons, the output-line will not
3258 ;; reflect the actual line on the screen. But given the
3259 ;; possibility of multiline input, the fix is not as
3260 ;; straightforward, so we don't bother.
3261 ;;
3262 ;; Also note that the readline implementation papers over
3263 ;; these concerns, because it's readline itself printing the
3264 ;; prompt, and not Guile.
3265 (set-port-column! (current-output-port) 0)))
3266 (force-output)
3267 (run-hook before-read-hook)
3268 ((or reader read) (current-input-port))))
3269
3270
3271 \f
3272
3273 ;;; {IOTA functions: generating lists of numbers}
3274 ;;;
3275
3276 (define (iota n)
3277 (let loop ((count (1- n)) (result '()))
3278 (if (< count 0) result
3279 (loop (1- count) (cons count result)))))
3280
3281 \f
3282
3283 ;;; {While}
3284 ;;;
3285 ;;; with `continue' and `break'.
3286 ;;;
3287
3288 ;; The inliner will remove the prompts at compile-time if it finds that
3289 ;; `continue' or `break' are not used.
3290 ;;
3291 (define-syntax while
3292 (lambda (x)
3293 (syntax-case x ()
3294 ((while cond body ...)
3295 #`(let ((break-tag (make-prompt-tag "break"))
3296 (continue-tag (make-prompt-tag "continue")))
3297 (call-with-prompt
3298 break-tag
3299 (lambda ()
3300 (define-syntax #,(datum->syntax #'while 'break)
3301 (lambda (x)
3302 (syntax-case x ()
3303 ((_ arg (... ...))
3304 #'(abort-to-prompt break-tag arg (... ...)))
3305 (_
3306 #'(lambda args
3307 (apply abort-to-prompt break-tag args))))))
3308 (let lp ()
3309 (call-with-prompt
3310 continue-tag
3311 (lambda ()
3312 (define-syntax #,(datum->syntax #'while 'continue)
3313 (lambda (x)
3314 (syntax-case x ()
3315 ((_)
3316 #'(abort-to-prompt continue-tag))
3317 ((_ . args)
3318 (syntax-violation 'continue "too many arguments" x))
3319 (_
3320 #'(lambda ()
3321 (abort-to-prompt continue-tag))))))
3322 (do () ((not cond) #f) body ...))
3323 (lambda (k) (lp)))))
3324 (lambda (k . args)
3325 (if (null? args)
3326 #t
3327 (apply values args)))))))))
3328
3329
3330 \f
3331
3332 ;;; {Module System Macros}
3333 ;;;
3334
3335 ;; Return a list of expressions that evaluate to the appropriate
3336 ;; arguments for resolve-interface according to SPEC.
3337
3338 (eval-when (compile)
3339 (if (memq 'prefix (read-options))
3340 (error "boot-9 must be compiled with #:kw, not :kw")))
3341
3342 (define (keyword-like-symbol->keyword sym)
3343 (symbol->keyword (string->symbol (substring (symbol->string sym) 1))))
3344
3345 (define-syntax define-module
3346 (lambda (x)
3347 (define (keyword-like? stx)
3348 (let ((dat (syntax->datum stx)))
3349 (and (symbol? dat)
3350 (eqv? (string-ref (symbol->string dat) 0) #\:))))
3351 (define (->keyword sym)
3352 (symbol->keyword (string->symbol (substring (symbol->string sym) 1))))
3353
3354 (define (parse-iface args)
3355 (let loop ((in args) (out '()))
3356 (syntax-case in ()
3357 (() (reverse! out))
3358 ;; The user wanted #:foo, but wrote :foo. Fix it.
3359 ((sym . in) (keyword-like? #'sym)
3360 (loop #`(#,(->keyword (syntax->datum #'sym)) . in) out))
3361 ((kw . in) (not (keyword? (syntax->datum #'kw)))
3362 (syntax-violation 'define-module "expected keyword arg" x #'kw))
3363 ((#:renamer renamer . in)
3364 (loop #'in (cons* #',renamer #:renamer out)))
3365 ((kw val . in)
3366 (loop #'in (cons* #'val #'kw out))))))
3367
3368 (define (parse args imp exp rex rep aut)
3369 ;; Just quote everything except #:use-module and #:use-syntax. We
3370 ;; need to know about all arguments regardless since we want to turn
3371 ;; symbols that look like keywords into real keywords, and the
3372 ;; keyword args in a define-module form are not regular
3373 ;; (i.e. no-backtrace doesn't take a value).
3374 (syntax-case args ()
3375 (()
3376 (let ((imp (if (null? imp) '() #`(#:imports `#,imp)))
3377 (exp (if (null? exp) '() #`(#:exports '#,exp)))
3378 (rex (if (null? rex) '() #`(#:re-exports '#,rex)))
3379 (rep (if (null? rep) '() #`(#:replacements '#,rep)))
3380 (aut (if (null? aut) '() #`(#:autoloads '#,aut))))
3381 #`(#,@imp #,@exp #,@rex #,@rep #,@aut)))
3382 ;; The user wanted #:foo, but wrote :foo. Fix it.
3383 ((sym . args) (keyword-like? #'sym)
3384 (parse #`(#,(->keyword (syntax->datum #'sym)) . args)
3385 imp exp rex rep aut))
3386 ((kw . args) (not (keyword? (syntax->datum #'kw)))
3387 (syntax-violation 'define-module "expected keyword arg" x #'kw))
3388 ((#:no-backtrace . args)
3389 ;; Ignore this one.
3390 (parse #'args imp exp rex rep aut))
3391 ((#:pure . args)
3392 #`(#:pure #t . #,(parse #'args imp exp rex rep aut)))
3393 ((kw)
3394 (syntax-violation 'define-module "keyword arg without value" x #'kw))
3395 ((#:version (v ...) . args)
3396 #`(#:version '(v ...) . #,(parse #'args imp exp rex rep aut)))
3397 ((#:duplicates (d ...) . args)
3398 #`(#:duplicates '(d ...) . #,(parse #'args imp exp rex rep aut)))
3399 ((#:filename f . args)
3400 #`(#:filename 'f . #,(parse #'args imp exp rex rep aut)))
3401 ((#:use-module (name name* ...) . args)
3402 (and (and-map symbol? (syntax->datum #'(name name* ...))))
3403 (parse #'args #`(#,@imp ((name name* ...))) exp rex rep aut))
3404 ((#:use-syntax (name name* ...) . args)
3405 (and (and-map symbol? (syntax->datum #'(name name* ...))))
3406 #`(#:transformer '(name name* ...)
3407 . #,(parse #'args #`(#,@imp ((name name* ...))) exp rex rep aut)))
3408 ((#:use-module ((name name* ...) arg ...) . args)
3409 (and (and-map symbol? (syntax->datum #'(name name* ...))))
3410 (parse #'args
3411 #`(#,@imp ((name name* ...) #,@(parse-iface #'(arg ...))))
3412 exp rex rep aut))
3413 ((#:export (ex ...) . args)
3414 (parse #'args imp #`(#,@exp ex ...) rex rep aut))
3415 ((#:export-syntax (ex ...) . args)
3416 (parse #'args imp #`(#,@exp ex ...) rex rep aut))
3417 ((#:re-export (re ...) . args)
3418 (parse #'args imp exp #`(#,@rex re ...) rep aut))
3419 ((#:re-export-syntax (re ...) . args)
3420 (parse #'args imp exp #`(#,@rex re ...) rep aut))
3421 ((#:replace (r ...) . args)
3422 (parse #'args imp exp rex #`(#,@rep r ...) aut))
3423 ((#:replace-syntax (r ...) . args)
3424 (parse #'args imp exp rex #`(#,@rep r ...) aut))
3425 ((#:autoload name bindings . args)
3426 (parse #'args imp exp rex rep #`(#,@aut name bindings)))
3427 ((kw val . args)
3428 (syntax-violation 'define-module "unknown keyword or bad argument"
3429 #'kw #'val))))
3430
3431 (syntax-case x ()
3432 ((_ (name name* ...) arg ...)
3433 (and-map symbol? (syntax->datum #'(name name* ...)))
3434 (with-syntax (((quoted-arg ...)
3435 (parse #'(arg ...) '() '() '() '() '()))
3436 ;; Ideally the filename is either a string or #f;
3437 ;; this hack is to work around a case in which
3438 ;; port-filename returns a symbol (`socket') for
3439 ;; sockets.
3440 (filename (let ((f (assq-ref (or (syntax-source x) '())
3441 'filename)))
3442 (and (string? f) f))))
3443 #'(eval-when (eval load compile expand)
3444 (let ((m (define-module* '(name name* ...)
3445 #:filename filename quoted-arg ...)))
3446 (set-current-module m)
3447 m)))))))
3448
3449 ;; The guts of the use-modules macro. Add the interfaces of the named
3450 ;; modules to the use-list of the current module, in order.
3451
3452 ;; This function is called by "modules.c". If you change it, be sure
3453 ;; to change scm_c_use_module as well.
3454
3455 (define (process-use-modules module-interface-args)
3456 (let ((interfaces (map (lambda (mif-args)
3457 (or (apply resolve-interface mif-args)
3458 (error "no such module" mif-args)))
3459 module-interface-args)))
3460 (call-with-deferred-observers
3461 (lambda ()
3462 (module-use-interfaces! (current-module) interfaces)))))
3463
3464 (define-syntax use-modules
3465 (lambda (x)
3466 (define (keyword-like? stx)
3467 (let ((dat (syntax->datum stx)))
3468 (and (symbol? dat)
3469 (eqv? (string-ref (symbol->string dat) 0) #\:))))
3470 (define (->keyword sym)
3471 (symbol->keyword (string->symbol (substring (symbol->string sym) 1))))
3472
3473 (define (quotify-iface args)
3474 (let loop ((in args) (out '()))
3475 (syntax-case in ()
3476 (() (reverse! out))
3477 ;; The user wanted #:foo, but wrote :foo. Fix it.
3478 ((sym . in) (keyword-like? #'sym)
3479 (loop #`(#,(->keyword (syntax->datum #'sym)) . in) out))
3480 ((kw . in) (not (keyword? (syntax->datum #'kw)))
3481 (syntax-violation 'define-module "expected keyword arg" x #'kw))
3482 ((#:renamer renamer . in)
3483 (loop #'in (cons* #'renamer #:renamer out)))
3484 ((kw val . in)
3485 (loop #'in (cons* #''val #'kw out))))))
3486
3487 (define (quotify specs)
3488 (let lp ((in specs) (out '()))
3489 (syntax-case in ()
3490 (() (reverse out))
3491 (((name name* ...) . in)
3492 (and-map symbol? (syntax->datum #'(name name* ...)))
3493 (lp #'in (cons #''((name name* ...)) out)))
3494 ((((name name* ...) arg ...) . in)
3495 (and-map symbol? (syntax->datum #'(name name* ...)))
3496 (with-syntax (((quoted-arg ...) (quotify-iface #'(arg ...))))
3497 (lp #'in (cons #`(list '(name name* ...) quoted-arg ...)
3498 out)))))))
3499
3500 (syntax-case x ()
3501 ((_ spec ...)
3502 (with-syntax (((quoted-args ...) (quotify #'(spec ...))))
3503 #'(eval-when (eval load compile expand)
3504 (process-use-modules (list quoted-args ...))
3505 *unspecified*))))))
3506
3507 (include-from-path "ice-9/r6rs-libraries")
3508
3509 (define-syntax-rule (define-private foo bar)
3510 (define foo bar))
3511
3512 (define-syntax define-public
3513 (syntax-rules ()
3514 ((_ (name . args) . body)
3515 (begin
3516 (define name (lambda args . body))
3517 (export name)))
3518 ((_ name val)
3519 (begin
3520 (define name val)
3521 (export name)))))
3522
3523 (define-syntax-rule (defmacro-public name args body ...)
3524 (begin
3525 (defmacro name args body ...)
3526 (export-syntax name)))
3527
3528 ;; And now for the most important macro.
3529 (define-syntax-rule (λ formals body ...)
3530 (lambda formals body ...))
3531
3532 \f
3533 ;; Export a local variable
3534
3535 ;; This function is called from "modules.c". If you change it, be
3536 ;; sure to update "modules.c" as well.
3537
3538 (define (module-export! m names)
3539 (let ((public-i (module-public-interface m)))
3540 (for-each (lambda (name)
3541 (let* ((internal-name (if (pair? name) (car name) name))
3542 (external-name (if (pair? name) (cdr name) name))
3543 (var (module-ensure-local-variable! m internal-name)))
3544 (module-add! public-i external-name var)))
3545 names)))
3546
3547 (define (module-replace! m names)
3548 (let ((public-i (module-public-interface m)))
3549 (for-each (lambda (name)
3550 (let* ((internal-name (if (pair? name) (car name) name))
3551 (external-name (if (pair? name) (cdr name) name))
3552 (var (module-ensure-local-variable! m internal-name)))
3553 ;; FIXME: use a bit on variables instead of object
3554 ;; properties.
3555 (set-object-property! var 'replace #t)
3556 (module-add! public-i external-name var)))
3557 names)))
3558
3559 ;; Export all local variables from a module
3560 ;;
3561 (define (module-export-all! mod)
3562 (define (fresh-interface!)
3563 (let ((iface (make-module)))
3564 (set-module-name! iface (module-name mod))
3565 (set-module-version! iface (module-version mod))
3566 (set-module-kind! iface 'interface)
3567 (set-module-public-interface! mod iface)
3568 iface))
3569 (let ((iface (or (module-public-interface mod)
3570 (fresh-interface!))))
3571 (set-module-obarray! iface (module-obarray mod))))
3572
3573 ;; Re-export a imported variable
3574 ;;
3575 (define (module-re-export! m names)
3576 (let ((public-i (module-public-interface m)))
3577 (for-each (lambda (name)
3578 (let* ((internal-name (if (pair? name) (car name) name))
3579 (external-name (if (pair? name) (cdr name) name))
3580 (var (module-variable m internal-name)))
3581 (cond ((not var)
3582 (error "Undefined variable:" internal-name))
3583 ((eq? var (module-local-variable m internal-name))
3584 (error "re-exporting local variable:" internal-name))
3585 (else
3586 (module-add! public-i external-name var)))))
3587 names)))
3588
3589 (define-syntax-rule (export name ...)
3590 (eval-when (eval load compile expand)
3591 (call-with-deferred-observers
3592 (lambda ()
3593 (module-export! (current-module) '(name ...))))))
3594
3595 (define-syntax-rule (re-export name ...)
3596 (eval-when (eval load compile expand)
3597 (call-with-deferred-observers
3598 (lambda ()
3599 (module-re-export! (current-module) '(name ...))))))
3600
3601 (define-syntax-rule (export! name ...)
3602 (eval-when (eval load compile expand)
3603 (call-with-deferred-observers
3604 (lambda ()
3605 (module-replace! (current-module) '(name ...))))))
3606
3607 (define-syntax-rule (export-syntax name ...)
3608 (export name ...))
3609
3610 (define-syntax-rule (re-export-syntax name ...)
3611 (re-export name ...))
3612
3613 \f
3614
3615 ;;; {Parameters}
3616 ;;;
3617
3618 (define* (make-mutable-parameter init #:optional (converter identity))
3619 (let ((fluid (make-fluid (converter init))))
3620 (case-lambda
3621 (() (fluid-ref fluid))
3622 ((val) (fluid-set! fluid (converter val))))))
3623
3624
3625 \f
3626
3627 ;;; {Handling of duplicate imported bindings}
3628 ;;;
3629
3630 ;; Duplicate handlers take the following arguments:
3631 ;;
3632 ;; module importing module
3633 ;; name conflicting name
3634 ;; int1 old interface where name occurs
3635 ;; val1 value of binding in old interface
3636 ;; int2 new interface where name occurs
3637 ;; val2 value of binding in new interface
3638 ;; var previous resolution or #f
3639 ;; val value of previous resolution
3640 ;;
3641 ;; A duplicate handler can take three alternative actions:
3642 ;;
3643 ;; 1. return #f => leave responsibility to next handler
3644 ;; 2. exit with an error
3645 ;; 3. return a variable resolving the conflict
3646 ;;
3647
3648 (define duplicate-handlers
3649 (let ((m (make-module 7)))
3650
3651 (define (check module name int1 val1 int2 val2 var val)
3652 (scm-error 'misc-error
3653 #f
3654 "~A: `~A' imported from both ~A and ~A"
3655 (list (module-name module)
3656 name
3657 (module-name int1)
3658 (module-name int2))
3659 #f))
3660
3661 (define (warn module name int1 val1 int2 val2 var val)
3662 (format (current-warning-port)
3663 "WARNING: ~A: `~A' imported from both ~A and ~A\n"
3664 (module-name module)
3665 name
3666 (module-name int1)
3667 (module-name int2))
3668 #f)
3669
3670 (define (replace module name int1 val1 int2 val2 var val)
3671 (let ((old (or (and var (object-property var 'replace) var)
3672 (module-variable int1 name)))
3673 (new (module-variable int2 name)))
3674 (if (object-property old 'replace)
3675 (and (or (eq? old new)
3676 (not (object-property new 'replace)))
3677 old)
3678 (and (object-property new 'replace)
3679 new))))
3680
3681 (define (warn-override-core module name int1 val1 int2 val2 var val)
3682 (and (eq? int1 the-scm-module)
3683 (begin
3684 (format (current-warning-port)
3685 "WARNING: ~A: imported module ~A overrides core binding `~A'\n"
3686 (module-name module)
3687 (module-name int2)
3688 name)
3689 (module-local-variable int2 name))))
3690
3691 (define (first module name int1 val1 int2 val2 var val)
3692 (or var (module-local-variable int1 name)))
3693
3694 (define (last module name int1 val1 int2 val2 var val)
3695 (module-local-variable int2 name))
3696
3697 (define (noop module name int1 val1 int2 val2 var val)
3698 #f)
3699
3700 (set-module-name! m 'duplicate-handlers)
3701 (set-module-kind! m 'interface)
3702 (module-define! m 'check check)
3703 (module-define! m 'warn warn)
3704 (module-define! m 'replace replace)
3705 (module-define! m 'warn-override-core warn-override-core)
3706 (module-define! m 'first first)
3707 (module-define! m 'last last)
3708 (module-define! m 'merge-generics noop)
3709 (module-define! m 'merge-accessors noop)
3710 m))
3711
3712 (define (lookup-duplicates-handlers handler-names)
3713 (and handler-names
3714 (map (lambda (handler-name)
3715 (or (module-symbol-local-binding
3716 duplicate-handlers handler-name #f)
3717 (error "invalid duplicate handler name:"
3718 handler-name)))
3719 (if (list? handler-names)
3720 handler-names
3721 (list handler-names)))))
3722
3723 (define default-duplicate-binding-procedures
3724 (make-mutable-parameter #f))
3725
3726 (define default-duplicate-binding-handler
3727 (make-mutable-parameter '(replace warn-override-core warn last)
3728 (lambda (handler-names)
3729 (default-duplicate-binding-procedures
3730 (lookup-duplicates-handlers handler-names))
3731 handler-names)))
3732
3733 \f
3734
3735 ;;; {`load'.}
3736 ;;;
3737 ;;; Load is tricky when combined with relative paths, compilation, and
3738 ;;; the file system. If a path is relative, what is it relative to? The
3739 ;;; path of the source file at the time it was compiled? The path of
3740 ;;; the compiled file? What if both or either were installed? And how
3741 ;;; do you get that information? Tricky, I say.
3742 ;;;
3743 ;;; To get around all of this, we're going to do something nasty, and
3744 ;;; turn `load' into a macro. That way it can know the path of the
3745 ;;; source file with respect to which it was invoked, so it can resolve
3746 ;;; relative paths with respect to the original source path.
3747 ;;;
3748 ;;; There is an exception, and that is that if the source file was in
3749 ;;; the load path when it was compiled, instead of looking up against
3750 ;;; the absolute source location, we load-from-path against the relative
3751 ;;; source location.
3752 ;;;
3753
3754 (define %auto-compilation-options
3755 ;; Default `compile-file' option when auto-compiling.
3756 '(#:warnings (unbound-variable arity-mismatch format
3757 duplicate-case-datum bad-case-datum)))
3758
3759 (define* (load-in-vicinity dir path #:optional reader)
3760 "Load source file PATH in vicinity of directory DIR. Use a pre-compiled
3761 version of PATH when available, and auto-compile one when none is available,
3762 reading PATH with READER."
3763
3764 (define (canonical->suffix canon)
3765 (cond
3766 ((string-prefix? "/" canon) canon)
3767 ((and (> (string-length canon) 2)
3768 (eqv? (string-ref canon 1) #\:))
3769 ;; Paths like C:... transform to /C...
3770 (string-append "/" (substring canon 0 1) (substring canon 2)))
3771 (else canon)))
3772
3773 (define compiled-extension
3774 ;; File name extension of compiled files.
3775 (cond ((or (null? %load-compiled-extensions)
3776 (string-null? (car %load-compiled-extensions)))
3777 (warn "invalid %load-compiled-extensions"
3778 %load-compiled-extensions)
3779 ".go")
3780 (else (car %load-compiled-extensions))))
3781
3782 (define (more-recent? stat1 stat2)
3783 ;; Return #t when STAT1 has an mtime greater than that of STAT2.
3784 (or (> (stat:mtime stat1) (stat:mtime stat2))
3785 (and (= (stat:mtime stat1) (stat:mtime stat2))
3786 (>= (stat:mtimensec stat1)
3787 (stat:mtimensec stat2)))))
3788
3789 (define (fallback-file-name canon-path)
3790 ;; Return the in-cache compiled file name for source file CANON-PATH.
3791
3792 ;; FIXME: would probably be better just to append SHA1(canon-path)
3793 ;; to the %compile-fallback-path, to avoid deep directory stats.
3794 (and %compile-fallback-path
3795 (string-append %compile-fallback-path
3796 (canonical->suffix canon-path)
3797 compiled-extension)))
3798
3799 (define (compile file)
3800 ;; Compile source FILE, lazily loading the compiler.
3801 ((module-ref (resolve-interface '(system base compile))
3802 'compile-file)
3803 file
3804 #:opts %auto-compilation-options
3805 #:env (current-module)))
3806
3807 (define (warn-about-exception key args)
3808 (for-each (lambda (s)
3809 (if (not (string-null? s))
3810 (format (current-warning-port) ";;; ~a\n" s)))
3811 (string-split
3812 (call-with-output-string
3813 (lambda (port) (print-exception port #f key args)))
3814 #\newline)))
3815
3816 ;; Returns the .go file corresponding to `name'. Does not search load
3817 ;; paths, only the fallback path. If the .go file is missing or out of
3818 ;; date, and auto-compilation is enabled, will try auto-compilation, just
3819 ;; as primitive-load-path does internally. primitive-load is
3820 ;; unaffected. Returns #f if auto-compilation failed or was disabled.
3821 ;;
3822 ;; NB: Unless we need to compile the file, this function should not cause
3823 ;; (system base compile) to be loaded up. For that reason compiled-file-name
3824 ;; partially duplicates functionality from (system base compile).
3825
3826 (define (fresh-compiled-file-name name scmstat go-path)
3827 ;; Return GO-PATH after making sure that it contains a freshly compiled
3828 ;; version of source file NAME with stat SCMSTAT; return #f on failure.
3829 (catch #t
3830 (lambda ()
3831 (let ((gostat (and (not %fresh-auto-compile)
3832 (stat go-path #f))))
3833 (if (and gostat (more-recent? gostat scmstat))
3834 go-path
3835 (begin
3836 (if gostat
3837 (format (current-warning-port)
3838 ";;; note: source file ~a\n;;; newer than compiled ~a\n"
3839 name go-path))
3840 (cond
3841 (%load-should-auto-compile
3842 (%warn-auto-compilation-enabled)
3843 (format (current-warning-port) ";;; compiling ~a\n" name)
3844 (let ((cfn (compile name)))
3845 (format (current-warning-port) ";;; compiled ~a\n" cfn)
3846 cfn))
3847 (else #f))))))
3848 (lambda (k . args)
3849 (format (current-warning-port)
3850 ";;; WARNING: compilation of ~a failed:\n" name)
3851 (warn-about-exception k args)
3852 #f)))
3853
3854 (define (absolute-path? path)
3855 (string-prefix? "/" path))
3856
3857 (define (sans-extension file)
3858 (let ((dot (string-rindex file #\.)))
3859 (if dot
3860 (substring file 0 dot)
3861 file)))
3862
3863 (define (load-absolute abs-path)
3864 ;; Load from ABS-PATH, using a compiled file or auto-compiling if needed.
3865 (define scmstat
3866 (catch #t
3867 (lambda ()
3868 (stat abs-path))
3869 (lambda (key . args)
3870 (warn-about-exception key args)
3871 #f)))
3872
3873 (define (pre-compiled)
3874 (let ((go-path (search-path %load-compiled-path (sans-extension path)
3875 %load-compiled-extensions #t)))
3876 (and go-path
3877 (let ((gostat (stat go-path #f)))
3878 (and gostat (more-recent? gostat scmstat)
3879 go-path)))))
3880
3881 (define (fallback)
3882 (let ((canon (false-if-exception (canonicalize-path abs-path))))
3883 (and canon
3884 (let ((go-path (fallback-file-name canon)))
3885 (and go-path
3886 (fresh-compiled-file-name abs-path scmstat go-path))))))
3887
3888 (let ((compiled (and scmstat
3889 (or (pre-compiled) (fallback)))))
3890 (if compiled
3891 (begin
3892 (if %load-hook
3893 (%load-hook abs-path))
3894 (load-compiled compiled))
3895 (start-stack 'load-stack
3896 (primitive-load abs-path)))))
3897
3898 (save-module-excursion
3899 (lambda ()
3900 (with-fluids ((current-reader reader)
3901 (%file-port-name-canonicalization 'relative))
3902 (cond
3903 ((absolute-path? path)
3904 (load-absolute path))
3905 ((absolute-path? dir)
3906 (load-absolute (in-vicinity dir path)))
3907 (else
3908 (load-from-path (in-vicinity dir path))))))))
3909
3910 (define-syntax load
3911 (make-variable-transformer
3912 (lambda (x)
3913 (let* ((src (syntax-source x))
3914 (file (and src (assq-ref src 'filename)))
3915 (dir (and (string? file) (dirname file))))
3916 (syntax-case x ()
3917 ((_ arg ...)
3918 #`(load-in-vicinity #,(or dir #'(getcwd)) arg ...))
3919 (id
3920 (identifier? #'id)
3921 #`(lambda args
3922 (apply load-in-vicinity #,(or dir #'(getcwd)) args))))))))
3923
3924 \f
3925
3926 ;;; {`cond-expand' for SRFI-0 support.}
3927 ;;;
3928 ;;; This syntactic form expands into different commands or
3929 ;;; definitions, depending on the features provided by the Scheme
3930 ;;; implementation.
3931 ;;;
3932 ;;; Syntax:
3933 ;;;
3934 ;;; <cond-expand>
3935 ;;; --> (cond-expand <cond-expand-clause>+)
3936 ;;; | (cond-expand <cond-expand-clause>* (else <command-or-definition>))
3937 ;;; <cond-expand-clause>
3938 ;;; --> (<feature-requirement> <command-or-definition>*)
3939 ;;; <feature-requirement>
3940 ;;; --> <feature-identifier>
3941 ;;; | (and <feature-requirement>*)
3942 ;;; | (or <feature-requirement>*)
3943 ;;; | (not <feature-requirement>)
3944 ;;; <feature-identifier>
3945 ;;; --> <a symbol which is the name or alias of a SRFI>
3946 ;;;
3947 ;;; Additionally, this implementation provides the
3948 ;;; <feature-identifier>s `guile' and `r5rs', so that programs can
3949 ;;; determine the implementation type and the supported standard.
3950 ;;;
3951 ;;; Currently, the following feature identifiers are supported:
3952 ;;;
3953 ;;; guile r5rs srfi-0 srfi-4 srfi-6 srfi-13 srfi-14 srfi-55 srfi-61 srfi-105
3954 ;;;
3955 ;;; Remember to update the features list when adding more SRFIs.
3956 ;;;
3957
3958 (define %cond-expand-features
3959 ;; Adjust the above comment when changing this.
3960 '(guile
3961 guile-2
3962 guile-2.2
3963 r5rs
3964 srfi-0 ;; cond-expand itself
3965 srfi-4 ;; homogenous numeric vectors
3966 srfi-6 ;; open-input-string etc, in the guile core
3967 srfi-13 ;; string library
3968 srfi-14 ;; character sets
3969 srfi-23 ;; `error` procedure
3970 srfi-39 ;; parameterize
3971 srfi-55 ;; require-extension
3972 srfi-61 ;; general cond clause
3973 srfi-105 ;; curly infix expressions
3974 ))
3975
3976 ;; This table maps module public interfaces to the list of features.
3977 ;;
3978 (define %cond-expand-table (make-hash-table 31))
3979
3980 ;; Add one or more features to the `cond-expand' feature list of the
3981 ;; module `module'.
3982 ;;
3983 (define (cond-expand-provide module features)
3984 (let ((mod (module-public-interface module)))
3985 (and mod
3986 (hashq-set! %cond-expand-table mod
3987 (append (hashq-ref %cond-expand-table mod '())
3988 features)))))
3989
3990 (define-syntax cond-expand
3991 (lambda (x)
3992 (define (module-has-feature? mod sym)
3993 (or-map (lambda (mod)
3994 (memq sym (hashq-ref %cond-expand-table mod '())))
3995 (module-uses mod)))
3996
3997 (define (condition-matches? condition)
3998 (syntax-case condition (and or not)
3999 ((and c ...)
4000 (and-map condition-matches? #'(c ...)))
4001 ((or c ...)
4002 (or-map condition-matches? #'(c ...)))
4003 ((not c)
4004 (if (condition-matches? #'c) #f #t))
4005 (c
4006 (identifier? #'c)
4007 (let ((sym (syntax->datum #'c)))
4008 (if (memq sym %cond-expand-features)
4009 #t
4010 (module-has-feature? (current-module) sym))))))
4011
4012 (define (match clauses alternate)
4013 (syntax-case clauses ()
4014 (((condition form ...) . rest)
4015 (if (condition-matches? #'condition)
4016 #'(begin form ...)
4017 (match #'rest alternate)))
4018 (() (alternate))))
4019
4020 (syntax-case x (else)
4021 ((_ clause ... (else form ...))
4022 (match #'(clause ...)
4023 (lambda ()
4024 #'(begin form ...))))
4025 ((_ clause ...)
4026 (match #'(clause ...)
4027 (lambda ()
4028 (syntax-violation 'cond-expand "unfulfilled cond-expand" x)))))))
4029
4030 ;; This procedure gets called from the startup code with a list of
4031 ;; numbers, which are the numbers of the SRFIs to be loaded on startup.
4032 ;;
4033 (define (use-srfis srfis)
4034 (process-use-modules
4035 (map (lambda (num)
4036 (list (list 'srfi (string->symbol
4037 (string-append "srfi-" (number->string num))))))
4038 srfis)))
4039
4040 \f
4041
4042 ;;; srfi-55: require-extension
4043 ;;;
4044
4045 (define-syntax require-extension
4046 (lambda (x)
4047 (syntax-case x (srfi)
4048 ((_ (srfi n ...))
4049 (and-map integer? (syntax->datum #'(n ...)))
4050 (with-syntax
4051 (((srfi-n ...)
4052 (map (lambda (n)
4053 (datum->syntax x (symbol-append 'srfi- n)))
4054 (map string->symbol
4055 (map number->string (syntax->datum #'(n ...)))))))
4056 #'(use-modules (srfi srfi-n) ...)))
4057 ((_ (type arg ...))
4058 (identifier? #'type)
4059 (syntax-violation 'require-extension "Not a recognized extension type"
4060 x)))))
4061
4062 \f
4063 ;;; Defining transparently inlinable procedures
4064 ;;;
4065
4066 (define-syntax define-inlinable
4067 ;; Define a macro and a procedure such that direct calls are inlined, via
4068 ;; the macro expansion, whereas references in non-call contexts refer to
4069 ;; the procedure. Inspired by the `define-integrable' macro by Dybvig et al.
4070 (lambda (x)
4071 ;; Use a space in the prefix to avoid potential -Wunused-toplevel
4072 ;; warning
4073 (define prefix (string->symbol "% "))
4074 (define (make-procedure-name name)
4075 (datum->syntax name
4076 (symbol-append prefix (syntax->datum name)
4077 '-procedure)))
4078
4079 (syntax-case x ()
4080 ((_ (name formals ...) body ...)
4081 (identifier? #'name)
4082 (with-syntax ((proc-name (make-procedure-name #'name))
4083 ((args ...) (generate-temporaries #'(formals ...))))
4084 #`(begin
4085 (define (proc-name formals ...)
4086 (syntax-parameterize ((name (identifier-syntax proc-name)))
4087 body ...))
4088 (define-syntax-parameter name
4089 (lambda (x)
4090 (syntax-case x ()
4091 ((_ args ...)
4092 #'((syntax-parameterize ((name (identifier-syntax proc-name)))
4093 (lambda (formals ...)
4094 body ...))
4095 args ...))
4096 (_
4097 (identifier? x)
4098 #'proc-name))))))))))
4099
4100 \f
4101
4102 (define using-readline?
4103 (let ((using-readline? (make-fluid)))
4104 (make-procedure-with-setter
4105 (lambda () (fluid-ref using-readline?))
4106 (lambda (v) (fluid-set! using-readline? v)))))
4107
4108 \f
4109
4110 ;;; {Deprecated stuff}
4111 ;;;
4112
4113 (begin-deprecated
4114 (module-use! the-scm-module (resolve-interface '(ice-9 deprecated))))
4115
4116 \f
4117
4118 ;;; SRFI-4 in the default environment. FIXME: we should figure out how
4119 ;;; to deprecate this.
4120 ;;;
4121
4122 ;; FIXME:
4123 (module-use! the-scm-module (resolve-interface '(srfi srfi-4)))
4124
4125 \f
4126
4127 ;;; A few identifiers that need to be defined in this file are really
4128 ;;; internal implementation details. We shove them off into internal
4129 ;;; modules, removing them from the (guile) module.
4130 ;;;
4131
4132 (define-module (system syntax))
4133
4134 (let ()
4135 (define (steal-bindings! from to ids)
4136 (for-each
4137 (lambda (sym)
4138 (let ((v (module-local-variable from sym)))
4139 (module-remove! from sym)
4140 (module-add! to sym v)))
4141 ids)
4142 (module-export! to ids))
4143
4144 (steal-bindings! the-root-module (resolve-module '(system syntax))
4145 '(syntax-local-binding
4146 syntax-module
4147 syntax-locally-bound-identifiers
4148 syntax-session-id)))
4149
4150
4151 \f
4152
4153 ;;; Place the user in the guile-user module.
4154 ;;;
4155
4156 ;; Set filename to #f to prevent reload.
4157 (define-module (guile-user)
4158 #:autoload (system base compile) (compile compile-file)
4159 #:filename #f)
4160
4161 ;; Remain in the `(guile)' module at compilation-time so that the
4162 ;; `-Wunused-toplevel' warning works as expected.
4163 (eval-when (compile) (set-current-module the-root-module))
4164
4165 ;;; boot-9.scm ends here