There is source to a SICP metacircular evaluator can be found at https://mitpress.mit.edu/sites/default/files/sicp/code/ch4-mceval.scm
Does anyone know of mceval that includes an implementation of call-with-current-continuation?
There is source to a SICP metacircular evaluator can be found at https://mitpress.mit.edu/sites/default/files/sicp/code/ch4-mceval.scm
Does anyone know of mceval that includes an implementation of call-with-current-continuation?
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.