Assignment Elimination

This transformation eliminates the set! form from the incoming expression, translating it from analyzed form to assignmentless form.

This transformation involves changing all instances of the set! special form to calls to the vector-set! primitive, and shadows all bindings of side-effected variables with bindings of that same variable to a vector containing that variable. Basically, this pass selectively boxes all the assigned variables:

(lambda (x)         ==> (lambda (x)
  '(assigned x)           (let ((x (vector x)))
  (set! x (+ x '1)))        (vector-set! x '0
                              (+ (vector-ref x) '1))))
Of course, let isn't really in our language anymore (except for the one holding the heap literals at the top of the expression), and we have to keep the information about free variables current, so this is the real transformation:
(lambda (x)         ==> (lambda (x)
  '(assigned x)           '(free)
  '(free)                 ((lambda (x)
  (set! x (+ x '1)))         '(free)
                             (vector-set! x '0
                               (+ (vector-ref x '0) '1)))
                           (vector x)))

There are three kinds of expressions that are affected by this transformation:


The procedure assignmentless-form deals with taking off the let expression binding heap-allocated quotations and then putting it back.
(define assignmentless-form 
  (lambda (exp)
    (let ([qdecls (cadr exp)]
	  [subexp (caddr exp)])
      (let ([new-subexp (assignment-convert subexp '())])
	`(let ,qdecls ,new-subexp)))))

(define assignment-convert
  (lambda (exp env)
    (if (not (pair? exp))
	(record-case exp
	  [quote (obj) ... ]
	  [begin (a b) 
	    (let ([a-exp (assignment-convert a env)]
		  [b-exp (assignment-convert b env)])
	      `(begin ,a-exp ,b-exp))]
	  [if (t c a) ... ]
	  [set! (v e) ... ]
	  [lambda (formals poked free body) ... ]
	  [else ... ]))))