C311 Fall96. Assignment 8 (solution)

;;
;; C311 Assignment 8
;; CPS Transformation (Registers and Stacks)
;; Due F 11/08/96 @ 5:00pm
;;

(define arg1-reg 'ignored)
(define arg2-reg 'ignored)
(define arg3-reg 'ignored)

; 1. list index

(define list-index
  (lambda (a ls)
    (push! 'final-frame)
    (set! arg1-reg a)
    (set! arg2-reg ls)
    (list-index-cps/reg)))

(define list-index-cps/reg
  (lambda ()
    (cond
      [(null? arg2-reg)
       (set! arg1-reg -1)
       (apply-k/reg)]
      [(eq? (car arg2-reg) arg1-reg)
       (set! arg1-reg 0)
       (apply-k/reg)]
      [else
	(push! 'listindex-frame)
	(set! arg2-reg (cdr arg2-reg))
	(list-index-cps/reg)])))


; 2. intersection

(define intersection
  (lambda (s0 s1)
    (push! 'final-frame)
    (set! arg1-reg s0)
    (set! arg2-reg s1)
    (intersection-cps/reg)))

(define intersection-cps/reg
  (lambda ()
    (cond
      [(null? arg1-reg)
       (set! arg1-reg '())
       (apply-k/reg)]
      [(memq (car arg1-reg) arg2-reg)
       (push! arg1-reg)
       (push! 'intersection-frame)
       (set! arg1-reg (cdr arg1-reg))
       (intersection-cps/reg)]
      [else
	(set! arg1-reg (cdr arg1-reg))
	(intersection-cps/reg)])))


; 3 count-parens

(define count-parens
  (lambda (ls)
    (push! 'final-frame)
    (set! arg1-reg ls)
    (count-parens-cps/reg)))

(define count-parens-cps/reg
  (lambda ()
    (cond
      [(null? arg1-reg)
       (set! arg1-reg 2)
       (apply-k/reg)]
      [(list? (car arg1-reg))
       (push! arg1-reg)
       (push! 'countparens-frame)
       (set! arg1-reg (car arg1-reg))
       (count-parens-cps/reg)]
      [else
	(set! arg1-reg (cdr arg1-reg))
	(count-parens-cps/reg)])))


; 4 depth

(define depth
  (lambda (ls)
    (push! 'final-frame)
    (set! arg1-reg ls)
    (depth-cps/reg)))

(define depth-cps/reg
  (lambda ()
    (cond
      [(null? arg1-reg)
       (set! arg1-reg 1)
       (apply-k/reg)]
      [(pair? arg1-reg)
       (push! arg1-reg)
       (push! 'depth-frame)
       (set! arg1-reg (car arg1-reg))
       (depth-cps/reg)]
      [else
	(set! arg1-reg 0)
       	(apply-k/reg)])))


; vector-index

(define vector-index
  (lambda (a v)
    (push! 'final-frame)
    (set! arg1-reg a)
    (set! arg2-reg v)
    (vector-index-cps/reg)))

(define vector-index-cps/reg
  (lambda ()
    (let ([vlen (vector-length arg2-reg)])
      (letrec ([vindex-hlp-cps/reg
		 (lambda ()
		   (cond
		     [(= vlen arg3-reg)
		      (set! arg1-reg -1)
		      (apply-k/reg)]
		     [(eq? (vector-ref arg2-reg arg3-reg) arg1-reg)
		      (set! arg1-reg arg3-reg)
		      (apply-k/reg)]
		     [else
		       (set! arg3-reg (add1 arg3-reg))
		       (vindex-hlp-cps/reg)]))])
	(set! arg3-reg 0)
	(vindex-hlp-cps/reg)))))

;;
;; apply-k
;;

(define apply-k/reg
  (lambda ()
    (let ([frame-tag (top)])
      (pop!)
      (case frame-tag
	(listindex-frame
	  (if (= arg1-reg -1)
	      (apply-k/reg)
	      (begin
		(set! arg1-reg (add1 arg1-reg))
		(apply-k/reg))))
	(intersection-frame
	  (let ([s0 (top)])
	    (pop!)
	    (set! arg1-reg (cons (car s0) arg1-reg))
	    (apply-k/reg)))
	(countparens-frame
	  (let ([ls (top)])
	    (pop!)
	    (push! arg1-reg)
	    (push! 'countparens2-frame)
	    (set! arg1-reg (cdr ls))
	    (count-parens-cps/reg)))
	(countparens2-frame
	  (let ([v-car (top)])
	    (pop!)
	    (set! arg1-reg  (+ v-car arg1-reg))
	    (apply-k/reg)))
	(depth-frame
	  (let ([ls  (top)])
	    (pop!)
	    (push! arg1-reg)
	    (push! 'depth2-frame)
	    (set! arg1-reg (cdr ls))
	    (depth-cps/reg)))
	(depth2-frame
	  (let ([v-car (top)])
	    (pop!)
	    (set! arg1-reg (max (add1 v-car) arg1-reg))
	    (apply-k/reg)))
	(final-frame ()
	  arg1-reg)
	(else (error 'apply-k "invalid continuation ~s" frame))))))


;;
;;  stack
;;

(define empty? 'ignored)
(define push!  'ignored)
(define pop!   'ignored)
(define top    'ignored)
(let ([stack '()])
  (set! empty?
	(lambda ()
		(null? stack)))
  (set! push!
	(lambda (x)
	  (set! stack (cons x stack))))
  (set! pop!
	(lambda ()
	  (if (empty?)
	      (error 'stack-pop "stack is empty")
	      (set! stack (cdr stack)))))
  (set! top
	(lambda ()
	  (if (empty?)
	      (error 'stack-top "stack is empty")
	      (car stack)))))


Last modified on Thu Nov 7 10:48:45 1996