~ 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