[Top][All Lists]

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

[Gcl-devel] Re: reader problem with dot notation

From: Camm Maguire
Subject: [Gcl-devel] Re: reader problem with dot notation
Date: 14 Mar 2006 19:00:21 -0500
User-agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.2

Greetings, and thanks for the report!

I will try to take a look at this soon.  Thought I'd take a moment
here to share a progress report on the compiler typing work.  I should
be committing what I have now shortly.

1) The algorithm used heretofore in 2.7.0 to declare constant let
   bindings, which was exponential in the let binding nesting, has
   been scrapped.  The code is still there for the time being, but
   *dlbsrl* is -1 by default, which prevents it from running.

2) In its place, we have an algorithm as follows:
        1) add new slots to the var structure:
                dt (declared type)
                type (now denotes current type)
                brt  (implied type for this if branch)
                mt (maximum type for the life of the binding
                tag (symbol when a tag is found within the binding, t
                        when finalized, and nil otherwise)
        2) Each new lexical variable has its dt set according to
                explicit declarations (as type was heretofore), then
                sets type and mt to the type of the initializing form
        3) if parses the branch form and determines if a type is
                implied on either branch (i.e. '(if (symbolp x) (branch
                where x is symbol) (branch where x is not symbol)))
                Right now, predicates and '> '>= '< '<= are
                recognized, together with and or and not compounds.
                A stack is made of the original types,
                which are restored using unwind-protect on exit.  Then
                the true branch is processed with the variable types
                type-anded with the implied type, and the false branch
                type-anded with the complement.  If the branch form
                can be determined to return t or nil, the complement branch is
                eliminated from the code.
        4) setq sets the variable type to the setq form, and type-or's
                this type into the maximum type slot mt.  If mt expands,
                and if the tag slot on the variable is set, a
                potential loop is detected, and the modified variable
                is thrown back to the surrounding tagbody processing
                function.  Actually its a bit more involved:  if mt
                expands, first the setq is processed again with the
                new type.  If it expands again, or if the setq form
                refers to variables whose types have not been finalized (as 
                by the tag slot being t), then the variable type is
                set to the nearest "useful-c-type" and thrown
                back to tagbody.
        5) tagbody detects if new bindings with unset tag slots are in
                scope.  If not processing is as normal, otherwise
                processing is done within a catch and loops until no
                variable modifications are received.  Then a final
                pass is done with the new variables tag slot set to
                t.  tag slots are unset on exit.

Compilation is faster, more robust, and now allows for full
optimizations on code like the following without the usual required

(disassemble '(lambda (x y) (declare ((vector long-float) x y)) (let ((z 0.0)) 
(dotimes (i (min (length x) (length y))) (setq z (* (aref x i) (aref y i)))) 
z)) nil) 

(disassemble '(lambda (x) (let ((x (length x))) (do ((i 0 (1+ i))) ((> i x) 
i)))) nil)

All the ansi-tests are the same, and acl2 appears to work at first

Thse modifications lay the infrastructure for significant enhancements
in optimization in the time immediately ahead as we check the type
propagation for various useful functions, write
expanders/compiler-macros for them if needed and rely on the
simplification/branch elimination to prune the result.

This work has been a longstanding goal of mine.  It still needs
cleaning and there are doubtless still bugs, but the basic framework
appears now to be sound.

There are two other outstanding areas for type work in the compiler:

1) centralization of type normalization for performance and
2) A separate pass at the lisp level analyzing reverse type
   propagation and handling these with declaration insertions.  We
   might not have time for this for a while yet.

Anyway, this is be way of apology for falling a bit behind on
correspondence of late.  The benefits may not be immediately apparent
to users, but I feel that in the long run GCL will be stronger with
these facilities in place.

Take care,

Matt Kaufmann <address@hidden> writes:

> Thanks, Bob.
> By the way, Camm, I should have mentioned that it was easy for me to work
> around this problem.
> -- Matt
>    Date: Mon, 13 Mar 2006 17:09:18 -0600
>    From: Robert Boyer <address@hidden>
>    Thanks Matt.
>    Concerning:
>      '(7 . (a .
>              b) ; some comment
>            )
>    For what it is worth, same bug goes back at least to GCL 2.3.8.
>    In 2.7.0, the error report is now:
>     Error in READ [or a callee]: Read error on stream #<synonym stream to
>     *TERMINAL-IO*>: Expecting right parenthesis after dot and object.
>    Bob

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]