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