0.8.4.23:
[sbcl.git] / src / pcl / fngen.lisp
index 9c74f49..e4c6697 100644 (file)
 ;;;; specification.
 
 (in-package "SB-PCL")
-
-(sb-int:file-comment
-  "$Header$")
 \f
-;;; GET-FUNCTION is the main user interface to this code. It is like
-;;; COMPILE-LAMBDA, only more efficient. It achieves this efficiency by
+;;; GET-FUN is the main user interface to this code. It is like
+;;; COMPILE, only more efficient. It achieves this efficiency by
 ;;; reducing the number of times that the compiler needs to be called.
-;;; Calls to GET-FUNCTION in which the lambda forms differ only by constants
-;;; can use the same piece of compiled code. (For example, dispatch dfuns and
-;;; combined method functions can often be shared, if they differ only
-;;; by referring to different methods.)
+;;; Calls to GET-FUN in which the lambda forms differ only by
+;;; constants can use the same piece of compiled code. (For example,
+;;; dispatch dfuns and combined method functions can often be shared,
+;;; if they differ only by referring to different methods.)
 ;;;
-;;; If GET-FUNCTION is called with a lambda expression only, it will return
+;;; If GET-FUN is called with a lambda expression only, it will return
 ;;; a corresponding function. The optional constant-converter argument
 ;;; can be a function which will be called to convert each constant appearing
 ;;; in the lambda to whatever value should appear in the function.
 ;;;
 ;;; There are three internal functions which operate on the lambda argument
-;;; to GET-FUNCTION:
-;;;   compute-test converts the lambda into a key to be used for lookup,
-;;;   compute-code is used by get-new-function-generator-internal to
+;;; to GET-FUN:
+;;;   COMPUTE-TEST converts the lambda into a key to be used for lookup,
+;;;   COMPUTE-CODE is used by GET-NEW-FUN-GENERATOR-INTERNAL to
 ;;;            generate the actual lambda to be compiled, and
-;;;   compute-constants is used to generate the argument list that is
+;;;   COMPUTE-CONSTANTS is used to generate the argument list that is
 ;;;            to be passed to the compiled function.
 ;;;
-;;; Whether the returned function is actually compiled depends on whether
-;;; the compiler is present (see COMPILE-LAMBDA) and whether this shape of
-;;; code was precompiled.
-(defun get-function (lambda
-                     &optional (test-converter     #'default-test-converter)
-                               (code-converter     #'default-code-converter)
-                               (constant-converter #'default-constant-converter))
-  (function-apply (get-function-generator lambda test-converter code-converter)
+(defun get-fun (lambda &optional
+                (test-converter #'default-test-converter)
+                (code-converter #'default-code-converter)
+                (constant-converter #'default-constant-converter))
+  (function-apply (get-fun-generator lambda test-converter code-converter)
                  (compute-constants      lambda constant-converter)))
 
-(defun get-function1 (lambda
-                     &optional (test-converter     #'default-test-converter)
-                               (code-converter     #'default-code-converter)
-                               (constant-converter #'default-constant-converter))
-  (values (the function (get-function-generator lambda test-converter code-converter))
-         (compute-constants      lambda constant-converter)))
+(defun get-fun1 (lambda &optional
+                 (test-converter #'default-test-converter)
+                 (code-converter #'default-code-converter)
+                 (constant-converter #'default-constant-converter))
+  (values (the function
+           (get-fun-generator lambda test-converter code-converter))
+         (compute-constants lambda constant-converter)))
 
 (defun default-constantp (form)
   (and (constantp form)
     new))
 
 (defun fgen-test            (fgen) (svref fgen 0))
-(defun fgen-gensyms      (fgen) (svref fgen 1))
-(defun fgen-generator  (fgen) (svref fgen 2))
+(defun fgen-gensyms         (fgen) (svref fgen 1))
+(defun fgen-generator       (fgen) (svref fgen 2))
 (defun fgen-generator-lambda (fgen) (svref fgen 3))
-(defun fgen-system        (fgen) (svref fgen 4))
+(defun fgen-system          (fgen) (svref fgen 4))
 \f
-(defun get-function-generator (lambda test-converter code-converter)
+(defun get-fun-generator (lambda test-converter code-converter)
   (let* ((test (compute-test lambda test-converter))
         (fgen (lookup-fgen test)))
     (if fgen
        (fgen-generator fgen)
-       (get-new-function-generator lambda test code-converter))))
+       (get-new-fun-generator lambda test code-converter))))
 
-(defun get-new-function-generator (lambda test code-converter)
+(defun get-new-fun-generator (lambda test code-converter)
   (multiple-value-bind (gensyms generator-lambda)
-      (get-new-function-generator-internal lambda code-converter)
-    (let* ((generator (compile-lambda generator-lambda))
+      (get-new-fun-generator-internal lambda code-converter)
+    (let* ((generator (compile nil generator-lambda))
           (fgen (make-fgen test gensyms generator generator-lambda nil)))
       (store-fgen fgen)
       generator)))
 
-(defun get-new-function-generator-internal (lambda code-converter)
+(defun get-new-fun-generator-internal (lambda code-converter)
   (multiple-value-bind (code gensyms)
       (compute-code lambda code-converter)
     (values gensyms `(lambda ,gensyms (function ,code)))))
   (let ((*walk-form-expand-macros-p* t))
     (walk-form lambda
               nil
-              #'(lambda (f c e)
-                  (declare (ignore e))
-                  (if (neq c :eval)
-                      f
-                      (let ((converted (funcall test-converter f)))
-                        (values converted (neq converted f))))))))
+              (lambda (f c e)
+                (declare (ignore e))
+                (if (neq c :eval)
+                    f
+                    (let ((converted (funcall test-converter f)))
+                      (values converted (neq converted f))))))))
 
 (defun compute-code (lambda code-converter)
   (let ((*walk-form-expand-macros-p* t)
        (gensyms ()))
     (values (walk-form lambda
                       nil
-                      #'(lambda (f c e)
-                          (declare (ignore e))
-                          (if (neq c :eval)
-                              f
-                              (multiple-value-bind (converted gens)
-                                  (funcall code-converter f)
-                                (when gens (setq gensyms (append gensyms gens)))
-                                (values converted (neq converted f))))))
-             gensyms)))
+                      (lambda (f c e)
+                        (declare (ignore e))
+                        (if (neq c :eval)
+                            f
+                            (multiple-value-bind (converted gens)
+                                (funcall code-converter f)
+                              (when gens (setq gensyms (append gensyms gens)))
+                              (values converted (neq converted f))))))
+           gensyms)))
 
 (defun compute-constants (lambda constant-converter)
-  (let ((*walk-form-expand-macros-p* t)) ; doesn't matter here.
-    (macrolet ((appending ()
-                `(let ((result ()))
-                  (values #'(lambda (value) (setq result (append result value)))
-                   #'(lambda ()result)))))
-      (gathering1 (appending)
-                 (walk-form lambda
-                            nil
-                            #'(lambda (f c e)
-                                (declare (ignore e))
-                                (if (neq c :eval)
-                                    f
-                                    (let ((consts (funcall constant-converter f)))
-                                      (if consts
-                                          (progn (gather1 consts) (values f t))
-                                          f)))))))))
+  (let ((*walk-form-expand-macros-p* t) ; doesn't matter here.
+        collect)
+    (walk-form lambda
+               nil
+               (lambda (f c e)
+                (declare (ignore e))
+                (if (neq c :eval)
+                    f
+                    (let ((consts (funcall constant-converter f)))
+                      (if consts
+                          (progn
+                            (setq collect (append collect consts))
+                            (values f t))
+                          f)))))
+    collect))
 \f
 (defmacro precompile-function-generators (&optional system)
-  (let ((index -1))
-    `(progn ,@(gathering1 (collecting)
-               (dolist (fgen *fgens*)
-                 (when (or (null (fgen-system fgen))
-                           (eq (fgen-system fgen) system))
-                   (when system (setf (svref fgen 4) system))
-                   (gather1
-                    (make-top-level-form
-                     `(precompile-function-generators ,system ,(incf index))
-                     '(:load-toplevel)
-                     `(load-function-generator
-                       ',(fgen-test fgen)
-                       ',(fgen-gensyms fgen)
-                       (function ,(fgen-generator-lambda fgen))
-                       ',(fgen-generator-lambda fgen)
-                       ',system)))))))))
+  `(progn
+    ,@(let (collect)
+        (dolist (fgen *fgens*)
+          (when (or (null (fgen-system fgen))
+                    (eq (fgen-system fgen) system))
+            (when system (setf (svref fgen 4) system))
+            (push `(load-function-generator
+                    ',(fgen-test fgen)
+                    ',(fgen-gensyms fgen)
+                    (function ,(fgen-generator-lambda fgen))
+                    ',(fgen-generator-lambda fgen)
+                    ',system)
+                  collect)))
+        (nreverse collect))))
 
 (defun load-function-generator (test gensyms generator generator-lambda system)
   (store-fgen (make-fgen test gensyms generator generator-lambda system)))
-