Hi, "Julian Graham" <[EMAIL PROTECTED]> writes:
> What if we added another reader option, say, (keywords 'postfix), > which would recognize SRFI-88-style keywords? I think now is a good time so I just committed the attached patch. Now, we should do something about `cond-expand' and `require-extension'. For the former, we should probably look at the current value of `(read-options)', but that requires changing the implementation of `cond-expand'. For the latter, we can provide a dummy module that modifies `read-options' and re-export the needed procedures. Thoughts? Thanks, Ludovic.
>From 75946eddfc4b086f59766ea1e207480261be0315 Mon Sep 17 00:00:00 2001 From: =?utf-8?q?Ludovic=20Court=C3=A8s?= <[EMAIL PROTECTED]> Date: Tue, 15 Apr 2008 19:52:43 +0200 Subject: [PATCH] Add support for SRFI-88-like postfix keyword read syntax. --- NEWS | 4 ++++ doc/ref/ChangeLog | 7 +++++++ doc/ref/api-data.texi | 22 ++++++++++++++++++++-- doc/ref/api-options.texi | 6 +++--- libguile/ChangeLog | 7 +++++++ libguile/read.c | 26 ++++++++++++++++++++------ test-suite/ChangeLog | 5 +++++ test-suite/tests/reader.test | 16 +++++++++++++++- 8 files changed, 81 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 6d889d3..02b90e6 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,10 @@ The new repository can be accessed using "git-clone git://git.sv.gnu.org/guile.git", or can be browsed on-line at http://git.sv.gnu.org/gitweb/?p=guile.git . See `README' for details. +* New features (see the manual for details) + +** New `postfix' read option, for SRFI-88 keyword syntax + * Bugs fixed ** `scm_add_slot ()' no longer segfaults (fixes bug #22369) diff --git a/doc/ref/ChangeLog b/doc/ref/ChangeLog index b41db5c..371cac3 100644 --- a/doc/ref/ChangeLog +++ b/doc/ref/ChangeLog @@ -1,3 +1,10 @@ +2008-04-15 Ludovic Courtès <[EMAIL PROTECTED]> + + * api-data.texi (Keywords): Mention postfix syntax. + (Keyword Read Syntax): Document `postfix' read option. + * api-options.texi (Reader options): Update examples. + (Examples of option use): Likewise. + 2008-03-19 Neil Jerram <[EMAIL PROTECTED]> * api-debug.texi (Debugging Examples): New (from CVS HEAD). diff --git a/doc/ref/api-data.texi b/doc/ref/api-data.texi index f4549f6..31c1c6b 100755 --- a/doc/ref/api-data.texi +++ b/doc/ref/api-data.texi @@ -4894,7 +4894,7 @@ makes them easy to type. Guile's keyword support conforms to R5RS, and adds a (switchable) read syntax extension to permit keywords to begin with @code{:} as well as [EMAIL PROTECTED]:}. [EMAIL PROTECTED]:}, or to end with @code{:}. @menu * Why Use Keywords?:: Motivation for keyword usage. @@ -5039,9 +5039,17 @@ If the @code{keyword} 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. [EMAIL PROTECTED] SRFI-88 keyword syntax + +If the @code{keyword} read option is set to @code{'postfix}, Guile +recognizes the @uref{http://srfi.schemers.org/srfi-88/srfi-88.html, +SRFI-88 read syntax} @code{NAME:}. Otherwise, tokens of this form are +read as symbols. + To enable and disable the alternative non-R5RS keyword syntax, you use the @code{read-set!} procedure documented in @ref{User level options -interfaces} and @ref{Reader options}. +interfaces} and @ref{Reader options}. Note that the @code{prefix} and [EMAIL PROTECTED] syntax are mutually exclusive. @smalllisp (read-set! keywords 'prefix) @@ -5054,6 +5062,16 @@ interfaces} and @ref{Reader options}. @result{} #:type +(read-set! keywords 'postfix) + +type: [EMAIL PROTECTED] +#:type + +:type [EMAIL PROTECTED] +:type + (read-set! keywords #f) #:type diff --git a/doc/ref/api-options.texi b/doc/ref/api-options.texi index ed1c42d..0805108 100644 --- a/doc/ref/api-options.texi +++ b/doc/ref/api-options.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Guile Reference Manual. [EMAIL PROTECTED] Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006 [EMAIL PROTECTED] Copyright (C) 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008 @c Free Software Foundation, Inc. @c See the file guile.texi for copying conditions. @@ -491,7 +491,7 @@ Here is the list of reader options generated by typing values. @smalllisp -keywords #f Style of keyword recognition: #f or 'prefix +keywords #f Style of keyword recognition: #f, 'prefix or 'postfix case-insensitive no Convert symbols to lower case. positions yes Record positions of source code expressions. copy no Copy source code expressions. @@ -715,7 +715,7 @@ ABORT: (misc-error) Type "(backtrace)" to get more information. guile> (read-options 'help) -keywords #f Style of keyword recognition: #f or 'prefix +keywords #f Style of keyword recognition: #f, 'prefix or 'postfix case-insensitive no Convert symbols to lower case. positions yes Record positions of source code expressions. copy no Copy source code expressions. diff --git a/libguile/ChangeLog b/libguile/ChangeLog index 93453f4..5692927 100644 --- a/libguile/ChangeLog +++ b/libguile/ChangeLog @@ -1,3 +1,10 @@ +2008-04-15 Ludovic Courtès <[EMAIL PROTECTED]> + Julian Graham <[EMAIL PROTECTED]> + + * read.c (scm_keyword_postfix): New. + (scm_read_opts): Update docstring for `keywords'. + (scm_read_mixed_case_symbol): Add support for postfix keywords. + 2008-04-13 Ludovic Courtès <[EMAIL PROTECTED]> * inline.h (SCM_C_USE_EXTERN_INLINE): New macro. Use it to make diff --git a/libguile/read.c b/libguile/read.c index 8290f19..8bc1dff 100644 --- a/libguile/read.c +++ b/libguile/read.c @@ -54,6 +54,7 @@ SCM_GLOBAL_SYMBOL (scm_sym_dot, "."); SCM_SYMBOL (scm_keyword_prefix, "prefix"); +SCM_SYMBOL (scm_keyword_postfix, "postfix"); scm_t_option scm_read_opts[] = { { SCM_OPTION_BOOLEAN, "copy", 0, @@ -63,7 +64,7 @@ scm_t_option scm_read_opts[] = { { SCM_OPTION_BOOLEAN, "case-insensitive", 0, "Convert symbols to lower case."}, { SCM_OPTION_SCM, "keywords", SCM_UNPACK (SCM_BOOL_F), - "Style of keyword recognition: #f or 'prefix."} + "Style of keyword recognition: #f, 'prefix or 'postfix."}, #if SCM_ENABLE_ELISP , { SCM_OPTION_BOOLEAN, "elisp-vectors", 0, @@ -561,15 +562,19 @@ static SCM scm_read_mixed_case_symbol (int chr, SCM port) { SCM result, str = SCM_EOL; - int overflow = 0; + int overflow = 0, ends_with_colon = 0; char buffer[READER_BUFFER_SIZE]; size_t read = 0; + int postfix = scm_is_eq (SCM_PACK (SCM_KEYWORD_STYLE), scm_keyword_postfix); scm_ungetc (chr, port); do { overflow = read_token (port, buffer, sizeof (buffer), &read); + if (read > 0) + ends_with_colon = (buffer[read - 1] == ':'); + if ((overflow) || (scm_is_pair (str))) str = scm_cons (scm_from_locale_stringn (buffer, read), str); } @@ -579,12 +584,21 @@ scm_read_mixed_case_symbol (int chr, SCM port) { str = scm_string_concatenate (scm_reverse_x (str, SCM_EOL)); result = scm_string_to_symbol (str); + + /* Per SRFI-88, `:' alone is an identifier, not a keyword. */ + if (postfix && ends_with_colon && (scm_c_string_length (result) > 1)) + result = scm_symbol_to_keyword (result); } else - /* For symbols smaller than `sizeof (buffer)', we don't need to recur to - Scheme strings. Therefore, we only create one Scheme object (a - symbol) per symbol read. */ - result = scm_from_locale_symboln (buffer, read); + { + /* For symbols smaller than `sizeof (buffer)', we don't need to recur + to Scheme strings. Therefore, we only create one Scheme object (a + symbol) per symbol read. */ + if (postfix && ends_with_colon && (read > 1)) + result = scm_from_locale_keywordn (buffer, read - 1); + else + result = scm_from_locale_symboln (buffer, read); + } return result; } diff --git a/test-suite/ChangeLog b/test-suite/ChangeLog index 518e53f..210c802 100644 --- a/test-suite/ChangeLog +++ b/test-suite/ChangeLog @@ -1,3 +1,8 @@ +2008-04-15 Ludovic Courtès <[EMAIL PROTECTED]> + + * tests/reader.test (read-options)[prefix non-keywords, postfix + keywords, `:' is not a postfix keyword (per SRFI-88)]: New tests. + 2008-04-13 Ludovic Courtès <[EMAIL PROTECTED]> * tests/goops.test (defining classes)[interaction with diff --git a/test-suite/tests/reader.test b/test-suite/tests/reader.test index d6047a2..0b13cf1 100644 --- a/test-suite/tests/reader.test +++ b/test-suite/tests/reader.test @@ -1,6 +1,6 @@ ;;;; reader.test --- Exercise the reader. -*- Scheme -*- ;;;; -;;;; Copyright (C) 1999, 2001, 2002, 2003, 2007 Free Software Foundation, Inc. +;;;; Copyright (C) 1999, 2001, 2002, 2003, 2007, 2008 Free Software Foundation, Inc. ;;;; Jim Blandy <[EMAIL PROTECTED]> ;;;; ;;;; This library is free software; you can redistribute it and/or @@ -149,6 +149,20 @@ (with-read-options '(keywords prefix case-insensitive) (lambda () (read-string ":KeyWord"))))) + (pass-if "prefix non-keywords" + (symbol? (with-read-options '(keywords prefix) + (lambda () + (read-string "srfi88-keyword:"))))) + (pass-if "postfix keywords" + (eq? #:keyword + (with-read-options '(keywords postfix) + (lambda () + (read-string "keyword:"))))) + (pass-if "`:' is not a postfix keyword (per SRFI-88)" + (eq? ': + (with-read-options '(keywords postfix) + (lambda () + (read-string ":"))))) (pass-if "no positions" (let ((sexp (with-read-options '() (lambda () -- 1.5.5
