Is there a SICP metacircular evaluator that implements call-with-current-continuation

Viewed 92
1 Answers

Because it is a metacircular-evaluator, you can implement call/cc in terms of call/cc.

Just add the following code to ch4-mceval.scm.

(define (call/cc? exp) (tagged-list? exp 'call/cc))
(define (call/cc-e exp) (cadr exp))

(define (throw? exp) (tagged-list? exp 'throw))
(define (throw-k exp) (cadr exp))
(define (throw-v exp) (caddr exp))

(define (evaluate exp env)
  (cond ((self-evaluating? exp) exp)
        ;; ... original code 
        ((call/cc? exp)
         (let ((p (evaluate (call/cc-e exp) env)))
           (call/cc (λ (k) (apply-procedure p (list k))))))
        ((throw? exp)
         (let ((k (evaluate (throw-k exp) env))
               (v (evaluate (throw-v exp) env)))
           (k v)))
        ;; ... original code
        ))

An example of using the call/cc.

(run '(+ 1 (call/cc (lambda (k) (* 10 (throw k 5))))))
;; 6

For simplicity's sake, I created a new special form throw to call the continuation. Here is (throw k 5). However, you can make it support call k directly. It should not be too hard.

Related