|
@@ -1433,8 +1433,8 @@ same input $i$ yields the same output $o$.
|
|
|
\node (o) at (3, -2.5) {$o$};
|
|
|
|
|
|
\path[->] (p1) edge [above] node {compile} (p2);
|
|
|
- \path[->] (p2) edge [right] node {interp-$\mathcal{L}_2$($i$)} (o);
|
|
|
- \path[->] (p1) edge [left] node {interp-$\mathcal{L}_1$($i$)} (o);
|
|
|
+ \path[->] (p2) edge [right] node {interp\_$\mathcal{L}_2$($i$)} (o);
|
|
|
+ \path[->] (p1) edge [left] node {interp\_$\mathcal{L}_1$($i$)} (o);
|
|
|
\end{tikzpicture}
|
|
|
\end{equation}
|
|
|
In the next section we see our first example of a compiler.
|
|
@@ -1850,28 +1850,28 @@ that dispatches to the \code{interp\_exp} in \LangVar{}.
|
|
|
{\if\edition\racketEd\color{olive}
|
|
|
\begin{minipage}{0.45\textwidth}
|
|
|
\begin{lstlisting}
|
|
|
-(define interp-Rvar-class
|
|
|
+(define interp_Rvar_class
|
|
|
(class object%
|
|
|
- (define/public (interp-exp e)
|
|
|
+ (define/public (interp_exp e)
|
|
|
(match e
|
|
|
[(Prim '- (list e))
|
|
|
- (fx- 0 (interp-exp e))]
|
|
|
+ (fx- 0 (interp_exp e))]
|
|
|
...))
|
|
|
...))
|
|
|
\end{lstlisting}
|
|
|
\end{minipage}
|
|
|
\begin{minipage}{0.45\textwidth}
|
|
|
\begin{lstlisting}
|
|
|
-(define interp-Rif-class
|
|
|
- (class interp-Rvar-class
|
|
|
- (define/override (interp-exp e)
|
|
|
+(define interp_Rif_class
|
|
|
+ (class interp_Rvar_class
|
|
|
+ (define/override (interp_exp e)
|
|
|
(match e
|
|
|
[(If cnd thn els)
|
|
|
- (match (interp-exp cnd)
|
|
|
- [#t (interp-exp thn)]
|
|
|
- [#f (interp-exp els)])]
|
|
|
+ (match (interp_exp cnd)
|
|
|
+ [#t (interp_exp thn)]
|
|
|
+ [#f (interp_exp els)])]
|
|
|
...
|
|
|
- [else (super interp-exp e)]))
|
|
|
+ [else (super interp_exp e)]))
|
|
|
...
|
|
|
))
|
|
|
\end{lstlisting}
|
|
@@ -1924,7 +1924,7 @@ expression, call it \code{e0}, by creating an object of the \LangIf{} class
|
|
|
and calling the \code{interp\_exp} method.
|
|
|
{\if\edition\racketEd\color{olive}
|
|
|
\begin{lstlisting}
|
|
|
-(send (new interp-Rif-class) interp-exp e0)
|
|
|
+(send (new interp_Rif_class) interp_exp e0)
|
|
|
\end{lstlisting}
|
|
|
\fi}
|
|
|
{\if\edition\pythonEd\color{purple}
|
|
@@ -2016,7 +2016,7 @@ looks up the corresponding value in the dictionary.
|
|
|
\begin{figure}[tp]
|
|
|
{\if\edition\racketEd\color{olive}
|
|
|
\begin{lstlisting}
|
|
|
-(define interp-Rvar-class
|
|
|
+(define interp_Rvar_class
|
|
|
(class object%
|
|
|
(super-new)
|
|
|
|
|
@@ -2035,13 +2035,13 @@ looks up the corresponding value in the dictionary.
|
|
|
(define new-env (dict-set env x ((interp_exp env) e)))
|
|
|
((interp_exp new-env) body)]))
|
|
|
|
|
|
- (define/public (interp-program p)
|
|
|
+ (define/public (interp_program p)
|
|
|
(match p
|
|
|
[(Program '() e) ((interp_exp '()) e)]))
|
|
|
))
|
|
|
|
|
|
-(define (interp-Rvar p)
|
|
|
- (send (new interp-Rvar-class) interp-program p))
|
|
|
+(define (interp_Rvar p)
|
|
|
+ (send (new interp_Rvar_class) interp_program p))
|
|
|
\end{lstlisting}
|
|
|
\fi}
|
|
|
{\if\edition\pythonEd\color{purple}
|
|
@@ -2782,7 +2782,7 @@ for each pass in your compiler. For now, define \code{passes} to
|
|
|
contain just one entry for \code{uniquify} as shown below.
|
|
|
\begin{lstlisting}
|
|
|
(define passes
|
|
|
- (list (list "uniquify" uniquify interp-Rvar type-check-Rvar)))
|
|
|
+ (list (list "uniquify" uniquify interp_Rvar type-check-Rvar)))
|
|
|
\end{lstlisting}
|
|
|
Run the \key{run-tests.rkt} script in the support code to check
|
|
|
whether the output programs produce the same result as the input
|
|
@@ -3023,7 +3023,7 @@ regarding file names described in Exercise~\ref{ex:Rvar}.
|
|
|
In the \code{run-tests.rkt} script, add the following entry to the
|
|
|
list of \code{passes} and then run the script to test your compiler.
|
|
|
\begin{lstlisting}
|
|
|
-(list "remove-complex" remove-complex-opera* interp-Rvar type-check-Rvar)
|
|
|
+(list "remove-complex" remove-complex-opera* interp_Rvar type-check-Rvar)
|
|
|
\end{lstlisting}
|
|
|
While debugging your compiler, it is often useful to see the
|
|
|
intermediate programs that are output from each pass. To print the
|
|
@@ -3060,7 +3060,7 @@ end with the file extension \key{.py}.
|
|
|
%% contain just one entry for \code{uniquify} as shown below.
|
|
|
%% \begin{lstlisting}
|
|
|
%% (define passes
|
|
|
-%% (list (list "uniquify" uniquify interp-Rvar type-check-Rvar)))
|
|
|
+%% (list (list "uniquify" uniquify interp_Rvar type-check-Rvar)))
|
|
|
%% \end{lstlisting}
|
|
|
Run the \key{run-tests.py} script in the support code to check
|
|
|
whether the output programs produce the same result as the input
|
|
@@ -3180,7 +3180,7 @@ exercise the code in \code{explicate-control}.
|
|
|
In the \code{run-tests.rkt} script, add the following entry to the
|
|
|
list of \code{passes} and then run the script to test your compiler.
|
|
|
\begin{lstlisting}
|
|
|
-(list "explicate control" explicate-control interp-Cvar type-check-Cvar)
|
|
|
+(list "explicate control" explicate-control interp_Cvar type-check-Cvar)
|
|
|
\end{lstlisting}
|
|
|
\end{exercise}
|
|
|
\fi}
|
|
@@ -3302,7 +3302,7 @@ designed to exercise all of the interesting cases in this pass.
|
|
|
In the \code{run-tests.rkt} script, add the following entry to the
|
|
|
list of \code{passes} and then run the script to test your compiler.
|
|
|
\begin{lstlisting}
|
|
|
-(list "instruction selection" select-instructions interp-pseudo-x86-0)
|
|
|
+(list "instruction selection" select-instructions interp_pseudo-x86-0)
|
|
|
\end{lstlisting}
|
|
|
\fi}
|
|
|
{\if\edition\pythonEd\color{purple}
|
|
@@ -3405,7 +3405,7 @@ parameter that maps variable names to homes (stack locations for now).
|
|
|
In the \code{run-tests.rkt} script, add the following entry to the
|
|
|
list of \code{passes} and then run the script to test your compiler.
|
|
|
\begin{lstlisting}
|
|
|
-(list "assign homes" assign-homes interp-x86-0)
|
|
|
+(list "assign homes" assign-homes interp_x86-0)
|
|
|
\end{lstlisting}
|
|
|
\fi}
|
|
|
{\if\edition\pythonEd\color{purple}
|
|
@@ -3479,7 +3479,7 @@ designed to exercise all of the interesting cases in this pass.
|
|
|
In the \code{run-tests.rkt} script, add the following entry to the
|
|
|
list of \code{passes} and then run the script to test your compiler.
|
|
|
\begin{lstlisting}
|
|
|
-(list "patch instructions" patch-instructions interp-x86-0)
|
|
|
+(list "patch instructions" patch-instructions interp_x86-0)
|
|
|
\end{lstlisting}
|
|
|
\fi}
|
|
|
{\if\edition\pythonEd\color{purple}
|
|
@@ -6184,9 +6184,8 @@ handled in later passes.
|
|
|
statements into control-flow graphs
|
|
|
(Section~\ref{sec:explicate-control-Rif}).}
|
|
|
%
|
|
|
-Regarding register allocation, liveness analysis now has multiple
|
|
|
-basic blocks to process and there is the interesting question of how
|
|
|
-to handle conditional jumps.
|
|
|
+Regarding register allocation, there is the interesting question of
|
|
|
+how to handle conditional jumps during liveness analysis.
|
|
|
|
|
|
|
|
|
\section{The \LangIf{} Language}
|
|
@@ -6299,33 +6298,39 @@ operators to include
|
|
|
|
|
|
Figure~\ref{fig:interp-Rif} defines the interpreter for \LangIf{},
|
|
|
which inherits from the interpreter for \LangVar{}
|
|
|
-(Figure~\ref{fig:interp-Rvar}). The literals \code{\#t} and \code{\#f}
|
|
|
+(Figure~\ref{fig:interp-Rvar}). The literals \TRUE{} and \FALSE{}
|
|
|
evaluate to the corresponding Boolean values. The conditional
|
|
|
-expression $(\key{if}\, \itm{cnd}\,\itm{thn}\,\itm{els})$ evaluates
|
|
|
-\itm{cnd} and then either evaluates \itm{thn} or \itm{els} depending
|
|
|
-on whether \itm{cnd} produced \code{\#t} or \code{\#f}. The logical
|
|
|
-operations \code{not} and \code{and} behave as you might expect, but
|
|
|
-note that the \code{and} operation is short-circuiting. That is, given
|
|
|
-the expression $(\key{and}\,e_1\,e_2)$, the expression $e_2$ is not
|
|
|
-evaluated if $e_1$ evaluates to \code{\#f}.
|
|
|
-
|
|
|
-With the increase in the number of primitive operations, the
|
|
|
-interpreter would become repetitive without some care. We refactor
|
|
|
-the case for \code{Prim}, moving the code that differs with each
|
|
|
-operation into the \code{interp-op} method shown in in
|
|
|
-Figure~\ref{fig:interp-op-Rif}. We handle the \code{and} operation
|
|
|
-separately because of its short-circuiting behavior.
|
|
|
+expression $\CIF{\itm{cnd}}{\itm{thn}}{\itm{els}}$ evaluates \itm{cnd}
|
|
|
+and then either evaluates \itm{thn} or \itm{els} depending on whether
|
|
|
+\itm{cnd} produced \TRUE{} or \FALSE{}. The logical operations
|
|
|
+\code{and}, \code{or}, and \code{not} behave as you might expect, but
|
|
|
+note that the \code{and} an \code{or} operations are
|
|
|
+short-circuiting.
|
|
|
+%
|
|
|
+That is, given the expression $\CAND{e_1}{e_2}$, the expression $e_2$
|
|
|
+is not evaluated if $e_1$ evaluates to \FALSE{}.
|
|
|
+%
|
|
|
+Similarly, given the expression $\COR{e_1}{e_2}$, the expression $e_2$
|
|
|
+is not evaluated if $e_1$ evaluates to \TRUE{}.
|
|
|
+
|
|
|
+\racket{With the increase in the number of primitive operations, the
|
|
|
+ interpreter would become repetitive without some care. We refactor
|
|
|
+ the case for \code{Prim}, moving the code that differs with each
|
|
|
+ operation into the \code{interp_op} method shown in in
|
|
|
+ Figure~\ref{fig:interp-op-Rif}. We handle the \code{and} operation
|
|
|
+ separately because of its short-circuiting behavior.}
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
+{\if\edition\racketEd\color{olive}
|
|
|
\begin{lstlisting}
|
|
|
-(define interp-Rif-class
|
|
|
- (class interp-Rvar-class
|
|
|
+(define interp_Rif_class
|
|
|
+ (class interp_Rvar_class
|
|
|
(super-new)
|
|
|
|
|
|
- (define/public (interp-op op) ...)
|
|
|
+ (define/public (interp_op op) ...)
|
|
|
|
|
|
- (define/override ((interp-exp env) e)
|
|
|
- (define recur (interp-exp env))
|
|
|
+ (define/override ((interp_exp env) e)
|
|
|
+ (define recur (interp_exp env))
|
|
|
(match e
|
|
|
[(Bool b) b]
|
|
|
[(If cnd thn els)
|
|
@@ -6337,21 +6342,76 @@ separately because of its short-circuiting behavior.
|
|
|
[#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)]))
|
|
|
+ (apply (interp_op op) (for/list ([e args]) (recur e)))]
|
|
|
+ [else ((super interp_exp env) e)]))
|
|
|
))
|
|
|
|
|
|
-(define (interp-Rif p)
|
|
|
- (send (new interp-Rif-class) interp-program p))
|
|
|
+(define (interp_Rif p)
|
|
|
+ (send (new interp_Rif_class) interp_program p))
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd\color{purple}
|
|
|
+\begin{lstlisting}
|
|
|
+class InterpPif(InterpPvar):
|
|
|
+
|
|
|
+ def interp_exp(self, e, env):
|
|
|
+ match e:
|
|
|
+ case IfExp(test, body, orelse):
|
|
|
+ match self.interp_exp(test, env):
|
|
|
+ case True:
|
|
|
+ return self.interp_exp(body, env)
|
|
|
+ case False:
|
|
|
+ return self.interp_exp(orelse, env)
|
|
|
+ case BinOp(left, Sub(), right):
|
|
|
+ l = self.interp_exp(left, env)
|
|
|
+ r = self.interp_exp(right, env)
|
|
|
+ return l - r
|
|
|
+ case UnaryOp(Not(), v):
|
|
|
+ return not self.interp_exp(v, env)
|
|
|
+ case BoolOp(left, And(), right):
|
|
|
+ match self.interp_exp(left, env):
|
|
|
+ case True:
|
|
|
+ return self.interp_exp(right, env)
|
|
|
+ case False:
|
|
|
+ return False
|
|
|
+ case BoolOp(left, Or(), right):
|
|
|
+ match self.interp_exp(left, env):
|
|
|
+ case True:
|
|
|
+ return True
|
|
|
+ case False:
|
|
|
+ return self.interp_exp(right, env)
|
|
|
+ case Compare(left, [cmp], [right]):
|
|
|
+ l = self.interp_exp(left, env)
|
|
|
+ r = self.interp_exp(right, env)
|
|
|
+ return self.interp_cmp(cmp)(l, r)
|
|
|
+ case _:
|
|
|
+ return super().interp_exp(e, env)
|
|
|
+
|
|
|
+ def interp_stmts(self, ss, env):
|
|
|
+ if len(ss) == 0:
|
|
|
+ return
|
|
|
+ match ss[0]:
|
|
|
+ case If(test, body, orelse):
|
|
|
+ match self.interp_exp(test, env):
|
|
|
+ case True:
|
|
|
+ return self.interp_stmts(body + ss[1:], env)
|
|
|
+ case False:
|
|
|
+ return self.interp_stmts(orelse + ss[1:], env)
|
|
|
+ case _:
|
|
|
+ return super().interp_stmts(ss, env)
|
|
|
+ ...
|
|
|
\end{lstlisting}
|
|
|
-\caption{Interpreter for the \LangIf{} language. (See
|
|
|
- Figure~\ref{fig:interp-op-Rif} for \code{interp-op}.)}
|
|
|
+\fi}
|
|
|
+\caption{Interpreter for the \LangIf{} language. \racket{(See
|
|
|
+ Figure~\ref{fig:interp-op-Rif} for \code{interp-op}.)}
|
|
|
+ \python{(See Figure~\ref{fig:interp-cmp-Rif} for \code{interp\_cmp}.)}}
|
|
|
\label{fig:interp-Rif}
|
|
|
\end{figure}
|
|
|
|
|
|
+{\if\edition\racketEd\color{olive}
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}
|
|
|
-(define/public (interp-op op)
|
|
|
+(define/public (interp_op op)
|
|
|
(match op
|
|
|
['+ fx+]
|
|
|
['- fx-]
|
|
@@ -6377,12 +6437,38 @@ separately because of its short-circuiting behavior.
|
|
|
['>= (lambda (v1 v2)
|
|
|
(cond [(and (fixnum? v1) (fixnum? v2))
|
|
|
(>= v1 v2)]))]
|
|
|
- [else (error 'interp-op "unknown operator")]))
|
|
|
+ [else (error 'interp_op "unknown operator")]))
|
|
|
\end{lstlisting}
|
|
|
\caption{Interpreter for the primitive operators in the \LangIf{} language.}
|
|
|
\label{fig:interp-op-Rif}
|
|
|
\end{figure}
|
|
|
+\fi}
|
|
|
+
|
|
|
+{\if\edition\pythonEd\color{purple}
|
|
|
+\begin{figure}
|
|
|
+\begin{lstlisting}
|
|
|
+class InterpPif(InterpPvar):
|
|
|
+ ...
|
|
|
|
|
|
+ def interp_cmp(self, cmp):
|
|
|
+ match cmp:
|
|
|
+ case Lt():
|
|
|
+ return lambda x, y: x < y
|
|
|
+ case LtE():
|
|
|
+ return lambda x, y: x <= y
|
|
|
+ case Gt():
|
|
|
+ return lambda x, y: x > y
|
|
|
+ case GtE():
|
|
|
+ return lambda x, y: x >= y
|
|
|
+ case Eq():
|
|
|
+ return lambda x, y: x == y
|
|
|
+ case NotEq():
|
|
|
+ return lambda x, y: x != y
|
|
|
+\end{lstlisting}
|
|
|
+\caption{Interpreter for the comparison operators in the \LangIf{} language.}
|
|
|
+\label{fig:interp-cmp-Rif}
|
|
|
+\end{figure}
|
|
|
+\fi}
|
|
|
|
|
|
\section{Type Checking \LangIf{} Programs}
|
|
|
\label{sec:type-check-Rif}
|
|
@@ -6392,26 +6478,48 @@ separately because of its short-circuiting behavior.
|
|
|
It is helpful to think about type checking in two complementary
|
|
|
ways. A type checker predicts the type of value that will be produced
|
|
|
by each expression in the program. For \LangIf{}, we have just two types,
|
|
|
-\key{Integer} and \key{Boolean}. So a type checker should predict that
|
|
|
+\INTTY{} and \BOOLTY{}. So a type checker should predict that
|
|
|
+{\if\edition\racketEd\color{olive}
|
|
|
\begin{lstlisting}
|
|
|
(+ 10 (- (+ 12 20)))
|
|
|
\end{lstlisting}
|
|
|
-produces an \key{Integer} while
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd\color{purple}
|
|
|
+\begin{lstlisting}
|
|
|
+ 10 + -(12 + 20)
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
+\noindent produces a value of type \INTTY{} while
|
|
|
+{\if\edition\racketEd\color{olive}
|
|
|
\begin{lstlisting}
|
|
|
(and (not #f) #t)
|
|
|
\end{lstlisting}
|
|
|
-produces a \key{Boolean}.
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd\color{purple}
|
|
|
+\begin{lstlisting}
|
|
|
+ (not False) and True
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
+\noindent produces a value of type \BOOLTY{}.
|
|
|
|
|
|
Another way to think about type checking is that it enforces a set of
|
|
|
rules about which operators can be applied to which kinds of
|
|
|
values. For example, our type checker for \LangIf{} signals an error
|
|
|
for the below expression
|
|
|
+{\if\edition\racketEd\color{olive}
|
|
|
\begin{lstlisting}
|
|
|
(not (+ 10 (- (+ 12 20))))
|
|
|
\end{lstlisting}
|
|
|
-The subexpression \code{(+ 10 (- (+ 12 20)))} has type \key{Integer}
|
|
|
-but the type checker enforces the rule that the argument of \code{not}
|
|
|
-must be a \key{Boolean}.
|
|
|
+\fi}
|
|
|
+{\if\edition\pythonEd\color{purple}
|
|
|
+\begin{lstlisting}
|
|
|
+ not (10 + -(12 + 20))
|
|
|
+\end{lstlisting}
|
|
|
+\fi}
|
|
|
+The subexpression
|
|
|
+\racket{\code{(+ 10 (- (+ 12 20)))}}\python{\code{(10 + -(12 + 20))}}
|
|
|
+has type \INTTY{} but the type checker enforces the rule that the argument of
|
|
|
+\code{not} must be an expression of type \BOOLTY{}.
|
|
|
|
|
|
We implement type checking using classes and methods because they
|
|
|
provide the open recursion needed to reuse code as we extend the type
|
|
@@ -6422,18 +6530,21 @@ We separate the type checker for the \LangVar{} fragment into its own
|
|
|
class, shown in Figure~\ref{fig:type-check-Rvar}. The type checker for
|
|
|
\LangIf{} is shown in Figure~\ref{fig:type-check-Rif} and it inherits
|
|
|
from the type checker for \LangVar{}. These type checkers are in the
|
|
|
-files \code{type-check-Rvar.rkt} and \code{type-check-Rif.rkt} of the
|
|
|
-support code.
|
|
|
+files
|
|
|
+\racket{\code{type-check-Rvar.rkt}}\python{\code{type\_check\_Pvar.py}}
|
|
|
+and
|
|
|
+\racket{\code{type-check-Rif.rkt}}\python{\code{type\_check\_Pif.py}}
|
|
|
+of the support code.
|
|
|
%
|
|
|
Each type checker is a structurally recursive function over the AST.
|
|
|
Given an input expression \code{e}, the type checker either signals an
|
|
|
-error or returns an expression and its type (\key{Integer} or
|
|
|
-\key{Boolean}). It returns an expression because there are situations
|
|
|
+error or returns an expression and its type (\INTTY{} or
|
|
|
+\BOOLTY{}). It returns an expression because there are situations
|
|
|
in which we want to change or update the expression.
|
|
|
|
|
|
-Next we discuss the \code{match} cases in \code{type-check-exp} of
|
|
|
+Next we discuss the \code{match} cases in \code{type\_check\_exp} of
|
|
|
Figure~\ref{fig:type-check-Rvar}. The type of an integer constant is
|
|
|
-\code{Integer}. To handle variables, the type checker uses the
|
|
|
+\INTTY{}. To handle variables, the type checker uses the
|
|
|
environment \code{env} to map variables to types. Consider the case
|
|
|
for \key{let}. We type check the initializing expression to obtain
|
|
|
its type \key{T} and then associate type \code{T} with the variable
|
|
@@ -6441,7 +6552,7 @@ its type \key{T} and then associate type \code{T} with the variable
|
|
|
\key{let}. Thus, when the type checker encounters a use of variable
|
|
|
\code{x}, it can find its type in the environment. Regarding
|
|
|
primitive operators, we recursively analyze the arguments and then
|
|
|
-invoke \code{type-check-op} to check whether the argument types are
|
|
|
+invoke \code{type\_check\_op} to check whether the argument types are
|
|
|
allowed.
|
|
|
|
|
|
Several auxiliary methods are used in the type checker. The method
|
|
@@ -6457,7 +6568,7 @@ return type of the operator.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
-(define type-check-Rvar-class
|
|
|
+(define type-check-Rvar_class
|
|
|
(class object%
|
|
|
(super-new)
|
|
|
|
|
@@ -6505,7 +6616,7 @@ return type of the operator.
|
|
|
))
|
|
|
|
|
|
(define (type-check-Rvar p)
|
|
|
- (send (new type-check-Rvar-class) type-check-program p))
|
|
|
+ (send (new type-check-Rvar_class) type-check-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Type checker for the \LangVar{} language.}
|
|
|
\label{fig:type-check-Rvar}
|
|
@@ -6513,8 +6624,8 @@ return type of the operator.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
-(define type-check-Rif-class
|
|
|
- (class type-check-Rvar-class
|
|
|
+(define type-check-Rif_class
|
|
|
+ (class type-check-Rvar_class
|
|
|
(super-new)
|
|
|
(inherit check-type-equal?)
|
|
|
|
|
@@ -6550,7 +6661,7 @@ return type of the operator.
|
|
|
))
|
|
|
|
|
|
(define (type-check-Rif p)
|
|
|
- (send (new type-check-Rif-class) type-check-program p))
|
|
|
+ (send (new type-check-Rif_class) type-check-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Type checker for the \LangIf{} language.}
|
|
|
\label{fig:type-check-Rif}
|
|
@@ -6809,10 +6920,10 @@ In the \code{run-tests.rkt} script, add the following entry for
|
|
|
\code{shrink} to the list of passes (it should be the only pass at
|
|
|
this point).
|
|
|
\begin{lstlisting}
|
|
|
-(list "shrink" shrink interp-Rif type-check-Rif)
|
|
|
+(list "shrink" shrink interp_Rif type-check-Rif)
|
|
|
\end{lstlisting}
|
|
|
This instructs \code{interp-tests} to run the intepreter
|
|
|
-\code{interp-Rif} and the type checker \code{type-check-Rif} on the
|
|
|
+\code{interp\_Rif} and the type checker \code{type-check-Rif} on the
|
|
|
output of \code{shrink}.
|
|
|
%
|
|
|
Run the script to test your compiler on all the test programs.
|
|
@@ -6826,10 +6937,10 @@ Add cases to \code{uniquify-exp} to handle Boolean constants and
|
|
|
\code{if} expressions.
|
|
|
|
|
|
\begin{exercise}\normalfont
|
|
|
-Update the \code{uniquify-exp} for \LangIf{} and add the following
|
|
|
+Update the \code{uniquify\_exp} for \LangIf{} and add the following
|
|
|
entry to the list of \code{passes} in the \code{run-tests.rkt} script.
|
|
|
\begin{lstlisting}
|
|
|
-(list "uniquify" uniquify interp-Rif type-check-Rif)
|
|
|
+(list "uniquify" uniquify interp_Rif type_check_Rif)
|
|
|
\end{lstlisting}
|
|
|
Run the script to test your compiler.
|
|
|
\end{exercise}
|
|
@@ -8043,8 +8154,8 @@ otherwise.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}
|
|
|
-(define interp-Rvec-class
|
|
|
- (class interp-Rif-class
|
|
|
+(define interp-Rvec_class
|
|
|
+ (class interp-Rif_class
|
|
|
(super-new)
|
|
|
|
|
|
(define/override (interp-op op)
|
|
@@ -8072,7 +8183,7 @@ otherwise.
|
|
|
))
|
|
|
|
|
|
(define (interp-Rvec p)
|
|
|
- (send (new interp-Rvec-class) interp-program p))
|
|
|
+ (send (new interp-Rvec_class) interp-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Interpreter for the \LangVec{} language.}
|
|
|
\label{fig:interp-Rvec}
|
|
@@ -8095,8 +8206,8 @@ start and end parentheses. \index{subject}{unquote-slicing}
|
|
|
|
|
|
\begin{figure}[tp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
-(define type-check-Rvec-class
|
|
|
- (class type-check-Rif-class
|
|
|
+(define type-check-Rvec_class
|
|
|
+ (class type-check-Rif_class
|
|
|
(super-new)
|
|
|
(inherit check-type-equal?)
|
|
|
|
|
@@ -8151,7 +8262,7 @@ start and end parentheses. \index{subject}{unquote-slicing}
|
|
|
))
|
|
|
|
|
|
(define (type-check-Rvec p)
|
|
|
- (send (new type-check-Rvec-class) type-check-program p))
|
|
|
+ (send (new type-check-Rvec_class) type-check-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Type checker for the \LangVec{} language.}
|
|
|
\label{fig:type-check-Rvec}
|
|
@@ -9374,8 +9485,8 @@ update the \code{lambda} values to use the top-level environment.
|
|
|
|
|
|
\begin{figure}[tp]
|
|
|
\begin{lstlisting}
|
|
|
-(define interp-Rfun-class
|
|
|
- (class interp-Rvec-class
|
|
|
+(define interp-Rfun_class
|
|
|
+ (class interp-Rvec_class
|
|
|
(super-new)
|
|
|
|
|
|
(define/override ((interp-exp env) e)
|
|
@@ -9415,7 +9526,7 @@ update the \code{lambda} values to use the top-level environment.
|
|
|
))
|
|
|
|
|
|
(define (interp-Rfun p)
|
|
|
- (send (new interp-Rfun-class) interp-program p))
|
|
|
+ (send (new interp-Rfun_class) interp-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Interpreter for the \LangFun{} language.}
|
|
|
\label{fig:interp-Rfun}
|
|
@@ -9428,8 +9539,8 @@ The type checker for \LangFun{} is in Figure~\ref{fig:type-check-Rfun}.
|
|
|
|
|
|
\begin{figure}[tp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
-(define type-check-Rfun-class
|
|
|
- (class type-check-Rvec-class
|
|
|
+(define type-check-Rfun_class
|
|
|
+ (class type-check-Rvec_class
|
|
|
(super-new)
|
|
|
(inherit check-type-equal?)
|
|
|
|
|
@@ -9480,7 +9591,7 @@ The type checker for \LangFun{} is in Figure~\ref{fig:type-check-Rfun}.
|
|
|
(ProgramDefsExp info ds^ body^)]))))
|
|
|
|
|
|
(define (type-check-Rfun p)
|
|
|
- (send (new type-check-Rfun-class) type-check-program p))
|
|
|
+ (send (new type-check-Rfun_class) type-check-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Type checker for the \LangFun{} language.}
|
|
|
\label{fig:type-check-Rfun}
|
|
@@ -10608,8 +10719,8 @@ values.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}
|
|
|
-(define interp-Rlambda-class
|
|
|
- (class interp-Rfun-class
|
|
|
+(define interp-Rlambda_class
|
|
|
+ (class interp-Rfun_class
|
|
|
(super-new)
|
|
|
|
|
|
(define/override (interp-op op)
|
|
@@ -10630,7 +10741,7 @@ values.
|
|
|
))
|
|
|
|
|
|
(define (interp-Rlambda p)
|
|
|
- (send (new interp-Rlambda-class) interp-program p))
|
|
|
+ (send (new interp-Rlambda_class) interp-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Interpreter for \LangLam{}.}
|
|
|
\label{fig:interp-Rlambda}
|
|
@@ -11481,8 +11592,8 @@ in Figure~\ref{fig:apply-project}.
|
|
|
|
|
|
\begin{figure}[btp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\small]
|
|
|
-(define type-check-Rany-class
|
|
|
- (class type-check-Rlambda-class
|
|
|
+(define type-check-Rany_class
|
|
|
+ (class type-check-Rlambda_class
|
|
|
(super-new)
|
|
|
(inherit check-type-equal?)
|
|
|
|
|
@@ -11605,8 +11716,8 @@ in Figure~\ref{fig:apply-project}.
|
|
|
|
|
|
\begin{figure}[btp]
|
|
|
\begin{lstlisting}
|
|
|
-(define interp-Rany-class
|
|
|
- (class interp-Rlambda-class
|
|
|
+(define interp-Rany_class
|
|
|
+ (class interp-Rlambda_class
|
|
|
(super-new)
|
|
|
|
|
|
(define/override (interp-op op)
|
|
@@ -11644,7 +11755,7 @@ in Figure~\ref{fig:apply-project}.
|
|
|
))
|
|
|
|
|
|
(define (interp-Rany p)
|
|
|
- (send (new interp-Rany-class) interp-program p))
|
|
|
+ (send (new interp-Rany_class) interp-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Interpreter for \LangAny{}.}
|
|
|
\label{fig:interp-Rany}
|
|
@@ -12330,8 +12441,8 @@ and returns the result from \itm{body}.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
-(define interp-Rwhile-class
|
|
|
- (class interp-Rany-class
|
|
|
+(define interp-Rwhile_class
|
|
|
+ (class interp-Rany_class
|
|
|
(super-new)
|
|
|
|
|
|
(define/override ((interp-exp env) e)
|
|
@@ -12351,7 +12462,7 @@ and returns the result from \itm{body}.
|
|
|
))
|
|
|
|
|
|
(define (interp-Rwhile p)
|
|
|
- (send (new interp-Rwhile-class) interp-program p))
|
|
|
+ (send (new interp-Rwhile_class) interp-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Interpreter for \LangLoop{}.}
|
|
|
\label{fig:interp-Rwhile}
|
|
@@ -12366,8 +12477,8 @@ variable and the right-hand-side must agree. The result type is
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
-(define type-check-Rwhile-class
|
|
|
- (class type-check-Rany-class
|
|
|
+(define type-check-Rwhile_class
|
|
|
+ (class type-check-Rany_class
|
|
|
(super-new)
|
|
|
(inherit check-type-equal?)
|
|
|
|
|
@@ -12394,7 +12505,7 @@ variable and the right-hand-side must agree. The result type is
|
|
|
))
|
|
|
|
|
|
(define (type-check-Rwhile p)
|
|
|
- (send (new type-check-Rwhile-class) type-check-program p))
|
|
|
+ (send (new type-check-Rwhile_class) type-check-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Type checking \key{SetBang}, \key{WhileLoop},
|
|
|
and \code{Begin} in \LangLoop{}.}
|
|
@@ -13240,8 +13351,8 @@ predicate.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
-(define type-check-Rvecof-class
|
|
|
- (class type-check-Rwhile-class
|
|
|
+(define type-check-Rvecof_class
|
|
|
+ (class type-check-Rwhile_class
|
|
|
(super-new)
|
|
|
(inherit check-type-equal?)
|
|
|
|
|
@@ -13290,7 +13401,7 @@ predicate.
|
|
|
))
|
|
|
|
|
|
(define (type-check-Rvecof p)
|
|
|
- (send (new type-check-Rvecof-class) type-check-program p))
|
|
|
+ (send (new type-check-Rvecof_class) type-check-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Type checker for the \LangArray{} language.}
|
|
|
\label{fig:type-check-Rvecof}
|
|
@@ -13304,8 +13415,8 @@ integers.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
-(define interp-Rvecof-class
|
|
|
- (class interp-Rwhile-class
|
|
|
+(define interp-Rvecof_class
|
|
|
+ (class interp-Rwhile_class
|
|
|
(super-new)
|
|
|
|
|
|
(define/override (interp-op op)
|
|
@@ -13317,7 +13428,7 @@ integers.
|
|
|
))
|
|
|
|
|
|
(define (interp-Rvecof p)
|
|
|
- (send (new interp-Rvecof-class) interp-program p))
|
|
|
+ (send (new interp-Rvecof_class) interp-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{Interpreter for \LangArray{}.}
|
|
|
\label{fig:interp-Rvecof}
|
|
@@ -13704,8 +13815,8 @@ and \ref{fig:type-check-Rgradual-3}.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
|
|
|
-(define type-check-gradual-class
|
|
|
- (class type-check-Rwhile-class
|
|
|
+(define type-check-gradual_class
|
|
|
+ (class type-check-Rwhile_class
|
|
|
(super-new)
|
|
|
(inherit operator-types type-predicates)
|
|
|
|
|
@@ -14102,8 +14213,8 @@ functions in Figure~\ref{fig:guarded-vector}.
|
|
|
|
|
|
\begin{figure}[tbp]
|
|
|
\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
|
|
|
-(define interp-Rcast-class
|
|
|
- (class interp-Rwhile-class
|
|
|
+(define interp-Rcast_class
|
|
|
+ (class interp-Rwhile_class
|
|
|
(super-new)
|
|
|
(inherit apply-fun apply-inject apply-project)
|
|
|
|
|
@@ -14133,7 +14244,7 @@ functions in Figure~\ref{fig:guarded-vector}.
|
|
|
))
|
|
|
|
|
|
(define (interp-Rcast p)
|
|
|
- (send (new interp-Rcast-class) interp-program p))
|
|
|
+ (send (new interp-Rcast_class) interp-program p))
|
|
|
\end{lstlisting}
|
|
|
\caption{The interpreter for \LangCast{}.}
|
|
|
\label{fig:interp-Rcast}
|