From: Chris Hanson Date: Sun, 28 Jan 2018 23:36:17 +0000 (-0800) Subject: Implement quote-identifier, which is needed for macro-generating macros. X-Git-Tag: mit-scheme-pucked-x11-0.3.1~7^2~293 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=8a108d5bea363be54d0889730e0897f11f2efbab;p=mit-scheme.git Implement quote-identifier, which is needed for macro-generating macros. I'm not entirely happy with this; it feels like a wart. But I don't see an alternative at the moment. --- diff --git a/src/runtime/mit-syntax.scm b/src/runtime/mit-syntax.scm index 30628f3b2..b67401551 100644 --- a/src/runtime/mit-syntax.scm +++ b/src/runtime/mit-syntax.scm @@ -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) diff --git a/src/runtime/runtime.pkg b/src/runtime/runtime.pkg index d0ae71bb7..f4a41bca7 100644 --- a/src/runtime/runtime.pkg +++ b/src/runtime/runtime.pkg @@ -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) diff --git a/src/runtime/syntax-definitions.scm b/src/runtime/syntax-definitions.scm index 79321085f..a45af37e5 100644 --- a/src/runtime/syntax-definitions.scm +++ b/src/runtime/syntax-definitions.scm @@ -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 diff --git a/src/runtime/syntax-output.scm b/src/runtime/syntax-output.scm index 261bf8053..d2fd6ff77 100644 --- a/src/runtime/syntax-output.scm +++ b/src/runtime/syntax-output.scm @@ -38,6 +38,11 @@ USA. (define (output/constant datum) datum) +(define-record-type + (output/quoted-identifier identifier) + quoted-identifier? + (identifier quoted-identifier-identifier)) + (define (output/assignment name value) (make-scode-assignment name value)) diff --git a/src/runtime/syntax-rename.scm b/src/runtime/syntax-rename.scm index e6b974682..a0b988c10 100644 --- a/src/runtime/syntax-rename.scm +++ b/src/runtime/syntax-rename.scm @@ -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 diff --git a/tests/check.scm b/tests/check.scm index fcc82249f..633e3a1cf 100644 --- a/tests/check.scm +++ b/tests/check.scm @@ -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 index 000000000..600f3f454 --- /dev/null +++ b/tests/runtime/test-syntax-rename.scm @@ -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)) + +(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