Tuesday, October 5, 2010

One Last Patch...

With regards to Compiler Birdie...

Ok, I swore that I'd leave the current compiler be (hoping it be trampled by the new Lisp-based compiler). But in looking (I shouldn't have) in how I handle bindings for special variables in LET, I found a way to stuff in lexical bindings for special parameters. It's not the right way, but it's good enough to let me compile the LOOP macro.

Here's I'm going to do. Let's say that I have a form (lambda (x) (declare (special x)) ..do stuff..). A function application of this lambda would look like:

(let ((#:g42 (some form))) 
  (%function-application the-lambda-reference #:g42)))

At this point, the compile ignores the 'special' declaration - because I didn't bother in the early days. The current compiler would turn this into a Java method call to the function instance with one argument. I propose to add one more transform in the current compiler. When it notices the 'special' declaration, it will the form into this:

(lambda (x) (let ((x x)) (declare (special x)) ..do stuff..)).

The current compiler does know how to deal with a LET binding for special variables. Easy. What's the catch? Not so easy. The elements in the parameter are not being evaluation at the wrong time. If the lambda list looked like:

(lambda (&optional (x 42) (y (- (incf x 42)))) 
  (declare (special x y)) 
  (+ x y))

The function application form would be:

(let ((#:g42 42) (#:g43 (incf x 42))) 
  (%function-application the-lambda-reference #:g42 #:g43)))

The new transform would make the lambda:


(lambda (&optional (x 42) (y (- (incf x 42)))) 
  (let ((x x) (y y)) 
    (declare (special x y)) 
    (+ x y)))


In this instance, x would not be bound until the LET form in the body. So, a quick hack. But not a long-term fix.

No comments:

Post a Comment