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

Re: A whole bunch of bug reports and patches



Trent Lange <lange@CS.UCLA.EDU> writes:
> - Added single-float, double-float, long-float, and short-float to
>   the list of types that ONLY-SIMPLE-TYPES recognizes, to allow
>   loop variables to use them as type specs.

Well, page 743 of CLtL2 says that the ``of-type'' can be left out if
the type spec contains only uses of fixnum, float, t, nil.  I guess
enumerating the subtypes of float is reasonable.

> - Modified PARSE-REPEAT to declare the temporary variable used in
>   the REPEAT iteration construct as type fixnum (where before it
>   was undeclared).  Because the user's count form might not be a fixnum,
>   PARSE-REPEAT also sets up the form to check that, using the FLOOR of
>   its value if it is not.

But it might be larger than MOST-POSITIVE-FIXNUM.

> - Optimized the forms produced by PARSE-ACCUMULATION in a number of ways:
> 
>     - Modified the COUNT, COUNTING, SUM, and SUMMING forms to pick
>       the initial value using PICK-DEFAULT-VALUE rather than 0
>       (eliminating a compiler warning when their types were non-fixnum.
> 
>     - The MAXIMIZE and MAXIMIZING forms were very slow because their
>       accumulation variables used NIL to represent their value when
>       the forms had not yet been evaluated.  This stopped the compiler
>       from allocating fixnum or single-float registers for them, and
>       required that it be checked for NIL every time the MAXIMIZE form
>       was evaluated.  I modified this to use the most negative possible
>       value for the type-spec (from new function PICK-MOST-NEGATIVE-VALUE)
>       as the initial value of the accumulation variable, when possible.
>       The MAXIMIZE form check then just checks to see if the evaluated
>       form is > than the accumulation variable, which it will definitely
>       be than the initial most-negative value, rather than having to
>       also check for NIL.  When PICK-MOST-NEGATIVE-VALUE cannot find
>       the most-negative possible value of the type (e.g. for 'number),
>       the old method of using NIL as the initial value is used.
>       The new definition also defines the type of the temporary variable
>       ,Temp.
> 
>     - Also modified the MINIMIZE and MINIMIZING forms in the same way,
>       only using the new PICK-MOST-POSITIVE-VALUE.

Sounds good.

I'll add these patches to our sources.

> ========================================================================
> While on the subject of the LOOP macro, there were also a couple of
> bugs which I didn't try to come up with patches for:
> 
> --------
> WHILE clauses cause loop parser to go haywire when placed before
>       other LOOP constructs (FOR and WITH), though it works fine when
>       placed afterwards.

But that IS what the spec says.  From CLtL2, p. 714:

    loop ::= (LOOP [ NAMED name] {variables}* {main}*)

So your variable stuff must come before the while/until stuff.

[Okay, Okay, I'll make it more forgiving.]

> Very strange type checking error for LOOP macro:
> 
> * (proclaim '(optimize (speed 0)(safety 3)))
> 
> EXTENSIONS::%UNDEFINED%
> 
> * (defun test9 () (loop for j fixnum in '(1 2 3) collect j))
> 
> TEST9
> * (compile *)
> Compiling FUNCTION LAMBDA: 
> Compiling Top-Level Form: 
> 
> TEST9
> NIL
> NIL
> * (test9)
> 
> Type-error in TEST9:
>   NIL is not of type FIXNUM

The problem is that it pops the last value off the list, sets j to
(car nil), then tests to see if the list is empty.

I could change it to move the endp test before assigning J, but what
would I do for the first iteration?  I would have to decide there was
nothing to do before J was ever bound.  But it's not clear that the
LOOP semantics allow that.  Ack.

-William Lott
CMU Common Lisp Group