Lexical Variable Transformation

The final pass before code-generation has, as its only job, to deal with variables and lambdas.

It converts each variable reference into a ``free reference'' or a ``bound reference'', depending on whether the variable is found in the immediately-enclosing lambda or not. This reference includes the index into either the formals list of the immediately-enclosing lambda, or into the free variables list.

It converts lambda expressions into ``build-closure'' expressions:

(build-closure (lambda formals body)
  free-reference ...)
These expressions can be viewed much like calls to the primitive vector (so ``build-closure'' could be considered to be an inlined primitive). build-closure takes as its first ``argument'' an old-style lambda expression, and as its second and further arguments it takes ``references'' to the free variables of that lambda expression.

Useful code

(define list-index
  (lambda (v ls)
    (let loop ([ls ls] [acc 0])
        [(null? ls) #f]
        [(eq? (car ls) v) acc]
        [else (loop (cdr ls) (add1 acc))]))))


> (code-generation-form '(cons '1 '2))
(cons '1 '2)
> (code-generation-form '(lambda (x) '(free) x))
(build-closure (lambda (x) (bound 0 x)))
> (code-generation-form '
    (lambda (x) '(free) (lambda (y) '(free x) x)))
  (lambda (x)
    (build-closure (lambda (y) (free 0 x)) (bound 0 x))))
> (code-generation-form 
    '(lambda (x)
       (lambda (y z)
         '(free x)
         (lambda (w) '(free x y z) (w x y z)))))
  (lambda (x)
      (lambda (y z)
          (lambda (w) ((bound 0 w) (free 0 x) (free 1 y) (free 2 z)))
          (free 0 x)
          (bound 0 y)
          (bound 1 z)))
      (bound 0 x))))