Эх сурвалжийг харах

ch 4 in python, some progress

Jeremy Siek 3 жил өмнө
parent
commit
16da32c602
2 өөрчлөгдсөн 239 нэмэгдсэн , 117 устгасан
  1. 225 114
      book.tex
  2. 14 3
      defs.tex

+ 225 - 114
book.tex

@@ -1433,8 +1433,8 @@ same input $i$ yields the same output $o$.
  \node (o)  at (3, -2.5) {$o$};
  \node (o)  at (3, -2.5) {$o$};
 
 
  \path[->] (p1) edge [above] node {compile} (p2);
  \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{tikzpicture}
 \end{equation}
 \end{equation}
 In the next section we see our first example of a compiler.
 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}  
 {\if\edition\racketEd\color{olive}  
 \begin{minipage}{0.45\textwidth}
 \begin{minipage}{0.45\textwidth}
 \begin{lstlisting}
 \begin{lstlisting}
-(define interp-Rvar-class
+(define interp_Rvar_class
   (class object%
   (class object%
-    (define/public (interp-exp e)
+    (define/public (interp_exp e)
       (match e
       (match e
         [(Prim '- (list e))
         [(Prim '- (list e))
-         (fx- 0 (interp-exp e))]
+         (fx- 0 (interp_exp e))]
         ...))
         ...))
     ...))
     ...))
 \end{lstlisting}
 \end{lstlisting}
 \end{minipage}
 \end{minipage}
 \begin{minipage}{0.45\textwidth}
 \begin{minipage}{0.45\textwidth}
   \begin{lstlisting}
   \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
       (match e
         [(If cnd thn els)
         [(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}
 \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.
 and calling the \code{interp\_exp} method.
 {\if\edition\racketEd\color{olive}
 {\if\edition\racketEd\color{olive}
 \begin{lstlisting}
 \begin{lstlisting}
-(send (new interp-Rif-class) interp-exp e0)
+(send (new interp_Rif_class) interp_exp e0)
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
 {\if\edition\pythonEd\color{purple}
 {\if\edition\pythonEd\color{purple}
@@ -2016,7 +2016,7 @@ looks up the corresponding value in the dictionary.
 \begin{figure}[tp]
 \begin{figure}[tp]
 {\if\edition\racketEd\color{olive}  
 {\if\edition\racketEd\color{olive}  
 \begin{lstlisting}
 \begin{lstlisting}
-(define interp-Rvar-class
+(define interp_Rvar_class
   (class object%
   (class object%
     (super-new)
     (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)))
          (define new-env (dict-set env x ((interp_exp env) e)))
          ((interp_exp new-env) body)]))
          ((interp_exp new-env) body)]))
 
 
-    (define/public (interp-program p)
+    (define/public (interp_program p)
       (match p
       (match p
         [(Program '() e) ((interp_exp '()) e)]))
         [(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}
 \end{lstlisting}
 \fi}
 \fi}
 {\if\edition\pythonEd\color{purple}
 {\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.
 contain just one entry for \code{uniquify} as shown below.
 \begin{lstlisting}
 \begin{lstlisting}
 (define passes 
 (define passes 
-  (list (list "uniquify" uniquify interp-Rvar type-check-Rvar)))
+  (list (list "uniquify" uniquify interp_Rvar type-check-Rvar)))
 \end{lstlisting}
 \end{lstlisting}
 Run the \key{run-tests.rkt} script in the support code to check
 Run the \key{run-tests.rkt} script in the support code to check
 whether the output programs produce the same result as the input
 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
 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.
 list of \code{passes} and then run the script to test your compiler.
 \begin{lstlisting}
 \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}
 \end{lstlisting}
 While debugging your compiler, it is often useful to see the
 While debugging your compiler, it is often useful to see the
 intermediate programs that are output from each pass. To print 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.
 %% contain just one entry for \code{uniquify} as shown below.
 %% \begin{lstlisting}
 %% \begin{lstlisting}
 %% (define passes 
 %% (define passes 
-%%   (list (list "uniquify" uniquify interp-Rvar type-check-Rvar)))
+%%   (list (list "uniquify" uniquify interp_Rvar type-check-Rvar)))
 %% \end{lstlisting}
 %% \end{lstlisting}
 Run the \key{run-tests.py} script in the support code to check
 Run the \key{run-tests.py} script in the support code to check
 whether the output programs produce the same result as the input
 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
 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.
 list of \code{passes} and then run the script to test your compiler.
 \begin{lstlisting}
 \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{lstlisting}
 \end{exercise}
 \end{exercise}
 \fi}
 \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
 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.
 list of \code{passes} and then run the script to test your compiler.
 \begin{lstlisting}
 \begin{lstlisting}
-(list "instruction selection" select-instructions interp-pseudo-x86-0)
+(list "instruction selection" select-instructions interp_pseudo-x86-0)
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
 {\if\edition\pythonEd\color{purple}
 {\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
 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.
 list of \code{passes} and then run the script to test your compiler.
 \begin{lstlisting}
 \begin{lstlisting}
-(list "assign homes" assign-homes interp-x86-0)
+(list "assign homes" assign-homes interp_x86-0)
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
 {\if\edition\pythonEd\color{purple}
 {\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
 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.
 list of \code{passes} and then run the script to test your compiler.
 \begin{lstlisting}
 \begin{lstlisting}
-(list "patch instructions" patch-instructions interp-x86-0)
+(list "patch instructions" patch-instructions interp_x86-0)
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
 {\if\edition\pythonEd\color{purple}
 {\if\edition\pythonEd\color{purple}
@@ -6184,9 +6184,8 @@ handled in later passes.
   statements into control-flow graphs
   statements into control-flow graphs
   (Section~\ref{sec:explicate-control-Rif}).}
   (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}
 \section{The \LangIf{} Language}
@@ -6299,33 +6298,39 @@ operators to include
 
 
 Figure~\ref{fig:interp-Rif} defines the interpreter for \LangIf{},
 Figure~\ref{fig:interp-Rif} defines the interpreter for \LangIf{},
 which inherits from the interpreter for \LangVar{}
 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
 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]
 \begin{figure}[tbp]
+{\if\edition\racketEd\color{olive}    
 \begin{lstlisting}
 \begin{lstlisting}
-(define interp-Rif-class
-  (class interp-Rvar-class
+(define interp_Rif_class
+  (class interp_Rvar_class
     (super-new)
     (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
       (match e
         [(Bool b) b]
         [(Bool b) b]
         [(If cnd thn els)
         [(If cnd thn els)
@@ -6337,21 +6342,76 @@ separately because of its short-circuiting behavior.
            [#t (match (recur e2) [#t #t] [#f #f])]
            [#t (match (recur e2) [#t #t] [#f #f])]
            [#f #f])]
            [#f #f])]
         [(Prim op args)
         [(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}
 \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}
 \label{fig:interp-Rif}
 \end{figure}
 \end{figure}
 
 
+{\if\edition\racketEd\color{olive}
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}
 \begin{lstlisting}
-(define/public (interp-op op)
+(define/public (interp_op op)
   (match op
   (match op
     ['+ fx+]
     ['+ fx+]
     ['- fx-]
     ['- fx-]
@@ -6377,12 +6437,38 @@ separately because of its short-circuiting behavior.
     ['>= (lambda (v1 v2)
     ['>= (lambda (v1 v2)
            (cond [(and (fixnum? v1) (fixnum? v2))
            (cond [(and (fixnum? v1) (fixnum? v2))
                   (>= v1 v2)]))]
                   (>= v1 v2)]))]
-    [else (error 'interp-op "unknown operator")]))
+    [else (error 'interp_op "unknown operator")]))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Interpreter for the primitive operators in the \LangIf{} language.}
 \caption{Interpreter for the primitive operators in the \LangIf{} language.}
 \label{fig:interp-op-Rif}
 \label{fig:interp-op-Rif}
 \end{figure}
 \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}
 \section{Type Checking \LangIf{} Programs}
 \label{sec:type-check-Rif}
 \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
 It is helpful to think about type checking in two complementary
 ways. A type checker predicts the type of value that will be produced
 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,
 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}
 \begin{lstlisting}
    (+ 10 (- (+ 12 20)))
    (+ 10 (- (+ 12 20)))
 \end{lstlisting}
 \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}
 \begin{lstlisting}
    (and (not #f) #t)
    (and (not #f) #t)
 \end{lstlisting}
 \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
 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
 rules about which operators can be applied to which kinds of
 values. For example, our type checker for \LangIf{} signals an error
 values. For example, our type checker for \LangIf{} signals an error
 for the below expression
 for the below expression
+{\if\edition\racketEd\color{olive}
 \begin{lstlisting}
 \begin{lstlisting}
    (not (+ 10 (- (+ 12 20))))
    (not (+ 10 (- (+ 12 20))))
 \end{lstlisting}
 \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
 We implement type checking using classes and methods because they
 provide the open recursion needed to reuse code as we extend the type
 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
 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
 \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
 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.
 Each type checker is a structurally recursive function over the AST.
 Given an input expression \code{e}, the type checker either signals an
 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.
 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
 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
 environment \code{env} to map variables to types. Consider the case
 for \key{let}.  We type check the initializing expression to obtain
 for \key{let}.  We type check the initializing expression to obtain
 its type \key{T} and then associate type \code{T} with the variable
 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
 \key{let}. Thus, when the type checker encounters a use of variable
 \code{x}, it can find its type in the environment.  Regarding
 \code{x}, it can find its type in the environment.  Regarding
 primitive operators, we recursively analyze the arguments and then
 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.
 allowed.
 
 
 Several auxiliary methods are used in the type checker. The method
 Several auxiliary methods are used in the type checker. The method
@@ -6457,7 +6568,7 @@ return type of the operator.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define type-check-Rvar-class
+(define type-check-Rvar_class
   (class object%
   (class object%
     (super-new)
     (super-new)
 
 
@@ -6505,7 +6616,7 @@ return type of the operator.
     ))
     ))
 
 
 (define (type-check-Rvar p)
 (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}
 \end{lstlisting}
 \caption{Type checker for the \LangVar{} language.}
 \caption{Type checker for the \LangVar{} language.}
 \label{fig:type-check-Rvar}
 \label{fig:type-check-Rvar}
@@ -6513,8 +6624,8 @@ return type of the operator.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \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)
     (super-new)
     (inherit check-type-equal?)
     (inherit check-type-equal?)
     
     
@@ -6550,7 +6661,7 @@ return type of the operator.
     ))
     ))
 
 
 (define (type-check-Rif p)
 (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}
 \end{lstlisting}
 \caption{Type checker for the \LangIf{} language.}
 \caption{Type checker for the \LangIf{} language.}
 \label{fig:type-check-Rif}
 \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
 \code{shrink} to the list of passes (it should be the only pass at
 this point).
 this point).
 \begin{lstlisting}
 \begin{lstlisting}
-(list "shrink" shrink interp-Rif type-check-Rif)
+(list "shrink" shrink interp_Rif type-check-Rif)
 \end{lstlisting}
 \end{lstlisting}
 This instructs \code{interp-tests} to run the intepreter
 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}.
 output of \code{shrink}.
 %
 %
 Run the script to test your compiler on all the test programs.
 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.
 \code{if} expressions.
 
 
 \begin{exercise}\normalfont
 \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.
 entry to the list of \code{passes} in the \code{run-tests.rkt} script.
 \begin{lstlisting}
 \begin{lstlisting}
-(list "uniquify" uniquify interp-Rif type-check-Rif)
+(list "uniquify" uniquify interp_Rif type_check_Rif)
 \end{lstlisting}
 \end{lstlisting}
 Run the script to test your compiler.
 Run the script to test your compiler.
 \end{exercise}
 \end{exercise}
@@ -8043,8 +8154,8 @@ otherwise.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}
 \begin{lstlisting}
-(define interp-Rvec-class
-  (class interp-Rif-class
+(define interp-Rvec_class
+  (class interp-Rif_class
     (super-new)
     (super-new)
 
 
     (define/override (interp-op op)
     (define/override (interp-op op)
@@ -8072,7 +8183,7 @@ otherwise.
     ))
     ))
 
 
 (define (interp-Rvec p)
 (define (interp-Rvec p)
-  (send (new interp-Rvec-class) interp-program p))
+  (send (new interp-Rvec_class) interp-program p))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Interpreter for the \LangVec{} language.}
 \caption{Interpreter for the \LangVec{} language.}
 \label{fig:interp-Rvec}
 \label{fig:interp-Rvec}
@@ -8095,8 +8206,8 @@ start and end parentheses.  \index{subject}{unquote-slicing}
 
 
 \begin{figure}[tp]
 \begin{figure}[tp]
 \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
 \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)
     (super-new)
     (inherit check-type-equal?)
     (inherit check-type-equal?)
 
 
@@ -8151,7 +8262,7 @@ start and end parentheses.  \index{subject}{unquote-slicing}
     ))
     ))
 
 
 (define (type-check-Rvec p)
 (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}
 \end{lstlisting}
 \caption{Type checker for the \LangVec{} language.}
 \caption{Type checker for the \LangVec{} language.}
 \label{fig:type-check-Rvec}
 \label{fig:type-check-Rvec}
@@ -9374,8 +9485,8 @@ update the \code{lambda} values to use the top-level environment.
 
 
 \begin{figure}[tp]
 \begin{figure}[tp]
 \begin{lstlisting}
 \begin{lstlisting}
-(define interp-Rfun-class
-  (class interp-Rvec-class
+(define interp-Rfun_class
+  (class interp-Rvec_class
     (super-new)
     (super-new)
 
 
     (define/override ((interp-exp env) e)
     (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)
 (define (interp-Rfun p)
-  (send (new interp-Rfun-class) interp-program p))
+  (send (new interp-Rfun_class) interp-program p))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Interpreter for the \LangFun{} language.}
 \caption{Interpreter for the \LangFun{} language.}
 \label{fig:interp-Rfun}
 \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{figure}[tp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \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)
     (super-new)
     (inherit check-type-equal?)
     (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^)]))))
          (ProgramDefsExp info ds^ body^)]))))
 
 
 (define (type-check-Rfun p)
 (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}
 \end{lstlisting}
 \caption{Type checker for the \LangFun{} language.}
 \caption{Type checker for the \LangFun{} language.}
 \label{fig:type-check-Rfun}
 \label{fig:type-check-Rfun}
@@ -10608,8 +10719,8 @@ values.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}
 \begin{lstlisting}
-(define interp-Rlambda-class
-  (class interp-Rfun-class
+(define interp-Rlambda_class
+  (class interp-Rfun_class
     (super-new)
     (super-new)
 
 
     (define/override (interp-op op)
     (define/override (interp-op op)
@@ -10630,7 +10741,7 @@ values.
     ))
     ))
 
 
 (define (interp-Rlambda p)
 (define (interp-Rlambda p)
-  (send (new interp-Rlambda-class) interp-program p))
+  (send (new interp-Rlambda_class) interp-program p))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Interpreter for \LangLam{}.}
 \caption{Interpreter for \LangLam{}.}
 \label{fig:interp-Rlambda}
 \label{fig:interp-Rlambda}
@@ -11481,8 +11592,8 @@ in Figure~\ref{fig:apply-project}.
 
 
 \begin{figure}[btp]
 \begin{figure}[btp]
  \begin{lstlisting}[basicstyle=\ttfamily\small]
  \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)
     (super-new)
     (inherit check-type-equal?)
     (inherit check-type-equal?)
 
 
@@ -11605,8 +11716,8 @@ in Figure~\ref{fig:apply-project}.
 
 
 \begin{figure}[btp]
 \begin{figure}[btp]
 \begin{lstlisting}
 \begin{lstlisting}
-(define interp-Rany-class
-  (class interp-Rlambda-class
+(define interp-Rany_class
+  (class interp-Rlambda_class
     (super-new)
     (super-new)
 
 
     (define/override (interp-op op)
     (define/override (interp-op op)
@@ -11644,7 +11755,7 @@ in Figure~\ref{fig:apply-project}.
     ))
     ))
 
 
 (define (interp-Rany p)
 (define (interp-Rany p)
-  (send (new interp-Rany-class) interp-program p))
+  (send (new interp-Rany_class) interp-program p))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Interpreter for \LangAny{}.}
 \caption{Interpreter for \LangAny{}.}
 \label{fig:interp-Rany}
 \label{fig:interp-Rany}
@@ -12330,8 +12441,8 @@ and returns the result from \itm{body}.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define interp-Rwhile-class
-  (class interp-Rany-class
+(define interp-Rwhile_class
+  (class interp-Rany_class
     (super-new)
     (super-new)
 
 
     (define/override ((interp-exp env) e)
     (define/override ((interp-exp env) e)
@@ -12351,7 +12462,7 @@ and returns the result from \itm{body}.
     ))
     ))
 
 
 (define (interp-Rwhile p)
 (define (interp-Rwhile p)
-  (send (new interp-Rwhile-class) interp-program p))
+  (send (new interp-Rwhile_class) interp-program p))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Interpreter for \LangLoop{}.}
 \caption{Interpreter for \LangLoop{}.}
 \label{fig:interp-Rwhile}
 \label{fig:interp-Rwhile}
@@ -12366,8 +12477,8 @@ variable and the right-hand-side must agree. The result type is
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \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)
     (super-new)
     (inherit check-type-equal?)
     (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)
 (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}
 \end{lstlisting}
 \caption{Type checking \key{SetBang}, \key{WhileLoop},
 \caption{Type checking \key{SetBang}, \key{WhileLoop},
     and \code{Begin} in \LangLoop{}.}
     and \code{Begin} in \LangLoop{}.}
@@ -13240,8 +13351,8 @@ predicate.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \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)
     (super-new)
     (inherit check-type-equal?)
     (inherit check-type-equal?)
 
 
@@ -13290,7 +13401,7 @@ predicate.
     ))
     ))
 
 
 (define (type-check-Rvecof p)
 (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}
 \end{lstlisting}
 \caption{Type checker for the \LangArray{} language.}
 \caption{Type checker for the \LangArray{} language.}
 \label{fig:type-check-Rvecof}
 \label{fig:type-check-Rvecof}
@@ -13304,8 +13415,8 @@ integers.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define interp-Rvecof-class
-  (class interp-Rwhile-class
+(define interp-Rvecof_class
+  (class interp-Rwhile_class
     (super-new)
     (super-new)
 
 
     (define/override (interp-op op)
     (define/override (interp-op op)
@@ -13317,7 +13428,7 @@ integers.
     ))
     ))
 
 
 (define (interp-Rvecof p)
 (define (interp-Rvecof p)
-  (send (new interp-Rvecof-class) interp-program p))
+  (send (new interp-Rvecof_class) interp-program p))
 \end{lstlisting}
 \end{lstlisting}
 \caption{Interpreter for \LangArray{}.}
 \caption{Interpreter for \LangArray{}.}
 \label{fig:interp-Rvecof}
 \label{fig:interp-Rvecof}
@@ -13704,8 +13815,8 @@ and \ref{fig:type-check-Rgradual-3}.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\scriptsize]
 \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)
     (super-new)
     (inherit operator-types type-predicates)
     (inherit operator-types type-predicates)
 
 
@@ -14102,8 +14213,8 @@ functions in Figure~\ref{fig:guarded-vector}.
 
 
 \begin{figure}[tbp]
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define interp-Rcast-class
-  (class interp-Rwhile-class
+(define interp-Rcast_class
+  (class interp-Rwhile_class
     (super-new)
     (super-new)
     (inherit apply-fun apply-inject apply-project)
     (inherit apply-fun apply-inject apply-project)
 
 
@@ -14133,7 +14244,7 @@ functions in Figure~\ref{fig:guarded-vector}.
     ))
     ))
 
 
 (define (interp-Rcast p)
 (define (interp-Rcast p)
-  (send (new interp-Rcast-class) interp-program p))
+  (send (new interp-Rcast_class) interp-program p))
 \end{lstlisting}
 \end{lstlisting}
 \caption{The interpreter for \LangCast{}.}
 \caption{The interpreter for \LangCast{}.}
   \label{fig:interp-Rcast}
   \label{fig:interp-Rcast}

+ 14 - 3
defs.tex

@@ -141,6 +141,13 @@
 \newcommand{\BINOP}[3]{\key{(Prim}~#1~\code{(}#2~#3\code{))}}
 \newcommand{\BINOP}[3]{\key{(Prim}~#1~\code{(}#2~#3\code{))}}
 \newcommand{\CBINOP}[3]{\LP #1~#2~#3\RP}
 \newcommand{\CBINOP}[3]{\LP #1~#2~#3\RP}
 \newcommand{\IF}[3]{\key{(If}\,#1~#2~#3\key{)}}
 \newcommand{\IF}[3]{\key{(If}\,#1~#2~#3\key{)}}
+\newcommand{\CIF}[3]{\LP\key{if}~#1~#2~#3\RP}
+\newcommand{\AND}[2]{\key{(Prim}~\code{and}~\code{(}#1~#2\code{))}}
+\newcommand{\OR}[2]{\key{(Prim}~\code{or}~\code{(}#1~#2\code{))}}
+\newcommand{\CAND}[2]{\CBINOP{\key{and}}{#1}{#2}}
+\newcommand{\COR}[2]{\CBINOP{\key{or}}{#1}{#2}}
+\newcommand{\INTTY}{{\color{olive}\key{Integer}}}
+\newcommand{\BOOLTY}{{\color{olive}\key{Boolean}}}
 \fi
 \fi
 
 
 \if\edition\pythonEd
 \if\edition\pythonEd
@@ -163,6 +170,13 @@
 \newcommand{\TRUE}{\key{True}}
 \newcommand{\TRUE}{\key{True}}
 \newcommand{\FALSE}{\key{False}}
 \newcommand{\FALSE}{\key{False}}
 \newcommand{\IF}[3]{\key{IfExp}\LP #1 \code{,} #2 \code{,} #3 \RP}
 \newcommand{\IF}[3]{\key{IfExp}\LP #1 \code{,} #2 \code{,} #3 \RP}
+\newcommand{\CIF}[3]{#2~\key{if}~#1~\key{else}~#3}
+\newcommand{\AND}[2]{\BOOLOP{\key{And()}}{#1}{#2}}
+\newcommand{\CAND}[2]{#1~\key{and}~#2}
+\newcommand{\OR}[2]{\BOOLOP{\key{Or()}}{#1}{#2}}
+\newcommand{\COR}[2]{#1~\key{or}~#2}
+\newcommand{\INTTY}{{\color{purple}\key{int}}}
+\newcommand{\BOOLTY}{{\color{purple}\key{bool}}}
 \fi
 \fi
 
 
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
@@ -182,12 +196,9 @@
 \newcommand{\BEGIN}[2]{\LP\key{Begin}~#1~#2\RP}
 \newcommand{\BEGIN}[2]{\LP\key{Begin}~#1~#2\RP}
 \newcommand{\CSETBANG}[2]{\LP\key{set!}~#1~#2\RP}
 \newcommand{\CSETBANG}[2]{\LP\key{set!}~#1~#2\RP}
 \newcommand{\SETBANG}[2]{\LP\key{SetBang}~#1~#2\RP}
 \newcommand{\SETBANG}[2]{\LP\key{SetBang}~#1~#2\RP}
-\newcommand{\AND}[2]{\key{(Prim}~\code{and}~\code{(}#1~#2\code{))}}
-\newcommand{\OR}[2]{\key{(Prim}~\code{or}~\code{(}#1~#2\code{))}}
 \newcommand{\NOT}[1]{\key{(Prim}~\code{not}~\code{(}#1~\code{))}}
 \newcommand{\NOT}[1]{\key{(Prim}~\code{not}~\code{(}#1~\code{))}}
 \newcommand{\LET}[3]{\key{(Let}~#1~#2~#3\key{)}}
 \newcommand{\LET}[3]{\key{(Let}~#1~#2~#3\key{)}}
 \newcommand{\CLET}[3]{\LP\key{let}~\LP\LS#1~#2\RS\RP~#3\RP}
 \newcommand{\CLET}[3]{\LP\key{let}~\LP\LS#1~#2\RS\RP~#3\RP}
-\newcommand{\CIF}[3]{\LP\key{if}~#1~#2~#3\RP}
 \newcommand{\CAST}[3]{\LP\key{Cast}~#1~#2~#3\RP}
 \newcommand{\CAST}[3]{\LP\key{Cast}~#1~#2~#3\RP}
 \newcommand{\VECTOR}[1]{\LP\key{Prim}~\code{vector}~\LP~#1\RP\RP}
 \newcommand{\VECTOR}[1]{\LP\key{Prim}~\code{vector}~\LP~#1\RP\RP}
 \newcommand{\VECREF}[2]{\LP\key{Prim}~\code{vector-ref}~\LP~#1~#2\RP\RP}
 \newcommand{\VECREF}[2]{\LP\key{Prim}~\code{vector-ref}~\LP~#1~#2\RP\RP}