;;; r6rs-libraries.scm --- Support for the R6RS `library' and `import' forms ;; Copyright (C) 2010 Free Software Foundation, Inc. ;; ;; This library is free software; you can redistribute it and/or ;; modify it under the terms of the GNU Lesser General Public ;; License as published by the Free Software Foundation; either ;; version 3 of the License, or (at your option) any later version. ;; ;; This library is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;; Lesser General Public License for more details. ;; ;; You should have received a copy of the GNU Lesser General Public ;; License along with this library; if not, write to the Free Software ;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;; This file is included from boot-9.scm and assumes the existence of (and ;; expands into) procedures and syntactic forms defined therein. (define (resolve-r6rs-interface import-spec) (define (make-custom-interface mod) (let ((iface (make-module))) (set-module-kind! iface 'custom-interface) (set-module-name! iface (module-name mod)) iface)) (define (module-for-each/nonlocal f mod) (define (module-and-uses mod) (let lp ((in (list mod)) (out '())) (cond ((null? in) (reverse out)) ((memq (car in) out) (lp (cdr in) out)) (else (lp (append (module-uses (car in)) (cdr in)) (cons (car in) out)))))) (for-each (lambda (mod) (module-for-each f mod)) (module-and-uses mod))) (define (sym? x) (symbol? (syntax->datum x))) (syntax-case import-spec (library only except prefix rename srfi) ;; (srfi :n ...) -> (srfi srfi-n ...) ((library (srfi colon-n rest ... (version ...))) (and (and-map sym? #'(srfi rest ...)) (symbol? (syntax->datum #'colon-n)) (eqv? (string-ref (symbol->string (syntax->datum #'colon-n)) 0) #\:)) (let ((srfi-n (string->symbol (string-append "srfi-" (substring (symbol->string (syntax->datum #'colon-n)) 1))))) (resolve-r6rs-interface (syntax-case #'(rest ...) () (() #`(library (srfi #,srfi-n (version ...)))) ((name rest ...) ;; SRFI 97 says that the first identifier after the colon-n ;; is used for the libraries name, so it must be ignored. #`(library (srfi #,srfi-n rest ... (version ...)))))))) ((library (name name* ... (version ...))) (and-map sym? #'(name name* ...)) (resolve-interface (syntax->datum #'(name name* ...)) #:version (syntax->datum #'(version ...)))) ((library (name name* ...)) (and-map sym? #'(name name* ...)) (resolve-r6rs-interface #'(library (name name* ... ())))) ((only import-set identifier ...) (and-map sym? #'(identifier ...)) (let* ((mod (resolve-r6rs-interface #'import-set)) (iface (make-custom-interface mod))) (for-each (lambda (sym) (module-add! iface sym (or (module-variable mod sym) (error "no binding `~A' in module ~A" sym mod)))) (syntax->datum #'(identifier ...))) iface)) ((except import-set identifier ...) (and-map sym? #'(identifier ...)) (let* ((mod (resolve-r6rs-interface #'import-set)) (iface (make-custom-interface mod))) (module-for-each/nonlocal (lambda (sym var) (module-add! iface sym var)) mod) (for-each (lambda (sym) (if (module-local-variable iface sym) (module-remove! iface sym) (error "no binding `~A' in module ~A" sym mod))) (syntax->datum #'(identifier ...))) iface)) ((prefix import-set identifier) (sym? #'identifier) (let* ((mod (resolve-r6rs-interface #'import-set)) (iface (make-custom-interface mod)) (pre (syntax->datum #'identifier))) (module-for-each/nonlocal (lambda (sym var) (module-add! iface (symbol-append pre sym) var)) mod) iface)) ((rename import-set (from to) ...) (and (and-map sym? #'(from ...)) (and-map sym? #'(to ...))) (let* ((mod (resolve-r6rs-interface #'import-set)) (iface (make-custom-interface mod))) (module-for-each/nonlocal (lambda (sym var) (module-add! iface sym var)) mod) (let lp ((in (syntax->datum #'((from . to) ...))) (out '())) (cond ((null? in) (for-each (lambda (pair) (if (module-local-variable iface (car pair)) (error "duplicate binding for `~A' in module ~A" (car pair) mod) (module-add! iface (car pair) (cdr pair)))) out) iface) (else (let ((var (or (module-variable mod (caar in)) (error "no binding `~A' in module ~A" (caar in) mod)))) (module-remove! iface (caar in)) (lp (cdr in) (acons (cdar in) var out)))))))) ((name name* ... (version ...)) (and-map sym? #'(name name* ...)) (resolve-r6rs-interface #'(library (name name* ... (version ...))))) ((name name* ...) (and-map sym? #'(name name* ...)) (resolve-r6rs-interface #'(library (name name* ... ())))))) (define-syntax library (lambda (stx) (define (compute-exports ifaces specs) (define (re-export? sym) (or-map (lambda (iface) (module-variable iface sym)) ifaces)) (define (replace? sym) (module-variable the-scm-module sym)) (let lp ((specs specs) (e '()) (r '()) (x '())) (syntax-case specs (rename) (() (values e r x)) (((rename (from to) ...) . rest) (and (and-map identifier? #'(from ...)) (and-map identifier? #'(to ...))) (let lp2 ((in #'((from . to) ...)) (e e) (r r) (x x)) (syntax-case in () (() (lp #'rest e r x)) (((from . to) . in) (cond ((re-export? (syntax->datum #'from)) (lp2 #'in e (cons #'(from . to) r) x)) ((replace? (syntax->datum #'from)) (lp2 #'in e r (cons #'(from . to) x))) (else (lp2 #'in (cons #'(from . to) e) r x))))))) ((id . rest) (identifier? #'id) (let ((sym (syntax->datum #'id))) (cond ((re-export? sym) (lp #'rest e (cons #'id r) x)) ((replace? sym) (lp #'rest e r (cons #'id x))) (else (lp #'rest (cons #'id e) r x)))))))) (syntax-case stx (export import) ((_ (name name* ...) (export espec ...) (import ispec ...) body ...) (and-map identifier? #'(name name* ...)) ;; Add () as the version. #'(library (name name* ... ()) (export espec ...) (import ispec ...) body ...)) ((_ (name name* ... (version ...)) (export espec ...) (import ispec ...) body ...) (and-map identifier? #'(name name* ...)) (call-with-values (lambda () (compute-exports (map (lambda (im) (syntax-case im (for) ((for import-set import-level ...) (resolve-r6rs-interface #'import-set)) (import-set (resolve-r6rs-interface #'import-set)))) #'(ispec ...)) #'(espec ...))) (lambda (exports re-exports replacements) (with-syntax (((e ...) exports) ((r ...) re-exports) ((x ...) replacements)) ;; It would be nice to push the module that was current before the ;; definition, and pop it after the library definition, but I ;; actually can't see a way to do that. Helper procedures perhaps, ;; around a fluid that is rebound in save-module-excursion? Patches ;; welcome! #'(begin (define-module (name name* ...) #:pure #:version (version ...)) (import ispec) ... (export e ...) (re-export r ...) (export! x ...) (@@ @@ (name name* ...) body) ...)))))))) (define-syntax import (lambda (stx) (define (strip-for import-set) (syntax-case import-set (for) ((for import-set import-level ...) #'import-set) (import-set #'import-set))) (syntax-case stx () ((_ import-set ...) (with-syntax (((library-reference ...) (map strip-for #'(import-set ...)))) #'(eval-when (expand load eval) (let ((iface (resolve-r6rs-interface 'library-reference))) (call-with-deferred-observers (lambda () (module-use-interfaces! (current-module) (list iface))))) ... (if #f #f)))))))
Name | Type | Size | Permission | Actions |
---|---|---|---|---|
peg | Folder | 0755 |
|
|
and-let-star.scm | File | 2.53 KB | 0644 |
|
arrays.scm | File | 2.63 KB | 0644 |
|
atomic.scm | File | 1.55 KB | 0644 |
|
binary-ports.scm | File | 1.99 KB | 0644 |
|
boot-9.scm | File | 143.94 KB | 0644 |
|
buffered-input.scm | File | 4.82 KB | 0644 |
|
calling.scm | File | 10.54 KB | 0644 |
|
channel.scm | File | 5.19 KB | 0644 |
|
command-line.scm | File | 18.2 KB | 0644 |
|
common-list.scm | File | 8.95 KB | 0644 |
|
control.scm | File | 4.08 KB | 0644 |
|
curried-definitions.scm | File | 1.79 KB | 0644 |
|
debug.scm | File | 1.09 KB | 0644 |
|
deprecated.scm | File | 2.95 KB | 0644 |
|
documentation.scm | File | 7.41 KB | 0644 |
|
eval-string.scm | File | 2.99 KB | 0644 |
|
eval.scm | File | 25.12 KB | 0644 |
|
expect.scm | File | 5.5 KB | 0644 |
|
fdes-finalizers.scm | File | 1.06 KB | 0644 |
|
format.scm | File | 74.37 KB | 0644 |
|
ftw.scm | File | 24.17 KB | 0644 |
|
futures.scm | File | 10.49 KB | 0644 |
|
gap-buffer.scm | File | 10.14 KB | 0644 |
|
getopt-long.scm | File | 16.49 KB | 0644 |
|
hash-table.scm | File | 1.77 KB | 0644 |
|
hcons.scm | File | 2.55 KB | 0644 |
|
history.scm | File | 2.29 KB | 0644 |
|
i18n.scm | File | 20.51 KB | 0644 |
|
iconv.scm | File | 3.65 KB | 0644 |
|
lineio.scm | File | 3.85 KB | 0644 |
|
list.scm | File | 1.29 KB | 0644 |
|
local-eval.scm | File | 9.96 KB | 0644 |
|
ls.scm | File | 3.2 KB | 0644 |
|
mapping.scm | File | 4.84 KB | 0644 |
|
match.scm | File | 2 KB | 0644 |
|
match.upstream.scm | File | 35.92 KB | 0644 |
|
networking.scm | File | 3.33 KB | 0644 |
|
null.scm | File | 1.13 KB | 0644 |
|
occam-channel.scm | File | 7.26 KB | 0644 |
|
optargs.scm | File | 15.75 KB | 0644 |
|
peg.scm | File | 1.64 KB | 0644 |
|
poe.scm | File | 3.3 KB | 0644 |
|
poll.scm | File | 5.79 KB | 0644 |
|
popen.scm | File | 6.82 KB | 0644 |
|
ports.scm | File | 18.89 KB | 0644 |
|
posix.scm | File | 2.73 KB | 0644 |
|
pretty-print.scm | File | 16.88 KB | 0644 |
|
psyntax-pp.scm | File | 180.55 KB | 0644 |
|
psyntax.scm | File | 148.7 KB | 0644 |
|
q.scm | File | 4.2 KB | 0644 |
|
quasisyntax.scm | File | 5.22 KB | 0644 |
|
r5rs.scm | File | 1.56 KB | 0644 |
|
r6rs-libraries.scm | File | 9.43 KB | 0644 |
|
rdelim.scm | File | 7.72 KB | 0644 |
|
readline.scm | File | 9.56 KB | 0644 |
|
receive.scm | File | 1.06 KB | 0644 |
|
regex.scm | File | 8.87 KB | 0644 |
|
runq.scm | File | 8.18 KB | 0644 |
|
rw.scm | File | 1.02 KB | 0644 |
|
safe-r5rs.scm | File | 3.72 KB | 0644 |
|
safe.scm | File | 1.25 KB | 0644 |
|
sandbox.scm | File | 34.23 KB | 0644 |
|
save-stack.scm | File | 2.15 KB | 0644 |
|
scm-style-repl.scm | File | 11.62 KB | 0644 |
|
serialize.scm | File | 3.78 KB | 0644 |
|
session.scm | File | 17.72 KB | 0644 |
|
slib.scm | File | 1.55 KB | 0644 |
|
stack-catch.scm | File | 1.94 KB | 0644 |
|
streams.scm | File | 5.86 KB | 0644 |
|
string-fun.scm | File | 8.59 KB | 0644 |
|
suspendable-ports.scm | File | 29.87 KB | 0644 |
|
syncase.scm | File | 1.52 KB | 0644 |
|
textual-ports.scm | File | 2.29 KB | 0644 |
|
threads.scm | File | 12.54 KB | 0644 |
|
time.scm | File | 2.07 KB | 0644 |
|
top-repl.scm | File | 2.75 KB | 0644 |
|
unicode.scm | File | 1005 B | 0644 |
|
vlist.scm | File | 21.56 KB | 0644 |
|
weak-vector.scm | File | 1.2 KB | 0644 |
|