Update of /project/cl-unification/cvsroot/cl-unification
In directory common-lisp.net:/tmp/cvs-serv23912
Modified Files:
match-block.lisp
Log Message:
Added MATCH-CASE macro. Slightly modified from the version provided
by Peter Scott.
Date: Wed Apr 27 22:41:56 2005
Author: mantoniotti
Index: cl-unification/match-block.lisp
diff -u cl-unification/match-block.lisp:1.1.1.1 cl-unification/match-block.lisp:1.2
--- cl-unification/match-block.lisp:1.1.1.1 Wed Nov 17 23:19:54 2004
+++ cl-unification/match-block.lisp Wed Apr 27 22:41:56 2005
@@ -126,4 +126,59 @@
))
+
+(defmacro match-case ((object &key errorp default-substitution) &rest clauses)
+ "MATCH-CASE sets up a CASE-like environment for multiple template matching clauses.
+The syntax of MATCH-CASE comprises a number of clauses of the form
+
+ <clause> ::= <regular-clause> | <default-clause>
+ <regular-clause> ::= (<template> &body <forms>)
+ <default-clause> ::= (t &body <forms>)
+ | (otherwise &body <forms>)
+<form> and <forms> are regular Common Lisp forms.
+<template> is a unification template.
+
+The full syntax of MATCHING is
+
+ match-case <object> (&key errorp default-substitution) <clauses>
+
+Each clause evaluates its forms in an environment where the variables
+present in the template are bound lexically. Note that both variable
+names '?FOO' and 'FOO' are bound for convenience.
+
+The values returned by the MATCHING form are those of the last form in
+the first clause that satisfies the match test.
+
+If ERRORP is non-NIL then if none of the regular clauses matches, then
+an error of type UNIFICATION-NON-EXAUSTIVE is signalled, regardless of
+any default clause. Otherwise, the default clause behaves as a
+standard CASE default clause. The default value of ERRORP is NIL.
+"
+ (declare (ignore default-substitution)) ; For the time being.
+ (let* ((object-var (gensym "OBJECT-VAR-"))
+ (otherwise-clause-present-p
+ (member (caar (last clauses)) '(t otherwise)))
+ (non-otherwise-clauses
+ (if otherwise-clause-present-p
+ (butlast clauses)
+ clauses))
+ (otherwise-clause
+ (if otherwise-clause-present-p
+ (first (last clauses))
+ (when errorp
+ `(error 'unification-not-exhaustive))))
+ )
+ (labels ((generate-matchers (clauses)
+ (if (null clauses)
+ otherwise-clause
+ (destructuring-bind (pattern &rest body)
+ (car clauses)
+ `(handler-case (match (,pattern ,object-var)
+ ,@body)
+ (unification-failure ()
+ ,(generate-matchers (cdr clauses))))))))
+ `(let ((,object-var ,object))
+ ,(generate-matchers non-otherwise-clauses)))))
+
+
;;; end of file -- math-blocks.lisp --