Jeremy Siek 4 years ago
parent
commit
3629948c01
1 changed files with 382 additions and 287 deletions
  1. 382 287
      book.tex

+ 382 - 287
book.tex

@@ -1371,26 +1371,25 @@ environment with the result value bound to the variable, using
   (class object%
     (super-new)
     
-    (define/public (interp-exp env)
-      (lambda (e)
-        (match e
-          [(Int n) n]
-          [(Prim 'read '())
-           (define r (read))
-           (cond [(fixnum? r) r]
-                 [else (error 'interp-exp "expected an integer" r)])]
-          [(Prim '- (list e))
-           (define v ((interp-exp env) e))
-           (fx- 0 v)]
-          [(Prim '+ (list e1 e2))
-           (define v1 ((interp-exp env) e1))
-           (define v2 ((interp-exp env) e2))
-           (fx+ v1 v2)]
-          [(Var x) (dict-ref env x)]
-          [(Let x e body)
-           (define new-env (dict-set env x ((interp-exp env) e)))
-           ((interp-exp new-env) body)]
-          )))
+    (define/public ((interp-exp env) e)
+      (match e
+        [(Int n) n]
+        [(Prim 'read '())
+         (define r (read))
+         (cond [(fixnum? r) r]
+               [else (error 'interp-exp "expected an integer" r)])]
+        [(Prim '- (list e))
+         (define v ((interp-exp env) e))
+         (fx- 0 v)]
+        [(Prim '+ (list e1 e2))
+         (define v1 ((interp-exp env) e1))
+         (define v2 ((interp-exp env) e2))
+         (fx+ v1 v2)]
+        [(Var x) (dict-ref env x)]
+        [(Let x e body)
+         (define new-env (dict-set env x ((interp-exp env) e)))
+         ((interp-exp new-env) body)]
+        ))
 
     (define/public (interp-program p)
       (match p
@@ -4367,25 +4366,24 @@ for the \code{and} operation because of its short-circuiting behavior.
 
     (define/public (interp-op op) ...)
 
-    (define/override (interp-exp env)
-      (lambda (e)
-        (define recur (interp-exp env))
-        (match e
-          [(Bool b) b]
-          [(If cnd thn els)
-           (define b (recur cnd))
-           (match b
-             [#t (recur thn)]
-             [#f (recur els)])]
-          [(Prim 'and (list e1 e2))
-           (define v1 (recur e1))
-           (match v1
-             [#t (match (recur e2) [#t #t] [#f #f])]
-             [#f #f])]
-          [(Prim op args)
-           (apply (interp-op op) (for/list ([e args]) (recur e)))]
-          [else ((super interp-exp env) e)]
-          )))
+    (define/override ((interp-exp env) e)
+      (define recur (interp-exp env))
+      (match e
+        [(Bool b) b]
+        [(If cnd thn els)
+         (define b (recur cnd))
+         (match b
+           [#t (recur thn)]
+           [#f (recur els)])]
+        [(Prim 'and (list e1 e2))
+         (define v1 (recur e1))
+         (match v1
+           [#t (match (recur e2) [#t #t] [#f #f])]
+           [#f #f])]
+        [(Prim op args)
+         (apply (interp-op op) (for/list ([e args]) (recur e)))]
+        [else ((super interp-exp env) e)]
+        ))
     ))
 
 (define (interp-R2 p)
@@ -6021,14 +6019,13 @@ otherwise.
         [else (super interp-op op)]
         ))
 
-    (define/override (interp-exp env)
-      (lambda (e)
-        (define recur (interp-exp env))
-        (match e
-          [(HasType e t)  (recur e)]
-          [(Void)  (void)]
-          [else ((super interp-exp env) e)]
-          )))
+    (define/override ((interp-exp env) e)
+      (define recur (interp-exp env))
+      (match e
+        [(HasType e t)  (recur e)]
+        [(Void)  (void)]
+        [else ((super interp-exp env) e)]
+        ))
     ))
 
 (define (interp-R3 p)
@@ -7360,26 +7357,25 @@ update the \code{lambda} values to use the top-level environment.
   (class interp-R3-class
     (super-new)
 
-    (define/override (interp-exp env)
-      (lambda (e)
-        (define recur (interp-exp env))
-        (match e
-          [(Var x) (unbox (dict-ref env x))]
-          [(Let x e body)
-           (define new-env (dict-set env x (box (recur e))))
-           ((interp-exp new-env) body)]
-          [(Apply fun args)
-           (define fun-val (recur fun))
-           (define arg-vals (for/list ([e args]) (recur e)))
-           (match fun-val
-             [`(function (,xs ...) ,body ,fun-env)
-              (define params-args (for/list ([x xs] [arg arg-vals])
-                                    (cons x (box arg))))
-              (define new-env (append params-args fun-env))
-              ((interp-exp new-env) body)]
-             [else (error "interp-exp, expected function, not ~a" fun-val)])]
-          [else ((super interp-exp env) e)]
-          )))
+    (define/override ((interp-exp env) e)
+      (define recur (interp-exp env))
+      (match e
+        [(Var x) (unbox (dict-ref env x))]
+        [(Let x e body)
+         (define new-env (dict-set env x (box (recur e))))
+         ((interp-exp new-env) body)]
+        [(Apply fun args)
+         (define fun-val (recur fun))
+         (define arg-vals (for/list ([e args]) (recur e)))
+         (match fun-val
+           [`(function (,xs ...) ,body ,fun-env)
+            (define params-args (for/list ([x xs] [arg arg-vals])
+                                  (cons x (box arg))))
+            (define new-env (append params-args fun-env))
+            ((interp-exp new-env) body)]
+           [else (error 'interp-exp "expected function, not ~a" fun-val)])]
+        [else ((super interp-exp env) e)]
+        ))
 
     (define/public (interp-def d)
       (match d
@@ -8620,7 +8616,29 @@ values.
 
 \begin{figure}[tbp]
 \begin{lstlisting}
-UPDATE ME
+(define interp-R5-class
+  (class interp-R4-class
+    (super-new)
+
+    (define/override (interp-op op)
+      (match op
+        ['procedure-arity
+         (lambda (v)
+           (match v
+             [`(function (,xs ...) ,body ,lam-env)  (length xs)]
+             [else (error 'interp-op "expected a function, not ~a" v)]))]
+        [else (super interp-op op)]))
+
+    (define/override ((interp-exp env) e)
+      (define recur (interp-exp env))
+      (match e
+        [(Lambda (list `[,xs : ,Ts] ...) rT body)
+         `(function ,xs ,body ,env)]
+        [else ((super interp-exp env) e)]))
+    ))
+
+(define (interp-R5 p)
+  (send (new interp-R5-class) interp-program p))
 \end{lstlisting}
 \caption{Interpreter for $R_5$.}
 \label{fig:interp-R5}
@@ -9222,36 +9240,28 @@ and returns the result from \itm{body}.
 
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define (interp-exp env)
-  (lambda (e)
-    (define recur (interp-exp env))
-    (match e
-      [(Var x) (unbox (lookup x env))]
-      [(Let x e body)
-       (define new-env (cons (cons x (box (recur e))) env))
-       ((interp-exp new-env) body)]
-      [(Apply fun args)
-       (define fun-val (recur fun))
-       (define arg-vals (map recur args))
-       (match fun-val
-         [`(function (,xs ...) ,body ,lam-env)
-          (define new-env (append (for/list ([x xs] [arg arg-vals])
-                                       (cons x (box arg)))
-                                    lam-env))
-          ((interp-exp new-env) body)])]
-      [(SetBang x rhs)
-       (set-box! (lookup x env) (recur rhs))]
-      [(WhileLoop cnd body)
-       (define (loop)
-         (cond [(recur cnd)  (recur body) (loop)]
-               [else         (void)]))
-       (loop)]
-      [(Begin es body)
-       (for ([e es]) (recur e))
-       (recur body)]
-      ...
-      [else (error 'interp-exp "unrecognized expression ~a" e)]
-      )))
+(define interp-R8-class
+  (class interp-R6-class
+    (super-new)
+
+    (define/override ((interp-exp env) e)
+      (define recur (interp-exp env))
+      (match e
+        [(SetBang x rhs)
+         (set-box! (lookup x env) (recur rhs))]
+        [(WhileLoop cnd body)
+         (define (loop)
+           (cond [(recur cnd)  (recur body) (loop)]
+                 [else         (void)]))
+         (loop)]
+        [(Begin es body)
+         (for ([e es]) (recur e))
+         (recur body)]
+        [else ((super interp-exp env) e)]))
+    ))
+
+(define (interp-R8 p)
+  (send (new interp-R8-class) interp-program p))
 \end{lstlisting}
 \caption{Interpreter for $R_8$.}
 \label{fig:interp-R8}
@@ -9266,31 +9276,35 @@ variable and the right-hand-side must agree. The result type is
 
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define (type-check-R8 env)
-  (lambda (e)
-    (match e
-      [(SetBang x rhs)
-       (define-values (rhs^ rhsT) (recur rhs))
-       (define varT (dict-ref env x))
-       (unless (type-equal? rhsT varT)
-         (error 'type-check-exp
-                "variable and RHS of set! have different type, ~a != ~a"
-                varT rhsT))
-       (values (SetBang x rhs^) 'Void)]
-      [(WhileLoop cnd body)
-       (define-values (cnd^ Tc) (recur cnd))
-       (unless (type-equal? Tc 'Boolean)
-         (error 'type-check-exp
-                "expected Boolean in condition of if, not ~a" Tc))
-       (define-values (body^ Tbody) ((type-check-exp env) body))
-       (values (WhileLoop cnd^ body^) 'Void)]
-      [(Begin es body)
-       (define-values (es^ ts)
-         (for/lists (l1 l2) ([e es]) (recur e)))
-       (define-values (body^ Tbody) (recur body))
-       (values (Begin es^ body^) Tbody)]
-      ...
-      )))
+(define type-check-R8-class
+  (class type-check-R6-class
+    (super-new)
+    (inherit check-type-equal?)
+
+    (define/override (type-check-exp env)
+      (lambda (e)
+        (define recur (type-check-exp env))
+        (match e
+          [(SetBang x rhs)
+           (define-values (rhs^ rhsT) (recur rhs))
+           (define varT (dict-ref env x))
+           (check-type-equal? rhsT varT e)
+           (values (SetBang x rhs^) 'Void)]
+          [(WhileLoop cnd body)
+           (define-values (cnd^ Tc) (recur cnd))
+           (check-type-equal? Tc 'Boolean e)
+           (define-values (body^ Tbody) ((type-check-exp env) body))
+           (values (WhileLoop cnd^ body^) 'Void)]
+          [(Begin es body)
+           (define-values (es^ ts)
+             (for/lists (l1 l2) ([e es]) (recur e)))
+           (define-values (body^ Tbody) (recur body))
+           (values (Begin es^ body^) Tbody)]
+          [else ((super type-check-exp env) e)])))
+    ))
+
+(define (type-check-R8 p)
+  (send (new type-check-R8-class) type-check-program p))
 \end{lstlisting}
 \caption{Type checking \key{SetBang}, \key{WhileLoop},
     and \code{Begin} in $R_8$.}
@@ -10321,58 +10335,52 @@ The type predicates such as $\LP\key{boolean?}\,e\RP$ expect the
 expression $e$ to produce a tagged value; they return \key{\#t} if the
 tag corresponds to the predicate and they return \key{\#f} otherwise.
 
-The type checker for $R_6$ is shown in Figures~\ref{fig:type-check-R6-part-1}
-and \ref{fig:type-check-R6-part-2}.
-The interpreter for $R_6$ is in Figure~\ref{fig:interp-R6}.
+The type checker for $R_6$ is shown in
+Figures~\ref{fig:type-check-R6-part-1} and
+\ref{fig:type-check-R6-part-2} and uses the auxiliary functions in
+Figure~\ref{fig:type-check-R6-aux}.
+%
+The interpreter for $R_6$ is in Figure~\ref{fig:interp-R6} and the
+auxiliary function \code{apply-project} is in Figure~\ref{fig:apply-project}.
+
 
 \begin{figure}[btp]
  \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define (operator-types)
-  '(...
-    (integer? . ((Any) . Boolean))
-    (vector? . ((Any) . Boolean))
-    (procedure? . ((Any) . Boolean))
-    (void? . ((Any) . Boolean))
-    ))
-    
-(define (type-check-exp env)
-  (lambda (e)
-    (define recur (type-check-exp env))
-    (match e
-      ...  
-      [(Inject e ty)
-       (unless (flat-ty? ty)
-         (error 'type-check-exp
-                "may only inject a value of flat type, not ~a" ty))
-       (define-values (new-e e-ty) (recur e))
-       (cond
-        [(type-equal? e-ty ty)
-         (values (Inject new-e ty) 'Any)]
-        [else
-         (error 'type-check-exp
-                "injected expression does not have expected type" 
-                e e-ty ty)])]
-      [(Project e ty)
-       (unless (flat-ty? ty)
-         (error 'type-check-exp
-                "may only project to a flat type, not ~a" ty))
-       (define-values (new-e e-ty) (recur e))
-       (cond
-         [(type-equal? e-ty 'Any)
-          (values (Project new-e ty) ty)]
-        [else
-         (error 'type-check-exp
-                "project expression does not have type Any" e)])]
-      [(Prim pred (list e))
-       #:when (set-member? type-predicates pred)
-       (define-values (new-e e-ty) (recur e))
-       (cond
-         [(type-equal? e-ty 'Any)
-          (values (Prim pred (list new-e)) 'Boolean)]
-         [else
-          (error 'type-check-exp
-                 "type predicate expected argument of type Any, not ~a" e-ty)])]
-      ...
+(define type-check-R6-class
+  (class type-check-R5-class
+    (super-new)
+    (inherit check-type-equal?)
+
+    (define/override (type-check-exp env)
+      (lambda (e)
+        (define recur (type-check-exp env))
+        (match e
+          [(If cnd thn els)
+           (define-values (cnd^ Tc) (recur cnd))
+           (define-values (thn^ Tt) (recur thn))
+           (define-values (els^ Te) (recur els))
+           (check-type-equal? Tc 'Boolean cnd)
+           (check-type-equal? Tt Te e)
+           (values (If cnd^ thn^ els^) (combine-types Tt Te))]
+          [(Prim 'vector-length (list e))
+           (define-values (e^ t) (recur e))
+           (match t
+             [(or `(Vector ,_ ...) `(Vectorof ,_))
+              (values (Prim 'vector-length (list e^))  'Integer)]
+             [else (error 'type-check "expected a vector, not ~a\nin ~v" t e)])]
+          [(Prim 'vector-ref (list e1 ei))
+           (define-values (e^ t) (recur e1))
+           (define-values (i it) (recur ei))
+           (check-type-equal? it 'Integer e)
+           (match (list t i)
+             [(list `(Vector ,ts ...) (Int i^))
+              (unless (and (0 . <= . i^) (i^ . < . (length ts)))
+                (error 'type-check-exp "invalid index ~a in ~a" i^ e))
+              (let ([t (list-ref ts i^)])
+                (values (Prim 'vector-ref (list e^ (Int i^))) t))]
+             [(list `(Vectorof ,t) i)
+              (values (Prim 'vector-ref (list e^ i))  t)]
+             [else (error "expected a vector in vector-ref, not" t)])]
 \end{lstlisting}
 \caption{Type checker for the $R_6$ language, part 1.}
 \label{fig:type-check-R6-part-1}
@@ -10380,110 +10388,224 @@ The interpreter for $R_6$ is in Figure~\ref{fig:interp-R6}.
 
 \begin{figure}[btp]
  \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-      [(Prim 'vector-ref (list e ei))
-       (define-values (e^ t) (recur e))
-       (define-values (i it) (recur ei))
-       (unless (type-equal? it 'Integer)
-         (error 'type-check-exp "vector-ref: index not Integer: ~a" it))
-       (match (list t i)
-         [(list `(Vector ,ts ...) (Int i^))
-          (unless (and (exact-nonnegative-integer? i^)
-                       (i^ . < . (length ts)))
-            (error 'type-check-exp "invalid index ~a in ~a" i^ e))
-          (let ([t (list-ref ts i^)])
-            (values (Prim 'vector-ref (list e^ (Int i^))) t))]
-         [(list `(Vectorof ,t) i)
-          (values (Prim 'vector-ref (list e^ i))  t)]
-         [else (error "expected a vector in vector-ref, not" t)])]
-      [(Prim 'vector-set! (list e-vec e-i e-arg))
-       (define-values (e-vec^ t-vec) (recur e-vec))
-       (define-values (i it) (recur e-i))
-       (define-values (e-arg^ t-arg) (recur e-arg))
-       (unless (type-equal? it 'Integer)
-         (error 'type-check-exp "vector-set!: index not Integer: ~a" it))
-       (match (list t-vec i)
-         [(list `(Vector ,ts ...) (Int i^))
-          (unless (and (exact-nonnegative-integer? i^)
-                       (i^ . < . (length ts)))
-            (error 'type-check-exp "invalid index ~a in ~a" i^ e))
-          (unless (type-equal? (list-ref ts i^) t-arg)
-            (error 'type-check-exp "type mismatch in vector-set! ~a ~a" 
-                   (list-ref ts i^) t-arg))
-          (values (Prim 'vector-set! (list e-vec^ (Int i^) e-arg^))  'Void)]
-         [(list `(Vectorof ,t) i)
-          (unless (type-equal? t t-arg)
-            (error 'type-check-exp "type mismatch in vector-set! ~a ~a" 
-                   t t-arg))
-          (values (Prim 'vector-set! (list e-vec^ i e-arg^))  'Void)]
-         [else
-          (error 'type-check-exp "expected a vector in vector-set!, not ~a"
-                 t-vec)])]
-      ...
-      [else 
-       (error 'type-check-exp "R6/unmatched ~a" e)]
-      )))
+          [(Prim 'vector-set! (list e-vec e-i e-arg))
+           (define-values (e-vec^ t-vec) (recur e-vec))
+           (define-values (i it) (recur e-i))
+           (define-values (e-arg^ t-arg) (recur e-arg))
+           (check-type-equal? it 'Integer e)
+           (match (list t-vec i)
+             [(list `(Vector ,ts ...) (Int i^))
+              (unless (and (0 . <= . i^) (i^ . < . (length ts)))
+                (error 'type-check-exp "invalid index ~a in ~a" i^ e))
+              (check-type-equal? (list-ref ts i^) t-arg e)
+              (values (Prim 'vector-set! (list e-vec^ (Int i^) e-arg^)) 'Void)]
+             [(list `(Vectorof ,t) i)
+              (check-type-equal? t t-arg e)
+              (values (Prim 'vector-set! (list e-vec^ i e-arg^)) 'Void)]
+             [else
+              (error 'type-check-exp "expected a vector, not ~a" t-vec)])]
+          [(Inject e1 ty)
+           (unless (flat-ty? ty)
+             (error 'type-check "may only inject from flat type, not ~a" ty))
+           (define-values (new-e1 e-ty) (recur e1))
+           (check-type-equal? e-ty ty e)
+           (values (Inject new-e1 ty) 'Any)]
+          [(ValueOf e ty)
+           (define-values (new-e e-ty) (recur e))
+           (values (ValueOf new-e ty) ty)]
+          [(Project e1 ty)
+           (unless (flat-ty? ty)
+             (error 'type-check "may only project to flat type, not ~a" ty))
+           (define-values (new-e1 e-ty) (recur e1))
+           (check-type-equal? e-ty 'Any e)
+           (values (Project new-e1 ty) ty)]
+          [(Prim pred (list e1))
+           #:when (set-member? (type-predicates) pred)
+           (define-values (new-e1 e-ty) (recur e1))
+           (check-type-equal? e-ty 'Any e)
+           (values (Prim pred (list new-e1)) 'Boolean)]
+          [(Exit)
+           (values (Exit) '_)]
+          [(Prim 'eq? (list arg1 arg2))
+           (define-values (e1 t1) (recur arg1))
+           (define-values (e2 t2) (recur arg2))
+           (match* (t1 t2)
+             ;; allow comparison of vectors of different element types
+             [(`(Vector ,ts1 ...) `(Vector ,ts2 ...))   (void)]
+             [(`(Vectorof ,t1) `(Vectorof ,t2))         (void)]
+             [(other wise) (check-type-equal? t1 t2 e)])
+           (values (Prim 'eq? (list e1 e2)) 'Boolean)]
+          [else ((super type-check-exp env) e)])))
+
+    ))
 \end{lstlisting}
 \caption{Type checker for the $R_6$ language, part 2.}
 \label{fig:type-check-R6-part-2}
 \end{figure}
 
 
+\begin{figure}[tbp]
+\begin{lstlisting}
+    (define/override (operator-types)
+      (append
+       '((integer? . ((Any) . Boolean))
+         (vector? . ((Any) . Boolean))
+         (procedure? . ((Any) . Boolean))
+         (void? . ((Any) . Boolean))
+         (tag-of-any . ((Any) . Integer))
+         (make-any . ((_ Integer) . Any))
+         )
+       (super operator-types)))
+
+    (define/public (type-predicates)
+      (set 'boolean? 'integer? 'vector? 'procedure? 'void?))
+
+    (define/public (combine-types t1 t2)
+      (match (list t1 t2)
+        [(list '_ t2) t2]
+        [(list t1 '_) t1]
+        [(list `(Vector ,ts1 ...)
+               `(Vector ,ts2 ...))
+         `(Vector ,@(for/list ([t1 ts1] [t2 ts2])
+                      (combine-types t1 t2)))]
+        [(list `(,ts1 ... -> ,rt1)
+               `(,ts2 ... -> ,rt2))
+         `(,@(for/list ([t1 ts1] [t2 ts2])
+               (combine-types t1 t2))
+           -> ,(combine-types rt1 rt2))]
+        [else t1]))
+
+    (define/public (flat-ty? ty)
+      (match ty
+        [(or `Integer `Boolean '_ `Void) #t]
+        [`(Vector ,ts ...) (for/and ([t ts]) (eq? t 'Any))]
+        [`(Vectorof Any) #t]
+        [`(,ts ... -> ,rt)
+         (and (eq? rt 'Any) (for/and ([t ts]) (eq? t 'Any)))]
+        [else #f]))
+\end{lstlisting}
+\caption{Auxiliary methods for type checking $R_6$.}
+\label{fig:type-check-R6-aux}
+\end{figure}
+
 % to do: add rules for vector-ref, etc. for Vectorof
 %Also, \key{eq?} is extended to operate on values of type \key{Any}.
 
 \begin{figure}[btp]
 \begin{lstlisting}
-(define (interp-op op)
-  (match op
-    ...
-    ['boolean? (lambda (v)
-		 (match v
-		   [`(tagged ,v1 ,tg)
-                    (equal? tg (any-tag 'Boolean))]
-		   [else #f]))]
-    ['integer? (lambda (v)
-		 (match v
-		   [`(tagged ,v1 ,tg)
-                    (equal? tg (any-tag 'Integer))]
-		   [else #f]))]
-    ['vector? (lambda (v)
-		(match v
-		  [`(tagged ,v1 ,tg)
-                   (equal? tg (any-tag `(Vector Any)))]
-		  [else #f]))]
-    ['procedure? (lambda (v)
-		   (match v
-		     [`(tagged ,v1 ,tg)
-                      (equal? tg (any-tag `(Any -> Any)))]
-		     [else #f]))]
-    ...
+(define interp-R6-class
+  (class interp-R5-class
+    (super-new)
+
+    (define/override (interp-op op)
+      (match op
+        ['boolean? (match-lambda
+                     [`(tagged ,v1 ,tg) (equal? tg (any-tag 'Boolean))]
+                     [else #f])]
+        ['integer? (match-lambda
+                     [`(tagged ,v1 ,tg) (equal? tg (any-tag 'Integer))]
+                     [else #f])]
+        ['vector? (match-lambda
+                    [`(tagged ,v1 ,tg) (equal? tg (any-tag `(Vector Any)))]
+                    [else #f])]
+        ['procedure? (match-lambda
+                       [`(tagged ,v1 ,tg) (equal? tg (any-tag `(Any -> Any)))]
+                       [else #f])]
+        ['eq? (match-lambda*
+                [`((tagged ,v1^ ,tg1) (tagged ,v2^ ,tg2))
+                 (and (eq? v1^ v2^) (equal? tg1 tg2))]
+                [ls (apply (super interp-op op) ls)])]
+        ['make-any (lambda (v tg) `(tagged ,v ,tg))]
+        ['tag-of-any
+         (match-lambda
+           [`(tagged ,v^ ,tg)  tg]
+           [v  (error 'interp-op "expected tagged value, not ~a" v)])]
+        [else (super interp-op op)]))
+
+    (define/override ((interp-exp env) e)
+      (define recur (interp-exp env))
+      (match e
+        [(Inject e ty) `(tagged ,(recur e) ,(any-tag ty))]
+        [(Project e ty2)  (apply-project (recur e) ty2)]
+        [(ValueOf e ty)
+         (match (recur e)
+           [`(tagged ,v^ ,tg)  v^]
+           [v (error 'interp-op "expected tagged value, not ~a" v)])]
+        [(Exit) (error 'interp-exp "exiting")]
+        [else ((super interp-exp env) e)]))
     ))
 
-(define (interp-exp env)
-  (lambda (e)
-    (define recur (interp-exp env))
-    (let ([ret
-           (match e
-             ...
-             [(Inject e ty)
-              (apply-inject ((interp-exp env) e) (any-tag ty))]
-             [(Project e ty2)
-              (define v (recur e))
-              (apply-project v ty2)]
-             [(Exit)
-              (error 'interp-exp "exiting")]
-             [else (error 'interp-exp "unrecognized expression ~a" e)]
-             )])
-      (verbose "R6/interp-exp ==>" ret)
-      ret)))
+(define (interp-R6 p)
+  (send (new interp-R6-class) interp-program p))
 \end{lstlisting}
 \caption{Interpreter for $R_6$.}
 \label{fig:interp-R6}
 \end{figure}
 
+\begin{figure}[tbp]
+\begin{lstlisting}
+(define (apply-project v ty2)
+  (define tag2 (any-tag ty2))
+  (match v
+    [`(tagged ,v1 ,tag1)
+     (cond [(eq? tag1 tag2)
+            (match ty2
+              [`(Vector ,ts ...)
+               (cond [(eq? (vector-length v1) (length ts)) v1]
+                     [else
+                      (error 'apply-project
+                             "length ~a does not match vector type length ~a"
+                             (vector-length v1) (length ts))])]
+              [`(,ts ... -> ,rt)
+               (match v1
+                 [`(function ,xs ,body ,env)
+                  (cond [(eq? (length xs) (length ts)) v1]
+                        [else
+                         (error 'apply-project
+                                "arity ~a does not match type arity ~a"
+                                (length xs) (length ts))])]
+                 [else (error 'apply-project "expected a function, not ~a" v1)])]
+              [else v1])]
+           [else (error 'apply-project "tag mismatch ~a != ~a" tag1 tag2)])]
+    [else (error 'apply-project "expected tagged value, not ~a" v)]))
+\end{lstlisting}
+  \caption{Auxiliary function to apply a projection.}
+  \label{fig:apply-project}
+\end{figure}
 %\clearpage
 
-\section{Shrinking $R_6$}
+
+
+
+\section{Check Bounds}
+\label{sec:check-bounds-r6}
+
+When the type of the vector argument is \code{Vectorof}, the static
+type checking does not guarantee that the index in a \code{vector-ref}
+or \code{vector-set!} operation is within bounds. Thus, we need to
+insert bounds checking as follows.
+
+\begin{lstlisting}
+(vector-ref e1 e2)
+|$\Rightarrow$|
+(let ([v e1'])
+  (let ([i e2'])
+    (if (and (<= 0 i) (< i (vector-length v)))
+        (vector-ref v i)
+        (exit))))
+\end{lstlisting}
+
+\begin{lstlisting}
+(vector-set! e1 e2 e3)
+|$\Rightarrow$|
+(let ([v e1'])
+  (let ([i e2'])
+    (if (and (<= 0 i) (< i (vector-length v)))
+        (vector-set! v i e3')
+        (exit))))
+\end{lstlisting}
+
+\section{Shrink $R_6$}
 \label{sec:shrink-r6}
 
 % TODO: define R'_6
@@ -10539,34 +10661,6 @@ takes a tag instead of a type. \\
 We recommend translating the type predicates (\code{boolean?}, etc.)
 into uses of \code{tag-of-any} and \code{eq?}.
 
-\section{Check Bounds}
-\label{sec:check-bounds-r6}
-
-UNDER CONSTRUCTION
-
-When the type of the vector argument is \code{Vectorof}, insert bounds
-checking.
-
-\begin{lstlisting}
-(vector-ref e1 e2)
-|$\Rightarrow$|
-(let ([v e1'])
-  (let ([i e2'])
-    (if (< i (vector-length v))
-        (vector-ref v i)
-        (exit))))
-\end{lstlisting}
-
-\begin{lstlisting}
-(vector-set! e1 e2 e3)
-|$\Rightarrow$|
-(let ([v e1'])
-  (let ([i e2'])
-    (if (< i (vector-length v))
-        (vector-set! v i e3')
-        (exit))))
-\end{lstlisting}
-
 \section{Remove Complex Operands}
 \label{sec:rco-r6}
 
@@ -10581,6 +10675,7 @@ syntax is defined in Figure~\ref{fig:c5-syntax}. The \code{ValueOf}
 form that we added to $R_6$ remains an expression and the \code{Exit}
 expression becomes a statement.
 
+
 \begin{figure}[tp]
 \fbox{
 \begin{minipage}{0.96\textwidth}
@@ -10590,12 +10685,12 @@ expression becomes a statement.
 \Exp &::= & \ldots
    \mid \VALUEOF{\Exp}{\FType} \\
 \Stmt &::=& \gray{ \ASSIGN{\VAR{\Var}}{\Exp} 
-  \mid \LP\key{Collect} \,\itm{int}\RP }
-  \mid \LP\key{Exit}\RP \\
+  \mid \LP\key{Collect} \,\itm{int}\RP }\\
 \Tail &::= & \gray{ \RETURN{\Exp} \mid \SEQ{\Stmt}{\Tail} 
        \mid \GOTO{\itm{label}} } \\
     &\mid& \gray{ \IFSTMT{\BINOP{\itm{cmp}}{\Atm}{\Atm}}{\GOTO{\itm{label}}}{\GOTO{\itm{label}}}  }\\
-    &\mid& \gray{ \TAILCALL{\Atm}{\Atm\ldots} } \\
+&\mid& \gray{ \TAILCALL{\Atm}{\Atm\ldots} } 
+  \mid \LP\key{Exit}\RP \\
 \Def &::=& \gray{ \DEF{\itm{label}}{\LP[\Var\key{:}\Type]\ldots\RP}{\Type}{\itm{info}}{\LP\LP\itm{label}\,\key{.}\,\Tail\RP\ldots\RP} }\\
 C_4 & ::= & \gray{ \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP} }
 \end{array}