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