[armedbear-cvs] r11786 - trunk/abcl/src/org/armedbear/lisp

Erik Huelsmann ehuelsmann at common-lisp.net
Sun Apr 26 07:08:44 UTC 2009


Author: ehuelsmann
Date: Sun Apr 26 03:08:43 2009
New Revision: 11786

Log:
Add support for non-constant initforms on functions.

This fixes DEFUN.6, DEFUN.7, LABELS.7C and LABELS.7D.


Modified:
   trunk/abcl/src/org/armedbear/lisp/precompiler.lisp

Modified: trunk/abcl/src/org/armedbear/lisp/precompiler.lisp
==============================================================================
--- trunk/abcl/src/org/armedbear/lisp/precompiler.lisp	(original)
+++ trunk/abcl/src/org/armedbear/lisp/precompiler.lisp	Sun Apr 26 03:08:43 2009
@@ -353,6 +353,7 @@
 
 (declaim (ftype (function (t) t) precompile1))
 (defun precompile1 (form)
+;;  (sys::%format t "~S~%" form)
   (cond ((symbolp form)
          (let ((varspec (find-varspec form)))
            (cond ((and varspec (eq (second varspec) :symbol-macro))
@@ -599,6 +600,30 @@
           (rewrite-aux-vars-process-decls decls (lambda-list-names lambda-list) aux-vars)
         `(lambda ,lambda-list , at lambda-decls (let* ,lets , at let-decls , at body))))))
 
+#|
+(defun split-declarations (related-symbols decls)
+  "Splits IGNORE, IGNORABLE, DYNAMIC-EXTENT, TYPE, FTYPE and <type-specifier>
+into the declarations related to `related-symbols' and the rest."
+  ;; IGNORE, IGNORABLE and DYNAMIC-EXTENT have the same format
+  (let (related-decls other-decls)
+    (dolist (decl-form decls)
+      (dolist (decl (cdr decl-form))
+        (case (car decl)
+          ((IGNORE IGNORABLE DYNAMIC-EXTENT SPECIAL)
+           (let (rel oth)
+             
+           ...)
+          ((TYPE FTYPE) ;; FUNCTION?
+           ...)
+          ((INLINE NOTINLINE OPTIMIZE DECLARATION)
+           (push decl other-decls))
+          (t
+           (if (symbolp (car decl)) ;; a type specifier
+               ...
+               (push decl other-decls))))))
+    (values related-decls other-decls)))
+|#
+
 (defun maybe-rewrite-lambda (form)
   (let* ((lambda-list (cadr form)))
     (when (memq '&AUX lambda-list)
@@ -606,10 +631,64 @@
       (setq lambda-list (cadr form)))
     (multiple-value-bind (body decls doc)
         (parse-body (cddr form))
-        `(lambda ,lambda-list , at decls ,@(when doc `(,doc)) , at body))))
+      (let (state let-bindings symbols new-lambda-list
+            (non-constants 0))
+        (do* ((vars lambda-list (cdr vars))
+              (var (car vars) (car vars)))
+             ((endp vars))
+          (push (car vars) new-lambda-list)
+          (let ((replacement (gensym)))
+            (case var
+              (&optional (setf state :optional))
+              (&key (setf state :key))
+              ((&whole &environment &rest &body &allow-other-keys)
+               ;; do nothing
+               )
+              (t
+               (when (and (atom var)
+                          (eq state :key))
+                 (setf var (list var)))
+               (cond
+                 ((and (atom var)
+                       (neq state :key))
+                  (setf (car new-lambda-list) replacement)
+                  (push (list var replacement)
+                        let-bindings)) ;; do nothing
+                 (t ;; "(x (some-function))" "((:x q) (some-function))"
+                  ;; or even "(x (some-function) x-supplied-p)"
+                  (destructuring-bind
+                        (name &optional (initform nil initform-supplied-p)
+                              (supplied-p nil supplied-p-supplied-p))
+                      var
+                    (when (and initform-supplied-p
+                               (not (constantp initform)))
+                      (incf non-constants))
+                    (let* ((symbol (if (listp name) (second name) name))
+                           (keyword (if (listp name) (car name)
+                                        (intern (symbol-name symbol)
+                                                (find-package "KEYWORD"))))
+                           (supplied-p-replacement
+                            (if supplied-p-supplied-p
+                                supplied-p (gensym))))
+                      (setf (car new-lambda-list)
+                            `(,(if (eq state :key)
+                                   (list keyword replacement) replacement)
+                               nil ,supplied-p-replacement))
+                      (push `(,symbol (if ,supplied-p-replacement
+                                          ,replacement ,initform))
+                            let-bindings)
+                      (push symbol symbols)))))))))
+        (if (zerop non-constants)
+            ;; there was no reason to rewrite...
+            form
+            `(lambda ,(nreverse new-lambda-list)
+               ,@(when doc (list doc))
+               (let* ,(nreverse let-bindings)
+                 , at decls , at body)))))))
 
 (defun precompile-lambda (form)
   (setq form (maybe-rewrite-lambda form))
+;;  (sys::%format t "~S~%" form)
   (let ((body (cddr form))
         (*inline-declarations* *inline-declarations*))
     (process-optimization-declarations body)
@@ -804,9 +883,14 @@
                 (when (find-use name (cddr local))
                   (setf used-p t)
                   (return))
-                ;; Scope of defined function names includes &AUX parameters (LABELS.7B).
-                (let ((aux-vars (cdr (memq '&aux (cadr local)))))
-                  (when (and aux-vars (find-use name aux-vars)
+                ;; Scope of defined function names includes
+                ;; &OPTIONAL, &KEY and &AUX parameters
+                ;; (LABELS.7B, LABELS.7C and LABELS.7D).
+                (let ((vars (or
+                             (cdr (memq '&optional (cadr local)))
+                             (cdr (memq '&key (cadr local)))
+                             (cdr (memq '&aux (cadr local))))))
+                  (when (and vars (find-use name vars)
                              (setf used-p t)
                              (return))))))))
         (unless used-p




More information about the armedbear-cvs mailing list