diff --git a/collects/mzlib/match.ss b/collects/mzlib/match.ss index 6142238779..47d4b74377 100644 --- a/collects/mzlib/match.ss +++ b/collects/mzlib/match.ss @@ -1,25 +1,14 @@ ;; (documentation (name match)) ;;
Pattern Matching Syntactic Extensions for Scheme
 ;;
-;; All bugs or questions concerning this software should be directed to
-;; Bruce Hauman .  The latest version of this software
-;; can be obtained from http://sol.cs.wcu.edu/~bhauman/scheme/pattern.php.
-;;
 ;; Special thanks go out to:
 ;; Robert Bruce Findler for support and bug detection.
 ;; Doug Orleans for pointing out that pairs should be reused while
 ;; matching lists.
 ;;
-;;
 ;; Originally written by Andrew K. Wright, 1993 (wright@research.nj.nec.com)
 ;; which in turn was adapted from code written by Bruce F. Duba, 1991.
 ;;
-;; This software is in the public domain.  Feel free to copy,
-;; distribute, and modify this software as desired.  No warranties
-;; nor guarantees of any kind apply.  Please return any improvements
-;; or bug fixes to bhauman@cs.wcu.edu so that they may be included
-;; in future releases.
-;;
 ;; This macro package extends Scheme with several new expression forms.
 ;; Following is a brief summary of the new forms.  See the associated
 ;; LaTeX documentation for a full description of their functionality.
@@ -128,7 +117,8 @@
    match-equality-test
    exn:misc:match?
    exn:misc:match-value
-   define-match-expander)
+   define-match-expander
+   match:test-no-order)
   
   ;; FIXME: match-helper and match-error should each be split
   ;; into a compile-time part and a run-time part.
@@ -139,7 +129,8 @@
   (require  (prefix plt: "private/match-internal-func.ss")
 	    "private/match-expander.ss"
 	    "private/match-helper.ss"
-	    "private/match-error.ss")
+	    "private/match-error.ss"
+	    "private/test-no-order.ss")
   
   (define-syntax (match-lambda stx)
     (syntax-case stx ()
diff --git a/collects/mzlib/plt-match.ss b/collects/mzlib/plt-match.ss
index c733ac1a44..1c7ba685c4 100644
--- a/collects/mzlib/plt-match.ss
+++ b/collects/mzlib/plt-match.ss
@@ -142,12 +142,14 @@
    exn:misc:match?
    exn:misc:match-value
    match-equality-test
-   define-match-expander) 
+   define-match-expander
+   match:test-no-order) 
   
   (require "private/match-internal-func.ss"
            "private/match-expander.ss"
            "private/match-helper.ss"
-           "private/match-error.ss")
+           "private/match-error.ss"
+	   "private/test-no-order.ss")
   
   )
 
diff --git a/collects/mzlib/private/match-helper.ss b/collects/mzlib/private/match-helper.ss
index 6e7c721851..f68293d2d1 100644
--- a/collects/mzlib/private/match-helper.ss
+++ b/collects/mzlib/private/match-helper.ss
@@ -8,6 +8,8 @@
            "match-error.ss"
            (lib "list.ss"))
   
+  (require (only (lib "1.ss" "srfi") zip unzip2))
+  
   (require-for-template mzscheme)
   
   ;; define a syntax-transformer in terms of a two-argument function  
@@ -33,10 +35,10 @@
     (string->symbol (apply string-append (map data->string l))))
   
   ;;!(function struct-pred-accessors-mutators
-  ;;          (form (struct-pred-accessors-mutators struct-name failure-thunk)
+  ;;          (form (struct-pred-accessors-mutators struct-name)
   ;;                ->
   ;;                (values pred accessors mutators parental-chain))
-  ;;          (contract (syntax-object (any -> void))
+  ;;          (contract (syntax-object)
   ;;                     ->
   ;;                     (values (any -> bool) list list)))
   ;; This function takes a syntax-object that is the name of a structure
@@ -44,8 +46,8 @@
   ;; a predicate for the structure.  The second is a list of accessors
   ;; in the same order as the fields of the structure declaration.  The
   ;; third is a list of mutators for the structure also in the same
-  ;; order.  The last is a list of supertypes of this struct. The
-  ;; failure thunk is invoked if the struct-name is not bound to a
+  ;; order.  The last is a list of supertypes of this struct. An
+  ;; error is raised if the struct-name is not bound to a
   ;; structure.
   (define (struct-pred-accessors-mutators struct-name)
     (define accessors-index 3)
@@ -56,23 +58,31 @@
       (match:syntax-err struct-name 
                         "not a defined structure"))
     (define (local-val sn) (syntax-local-value sn failure-thunk))
-    (define (handle-acc-list l)
-      (reverse (filter (lambda (x) x) l)))
+    ;; accessor/mutator lists are stored in reverse order, and can contain #f
+    ;; we only filter out a mutator if the accessor is also false.
+    ;; this function returns 2 lists of the same length if the inputs were the same length
+    (define (handle-acc/mut-lists accs muts)
+      (let*-values ([(filtered-lists) (filter (lambda (x) (car x)) (zip accs muts))]
+                    [(accs muts) (unzip2 filtered-lists)])
+        (values (reverse accs)
+                (reverse muts))))
+    
     (define (get-lineage struct-name)
       (let ([super (list-ref 
                     (local-val struct-name)
                     super-type-index)])
-        (cond [(equal? super #t) '()]
-              [(equal? super #f) '()] ;; not sure what to do in case where super-type is unknown
+        (cond [(equal? super #t) '()] ;; no super type exists
+              [(equal? super #f) '()] ;; super type is unknown
               [else (cons super (get-lineage super))])))
     (define info-on-struct (local-val struct-name))
     
     (define (get-info info-on-struct)
-      (values (handle-acc-list
-               (list-ref info-on-struct accessors-index))
-              (handle-acc-list
-               (list-ref info-on-struct mutators-index))
-              (list-ref info-on-struct pred-index)))
+      (let-values ([(accs muts)
+                    (handle-acc/mut-lists 
+                     (list-ref info-on-struct accessors-index)
+                     (list-ref info-on-struct mutators-index))])
+        (values accs muts
+                (list-ref info-on-struct pred-index))))
     
     (unless (struct-declaration-info? info-on-struct) (failure-thunk))
     
diff --git a/collects/mzlib/private/render-test-list.scm b/collects/mzlib/private/render-test-list.scm
index 62240df115..a39425f2bd 100644
--- a/collects/mzlib/private/render-test-list.scm
+++ b/collects/mzlib/private/render-test-list.scm
@@ -16,14 +16,17 @@
            "match-expander-struct.ss"
 
            ;; the following are only used by render-test-list
-           "render-helpers.ss")
+           "render-helpers.ss"
+           "test-no-order.ss")
 
   (require-for-syntax "match-helper.ss"
-                      "match-expander-struct.ss")
+                      "match-expander-struct.ss"
+                      "test-no-order.ss")
   
   (require-for-template mzscheme
 			"match-error.ss"
-			"test-no-order.ss")
+			"test-no-order.ss"
+                        "match-helper.ss")
   
    ;; BEGIN SPECIAL-GENERATORS.SCM
 
@@ -1195,7 +1198,7 @@
         "improperly formed hash table pattern"))
       
       ((struct struct-name (fields ...))
-       (identifier? (syntax struct-name))       
+       (identifier? (syntax struct-name))
        (let*-values ([(field-pats) (syntax->list (syntax (fields ...)))]
                      [(num-of-fields) (length field-pats)]
                      [(pred accessors mutators parental-chain)
@@ -1217,7 +1220,8 @@
           (map-append 
              (lambda (cur-pat cur-mutator cur-accessor) 
                (syntax-case cur-pat (set! get!)
-                 [(set! . rest) 
+                 [(set! . rest)
+                  (unless cur-mutator (match:syntax-err cur-pat "Cannot use set! pattern with immutable fields"))
                   (set/get-matcher 'set! ae stx (syntax rest)
                                    #`(lambda (y)
                                        (#,cur-mutator #,ae y)))]