This is an automated email from the git hooks/post-receive script.

wingo pushed a commit to branch master
in repository guile.

The following commit(s) were added to refs/heads/master by this push:
     new a04a024  Implement read-syntax
a04a024 is described below

commit a04a024f205e1e2cd04e80c1eece649acf6e2fa8
Author: Andy Wingo <wi...@pobox.com>
AuthorDate: Sun Feb 21 20:48:15 2021 +0100

    Implement read-syntax
    
    * doc/ref/api-macros.texi (Syntax Case): Update documentation for
      datum->syntax.
    * module/ice-9/psyntax.scm (datum->syntax): Use #:source keyword for
      source location info instead of an optional, and allow an alist.
    * module/ice-9/psyntax-pp.scm: Regenerate.
    * module/ice-9/read.scm (%read, read): Refactor to allow read and
      read-syntax to share an implementation.
      (read-syntax): New function.
---
 doc/ref/api-macros.texi     | 10 +++----
 module/ice-9/psyntax-pp.scm |  8 +++---
 module/ice-9/psyntax.scm    |  8 +++---
 module/ice-9/read.scm       | 69 +++++++++++++++++++++++++++------------------
 4 files changed, 55 insertions(+), 40 deletions(-)

diff --git a/doc/ref/api-macros.texi b/doc/ref/api-macros.texi
index 7bcca7a..90cba24 100644
--- a/doc/ref/api-macros.texi
+++ b/doc/ref/api-macros.texi
@@ -638,18 +638,18 @@ won't have access to the binding of @code{it}.
 
 But they can, if we explicitly introduce a binding via @code{datum->syntax}.
 
-@deffn {Scheme Procedure} datum->syntax template-id datum [srcloc]
+@deffn {Scheme Procedure} datum->syntax template-id datum [#:source=#f]
 Create a syntax object that wraps @var{datum}, within the lexical
 context corresponding to the identifier @var{template-id}.  If
 @var{template-id} is false, the datum will have no lexical context
 information.
 
 Syntax objects have an associated source location.  @xref{Source
-Properties}.  If a syntax object is passed as @var{srcloc}, the
-resulting syntax object will have the source properties of @var{srcloc}.
-Otherwise if @var{srcloc} is a source properties alist, those will be
+Properties}.  If a syntax object is passed as @var{source}, the
+resulting syntax object will have the source properties of @var{source}.
+Otherwise if @var{source} is a source properties alist, those will be
 the source properties of the resulting syntax object.  Otherwise if
-@var{srcloc} is false, the source properties are computed as
+@var{source} is false, the source properties are computed as
 @code{(source-properties @var{datum})}.
 @end deffn
 
diff --git a/module/ice-9/psyntax-pp.scm b/module/ice-9/psyntax-pp.scm
index da14453..f0ee5eb 100644
--- a/module/ice-9/psyntax-pp.scm
+++ b/module/ice-9/psyntax-pp.scm
@@ -2421,16 +2421,16 @@
           (cons 'hygiene (module-name (current-module))))))
     (set! identifier? (lambda (x) (nonsymbol-id? x)))
     (set! datum->syntax
-      (lambda* (id datum #:optional (srcloc #f))
+      (lambda* (id datum #:key (source #f #:source))
         (make-syntax
           datum
           (if id (syntax-wrap id) '((top)))
           (if id
             (syntax-module id)
             (cons 'hygiene (module-name (current-module))))
-          (cond ((not srcloc) (source-properties datum))
-                ((and (list? srcloc) (and-map pair? srcloc)) srcloc)
-                (else (syntax-source srcloc))))))
+          (cond ((not source) (source-properties datum))
+                ((and (list? source) (and-map pair? source)) source)
+                (else (syntax-source source))))))
     (set! syntax->datum (lambda (x) (strip x '(()))))
     (set! generate-temporaries
       (lambda (ls)
diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm
index c5c85fd..061beb9 100644
--- a/module/ice-9/psyntax.scm
+++ b/module/ice-9/psyntax.scm
@@ -2763,7 +2763,7 @@
             (nonsymbol-id? x)))
 
     (set! datum->syntax
-          (lambda* (id datum #:optional srcloc)
+          (lambda* (id datum #:key source)
             (make-syntax datum
                          (if id
                              (syntax-wrap id)
@@ -2772,9 +2772,9 @@
                              (syntax-module id)
                              (cons 'hygiene (module-name (current-module))))
                          (cond
-                          ((not srcloc) (source-properties datum))
-                          ((and (list? srcloc) (and-map pair? srcloc)) srcloc)
-                          (else (syntax-source srcloc))))))
+                          ((not source) (source-properties datum))
+                          ((and (list? source) (and-map pair? source)) source)
+                          (else (syntax-source source))))))
 
     (set! syntax->datum
           ;; accepts any object, since syntax objects may consist partially
diff --git a/module/ice-9/read.scm b/module/ice-9/read.scm
index 9683744..5b375e1 100644
--- a/module/ice-9/read.scm
+++ b/module/ice-9/read.scm
@@ -43,7 +43,8 @@
   #:use-module (srfi srfi-11)
   #:use-module (ice-9 textual-ports)
   #:use-module (rnrs bytevectors)
-  #:replace (read))
+  #:replace (read)
+  #:export (read-syntax))
 
 (define read-hash-procedures
   (fluid->parameter %read-hash-procedures))
@@ -110,7 +111,7 @@
                                        read-options-inherit-all)
                                    field value)))
 
-(define* (read #:optional (port (current-input-port)))
+(define (%read port annotate strip-annotation)
   ;; init read options
   (define opts (compute-reader-options port))
   (define (enabled? field)
@@ -118,7 +119,6 @@
   (define (set-reader-option! field value)
     (set! opts (set-option opts field value))
     (set-port-read-option! port field value))
-  (define (record-positions?) (enabled? bitfield:record-positions?))
   (define (case-insensitive?) (enabled? bitfield:case-insensitive?))
   (define (keyword-style) (logand read-option-mask
                                   (ash opts (- bitfield:keyword-style))))
@@ -134,21 +134,6 @@
   (define (get-pos) (cons (port-line port) (port-column port)))
   ;; We are only ever interested in whether an object is a char or not.
   (define (eof-object? x) (not (char? x)))
-  (define (annotate line column datum)
-    ;; FIXME: Return a syntax object instead, so we can avoid the
-    ;; srcprops side table.
-    (when (and (record-positions?)
-               (supports-source-properties? datum)
-               ;; Line or column can be invalid via set-port-column! or
-               ;; ungetting chars beyond start of line.
-               (<= 0 line)
-               (<= 1 column))
-      ;; We always capture the column after one char of lookahead;
-      ;; subtract off that lookahead value.
-      (set-source-properties! datum `((filename . ,filename)
-                                      (line . ,line)
-                                      (column . ,(1- column)))))
-    datum)
 
   (define (input-error msg args)
     (scm-error 'read-error #f
@@ -248,7 +233,7 @@
            ;; Note that it is possible for scm_read_expression to
            ;; return `.', but not as part of a dotted pair: as in
            ;; #{.}#.  Indeed an example is here!
-           (if (and (eqv? ch #\.) (eq? expr '#{.}#))
+           (if (and (eqv? ch #\.) (eq? (strip-annotation expr) '#{.}#))
                (let* ((tail (read-expr (next-non-whitespace)))
                       (close (next-non-whitespace)))
                  (unless (eqv? close rdelim)
@@ -481,7 +466,7 @@
     (let ((ch (next-non-whitespace)))
       (when (eof-object? ch)
         (error "end of input while reading keyword"))
-      (let ((expr (read-expr ch)))
+      (let ((expr (strip-annotation (read-expr ch))))
         (unless (symbol? expr)
           (error "keyword prefix #: not followed by a symbol: ~a" expr))
         (symbol->keyword expr))))
@@ -716,7 +701,7 @@
            (let ((ch (next-non-whitespace)))
              (when (eof-object? ch)
                (error "unexpected end of input while reading :keyword"))
-             (symbol->keyword (read-expr ch)))
+             (symbol->keyword (strip-annotation (read-expr ch))))
            (read-mixed-case-symbol ch)))
       ((#\0 #\1 #\2 #\3 #\4 #\5 #\6 #\7 #\8 #\9 #\+ #\- #\.)
        (read-number ch))
@@ -749,12 +734,11 @@
   (define (read-expr ch)
     (let ((line (port-line port))
           (column (port-column port)))
-      (annotate
-       line
-       column
-       (if (zero? neoteric)
-           (read-expr* ch)
-           (read-neoteric ch)))))
+      (annotate line
+                column
+                (if (zero? neoteric)
+                    (read-expr* ch)
+                    (read-neoteric ch)))))
 
   (define (read-directive)
     (let ((ch (next)))
@@ -871,3 +855,34 @@
     (if (eof-object? ch)
         ch
         (read-expr ch))))
+
+(define* (read #:optional (port (current-input-port)))
+  (define filename (port-filename port))
+  (define annotate
+    (if (memq 'positions (read-options))
+        (lambda (line column datum)
+          (when (and (supports-source-properties? datum)
+                     ;; Line or column can be invalid via
+                     ;; set-port-column! or ungetting chars beyond start
+                     ;; of line.
+                     (<= 0 line)
+                     (<= 1 column))
+            ;; We always capture the column after one char of lookahead;
+            ;; subtract off that lookahead value.
+            (set-source-properties! datum
+                                    `((filename . ,filename)
+                                      (line . ,line)
+                                      (column . ,(1- column)))))
+          datum)
+        identity))
+  (%read port annotate identity))
+
+(define* (read-syntax #:optional (port (current-input-port)))
+  (define filename (port-filename port))
+  (define (annotate line column datum)
+    (datum->syntax #f ; No lexical context.
+                   datum
+                   #:source `((filename . ,filename)
+                              (line . ,line)
+                              (column . ,(1- column)))))
+  (%read port annotate syntax->datum))

Reply via email to