[movitz-cvs] CVS movitz/losp/muerte

ffjeld ffjeld at common-lisp.net
Fri Mar 21 00:06:07 UTC 2008


Update of /project/movitz/cvsroot/movitz/losp/muerte
In directory clnet:/tmp/cvs-serv16983

Modified Files:
	eval.lisp 
Log Message:
Support macrolet in eval.


--- /project/movitz/cvsroot/movitz/losp/muerte/eval.lisp	2008/03/20 22:49:28	1.25
+++ /project/movitz/cvsroot/movitz/losp/muerte/eval.lisp	2008/03/21 00:06:07	1.26
@@ -10,7 +10,7 @@
 ;;;; Author:        Frode Vatvedt Fjeld <frodef at acm.org>
 ;;;; Created at:    Fri Oct 19 21:15:12 2001
 ;;;;                
-;;;; $Id: eval.lisp,v 1.25 2008/03/20 22:49:28 ffjeld Exp $
+;;;; $Id: eval.lisp,v 1.26 2008/03/21 00:06:07 ffjeld Exp $
 ;;;;                
 ;;;;------------------------------------------------------------------
 
@@ -39,24 +39,29 @@
   ;; (warn "env: ~S in ~S" var env)
   (find var env :key #'car))
 
-(defun op-env-binding (type env var)
+(defun op-env-binding (env var &rest types)
+  (declare (dynamic-extent types))
   (dolist (binding env)
-    (when (and (eq type (car binding))
-	       (eq var (cadr binding)))
-      (return (cdr binding)))))
+    (when (and (consp (cdr binding))
+	       (eq var (cadr binding))
+	       (or (null types)
+		   (member (car binding) types)))
+      (return binding))))
 
 ;; These are integers because regular (lexical) bindings are never
 ;; named by integers.
 (defconstant +eval-binding-type-flet+ 0)
 (defconstant +eval-binding-type-go-tag+ 1)
 (defconstant +eval-binding-type-block+ 2)
+(defconstant +eval-binding-type-macrolet+ 3)
 
 (defun eval-symbol (form env)
   "3.1.2.1.1 Symbols as Forms"
   (if (symbol-constant-variable-p form)
       (symbol-value form)
     (let ((binding (env-binding env form)))
-      (or (and binding (cdr binding))
+      (if binding
+	  (cdr binding)
 	  (symbol-value form)))))
 
 ;;;  block      let*                  return-from      
@@ -91,8 +96,20 @@
 				(cadr form)
 				form)
 			 env))))
+    ((macrolet)
+     (dolist (macrolet (cadr form))
+       (destructuring-bind (name lambda &body body)
+	   macrolet
+	 (check-type name symbol)
+	 (check-type lambda list)
+	 (push (list* +eval-binding-type-macrolet+
+		      name
+		      (cdr macrolet))
+	       env)))
+     (eval-progn (cddr form)
+		 env))
     ((return-from)
-     (let ((b (op-env-binding +eval-binding-type-block+ env  (cadr form))))
+     (let ((b (cdr (op-env-binding env (cadr form) +eval-binding-type-block+))))
        (unless b (error "Block ~S is not visible." (cadr form)))
        (throw (cdr b)
 	 (eval-form (caddr form) env))))
@@ -126,7 +143,7 @@
      (unwind-protect
 	  (eval-form (second form) env)
        (eval-progn (cddr form) env)))
-    ((macrolet symbol-macrolet let*)
+    ((symbol-macrolet let*)
      (error "Special operator ~S not implemented in ~S." (car form) 'eval))
     (t (eval-funcall form env))))
 
@@ -360,7 +377,7 @@
 (defun eval-function (function-name env)
   (etypecase function-name
     (symbol
-     (let ((binding (op-env-binding +eval-binding-type-flet+ env function-name)))
+     (let ((binding (cdr (op-env-binding env function-name +eval-binding-type-flet+))))
        (or (and binding (cdr binding))
 	   (symbol-function function-name))))
     (list
@@ -420,7 +437,7 @@
 (defun eval-go (form env)
   (declare (ignore))
   (let* ((tag (cadr form))
-	 (b (op-env-binding +eval-binding-type-go-tag+ env tag)))
+	 (b (cdr (op-env-binding env tag +eval-binding-type-go-tag+))))
     (unless b (error "Go-tag ~S is not visible." tag))
     (throw (cdr b) (values tag))))
 
@@ -482,13 +499,26 @@
 
 (defun macroexpand-1 (form &optional env)
   (if (atom form)
-      (values form nil)
-      (let ((macro-function (macro-function (car form))))
-	(if macro-function
-	    (values (funcall *macroexpand-hook* macro-function form env)
-		    t)
-	    (values form
-		    nil)))))
+      (values form nil) ; no symbol-macros yet
+      (let* ((operator (car form))
+	     (macrolet-binding (op-env-binding env operator +eval-binding-type-macrolet+)))
+	(if macrolet-binding
+	    (destructuring-bind (lambda-list &body body)
+		(cddr macrolet-binding)
+	      (let ((expander (lambda (form env)
+				(eval-form `(destructuring-bind (ignore-operator , at lambda-list)
+						',form
+					      (declare (ignore ignore-operator))
+					      , at body)
+					   env))))
+		(values (funcall *macroexpand-hook* expander form env)
+			t)))
+	    (let ((macro-function (macro-function operator)))
+	      (if macro-function
+		  (values (funcall *macroexpand-hook* macro-function form env)
+			  t)
+		  (values form
+			  nil)))))))
 
 (defun macroexpand (form &optional env)
   (do ((expanded-at-all-p nil)) (nil)




More information about the Movitz-cvs mailing list