Changeset 11786


Ignore:
Timestamp:
04/26/09 07:08:43 (14 years ago)
Author:
ehuelsmann
Message:

Add support for non-constant initforms on functions.

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/abcl/src/org/armedbear/lisp/precompiler.lisp

    r11755 r11786  
    354354(declaim (ftype (function (t) t) precompile1))
    355355(defun precompile1 (form)
     356;;  (sys::%format t "~S~%" form)
    356357  (cond ((symbolp form)
    357358         (let ((varspec (find-varspec form)))
     
    600601        `(lambda ,lambda-list ,@lambda-decls (let* ,lets ,@let-decls ,@body))))))
    601602
     603#|
     604(defun split-declarations (related-symbols decls)
     605  "Splits IGNORE, IGNORABLE, DYNAMIC-EXTENT, TYPE, FTYPE and <type-specifier>
     606into the declarations related to `related-symbols' and the rest."
     607  ;; IGNORE, IGNORABLE and DYNAMIC-EXTENT have the same format
     608  (let (related-decls other-decls)
     609    (dolist (decl-form decls)
     610      (dolist (decl (cdr decl-form))
     611        (case (car decl)
     612          ((IGNORE IGNORABLE DYNAMIC-EXTENT SPECIAL)
     613           (let (rel oth)
     614             
     615           ...)
     616          ((TYPE FTYPE) ;; FUNCTION?
     617           ...)
     618          ((INLINE NOTINLINE OPTIMIZE DECLARATION)
     619           (push decl other-decls))
     620          (t
     621           (if (symbolp (car decl)) ;; a type specifier
     622               ...
     623               (push decl other-decls))))))
     624    (values related-decls other-decls)))
     625|#
     626
    602627(defun maybe-rewrite-lambda (form)
    603628  (let* ((lambda-list (cadr form)))
     
    607632    (multiple-value-bind (body decls doc)
    608633        (parse-body (cddr form))
    609         `(lambda ,lambda-list ,@decls ,@(when doc `(,doc)) ,@body))))
     634      (let (state let-bindings symbols new-lambda-list
     635            (non-constants 0))
     636        (do* ((vars lambda-list (cdr vars))
     637              (var (car vars) (car vars)))
     638             ((endp vars))
     639          (push (car vars) new-lambda-list)
     640          (let ((replacement (gensym)))
     641            (case var
     642              (&optional (setf state :optional))
     643              (&key (setf state :key))
     644              ((&whole &environment &rest &body &allow-other-keys)
     645               ;; do nothing
     646               )
     647              (t
     648               (when (and (atom var)
     649                          (eq state :key))
     650                 (setf var (list var)))
     651               (cond
     652                 ((and (atom var)
     653                       (neq state :key))
     654                  (setf (car new-lambda-list) replacement)
     655                  (push (list var replacement)
     656                        let-bindings)) ;; do nothing
     657                 (t ;; "(x (some-function))" "((:x q) (some-function))"
     658                  ;; or even "(x (some-function) x-supplied-p)"
     659                  (destructuring-bind
     660                        (name &optional (initform nil initform-supplied-p)
     661                              (supplied-p nil supplied-p-supplied-p))
     662                      var
     663                    (when (and initform-supplied-p
     664                               (not (constantp initform)))
     665                      (incf non-constants))
     666                    (let* ((symbol (if (listp name) (second name) name))
     667                           (keyword (if (listp name) (car name)
     668                                        (intern (symbol-name symbol)
     669                                                (find-package "KEYWORD"))))
     670                           (supplied-p-replacement
     671                            (if supplied-p-supplied-p
     672                                supplied-p (gensym))))
     673                      (setf (car new-lambda-list)
     674                            `(,(if (eq state :key)
     675                                   (list keyword replacement) replacement)
     676                               nil ,supplied-p-replacement))
     677                      (push `(,symbol (if ,supplied-p-replacement
     678                                          ,replacement ,initform))
     679                            let-bindings)
     680                      (push symbol symbols)))))))))
     681        (if (zerop non-constants)
     682            ;; there was no reason to rewrite...
     683            form
     684            `(lambda ,(nreverse new-lambda-list)
     685               ,@(when doc (list doc))
     686               (let* ,(nreverse let-bindings)
     687                 ,@decls ,@body)))))))
    610688
    611689(defun precompile-lambda (form)
    612690  (setq form (maybe-rewrite-lambda form))
     691;;  (sys::%format t "~S~%" form)
    613692  (let ((body (cddr form))
    614693        (*inline-declarations* *inline-declarations*))
     
    805884                  (setf used-p t)
    806885                  (return))
    807                 ;; Scope of defined function names includes &AUX parameters (LABELS.7B).
    808                 (let ((aux-vars (cdr (memq '&aux (cadr local)))))
    809                   (when (and aux-vars (find-use name aux-vars)
     886                ;; Scope of defined function names includes
     887                ;; &OPTIONAL, &KEY and &AUX parameters
     888                ;; (LABELS.7B, LABELS.7C and LABELS.7D).
     889                (let ((vars (or
     890                             (cdr (memq '&optional (cadr local)))
     891                             (cdr (memq '&key (cadr local)))
     892                             (cdr (memq '&aux (cadr local))))))
     893                  (when (and vars (find-use name vars)
    810894                             (setf used-p t)
    811895                             (return))))))))
Note: See TracChangeset for help on using the changeset viewer.