anchor.diff:  ;;;; Preconditions
   ;;; The CPS transform assumes the following:
   ;;; 1. Scope analysis transformation has been performed (and therefore all identifiers are unique)
  -;;; 2. Explicitization transformation has been performed (and therefore all result values are unique)
  +;;; 2. Explicitization transformation has been performed (and therefore all result values have an
  +;;;    explicit and unique name).
  +;;; 3. The loop transformation has been performed, so all loops have been transformed to canonical
  +;;;    while form.
   
   ;; These elements should have been removed by LOOP-TO-FUNCTION
   (forbid-transformation-elements cps (do-statement for for-in))
  
positive.code: ;;; This method only handles function calls where the return value is ignored.
  ;;;
  ;;; Function calls that are the initializers for variable declarations are handled
  ;;; in (METHOD TRANSFORM ((EQL 'CPS) VAR-DECL-STATEMENT)).  Function calls that are
  ;;; assigned to existing variables or used as intermediate values in calculations are
  ;;; transformed to variable-decl initializers in the EXPLICITIZE transformation.
  ;;; Tail calls (ie, those that are the argument to a return statement) are handled
  ;;; in (METHOD TRANSFORM ((EQL 'CPS) RETURN-STATEMENT)).
  (defmethod transform ((xform (eql 'cps)) (elm fn-call))
    (let ((new-fn-call
           (if (null *statement-tail*)
             ;; Tailless call
             (make-fn-call
              :fn (fn-call-fn elm)
              :args (cons (make-void-continuation *cont-id*)
                          (mapcar (lambda (item)
                                    (transform 'cps item))
                                  (fn-call-args elm))))
  
             ;; Call w/statement-tail
             (make-fn-call
              :fn (fn-call-fn elm)
              :args (consume-statement-tail (statement-tail)
                      (cons (make-continuation-function :parameters (list (genvar "dummy"))
                                                        :body (transform 'cps statement-tail))
                            (mapcar (lambda (item)
                                      (transform 'cps item))
                                    (fn-call-args elm))))))))
      (if *in-local-scope*
        (make-return-statement :arg new-fn-call)
        new-fn-call)))
  
  (defmethod transform ((xform (eql 'cps)) (elm-list list))
    (unless (null elm-list)
      (let ((statements-consumed nil)
            (head nil))
  
        ;; Transform the first source element with the rest prepended to the statement tail.
        ;; We keep track of whether this new statement-tail gets consumed (by being set to NIL)
        ;; in a separate flag, because we need to propogate this consumedness (by setting our
        ;; original statement-tail to NIL) /after/ the new statement tail is no longer bound.
        (with-statement-tail ((cdr elm-list))
          (setf head (transform 'cps (car elm-list)))
          (when (null *statement-tail*)
            (setf statements-consumed t)))
        
        ;; Guarantee that HEAD is a list
        (unless (listp head)
          (setf head (list head)))
  
        ;; If the new statement tail was consumed, then it will be incorporated into the
        ;; transformed version of HEAD, so we shouldn't recurse.
        (if statements-consumed
          (progn
            (setf *statement-tail* nil)
            head)
          (append head (transform 'cps (cdr elm-list)))))))
  
  (defmethod transform ((xform (eql 'cps)) (elm var-decl-statement))
    ;; Assuming one decl per statment because that is one of the results of explicitization
    (with-slots (var-decls) elm
      (assert (<= (length var-decls) 1))
      (let ((name (var-decl-name (car var-decls)))
            (initializer (var-decl-initializer (car var-decls))))
        (cond
          ((fn-call-p initializer)
           (consume-statement-tail (statement-tail)
             (let ((new-call  (make-fn-call :fn (fn-call-fn initializer)
                                            :args (cons
                                                   (make-continuation-function :parameters (list name)
                                                                               :body (transform 'cps statement-tail))
                                                   (fn-call-args initializer)))))
               (make-return-statement :arg new-call))))
          (t
           (make-var-decl-statement :var-decls
                                    (mapcar (lambda (item) (transform 'cps item))
                                            var-decls)))))))
    
  (defmethod transform ((xform (eql 'cps)) (elm if-statement))
    (let ((saved-statement-tail *statement-tail*)
          condition
          then-statement post-then-tail
          else-statement)
      
      ;; TODO There must be a nicer way to do this.  Think about refactoring
      ;; after we've done switch statements.
      ;; Specifically, the statement-tail that follows the if statement should
      ;; be assigned to a named continuation function expression and referenced
      ;; that way rather than just being slurped into the continuations for both
      ;; branches of the if.  This isn't lambda-calculus; we don't have to put up
      ;; with exponentially-expanding programs to get a usable CPS form.
      (setf condition (transform 'cps (if-statement-condition elm)))
  
      (setf *statement-tail* saved-statement-tail)
      (setf then-statement (transform 'cps (if-statement-then-statement elm)))
      (setf post-then-tail *statement-tail*)
  
      (setf *statement-tail* saved-statement-tail)
      (setf else-statement (transform 'cps (if-statement-else-statement elm)))
  
      (setf *statement-tail* (or post-then-tail *statement-tail*))
      (make-if-statement :condition condition
                         :then-statement then-statement
                         :else-statement else-statement)))
  
  ;;;; function_continuation transformation
  
  (defmethod transform ((xform (eql 'cps)) (elm special-value))
    (if (eq :function_continuation
            (special-value-symbol elm))
      *cont-id*
      (call-next-method)))
  
  
  ;;;; loop transformation
  
  ;; while loops only
  
negative.code: ;;; Basically, the statement-tail contains all of the statements that should go into a continuation,
  ;;; should we need to generate a continuation at this point.
  ;;;
  
  ;;;================================================================================
  ;;;; TRANSFORM method
  ;;;
  ;;; As with the explicitization transformation, the cps transformation has a fairly
  ;;; complicated protocol, so the TRANSFORM method is just a thin wrapper over the
  ;;; TX-CPS generic function.
  
  (defmethod transform ((xform (eql 'cps)) elm)
    (values
     (tx-cps elm nil)))
      
  ;;;================================================================================
  ;;;; TX-CPS
  ;;;
  ;;; Previously we bound the *STATEMENT-TAIL* special variable in order to provide
  ;;; it to "downstream" functions, but now we pass it as a parameter.
  ;;;
  ;;; The first return value of the TX-CPS function is the transformed source element.
  ;;; The second return value indicates whether the statement-tail has been consumed
  ;;; or not.
  
  (defgeneric tx-cps (elm statement-tail)
    (:documentation
     "Converts ELM (which should be explicitized) into CPS form and returns the
      new version as its first return value.  The second return value is T if
      STATEMENT-TAIL was consumed or NIL otherwise."))
  
  (defmethod tx-cps ((elm function-decl) statement-tail)
    (declare (ignore statement-tail))
    ;; The body has an empty return statement appended if not every control path
    ;; has an explicit return.
    (let ((body (if (explicit-return-p (function-decl-body elm))
                  (function-decl-body elm)
                  (postpend (function-decl-body elm) #s(return-statement)))))
      (values
       (make-function-decl :name (function-decl-name elm)
                           :parameters (cons *cont-name* (function-decl-parameters elm))
                           :body (in-local-scope
                                   (tx-cps body nil))) ; Each function starts with a fresh statement-tail
       nil)))
  
  (defmethod tx-cps ((elm function-expression) statement-tail)
    (declare (ignore statement-tail))
    ;; The body has an empty return statement appended if not every control path
    ;; has an explicit return.
    (let ((new-parameters (cons *cont-name* (function-expression-parameters elm)))
          (body (if (explicit-return-p (function-expression-body elm))
                  (function-expression-body elm)
                  (postpend (function-expression-body elm) #s(return-statement)))))
      (values
       (make-function-expression :name (function-expression-name elm)
                                  :parameters new-parameters
                                  :body (in-local-scope
                                          (tx-cps body nil))) ; Each function starts with a fresh statement-tail
       nil)))
  
  (defmethod tx-cps ((elm return-statement) statement-tail)
    (with-slots (arg) elm
      (let ((new-fn-call
             (if (fn-call-p arg)
               ;; Tail call
               (make-fn-call :fn (fn-call-fn arg)
                             :args (cons *cont-id*
                                         (mapcar (lambda (item)
                                                   (tx-cps item nil))
                                                 (fn-call-args arg))))
               ;; Simple return
               (make-fn-call :fn *cont-id*
                             :args (unless (null (return-statement-arg elm))
                                     (list (tx-cps (return-statement-arg elm) nil)))))))
        (values
         (make-return-statement :arg new-fn-call)
         nil))))
        
  
  (defun make-void-continuation (current-cont)
    "Returns a function expression that accepts an argument (which it ignores),
  