~ chicken-core (chicken-5) 045a0f256d9a5361871cc8fe4d4da52de0fcef75
commit 045a0f256d9a5361871cc8fe4d4da52de0fcef75 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Thu Dec 31 01:06:27 2009 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Thu Dec 31 01:06:27 2009 +0100 rename and compare procedures for ER macros handle any sexp diff --git a/expand.scm b/expand.scm index 91c56f6a..b5d37898 100644 --- a/expand.scm +++ b/expand.scm @@ -1,4 +1,4 @@ -;;;; expand.scm +;;;; expand.scm - The HI/LO expander ; ; Copyright (c) 2008-2009, The Chicken Team ; All rights reserved. @@ -709,7 +709,12 @@ (define ((##sys#er-transformer handler) form se dse) (let ((renv '())) ; keep rename-environment for this expansion (define (rename sym) - (cond ((assq sym renv) => + (cond ((pair? sym) + (cons (rename (car sym)) (rename (cdr sym)))) + ((vector? sym) + (list->vector (rename (vector->list sym)))) + ((not (symbol? sym)) sym) + ((assq sym renv) => (lambda (a) (dd `(RENAME/RENV: ,sym --> ,(cdr a))) (cdr a))) @@ -730,26 +735,37 @@ a)))) (define (compare s1 s2) (let ((result - (if (and (symbol? s1) (symbol? s2)) - (let ((ss1 (or (##sys#get s1 '##core#macro-alias) - (lookup2 1 s1 dse) - s1) ) - (ss2 (or (##sys#get s2 '##core#macro-alias) - (lookup2 2 s2 dse) - s2) ) ) - (cond ((symbol? ss1) - (cond ((symbol? ss2) - (eq? (or (##sys#get ss1 '##core#primitive) ss1) - (or (##sys#get ss2 '##core#primitive) ss2))) - ((assq ss1 (##sys#macro-environment)) => - (lambda (a) (eq? (cdr a) ss2))) - (else #f) ) ) - ((symbol? ss2) - (cond ((assq ss2 (##sys#macro-environment)) => - (lambda (a) (eq? ss1 (cdr a)))) - (else #f))) - (else (eq? ss1 ss2)))) - (eq? s1 s2))) ) + (cond ((pair? s1) + (and (pair? s2) + (compare (car s1) (car s2)) + (compare (cdr s1) (cdr s2)))) + ((vector? s1) + (and (vector? s2) + (let ((len (vector-length s1))) + (and (fx= len (vector-length s2)) + (do ((i 0 (fx+ i 1)) + (f #t (compare (vector-ref s1 i) (vector-ref s2 i)))) + ((or (fx>= i len) (not f)) f)))))) + ((and (symbol? s1) (symbol? s2)) + (let ((ss1 (or (##sys#get s1 '##core#macro-alias) + (lookup2 1 s1 dse) + s1) ) + (ss2 (or (##sys#get s2 '##core#macro-alias) + (lookup2 2 s2 dse) + s2) ) ) + (cond ((symbol? ss1) + (cond ((symbol? ss2) + (eq? (or (##sys#get ss1 '##core#primitive) ss1) + (or (##sys#get ss2 '##core#primitive) ss2))) + ((assq ss1 (##sys#macro-environment)) => + (lambda (a) (eq? (cdr a) ss2))) + (else #f) ) ) + ((symbol? ss2) + (cond ((assq ss2 (##sys#macro-environment)) => + (lambda (a) (eq? ss1 (cdr a)))) + (else #f))) + (else (eq? ss1 ss2))))) + (else (eq? s1 s2))) ) ) (dd `(COMPARE: ,s1 ,s2 --> ,result)) result)) (define (lookup2 n sym dse) diff --git a/manual/Modules and macros b/manual/Modules and macros index 73f02a65..3a7035ae 100644 --- a/manual/Modules and macros +++ b/manual/Modules and macros @@ -194,6 +194,12 @@ not hygienic. Like {{loop}}, it must be written using procedurally: (,(r 'if) (,(r 'not) ,test) (exit #f)) ,@body)))) +Note: this implementation of explicit-renaming macros allows passing +arbitrary expressions to the renaming and comparison procedures. When +being renamed, a fresh copy of the expression will be produced, with all +identifiers renamed appropriately. Comparison also supports arbitrary +expressions as arguments. + === Modules diff --git a/tests/syntax-tests.scm b/tests/syntax-tests.scm index 95ac3334..fb4b9a39 100644 --- a/tests/syntax-tests.scm +++ b/tests/syntax-tests.scm @@ -1,4 +1,4 @@ -;;;; mtest.scm - various macro tests +;;;; syntax-tests.scm - various macro tests (use extras) @@ -384,3 +384,22 @@ (import scheme m0001 extras) (pp (foo bar))) + +;;; renaming of arbitrary structures + +(module m1 (s1 s2) + + (import scheme) + + (define-syntax s1 (syntax-rules () ((_ x) (list x)))) + + (define-syntax s2 + (lambda (x r c) + (r `(vector (s1 ,(cadr x)))))) ) ; without renaming the local version of `s1' + ; below will be captured + +(import m1) + +(let-syntax ((s1 (syntax-rules () ((_ x) x)))) + (assert (equal? '#((99)) (s2 99)))) +Trap