gcl-devel
[Top][All Lists]
Advanced

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

Re: [Gcl-devel] dotimes in 2.6.2


From: Camm Maguire
Subject: Re: [Gcl-devel] dotimes in 2.6.2
Date: 30 Jun 2004 14:34:25 -0400
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Greetings, and thanks!  This is most certainly a bug.  I think the
following is the fix we want, still preserving efficiency where we
can:

Index: lsp/gcl_evalmacros.lsp
===================================================================
RCS file: /cvsroot/gcl/gcl/lsp/gcl_evalmacros.lsp,v
retrieving revision 1.3
diff -u -r1.3 gcl_evalmacros.lsp
--- lsp/gcl_evalmacros.lsp      2 Apr 2004 18:42:11 -0000       1.3
+++ lsp/gcl_evalmacros.lsp      30 Jun 2004 18:31:26 -0000
@@ -290,20 +290,23 @@
 ;; of the other argument in the comparison, apparently to symmetrize
 ;; the long integer range.  20040403 CM.
 (defmacro dotimes ((var form &optional (val nil)) &rest body)
-  (cond ((symbolp form)
-        `(cond ((< ,form 0)
-                (let ((,var 0))
-                  (declare (fixnum ,var) (ignorable ,var))
-                  ,val))
-               ((<= ,form most-positive-fixnum)
-                (let ((,form ,form))
-                  (declare (fixnum ,form))
-                  (do* ((,var 0 (1+ ,var))) ((>= ,var ,form) ,val)
-                    (declare (fixnum ,var))
-                    ,@body)))
-               (t 
-                (do* ((,var 0 (1+ ,var))) ((>= ,var ,form) ,val)
-                  ,@body))))
+  (cond
+   ((symbolp form)
+    (let ((temp (gensym)))
+      `(cond ((< ,form 0)
+             (let ((,var 0))
+               (declare (fixnum ,var) (ignorable ,var))
+               ,val))
+            ((<= ,form most-positive-fixnum)
+                 (let ((,temp ,form))
+                   (declare (fixnum ,temp))
+                   (do* ((,var 0 (1+ ,var))) ((>= ,var ,temp) ,val)
+                     (declare (fixnum ,var))
+                     ,@body)))
+                (t 
+                (let ((,temp ,form))
+                  (do* ((,var 0 (1+ ,var))) ((>= ,var ,temp) ,val)
+                    ,@body))))))
        ((constantp form)
         (cond ((< form 0)
                `(let ((,var 0))
@@ -333,6 +336,7 @@
                   (do* ((,var 0 (1+ ,var))) ((>= ,var ,temp) ,val)
                     ,@body))))))))
 
+
 (defmacro declaim (&rest l)
  `(eval-when (compile eval load)
             ,@(mapcar #'(lambda (x) `(proclaim ',x)) l)))
=============================================================================

I'll test and commit to head.  If all goes well, I'll post to the
errata page on the website.  At some perhaps near juncture, we can
role out into 2.6.3.  We can role out sooner rather than later if
someone can figure out an easy time-efficient way to reproduce the
testing achieved for 2.6.2 as reported in the release notes.

Take care,

Mark Saaltink <address@hidden> writes:

> Dear GCL team,
> 
> There is an error in the DOTIMES macro in 2.6.2, as can be seen in
> this example:
> 
> GCL (GNU Common Lisp)  2.6.2 CLtL1   Jun 28 2004 11:02:36
> 
> >(defconstant two 2)
> 
> TWO
> 
> >(defun foo () (dotimes (x two) (print x)))
> 
> FOO
> 
> >(compile 'foo)
> 
> Compiling gazonk0.lsp.
> ; (DEFUN FOO ...) is being compiled.
> ;;; The constant TWO is being bound.
> No FASL generated.
> 
> Error: Cannot open the file NIL..
> 
> 
> The macroexpansion makes the problem clear: TWO gets rebound.  This is
> a bad idea according to both CLtL and the ANSI spec, if I read them
> correctly.
> 
> >>(macroexpand-1 '(dotimes (x two) (print x)))
> 
> (COND
>   ((< TWO 0) (LET ((X 0)) (DECLARE (FIXNUM X) (IGNORABLE X)) NIL))
>   ((<= TWO MOST-POSITIVE-FIXNUM)
>    (LET ((TWO TWO))                ; <===
>      (DECLARE (FIXNUM TWO))
>      (DO* ((X 0 (1+ X))) ((>= X TWO) NIL)
>        (DECLARE (FIXNUM X))
>        (PRINT X))))
>   (T (DO* ((X 0 (1+ X))) ((>= X TWO) NIL) (PRINT X))))
> 
> 
> Another unexpected outcome arises because of that binding:
> 
> >(defvar x2 2)
> 
> X2
> 
> >(defun bar () (dotimes (x x2) (incf x2)))
> 
> BAR
> 
> >(compile 'bar)
> 
> #<compiled-function BAR>
> 
> >(bar)
> 
> This goes into an infinite loop, which I interrupted:
> 
> Error: Console interrupt.
> Fast links are on: do (si::use-fast-links nil) for debugging
> Error signalled by BAR.
> Broken at SYSTEM:TERMINAL-INTERRUPT.  Type :H for Help.
> 
> >>x2
> 
> 118486967
> 
> The count-form is only supposed to be evaluated once, and the body executed
> that number of times, so this behaviour is something of a surprise.
> 
> Perhaps a gensym should be used for the bound variable in the macro
> expansion, so that these problems are avoided.
> 
> Mark
> 
> 
> _______________________________________________
> Gcl-devel mailing list
> address@hidden
> http://lists.gnu.org/mailman/listinfo/gcl-devel
> 
> 
> 

-- 
Camm Maguire                                            address@hidden
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




reply via email to

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