Преглед на файлове

ch 4 in python, some progress

Jeremy Siek преди 3 години
родител
ревизия
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$};
 
  \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}

+ 14 - 3
defs.tex

@@ -141,6 +141,13 @@
 \newcommand{\BINOP}[3]{\key{(Prim}~#1~\code{(}#2~#3\code{))}}
 \newcommand{\CBINOP}[3]{\LP #1~#2~#3\RP}
 \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
 
 \if\edition\pythonEd
@@ -163,6 +170,13 @@
 \newcommand{\TRUE}{\key{True}}
 \newcommand{\FALSE}{\key{False}}
 \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
 
 \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{\CSETBANG}[2]{\LP\key{set!}~#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{\LET}[3]{\key{(Let}~#1~#2~#3\key{)}}
 \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{\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}