Implement quote-identifier, which is needed for macro-generating macros.
authorChris Hanson <org/chris-hanson/cph>
Sun, 28 Jan 2018 23:36:17 +0000 (15:36 -0800)
committerChris Hanson <org/chris-hanson/cph>
Sun, 28 Jan 2018 23:36:17 +0000 (15:36 -0800)
I'm not entirely happy with this; it feels like a wart.  But I don't see an
alternative at the moment.

src/runtime/mit-syntax.scm
src/runtime/runtime.pkg
src/runtime/syntax-definitions.scm
src/runtime/syntax-output.scm
src/runtime/syntax-rename.scm
tests/check.scm
tests/runtime/test-syntax-rename.scm [new file with mode: 0644]

index 30628f3b28da1c9a3d8076a2675660280831c0c5..b6740155118707c06cdc894b04a1f0bb969c03d8 100644 (file)
@@ -104,10 +104,17 @@ USA.
        (output/unspecific))))
 
 (define (compiler:quote form environment)
-  environment                          ;ignore
-  (syntax-check '(KEYWORD DATUM) form)
+  (declare (ignore environment))
+  (syntax-check '(keyword datum) form)
   (output/constant (strip-syntactic-closures (cadr form))))
 
+(define (compiler:quote-identifier form environment)
+  (syntax-check '(keyword identifier) form)
+  (let ((item (lookup-identifier (cadr form) environment)))
+    (if (not (variable-item? item))
+       (syntax-error "Can't quote a keyword identifier:" form))
+    (output/quoted-identifier (variable-item/name item))))
+
 (define (compiler:set! form environment)
   (syntax-check '(KEYWORD FORM ? EXPRESSION) form)
   (receive (name environment-item)
index d0ae71bb78d1d0d3fb50dfed9e4760be4bc75b24..f4a41bca78d685e0e3380d8882a1c1ee78a6c47d 100644 (file)
@@ -4525,6 +4525,7 @@ USA.
          output/let
          output/letrec
          output/named-lambda
+         output/quoted-identifier
          output/runtime-reference
          output/sequence
          output/the-environment
@@ -4535,6 +4536,8 @@ USA.
          output/unassigned-test
          output/unspecific
          output/variable
+         quoted-identifier-identifier
+         quoted-identifier?
          transformer-eval))
 
 (define-package (runtime syntax declaration)
@@ -4570,6 +4573,7 @@ USA.
          compiler:named-lambda
          compiler:or
          compiler:quote
+         compiler:quote-identifier
          compiler:set!
          compiler:the-environment)
   (export (runtime mit-macros)
index 79321085f0933a8496389684acf88378f2a6fe5f..a45af37e529a6f13e6b08d78f5ee21069afc214b 100644 (file)
@@ -58,5 +58,6 @@ USA.
   (define-compiler 'NAMED-LAMBDA compiler:named-lambda)
   (define-compiler 'OR compiler:or)
   (define-compiler 'QUOTE compiler:quote)
+  (define-compiler 'quote-identifier compiler:quote-identifier)
   (define-compiler 'SET! compiler:set!)
   (define-compiler 'THE-ENVIRONMENT compiler:the-environment))
\ No newline at end of file
index 261bf8053f396696db42df78783dca8374f8f376..d2fd6ff7796ecf088b02895ecd25224815b0ace9 100644 (file)
@@ -38,6 +38,11 @@ USA.
 (define (output/constant datum)
   datum)
 
+(define-record-type <quoted-identifier>
+    (output/quoted-identifier identifier)
+    quoted-identifier?
+  (identifier quoted-identifier-identifier))
+
 (define (output/assignment name value)
   (make-scode-assignment name value))
 
index e6b974682ff216efcb3a4f0a96a706dbaac5d272..a0b988c10c6a2046de98bd38b1833831c5e8b585 100644 (file)
@@ -225,6 +225,9 @@ USA.
                            (scode-open-block-actions expression)
                            mark-safe!)))
 
+   (define-cs-handler quoted-identifier?
+     (simple-subexpression quoted-identifier-identifier))
+
    (define-cs-handler scode-access?
      (simple-subexpression scode-access-environment))
 
@@ -308,6 +311,10 @@ USA.
      (lambda (substitution expression)
        (make-scode-variable (substitution (scode-variable-name expression)))))
 
+   (define-as-handler quoted-identifier?
+     (lambda (substitution expression)
+       (substitution (quoted-identifier-identifier expression))))
+
    (define-as-handler scode-assignment?
      (lambda (substitution expression)
        (make-scode-assignment
index fcc82249ffb98b3a08dfac47d3a0caa2f320c00a..633e3a1cf9b5b35f137379ce330e4afbd154e353 100644 (file)
@@ -78,6 +78,7 @@ USA.
     "runtime/test-string-normalization"
     "runtime/test-string-search"
     "runtime/test-syncproc"
+    "runtime/test-syntax-rename"
     "runtime/test-thread-queue"
     "runtime/test-url"
     ("runtime/test-wttree" (runtime wt-tree))
diff --git a/tests/runtime/test-syntax-rename.scm b/tests/runtime/test-syntax-rename.scm
new file mode 100644 (file)
index 0000000..600f3f4
--- /dev/null
@@ -0,0 +1,62 @@
+#| -*-Scheme-*-
+
+Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
+    2017 Massachusetts Institute of Technology
+
+This file is part of MIT/GNU Scheme.
+
+MIT/GNU Scheme is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+MIT/GNU Scheme 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
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MIT/GNU Scheme; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
+USA.
+
+|#
+
+;;;; Test of identifier renaming
+
+(declare (usual-integrations))
+\f
+(define test-environment
+  (the-environment))
+
+(define-syntax outer
+  (sc-macro-transformer
+   (lambda (form use-env)
+     (syntax-check '(keyword identifier) form)
+     (let* ((raw (cadr form))
+           (closed (close-syntax raw use-env)))
+       `(define-syntax inner
+         (sc-macro-transformer
+          (lambda (form use-env)
+            (syntax-check '(keyword) form)
+            `(,(quote-identifier ,raw)
+              ,(quote ,raw)
+              ,(quote-identifier ,closed)
+              ,(quote ,closed)))))))))
+
+;; A fairly complicated test that shows how quote-identifier works,
+;; how it's different from quote, and that weird binding combinations
+;; work as they should.
+(define-test 'quoting
+  (lambda ()
+    (let ((expr
+          '(let ((car 13))
+             (outer car)
+             (let ((car 15))
+               (car (inner))))))
+      (assert-equal (unsyntax (syntax expr test-environment))
+                   '(let ((.car.1 13))
+                      (let ((.car.2 15))
+                        (.car.2 (car car .car.1 car))))))))
\ No newline at end of file