; -- Convert to imperative form ---------------------- ; -- This puts it into a form where all of the --------- ; -- recursion can be replaced by assignments and "goto"s (load "chez-init.ss") (define any? (lambda (x) #t)) (define-datatype continuation continuation? ; no changes [init-k] [append-k (a any?) (k continuation?)] [rev1-k (car-L any?) (k continuation?)] [rev2-k (reversed-cdr (list-of any?)) (k continuation?)]) ; global variables take the place of parameters of ; substantial procedures. (define L) ; current list (define k) ; current continuation (define a) ; used for append (define b) ; used for append (define v) ; 2nd parameter of apply-k application ; The next 3 procedures are from the previous file. ; Convert them. (define apply-k (lambda (k v) (cases continuation k [init-k () (printf "answer: ~s~n" v)] [append-k (a k) (apply-k k (cons (car a) v))] [rev1-k (car-L k) (if (pair? car-L) (reverse*-cps car-L (rev2-k v k)) (append-cps v (list car-L) k))] [rev2-k (reversed-cdr k) (append-cps reversed-cdr (list v) k)]))) (define reverse*-cps (lambda (L k) (if (null? L) (apply-k k '()) (reverse*-cps (cdr L) (rev1-k (car L) k))))) (define append-cps (lambda (a b k) (if (null? a) (apply-k k b) (append-cps (cdr a) b (append-k a k))))) ; This driver procedure isn't really substantial, ; So it's okay for it to have a parameter. (define test-reverse (lambda (slist) (set! L slist) (set! k (init-k)) (reverse*-cps))) '(test-reverse '(1 ((2 3) () (((4)))))) (define *tracing* #f) (define trace-it (lambda (sym) (when *tracing* (printf "~a " sym) (printf "L=~s" L) (printf " a=~s" a) (printf " b=~s" b) (printf " v=~s~%" v) (printf " k=~s~%" k))))