DEFMACRO supports extended macro lambda lists
[jscl.git] / jscl.lisp
index 47899f0..03654ed 100644 (file)
--- a/jscl.lisp
+++ b/jscl.lisp
       (make-pathname :type type :directory directory :defaults defaults)
       (make-pathname            :directory directory :defaults defaults)))
 
+;;; BOOTSTRAP MAGIC: We record the macro definitions as lists during
+;;; the bootstrap. Once everything is compiled, we want to dump the
+;;; whole global environment to the output file to reproduce it in the
+;;; run-time. However, the environment must contain expander functions
+;;; rather than lists. We do not know how to dump function objects
+;;; itself, so we mark the list definitions with this object and the
+;;; compiler will be called when this object has to be dumped.
+;;; Backquote/unquote does a similar magic, but this use is exclusive.
+;;;
+;;; Indeed, perhaps to compile the object other macros need to be
+;;; evaluated. For this reason we define a valid macro-function for
+;;; this symbol.
+(defvar *magic-unquote-marker* (gensym "MAGIC-UNQUOTE"))
+(setf (macro-function *magic-unquote-marker*)
+      (lambda (form env)
+        (declare (ignore env))
+        (second form)))
+
 ;;; Compile jscl into the host
 (with-compilation-unit ()
   (dolist (input *source*)
@@ -78,7 +96,6 @@
               (when (plusp (length compilation))
                 (write-string compilation out)))))))
 
-
 (defun dump-global-environment (stream)
   (flet ((late-compile (form)
            (write-string (ls-compile-toplevel form) stream)))
     ;; for the compiler and it can be dumped.
     (dolist (b (lexenv-function *environment*))
       (when (eq (binding-type b) 'macro)
-        (push *magic-unquote-marker* (binding-value b))))
+        (setf (binding-value b) `(,*magic-unquote-marker* ,(binding-value b)))))
     (late-compile `(setq *environment* ',*environment*))
     ;; Set some counter variable properly, so user compiled code will
     ;; not collide with the compiler itself.