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: ;;; 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.
  ;;;
  ;;;; Statement tail protocol 
  ;;;
  ;;; The `*statement-tail*` special variable holds the current state of the statement-tail.
  ;;; The macro `with-statement-tail` adds new statements to the current statement-tail (eg,
  ;;; when entering a new block scope) by prepending them to the current tail.
  ;;;
  ;;; The macro `consume-statement-tail` grabs the current statement-tail and sets it to null
  ;;; to indicate that it has been "used up", and therefore the statements in the tail needn't
  ;;; be processed, because they will have already been processed as part of generating a
  ;;; continuation at an innermore scope.
  ;;;
  ;;; When we're processing return statements, we don't want to include the current tail in
  ;;; any function calls that might be part of the return value.  The `without-statement-tail`
  ;;; macro will suppress the current statement tail (by temporarily binding it to null).
  
  (defparameter *statement-tail* nil
    "Statements following the current statement in the current scope.")
  
  (defmacro with-statement-tail ((new-statements) &body body)
    "Execute BODY with NEW-STATEMENTS prepended to the current statement-tail"
    `(let ((*statement-tail* (append ,new-statements *statement-tail*)))
      ,@body))
  
  (defmacro consume-statement-tail ((tail-symbol) &body body)
    "Set the current statement tail to NIL (signalling that it has been consumed), and
     the execute BODY with TAIL-SYMBOL bound to the original value of *statement-tail*."
    `(let ((,tail-symbol *statement-tail*))
      (setf *statement-tail* nil)
      ,@body))
  
  (defmacro without-statement-tail (&body body)
    "Execute BODY with *STATEMENT-TAIL* bound to NIL"
    `(let ((*statement-tail* nil))
      ,@body))
  
  ;;;; CPS transform methods 
  
  (defmethod transform ((xform (eql 'cps)) (elm function-decl))
    ;; 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)))))
      (without-statement-tail             ; Each function starts with a fresh statement-tail
        (make-function-decl :name (function-decl-name elm)
                            :parameters (cons *cont-name* (function-decl-parameters elm))
                            :body (in-local-scope
                                    (transform 'cps body))))))
  
  
  (defmethod transform ((xform (eql 'cps)) (elm function-expression))
    ;; 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)))))
      (without-statement-tail             ; Each function starts with a fresh statement-tail
        (make-function-expression :name (function-expression-name elm)
                                  :parameters new-parameters
                                  :body (in-local-scope
                                          (transform 'cps body))))))
  
  (defmethod transform ((xform (eql 'cps)) (elm return-statement))
    (with-slots (arg) elm
      (let ((new-fn-call
             (if (fn-call-p arg)
               ;; Tail call
               (without-statement-tail
                 (make-fn-call :fn (fn-call-fn arg)
                               :args (cons *cont-id*
                                           (mapcar (lambda (item)
                                                     (transform 'cps item))
                                                   (fn-call-args arg)))))
               ;; Simple return
               (without-statement-tail
                 (make-fn-call :fn *cont-id*
                               :args (unless (null (return-statement-arg elm))
                                       (list (transform 'cps (return-statement-arg elm)))))))))
        (make-return-statement :arg new-fn-call))))
  
  (defun make-void-continuation (current-cont)
    "Returns a function expression that accepts an argument (which it ignores),
  
negative.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 TX-CPS (VAR-DECL-STATEMENT T)).  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 TX-CPS (RETURN-STATEMENT T)).
  (defmethod tx-cps ((elm fn-call) statement-tail)
    (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)
                                    (tx-cps item nil))
                                  (fn-call-args elm))))
  
             ;; Call w/statement-tail
             (make-fn-call
              :fn (fn-call-fn elm)
              :args (cons (make-continuation-function :parameters (list (genvar "dummy"))
                                                      :body (tx-cps statement-tail nil))
                            (mapcar (lambda (item)
                                      (tx-cps item nil))
                                    (fn-call-args elm)))))))
      (if *in-local-scope*
        (values (make-return-statement :arg new-fn-call) t)
        (values new-fn-call t))))
  
  (defmethod tx-cps ((elm-list list) statement-tail)
    (unless (null elm-list)
      ;; Transform the first source element with the rest prepended to the statement tail.
      (multiple-value-bind (head consumed)
          (tx-cps (car elm-list) (append (cdr elm-list) statement-tail))
        
        ;; Guarantee that HEAD is a list
        (unless (listp head)
          (setf head (list head)))
        
        ;; If the statement tail was consumed, then the incoming STATEMENT-TAIL was consumed,
        ;; so return T as our second return value.  The CDR of elm-list was also consued,
        ;; so don't recurse.
        ;;
        ;; If the statement tail wasn't consumed, then pass the same statement tail to
        ;; the recursive call.
        (if consumed
          (values head t)
          (multiple-value-bind (tail recursive-consumed)
              (tx-cps (cdr elm-list) statement-tail)
            (values (append head tail) recursive-consumed))))))
  
  (defmethod tx-cps ((elm var-decl-statement) statement-tail)
    ;; 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))))
  
        (if (fn-call-p initializer)
          (let ((new-call (make-fn-call :fn (fn-call-fn initializer)
                                        :args (cons
                                               (make-continuation-function :parameters (list name)
                                                                           :body (tx-cps statement-tail nil))
                                               (fn-call-args initializer)))))
            (values (make-return-statement :arg new-call) t))
          (multiple-value-bind (new-decl consumed)
              (tx-cps (car var-decls) statement-tail)
            (values (make-var-decl-statement :var-decls (list new-decl))
                    consumed))))))
    
  ;;TODO This transformation potentially doubles the size of the code, since the
  ;; statement-tail may be incorporated in both the then and else clauses. This
  ;; about refactoring after we're 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.
  (defmethod tx-cps ((elm if-statement) statement-tail)
    (let ((new-cond (tx-cps (if-statement-condition elm) nil)))
      (multiple-value-bind (new-then then-consumed)
          (tx-cps (if-statement-then-statement elm) statement-tail)
        (multiple-value-bind (new-else else-consumed)
            (tx-cps (if-statement-else-statement elm) statement-tail)
          (values
           (make-if-statement :condition new-cond
                              :then-statement new-then
                              :else-statement new-else)
           (and then-consumed else-consumed))))))
  
  ;;;================================================================================
  ;;;; function_continuation transformation
  
  (defmethod tx-cps ((elm special-value) statement-tail)
    (if (eq :function_continuation
            (special-value-symbol elm))
      (values *cont-id* nil)
      (call-next-method)))
  
  ;;;================================================================================
  ;;;; loop transformation
  
  ;; while loops only
  