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