mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-05 03:30:24 +02:00
Guile (3.0.8) reports a compilation error when cond-expand tries to check existence of a missing library: scheme@(guile-user)> (define-library (test) (cond-expand ((library (scheme sort)) (import (scheme sort))))) While compiling expression: no code for module (scheme sort) It looks like bug #40252 was not fully eliminated. Also, (library ...) cannot handle module names like (srfi 1), though (import (srfi 1)) works fine. For example, this code fails: scheme@(guile-user)> (define-library (test) (cond-expand ((library (srfi 1)) (import (srfi 1))))) While compiling expression: In procedure symbol->string: Wrong type argument in position 1 (expecting symbol): 1 There are probably other cases when (library ...) and (import ...) does not work identically: (library ...) uses resolve-interface while (import ...) uses resolve-r6rs-interface. This patch fixes both issues. * module/ice-9/r7rs-libraries.scm (define-library): Replace 'resolve-interface' call by 'resolve-r6rs-interface', wrapped in 'cond-expand'. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
108 lines
4.3 KiB
Scheme
108 lines
4.3 KiB
Scheme
;; R7RS library support
|
||
;; Copyright (C) 2020, 2021 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-syntax include-library-declarations
|
||
(lambda (x)
|
||
(syntax-violation
|
||
'include-library-declarations
|
||
"use of 'include-library-declarations' outside define-library" x x)))
|
||
|
||
;; FIXME: Implement properly!
|
||
(define-syntax-rule (include-ci filename)
|
||
(include filename))
|
||
|
||
(define-syntax define-library
|
||
(lambda (stx)
|
||
(define (handle-includes filenames)
|
||
(syntax-case filenames ()
|
||
(() #'())
|
||
((filename . filenames)
|
||
(append (call-with-include-port
|
||
#'filename
|
||
(lambda (p)
|
||
(let lp ()
|
||
(let ((x (read p)))
|
||
(if (eof-object? x)
|
||
#'()
|
||
(cons (datum->syntax #'filename x) (lp)))))))
|
||
(handle-includes #'filenames)))))
|
||
|
||
(define (handle-cond-expand clauses)
|
||
(define (has-req? req)
|
||
(syntax-case req (and or not library)
|
||
((and req ...)
|
||
(and-map has-req? #'(req ...)))
|
||
((or req ...)
|
||
(or-map has-req? #'(req ...)))
|
||
((not req)
|
||
(not (has-req? #'req)))
|
||
((library lib-name)
|
||
(->bool
|
||
(false-if-exception
|
||
(resolve-r6rs-interface
|
||
(syntax->datum #'lib-name)))))
|
||
(id
|
||
(identifier? #'id)
|
||
;; FIXME: R7RS (features) isn't quite the same as
|
||
;; %cond-expand-features; see scheme/base.scm.
|
||
(memq (syntax->datum #'id) %cond-expand-features))))
|
||
(syntax-case clauses ()
|
||
(() #'()) ; R7RS says this is not specified :-/
|
||
(((test decl ...) . clauses)
|
||
(if (has-req? #'test)
|
||
#'(decl ...)
|
||
(handle-cond-expand #'clauses)))))
|
||
|
||
(define (partition-decls decls exports imports code)
|
||
(syntax-case decls (export import begin include include-ci
|
||
include-library-declarations cond-expand)
|
||
(() (values exports imports (reverse code)))
|
||
(((export clause ...) . decls)
|
||
(partition-decls #'decls (append exports #'(clause ...)) imports code))
|
||
(((import clause ...) . decls)
|
||
(partition-decls #'decls exports (append imports #'(clause ...)) code))
|
||
(((begin expr ...) . decls)
|
||
(partition-decls #'decls exports imports
|
||
(cons #'(begin expr ...) code)))
|
||
(((include filename ...) . decls)
|
||
(partition-decls #'decls exports imports
|
||
(cons #'(begin (include filename) ...) code)))
|
||
(((include-ci filename ...) . decls)
|
||
(partition-decls #'decls exports imports
|
||
(cons #'(begin (include-ci filename) ...) code)))
|
||
(((include-library-declarations filename ...) . decls)
|
||
(syntax-case (handle-includes #'(filename ...)) ()
|
||
((decl ...)
|
||
(partition-decls #'(decl ... . decls) exports imports code))))
|
||
(((cond-expand clause ...) . decls)
|
||
(syntax-case (handle-cond-expand #'(clause ...)) ()
|
||
((decl ...)
|
||
(partition-decls #'(decl ... . decls) exports imports code))))))
|
||
|
||
(syntax-case stx ()
|
||
((_ name decl ...)
|
||
(call-with-values (lambda ()
|
||
(partition-decls #'(decl ...) '() '() '()))
|
||
(lambda (exports imports code)
|
||
#`(library name
|
||
(export . #,exports)
|
||
(import . #,imports)
|
||
. #,code)))))))
|