gcl-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gcl-devel] Re: possible dotimes enhancement


From: Paul F. Dietz
Subject: Re: [Gcl-devel] Re: possible dotimes enhancement
Date: Tue, 05 Aug 2003 07:41:12 -0500
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.2.1) Gecko/20030225

Camm Maguire wrote:

Greetings!  Paul sorry to bother you again today on this.  How is this
for a dotimes?

=============================================================================
(defmacro dotimes ((var form &optional (val nil)) &rest body
                                                  &aux (temp (gensym)) tdec 
tplus)

;; ;; first check if compiler has info on form in surrounding scope
;; only care about fixnum optimization
;;

  (dolist (v compiler::*vars*)
    (when (and (eq (compiler::var-name v) form) (eq (compiler::var-type v) 
'fixnum))
      (setq tdec `(declare (type fixnum ,temp)))))

Is it guaranteed that two vars with the same name will not be on 
compiler::*vars*?
If not, it could fail on something like this:

   (let ((foo 10))
     (declare (type fixnum foo))
     ...
     (let ((foo -100000000000000))
        (declare (type integer foo))
        ...
        (dotimes (i foo ...)
           ...)))

You should avoid this loop if FORM isn't a symbol, I suspect.

You should abstract out this logic, with some sort of internal
type-inferencing engine.   (compiler::try-to-infer-type <form>)
would look in compiler::*vars* for symbols, but would also recognize
other idioms like (the ... <form>), (f ...) where f has a declared
ftype, etc.  This could be useful in many other places than just
here.

You may also want to macroexpand FORM before doing anything to do.
Add an &environment env argument and do

   (setq form (macroexpand form env))


;; ;; Then check if form has been declared in body
;; only care about fixnum optimization
;;


  (unless tdec
(dolist (v body) (when (eq (car v) 'declare) (let ((vv (cadr v)))
          (when (eq (car vv) 'type)
            (setq vv (cdr vv)))
          (when (eq (car vv) 'fixnum)
            (dolist (vvv (cdr vv))
              (when (eq vvv form)
                (setq tdec `(declare (type fixnum ,temp))))))))))

You need to check that things are conses before you take their
car/cdr (you wouldn't want to take the car of a docstring, for
example).  Also, (declare ... (fixnum ...) ...) is a valid idiom.

I suggest you write a separate routine that pulls out the declaration
for the variable from a list of declarations, returning the type
and a success flag (again, this could be useful elsewhere).  If
the type is found, used subtypep to determine if it's a fixnum.
(You've essentially replicated this code below; refactor into a routine.)

BTW, I don't think declaring FORM in the body makes sense, does
it?  FORM is not in the scope of dolist, so the free declaration
should not apply to it.


;; ;; Finally check if var has been declared in body
;; only care about fixnum optimization
;; make sure to eval form once in general and check positivity
;;

  (unless tdec
(dolist (v body) (when (eq (car v) 'declare) (let ((vv (cadr v)))
          (when (eq (car vv) 'type)
            (setq vv (cdr vv)))
          (when (eq (car vv) 'fixnum)
            (dolist (vvv (cdr vv))
              (when (eq vvv var)
                (setq tplus t)
                (setq tdec `(declare (type fixnum ,temp))))))))))

See comment above about refactoring.

(when tdec
    (setq body (cons tdec body)))
  (if tplus
      `(let* ((,temp ,form))
         (cond ((plusp ,temp)
                (do* ((,temp ,form) (,var 0 (1+ ,var)))
                     ((>= ,var ,temp) ,val)
                     ,@body))
               (t
                (let ((,var 0))
                  ,val))))
    `(do* ((,temp ,form) (,var 0 (1+ ,var)))
          ((>= ,var ,temp) ,val)
          ,@body)
    ))

You might improve this by having the iteration variable var be separately
assigned on each pass through the loop.  The actual iteration variable could
then be safely declared with a type deduced from the type of FORM.

(do* ((,temp ,form)
      (,tempvar 0 (1+ ,tempvar))
      (,var ,tempvar ,tempvar))
     ((>- ,tempvar ,temp) ,val)
     (declare (type ,tempvar <something here deduced from type of FORM>))
       ,@body))

I don't think you can safely do that on var itself.

        Paul


but





reply via email to

[Prev in Thread] Current Thread [Next in Thread]