From 4c521cbd3e805ebb93e521ebea7234d797152a53 Mon Sep 17 00:00:00 2001 From: Freja Nordsiek Date: Tue, 28 Mar 2017 01:56:39 +0200 Subject: [PATCH] Added SRFI-97. * module/ice-9/boot-9.scm (resolve-module): Added SRFI-97 library name aliasing. * module/ice-9/boot-9.scm (%cond-expand-features): Added SRFI-97 * test-suite/tests/srfi-97.test: Added tests for SRFI-97 * test-suite/Makefile: Included new tests. * doc/ref/srfi-modules.texi: Added SRFI-97 documentation * doc/ref/api-modules.texi: Added SRFI-97 information to module import documentation * doc/ref/api-data.texi: Added note that keywords 'prefix and SRFI-97 do not work together. * doc/ref/api-evaluation.texi: Added note that keywords 'prefix and SRFI-97 do not work together. --- doc/ref/api-data.texi | 4 +++- doc/ref/api-evaluation.texi | 4 +++- doc/ref/api-modules.texi | 8 +++++++- doc/ref/srfi-modules.texi | 37 ++++++++++++++++++++++++++++++++++--- module/ice-9/boot-9.scm | 21 +++++++++++++++++++-- test-suite/Makefile.am | 1 + test-suite/tests/srfi-97.test | 28 ++++++++++++++++++++++++++++ 7 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 test-suite/tests/srfi-97.test diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index 214c6e2..33b11b0 100644 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -5410,7 +5410,9 @@ keywords are self-quoting objects. If the @code{keywords} read option is set to @code{'prefix}, Guile also recognizes the alternative read syntax @code{:NAME}. Otherwise, tokens -of the form @code{:NAME} are read as symbols, as required by R5RS. +of the form @code{:NAME} are read as symbols, as required by R5RS. Note +that this option prevents SRFI-97 style SRFI library references from +working (@pxref{SRFI-97}). @cindex SRFI-88 keyword syntax diff --git a/doc/ref/api-evaluation.texi b/doc/ref/api-evaluation.texi index 202ebdc..f397e4b 100644 --- a/doc/ref/api-evaluation.texi +++ b/doc/ref/api-evaluation.texi @@ -355,7 +355,9 @@ Similarly, the @code{#!curly-infix} reader directive sets the @code{curly-infix} read option on the port, and @code{#!curly-infix-and-bracket-lists} sets @code{curly-infix} and unsets @code{square-brackets} on the port (@pxref{SRFI-105}). There is -currently no other way to access or set the per-port read options. +currently no other way to access or set the per-port read options. Note +that setting @code{keywords} to @code{'prefix} prevents SRFI-97 style SRFI +library references from working (@pxref{SRFI-97}). The boolean options may be toggled with @code{read-enable} and @code{read-disable}. The non-boolean @code{keywords} option must be set diff --git a/doc/ref/api-modules.texi b/doc/ref/api-modules.texi index 8f18b1e..aea75a8 100644 --- a/doc/ref/api-modules.texi +++ b/doc/ref/api-modules.texi @@ -174,6 +174,10 @@ Note that just as with a @code{use-modules} statement, any module that has not yet been loaded will be loaded when referenced by a @code{@@} or @code{@@@@} form. +Note that SRFI libraries can be referred to as @code{(srfi address@hidden)} +or @code{(srfi :@var{number})}, where @var{number} is the number of the SRFI +needed. @xref{SRFI-97}, for documentation of the latter form. + You can also use the @code{@@} and @code{@@@@} syntaxes as the target of a @code{set!} when the binding refers to a variable. @@ -846,7 +850,9 @@ been defined and @var{autoload} is true, try to auto-load it. When it can't be found that way either, create an empty module if @var{ensure} is true, otherwise return @code{#f}. If @var{version} is true, ensure that the resulting module is compatible with the given version reference -(@pxref{R6RS Version References}). The name is a list of symbols. +(@pxref{R6RS Version References}). The name is a list of symbols. Note +that this procedure allows the usage of SRFI-97 style SRFI references +(@pxref{SRFI-97}). @end deffn @deffn {Scheme Procedure} resolve-interface name [#:select=#f] @ diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi index f712944..16e9f65 100644 --- a/doc/ref/srfi-modules.texi +++ b/doc/ref/srfi-modules.texi @@ -60,6 +60,7 @@ get the relevant SRFI documents from the SRFI home page * SRFI-69:: Basic hash tables. * SRFI-87:: => in case clauses. * SRFI-88:: Keyword objects. +* SRFI-97:: Standardized way to reference SRFI libraries. * SRFI-98:: Accessing environment variables. * SRFI-105:: Curly-infix expressions. * SRFI-111:: Boxes. @@ -81,8 +82,11 @@ There are several reasons for this inconsistency. First, the feature checking syntactic form @code{cond-expand} (@pxref{SRFI-0}) must be available immediately, because it must be there when the user wants to check for the Scheme implementation, that is, before she can know that -it is safe to use @code{use-modules} to load SRFI support modules. The -second reason is that some features defined in SRFIs had been +it is safe to use @code{use-modules} to load SRFI support modules. +Second, the feature to reference SRFI libraries using the syntax address@hidden(srfi :@var{number})} needs to be immediately available to +facilitate importing SRFI modules using it (@pxref{SRFI-97}). The +third reason is that some features defined in SRFIs had been implemented in Guile before the developers started to add SRFI implementations as modules (for example SRFI-13 (@pxref{SRFI-13})). In the future, it is possible that SRFIs in the core library might be @@ -94,7 +98,8 @@ you want, you can do that already. We have included the module but ensures that you can write future-safe code. Generally, support for a specific SRFI is made available by using -modules named @code{(srfi address@hidden)}, where @var{number} is the +modules named @code{(srfi address@hidden)} or address@hidden(srfi :@var{number})}, where @var{number} is the number of the SRFI needed. Another possibility is to use the command line option @code{--use-srfi}, which will load the necessary modules automatically (@pxref{Invoking Guile}). @@ -165,6 +170,7 @@ srfi-55 srfi-61 srfi-62 srfi-87 +srfi-97 srfi-105 @end example @@ -5457,6 +5463,31 @@ Return the keyword object whose name is @var{str}. @end example @end deffn address@hidden SRFI-97 address@hidden SRFI-97 - Alternative way to import SRFI libraries address@hidden SRFI-97 + +This SRFI lets a Scheme program import SRFI libraries in a portable fashion +across implementations by referencing them like @code{(srfi :@var{number})}, +where @var{number} is the number of the SRFI needed. To import SRFI-1 +this way, + address@hidden +(use-modules ((srfi :1))) address@hidden example + +or + address@hidden +(import (srfi :1)) address@hidden example + +This module is loaded by default. + +Note that this syntax for referring to SRFI libraries does not work if the address@hidden read option is set to @code{'prefix} +(@pxref{Keyword Read Syntax}). + @node SRFI-98 @subsection SRFI-98 Accessing environment variables. @cindex SRFI-98 diff --git a/module/ice-9/boot-9.scm b/module/ice-9/boot-9.scm index 2777672..df5ec26 100644 --- a/module/ice-9/boot-9.scm +++ b/module/ice-9/boot-9.scm @@ -2696,8 +2696,24 @@ deterministic." ;; Define the-root-module as '(guile). (module-define-submodule! root 'guile the-root-module) - (lambda* (name #:optional (autoload #t) (version #f) #:key (ensure #t)) - (let ((already (nested-ref-module root name))) + (lambda* (name-unproc #:optional (autoload #t) (version #f) #:key (ensure #t)) + ;; Implement SRFI-97 by first converting module names of the form + ;; ('srfi ':XXXXX ...) to ('srfi 'srfi-XXXXX) where X are base 10 digits. + (let* ((name (if (and (list? name-unproc) (not (null? name-unproc)) + (not (null? (cdr name-unproc))) + (equal? 'srfi (car name-unproc)) + (let ((s (symbol->string (cadr name-unproc))) + (digits (string->char-set "0123456789"))) + (and (string-prefix? ":" s) + (> (string-length s) 1) + (string-every (lambda (c) (char-set-contains? digits c)) + (substring s 1))))) + (list 'srfi + (string->symbol (string-append + "srfi-" + (substring (symbol->string (cadr name-unproc)) 1)))) + name-unproc)) + (already (nested-ref-module root name))) (cond ((and already (or (not autoload) (module-public-interface already))) @@ -3895,6 +3911,7 @@ when none is available, reading FILE-NAME with READER." srfi-61 ;; general cond clause srfi-62 ;; s-expression comments srfi-87 ;; => in case clauses + srfi-97 ;; allow SRFI library references to take the form (srfi :XXXX) srfi-105 ;; curly infix expressions )) diff --git a/test-suite/Makefile.am b/test-suite/Makefile.am index 3ce9070..793af52 100644 --- a/test-suite/Makefile.am +++ b/test-suite/Makefile.am @@ -156,6 +156,7 @@ SCM_TESTS = tests/00-initial-env.test \ tests/srfi-67.test \ tests/srfi-69.test \ tests/srfi-88.test \ + tests/srfi-97.test \ tests/srfi-98.test \ tests/srfi-105.test \ tests/srfi-111.test \ diff --git a/test-suite/tests/srfi-97.test b/test-suite/tests/srfi-97.test new file mode 100644 index 0000000..c9ccf00 --- /dev/null +++ b/test-suite/tests/srfi-97.test @@ -0,0 +1,28 @@ +;;;; srfi-97.test --- Test suite for importing SRFIs using (srfi :number) +;;;; +;;;; Copyright (C) 2017 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 + +(define-module (test-srfi-97) + #:use-module (test-suite lib) + #:use-module (srfi srfi-1)) + +(define (to-bool x) (if x #t #f)) + +(with-test-prefix "SRFI-97" + (pass-if "in cond-expand" (to-bool (find (lambda (x) (eq? 'srfi-97 x)) %cond-expand-features))) + (pass-if "use-modules" (to-bool (and (use-modules ((srfi :19))) (current-time time-utc)))) + (pass-if "import" (to-bool (and (import (srfi :60)) (bitwise-not 2))))) -- 2.9.3