Jeremy Siek hace 3 años
padre
commit
ddd8e2c505
Se han modificado 2 ficheros con 195 adiciones y 230 borrados
  1. 194 229
      book.tex
  2. 1 1
      defs.tex

+ 194 - 229
book.tex

@@ -16400,22 +16400,23 @@ closure is proportional to the number of its free variables.  Flat
 closures were reinvented by \citet{Dybvig:1987ab} in his Ph.D. thesis
 and used in Chez Scheme version 1~\citep{Dybvig:2006aa}.
 
-
+% todo: related work on assignment conversion (e.g. orbit and rabbit
+% compilers)
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \chapter{Dynamic Typing}
 \label{ch:Ldyn}
 \index{subject}{dynamic typing}
 
-In this chapter we discuss the compilation of \LangDyn{}, a
-dynamically typed language that is a subset of
-\racket{Racket}\python{Python}. The dynamic typing is in contrast to
-the previous chapters, which have studied the compilation of
-statically typed languages. In dynamically typed languages such as
-\LangDyn{}, a particular expression may produce a value of a different
-type each time it is executed. Consider the following example with a
-conditional \code{if} expression that may return a Boolean or an
-integer depending on the input to the program.
+In this chapter we learn how to compile \LangDyn{}, a dynamically
+typed language that is a subset of \racket{Racket}\python{Python}. The
+focus on dynamic typing is in contrast to the previous chapters, which
+have studied the compilation of statically typed languages. In
+dynamically typed languages such as \LangDyn{}, a particular
+expression may produce a value of a different type each time it is
+executed. Consider the following example with a conditional \code{if}
+expression that may return a Boolean or an integer depending on the
+input to the program.
 % part of  dynamic_test_25.rkt
 {\if\edition\racketEd
 \begin{lstlisting}
@@ -16430,7 +16431,7 @@ not (False if input_int() == 1 else 0)
 
 Languages that allow expressions to produce different kinds of values
 are called \emph{polymorphic}, a word composed of the Greek roots
-``poly'', meaning ``many'', and ``morphos'', meaning ``form''.  There
+``poly'', meaning ``many'', and ``morph'', meaning ``form''.  There
 are several kinds of polymorphism in programming languages, such as
 subtype polymorphism and parametric
 polymorphism~\citep{Cardelli:1985kx}. The kind of polymorphism we
@@ -16453,32 +16454,44 @@ operation
 results in a run-time error because the first argument must
 be a tuple, not a Boolean.
 
+\section{The \LangDyn{} Language}
+
+\newcommand{\LdynGrammarRacket}{
+\begin{array}{rcl}
+\Exp &::=& \LP\Exp \; \Exp\ldots\RP
+      \MID \LP\key{lambda}\;\LP\Var\ldots\RP\;\Exp\RP \\
+     & \MID & \LP\key{boolean?}\;\Exp\RP \MID \LP\key{integer?}\;\Exp\RP\\
+     & \MID & \LP\key{vector?}\;\Exp\RP \MID \LP\key{procedure?}\;\Exp\RP \MID \LP\key{void?}\;\Exp\RP \\
+  \Def &::=& \LP\key{define}\; \LP\Var \; \Var\ldots\RP \; \Exp\RP 
+\end{array}
+}
+
+\newcommand{\LdynASTRacket}{
+\begin{array}{lcl}
+  \Exp &::=& \APPLY{\Exp}{\Exp\ldots} 
+     \MID \LAMBDA{\LP\Var\ldots\RP}{\code{'Any}}{\Exp}\\
+ \Def &::=& \FUNDEF{\Var}{\LP\Var\ldots\RP}{\code{'Any}}{\code{'()}}{\Exp} 
+\end{array}
+}
+
 \begin{figure}[tp]
 \centering
 \fbox{
   \begin{minipage}{0.97\textwidth}
+    \small
 {\if\edition\racketEd    
 \[
+\begin{array}{l}
+  \gray{\LintGrammarRacket{}} \\ \hline
+  \gray{\LvarGrammarRacket{}} \\ \hline
+  \gray{\LifGrammarRacket{}} \\ \hline
+  \gray{\LwhileGrammarRacket} \\ \hline
+  \gray{\LtupGrammarRacket} \\ \hline
+  \LdynGrammarRacket \\
 \begin{array}{rcl}
-  \itm{cmp} &::= & \key{eq?} \MID \key{<} \MID \key{<=} \MID \key{>} \MID \key{>=} \\
-\Exp &::=& \Int \MID \CREAD{} \MID \CNEG{\Exp}
-      \MID \CADD{\Exp}{\Exp} \MID \CSUB{\Exp}{\Exp}  \\
-     &\MID&  \Var \MID \CLET{\Var}{\Exp}{\Exp} \\
-     &\MID& \key{\#t} \MID \key{\#f} 
-      \MID \CBINOP{\key{and}}{\Exp}{\Exp} 
-     \MID \CBINOP{\key{or}}{\Exp}{\Exp} 
-     \MID \CUNIOP{\key{not}}{\Exp} \\
-     &\MID& \LP\itm{cmp}\;\Exp\;\Exp\RP \MID \CIF{\Exp}{\Exp}{\Exp} \\
-     &\MID& \LP\key{vector}\;\Exp\ldots\RP \MID
-      \LP\key{vector-ref}\;\Exp\;\Exp\RP \\
-     &\MID& \LP\key{vector-set!}\;\Exp\;\Exp\;\Exp\RP \MID \LP\key{void}\RP \\
-      &\MID& \LP\Exp \; \Exp\ldots\RP
-      \MID \LP\key{lambda}\;\LP\Var\ldots\RP\;\Exp\RP \\
-     & \MID & \LP\key{boolean?}\;\Exp\RP \MID \LP\key{integer?}\;\Exp\RP\\
-     & \MID & \LP\key{vector?}\;\Exp\RP \MID \LP\key{procedure?}\;\Exp\RP \MID \LP\key{void?}\;\Exp\RP \\
-  \Def &::=& \LP\key{define}\; \LP\Var \; \Var\ldots\RP \; \Exp\RP \\
 \LangDynM{}  &::=& \Def\ldots\; \Exp
 \end{array}
+\end{array}
 \]
 \fi}
 {\if\edition\pythonEd
@@ -16518,16 +16531,17 @@ be a tuple, not a Boolean.
     \small
 {\if\edition\racketEd
 \[
+\begin{array}{l}
+  \gray{\LintASTRacket{}} \\ \hline
+  \gray{\LvarASTRacket{}} \\ \hline
+  \gray{\LifASTRacket{}} \\ \hline
+  \gray{\LwhileASTRacket} \\ \hline
+  \gray{\LtupASTRacket} \\  \hline
+\LdynASTRacket \\
 \begin{array}{lcl}
-  \Exp &::=& \INT{\Int} \MID \VAR{\Var} \MID \LET{\Var}{\Exp}{\Exp} \\
-       &\MID& \PRIM{\itm{op}}{\Exp\ldots} \\
-     &\MID& \BOOL{\itm{bool}}
-      \MID \IF{\Exp}{\Exp}{\Exp}  \\
-     &\MID& \VOID{} \MID \APPLY{\Exp}{\Exp\ldots} \\
-     &\MID& \LAMBDA{\LP\Var\ldots\RP}{\code{'Any}}{\Exp}\\
- \Def &::=& \FUNDEF{\Var}{\LP\Var\ldots\RP}{\code{'Any}}{\code{'()}}{\Exp} \\
   \LangDynM{} &::=& \PROGRAMDEFSEXP{\code{'()}}{\LP\Def\ldots\RP}{\Exp} 
 \end{array}
+\end{array}
 \]
 \fi}
 {\if\edition\pythonEd
@@ -16571,8 +16585,8 @@ be a tuple, not a Boolean.
 The concrete and abstract syntax of \LangDyn{} is defined in
 Figures~\ref{fig:r7-concrete-syntax} and \ref{fig:r7-syntax}.
 %
-There is no type checker for \LangDyn{} because dynamically typed
-languages check types at runtime.
+There is no type checker for \LangDyn{} because it only checks types
+at runtime.
 
 The definitional interpreter for \LangDyn{} is presented in
 \racket{Figure~\ref{fig:interp-Ldyn}}
@@ -16642,9 +16656,9 @@ length of the vector.
 
 \begin{figure}[tbp]
 {\if\edition\racketEd
-\begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
-(define ((interp-Rdyn-exp env) ast)
-  (define recur (interp-Rdyn-exp env))
+\begin{lstlisting}
+(define ((interp-Ldyn-exp env) ast)
+  (define recur (interp-Ldyn-exp env))
   (match ast
     [(Var x) (dict-ref env x)]
     [(Int n) (Tagged n 'Integer)]
@@ -16666,7 +16680,7 @@ length of the vector.
        (error 'trapped-error "index ~a too big\nin ~v" (Tagged-value i) ast))
      (vector-set! (Tagged-value vec) (Tagged-value i) arg)
      (Tagged (void) 'Void)]
-    [(Let x e body) ((interp-Rdyn-exp (cons (cons x (recur e)) env)) body)]
+    [(Let x e body) ((interp-Ldyn-exp (cons (cons x (recur e)) env)) body)]
     [(Prim 'and (list e1 e2)) (recur (If e1 e2 (Bool #f)))]
     [(Prim 'or (list e1 e2))
      (define v1 (recur e1))
@@ -16693,8 +16707,8 @@ length of the vector.
         (unless (eq? (length xs) (length args))
          (error 'trapped-error "~a != ~a\nin ~v" (length args) (length xs) ast))
         (define new-env (append (map cons xs args) lam-env))
-        ((interp-Rdyn-exp new-env) body)]
-       [else (error "interp-Rdyn-exp, expected function, not" f-val)])]))
+        ((interp-Ldyn-exp new-env) body)]
+       [else (error "interp-Ldyn-exp, expected function, not" f-val)])]))
 \end{lstlisting}
 \fi}
 {\if\edition\pythonEd
@@ -16766,6 +16780,7 @@ class InterpLdyn(InterpLlambda):
 \label{fig:interp-Ldyn}
 \end{figure}
 
+{\if\edition\pythonEd
 \begin{figure}[tbp]
 \begin{lstlisting}[basicstyle=\ttfamily\footnotesize]
 class InterpLdyn(InterpLlambda):
@@ -16801,6 +16816,7 @@ class InterpLdyn(InterpLlambda):
 \caption{Interpreter for the \LangDyn{} language\python{, part 2}.}
 \label{fig:interp-Ldyn-2}
 \end{figure}
+\fi}
 
 \begin{figure}[tbp]
 {\if\edition\racketEd
@@ -16901,15 +16917,15 @@ values at the bit level. Because almost every operation in \LangDyn{}
 involves manipulating tagged values, the representation must be
 efficient. Recall that all of our values are 64 bits.  We shall steal
 the 3 right-most bits to encode the tag.  We use $001$ to identify
-integers, $100$ for Booleans, $010$ for vectors, $011$ for procedures,
+integers, $100$ for Booleans, $010$ for tuples, $011$ for procedures,
 and $101$ for the void value\python{, \key{None}}. We define the following auxiliary
 function for mapping types to tag codes.
 {\if\edition\racketEd
 \begin{align*}
 \itm{tagof}(\key{Integer}) &= 001 \\
 \itm{tagof}(\key{Boolean}) &= 100 \\
-\itm{tagof}((\key{Vector} \ldots)) &= 010 \\
-\itm{tagof}((\ldots \key{->} \ldots)) &= 011 \\
+\itm{tagof}(\LP\key{Vector} \ldots\RP) &= 010 \\
+\itm{tagof}(\LP\ldots \key{->} \ldots\RP) &= 011 \\
 \itm{tagof}(\key{Void}) &= 101
 \end{align*}
 \fi}
@@ -16924,28 +16940,29 @@ function for mapping types to tag codes.
 \fi}
 This stealing of 3 bits comes at some price: integers are now restricted
 to the range from $-2^{60}$ to $2^{60}$. The stealing does not adversely
-affect vectors and procedures because those values are addresses, and
+affect tuples and procedures because those values are addresses, and
 our addresses are 8-byte aligned so the rightmost 3 bits are unused,
 they are always $000$. Thus, we do not lose information by overwriting
 the rightmost 3 bits with the tag and we can simply zero-out the tag
 to recover the original address.
 
 To make tagged values into first-class entities, we can give them a
-type, called \racket{\code{Any}}\python{\code{AnyType()}}, and define operations
-such as \code{Inject} and \code{Project} for creating and using them,
-yielding the \LangAny{} intermediate language. We describe how to
-compile \LangDyn{} to \LangAny{} in Section~\ref{sec:compile-r7}
-but first we describe the \LangAny{} language in greater detail.
+type, called \racket{\code{Any}}\python{\code{AnyType()}}, and define
+operations such as \code{Inject} and \code{Project} for creating and
+using them, yielding the statically typed \LangAny{} intermediate
+language. We describe how to compile \LangDyn{} to \LangAny{} in
+Section~\ref{sec:compile-r7} but first we describe the \LangAny{}
+language in greater detail.
 
 \section{The \LangAny{} Language}
 \label{sec:Rany-lang}
 
 \newcommand{\LanyASTRacket}{
 \begin{array}{lcl}
-\Type &::= & \key{Any} \\
+\Type &::= & \ANYTY \\
 \FType &::=& \key{Integer} \MID \key{Boolean} \MID \key{Void} 
-      \MID \LP\key{Vector}\; \key{Any}\ldots\RP \\
-     &\MID& \LP\key{Any}\ldots \; \key{->}\; \key{Any}\RP\\
+      \MID \LP\key{Vector}\; \ANYTY\ldots\RP 
+      \MID \LP\ANYTY\ldots \; \key{->}\; \ANYTY\RP\\
 \itm{op} &::= & \code{any-vector-length}
      \MID \code{any-vector-ref} \MID \code{any-vector-set!}\\
     &\MID& \code{boolean?} \MID \code{integer?} \MID \code{vector?}
@@ -16988,15 +17005,6 @@ but first we describe the \LangAny{} language in greater detail.
   \gray{\LlambdaASTRacket} \\ \hline
   \LanyASTRacket \\
 \begin{array}{lcl}
-%% \Type &::= & \ldots \MID \key{Any} \\
-%% \itm{op} &::= & \ldots \MID \code{any-vector-length}
-%%      \MID \code{any-vector-ref} \MID \code{any-vector-set!}\\
-%%     &\MID& \code{boolean?} \MID \code{integer?} \MID \code{vector?}
-%%      \MID \code{procedure?} \MID \code{void?} \\
-%% \Exp &::=& \ldots
-%%      \MID \gray{ \PRIM{\itm{op}}{\Exp\ldots} } \\
-%%     &\MID& \INJECT{\Exp}{\FType} \MID \PROJECT{\Exp}{\FType} \\
-%%  \Def &::=& \gray{ \FUNDEF{\Var}{\LP[\Var \code{:} \Type]\ldots\RP}{\Type}{\code{'()}}{\Exp} }\\
   \LangAnyM{} &::=& \PROGRAMDEFSEXP{\code{'()}}{\LP\Def\ldots\RP}{\Exp}
 \end{array}
 \end{array}
@@ -17022,12 +17030,12 @@ but first we describe the \LangAny{} language in greater detail.
 \end{minipage}
 }
 \caption{The abstract syntax of \LangAny{}, extending \LangLam{} (Figure~\ref{fig:Rlam-syntax}).}
-\label{fig:Rany-syntax}
+\label{fig:Lany-syntax}
 \end{figure}
 
-The abstract syntax of \LangAny{} is defined in Figure~\ref{fig:Rany-syntax}.
+The abstract syntax of \LangAny{} is defined in Figure~\ref{fig:Lany-syntax}.
 %% \racket{(The concrete syntax of \LangAny{} is in the Appendix,
-%%   Figure~\ref{fig:Rany-concrete-syntax}.)}
+%%   Figure~\ref{fig:Lany-concrete-syntax}.)}
 The $\INJECT{e}{T}$ form
 converts the value produced by expression $e$ of type $T$ into a
 tagged value.  The $\PROJECT{e}{T}$ form converts the tagged value
@@ -17051,10 +17059,10 @@ to produce a tagged value; they return  {\TRUE} if the tag corresponds to
 the predicate and they return {\FALSE} otherwise.}
 
 The type checker for \LangAny{} is shown in
-Figure~\ref{fig:type-check-Rany}
+Figure~\ref{fig:type-check-Lany}
 %
 \racket{ and uses the auxiliary functions in
-Figure~\ref{fig:type-check-Rany-aux}}.
+Figure~\ref{fig:type-check-Lany-aux}}.
 %
 The interpreter for \LangAny{} is in Figure~\ref{fig:interp-Lany} and
 its auxiliary functions are in Figure~\ref{fig:interp-Lany-aux}.
@@ -17063,7 +17071,7 @@ its auxiliary functions are in Figure~\ref{fig:interp-Lany-aux}.
 \begin{figure}[btp]
 {\if\edition\racketEd
 \begin{lstlisting}[basicstyle=\ttfamily\small]
-(define type-check-Rany-class
+(define type-check-Lany-class
   (class type-check-Llambda-class
     (super-new)
     (inherit check-type-equal?)
@@ -17102,31 +17110,19 @@ its auxiliary functions are in Figure~\ref{fig:interp-Lany-aux}.
            (check-type-equal? t2 'Integer e)
            (check-type-equal? t3 'Any e)
            (values (Prim 'any-vector-set! (list e1^ e2^ e3^)) 'Void)]
-      [(ValueOf e ty)
-       (define-values (new-e e-ty) (recur e))
-       (values (ValueOf new-e ty) ty)]
-      [(Prim pred (list e1))
-       #:when (set-member? (type-predicates) pred)
-       (define-values (new-e1 e-ty) (recur e1))
-       (check-type-equal? e-ty 'Any e)
-       (values (Prim pred (list new-e1)) 'Boolean)]
-      [(If cnd thn els)
-       (define-values (cnd^ Tc) (recur cnd))
-       (define-values (thn^ Tt) (recur thn))
-       (define-values (els^ Te) (recur els))
-       (check-type-equal? Tc 'Boolean cnd)
-       (check-type-equal? Tt Te e)
-       (values (If cnd^ thn^ els^) (combine-types Tt Te))]
-      [(Exit) (values (Exit) '_)]
-      [(Prim 'eq? (list arg1 arg2))
-       (define-values (e1 t1) (recur arg1))
-       (define-values (e2 t2) (recur arg2))
-       (match* (t1 t2)
-         [(`(Vector ,ts1 ...) `(Vector ,ts2 ...))   (void)]
-         [(other wise) (check-type-equal? t1 t2 e)])
-       (values (Prim 'eq? (list e1 e2)) 'Boolean)]
-      [else ((super type-check-exp env) e)])))
-
+          [(Prim pred (list e1))
+           #:when (set-member? (type-predicates) pred)
+           (define-values (new-e1 e-ty) (recur e1))
+           (check-type-equal? e-ty 'Any e)
+           (values (Prim pred (list new-e1)) 'Boolean)]
+          [(Prim 'eq? (list arg1 arg2))
+           (define-values (e1 t1) (recur arg1))
+           (define-values (e2 t2) (recur arg2))
+           (match* (t1 t2)
+             [(`(Vector ,ts1 ...) `(Vector ,ts2 ...))   (void)]
+             [(other wise) (check-type-equal? t1 t2 e)])
+           (values (Prim 'eq? (list e1 e2)) 'Boolean)]
+          [else ((super type-check-exp env) e)])))
 ))
 \end{lstlisting}
 \fi}
@@ -17161,14 +17157,6 @@ class TypeCheckLany(TypeCheckLlambda):
         self.type_check_exp(value, env)
         self.check_exp(tag, IntType(), env)
         return AnyType()
-      case ValueOf(value, typ):
-        self.check_exp(value, AnyType(), env)
-        return typ
-      case TagOf(value):
-        self.check_exp(value, AnyType(), env)
-        return IntType()
-      case Call(Name('exit'), []):
-        return Bottom()
       case AnnLambda(params, returns, body):
         new_env = {x:t for (x,t) in env.items()}
         for (x,t) in params:
@@ -17181,7 +17169,7 @@ class TypeCheckLany(TypeCheckLlambda):
 \end{lstlisting}
 \fi}
 \caption{Type checker for the \LangAny{} language.}
-\label{fig:type-check-Rany}
+\label{fig:type-check-Lany}
 \end{figure}
 
 {\if\edition\racketEd
@@ -17193,32 +17181,15 @@ class TypeCheckLany(TypeCheckLlambda):
    '((integer? . ((Any) . Boolean))
      (vector? . ((Any) . Boolean))
      (procedure? . ((Any) . Boolean))
-     (void? . ((Any) . Boolean))
-     (tag-of-any . ((Any) . Integer))
-     (make-any . ((_ Integer) . Any)))
+     (void? . ((Any) . Boolean)))
    (super operator-types)))
 
 (define/public (type-predicates)
   (set 'boolean? 'integer? 'vector? 'procedure? 'void?))
 
-(define/public (combine-types t1 t2)
-  (match (list t1 t2)
-    [(list '_ t2) t2]
-    [(list t1 '_) t1]
-    [(list `(Vector ,ts1 ...)
-      `(Vector ,ts2 ...))
-      `(Vector ,@(for/list ([t1 ts1] [t2 ts2])
-      (combine-types t1 t2)))]
-    [(list `(,ts1 ... -> ,rt1)
-      `(,ts2 ... -> ,rt2))
-      `(,@(for/list ([t1 ts1] [t2 ts2])
-      (combine-types t1 t2))
-      -> ,(combine-types rt1 rt2))]
-    [else t1]))
-
 (define/public (flat-ty? ty)
   (match ty
-    [(or `Integer `Boolean '_ `Void) #t]
+    [(or `Integer `Boolean `Void) #t]
     [`(Vector ,ts ...) (for/and ([t ts]) (eq? t 'Any))]
     ['(Vectorof Any) #t]
     [`(,ts ... -> ,rt)
@@ -17227,7 +17198,7 @@ class TypeCheckLany(TypeCheckLlambda):
 \end{lstlisting}
 \fi}
 \caption{Auxiliary methods for type checking \LangAny{}.}
-\label{fig:type-check-Rany-aux}
+\label{fig:type-check-Lany-aux}
 \end{figure}
 \fi}
 
@@ -17318,32 +17289,9 @@ class InterpLany(InterpLlambda):
             return len(value)
           case _:
             raise Exception('interp any_len unexpected ' + repr(v))
-      case Call(Name('make_any'), [value, tag]):
-        v = self.interp_exp(value, env)
-        t = self.interp_exp(tag, env)
-        return Tagged(v, t)
       case Call(Name('arity'), [fun]):
         f = self.interp_exp(fun, env)
         return self.arity(f)
-      case Call(Name('exit'), []):
-        trace('exiting!')
-        exit(0)
-      case TagOf(value):
-        v = self.interp_exp(value, env)
-        match v:
-          case Tagged(val, tag):
-            return tag
-          case _:
-            raise Exception('interp TagOf unexpected ' + repr(v))
-      case ValueOf(value, typ):
-        v = self.interp_exp(value, env)
-        match v:
-          case Tagged(val, tag):
-            return val
-          case _:
-            raise Exception('interp ValueOf unexpected ' + repr(v))
-      case AnnLambda(params, returns, body):
-        return Function('lambda', [x for (x,t) in params], [Return(body)], env)
       case _:
         return super().interp_exp(e, env)
 \end{lstlisting}
@@ -17424,21 +17372,22 @@ class InterpLany(InterpLlambda):
 \label{sec:compile-r7}
 
 The \code{cast\_insert} pass compiles from \LangDyn{} to \LangAny{}.
-Figure~\ref{fig:compile-r7-Rany} shows the compilation of many of the
-\LangDyn{} forms into \LangAny{}. An important invariant of this pass is that
-given a subexpression $e$ in the \LangDyn{} program, the pass will produce
-an expression $e'$ in \LangAny{} that has type \ANYTY{}. For example, the
-first row in Figure~\ref{fig:compile-r7-Rany} shows the compilation of
-the Boolean \TRUE{}, which must be injected to produce an
-expression of type \ANYTY{}.
-%
-The second row of Figure~\ref{fig:compile-r7-Rany}, the compilation of
+Figure~\ref{fig:compile-r7-Lany} shows the compilation of many of the
+\LangDyn{} forms into \LangAny{}. An important invariant of this pass
+is that given any subexpression $e$ in the \LangDyn{} program, the
+pass will produce an expression $e'$ in \LangAny{} that has type
+\ANYTY{}. For example, the first row in
+Figure~\ref{fig:compile-r7-Lany} shows the compilation of the Boolean
+\TRUE{}, which must be injected to produce an expression of type
+\ANYTY{}.
+%
+The second row of Figure~\ref{fig:compile-r7-Lany}, the compilation of
 addition, is representative of compilation for many primitive
 operations: the arguments have type \ANYTY{} and must be projected to
 \INTTYPE{} before the addition can be performed.
 
 The compilation of \key{lambda} (third row of
-Figure~\ref{fig:compile-r7-Rany}) shows what happens when we need to
+Figure~\ref{fig:compile-r7-Lany}) shows what happens when we need to
 produce type annotations: we simply use \ANYTY{}.
 %
 % TODO:update the following for python, and the tests and interpreter. -Jeremy
@@ -17696,13 +17645,13 @@ Call(Name('any_tuple_load'),[|$e_1'$|, |$e_2'$|])
 \end{tabular} 
 \fi}
 \caption{Cast Insertion}
-\label{fig:compile-r7-Rany}
+\label{fig:compile-r7-Lany}
 \end{figure}
 
 
 
 \section{Reveal Casts}
-\label{sec:reveal-casts-Rany}
+\label{sec:reveal-casts-Lany}
 
 % TODO: define R'_6
 
@@ -17774,7 +17723,7 @@ that the number of parameters in the function type matches the
 function's arity.
 
 Regarding \code{Inject}, we recommend compiling it to a slightly
-lower-level primitive operation named \code{make\_any}. This operation
+lower-level primitive operation named \racket{\code{make-any}}\python{\code{make\_any}}. This operation
 takes a tag instead of a type.
 \begin{center}
 \begin{minipage}{1.0\textwidth}
@@ -17815,24 +17764,26 @@ translation of \code{Project}.}
 The \code{any-vector-ref} and \code{any-vector-set!} operations
 combine the projection action with the vector operation.  Also, the
 read and write operations allow arbitrary expressions for the index so
-the type checker for \LangAny{} (Figure~\ref{fig:type-check-Rany})
+the type checker for \LangAny{} (Figure~\ref{fig:type-check-Lany})
 cannot guarantee that the index is within bounds. Thus, we insert code
 to perform bounds checking at runtime. The translation for
 \code{any-vector-ref} is as follows and the other two operations are
 translated in a similar way.
-
+\begin{center}
+\begin{minipage}{0.95\textwidth}
 \begin{lstlisting}
 (Prim 'any-vector-ref (list |$e_1$| |$e_2$|))
 |$\Rightarrow$|
 (Let |$v$| |$e'_1$|
   (Let |$i$| |$e'_2$|
     (If (Prim 'eq? (list (Prim 'tag-of-any (list (Var |$v$|))) (Int 2)))
-      (If (Prim '< (list (Var |$i$|)
-            (Prim 'any-vector-length (list (Var |$v$|)))))
+      (If (Prim '< (list (Var |$i$|) (Prim 'any-vector-length (list (Var |$v$|)))))
         (Prim 'any-vector-ref (list (Var |$v$|) (Var |$i$|)))
         (Exit))
       (Exit))))
 \end{lstlisting}
+\end{minipage}
+\end{center}
 \fi}
 %
 {\if\edition\pythonEd
@@ -17840,7 +17791,7 @@ translated in a similar way.
 The \code{any\_tuple\_load} operation combines the projection action
 with the load operation.  Also, the load operation allows arbitrary
 expressions for the index so the type checker for \LangAny{}
-(Figure~\ref{fig:type-check-Rany}) cannot guarantee that the index is
+(Figure~\ref{fig:type-check-Lany}) cannot guarantee that the index is
 within bounds. Thus, we insert code to perform bounds checking at
 runtime. The translation for \code{any\_tuple\_load} is as follows.
 
@@ -17874,7 +17825,7 @@ Update this pass to handle the \code{TagOf}, \code{ValueOf}, and
 \fi}
 
 \section{Remove Complex Operands}
-\label{sec:rco-Rany}
+\label{sec:rco-Lany}
 
 \racket{The \code{ValueOf} and \code{Exit} forms are both complex
   expressions.  The subexpression of \code{ValueOf} must be atomic.}
@@ -17883,7 +17834,7 @@ Update this pass to handle the \code{TagOf}, \code{ValueOf}, and
   complex expressions.  Their subexpressions must be atomic.}
 
 \section{Explicate Control and \LangCAny{}}
-\label{sec:explicate-Rany}
+\label{sec:explicate-Lany}
 
 The output of \code{explicate\_control} is the \LangCAny{} language
 whose syntax is defined in Figure~\ref{fig:c5-syntax}.
@@ -17891,7 +17842,7 @@ whose syntax is defined in Figure~\ref{fig:c5-syntax}.
 \racket{The \code{ValueOf} form that we added to \LangAny{} remains an
   expression and the \code{Exit} expression becomes a $\Tail$. Also,
   note that the index argument of \code{vector-ref} and
-  \code{vector-set!} is an $\Atm$ instead of an integer, as in
+  \code{vector-set!} is an $\Atm$ instead of an integer, as it was in
   \LangCVec{} (Figure~\ref{fig:c2-syntax}).}
 %
 \python{
@@ -17913,26 +17864,32 @@ whose syntax is defined in Figure~\ref{fig:c5-syntax}.
 \end{array}
 }
 
+\newcommand{\CanyASTRacket}{
+\begin{array}{lcl}
+\Exp &::= & \BINOP{\key{'any-vector-ref}}{\Atm}{\Atm}  \\
+   &\MID& (\key{Prim}~\key{'any-vector-set!}\,(\key{list}\,\Atm\,\Atm\,\Atm))\\
+   &\MID& \VALUEOF{\Atm}{\FType} \\
+\Tail &::= & \LP\key{Exit}\RP 
+\end{array}
+}
+
 \begin{figure}[tp]
 \fbox{
 \begin{minipage}{0.96\textwidth}
 \small
 {\if\edition\racketEd
 \[
+\begin{array}{l}
+  \gray{\CvarASTRacket} \\ \hline
+  \gray{\CifASTRacket} \\ \hline
+  \gray{\CloopASTRacket} \\ \hline
+  \gray{\CtupASTRacket} \\ \hline
+  \gray{\CfunASTRacket} \\ \hline
+  \gray{\ClambdaASTRacket} \\ \hline
+  \CanyASTRacket \\
 \begin{array}{lcl}
-\Exp &::= & \ldots
-   \MID \BINOP{\key{'any-vector-ref}}{\Atm}{\Atm}  \\
-   &\MID& (\key{Prim}~\key{'any-vector-set!}\,(\key{list}\,\Atm\,\Atm\,\Atm))\\
-   &\MID& \VALUEOF{\Exp}{\FType} \\
-\Stmt &::=& \gray{ \ASSIGN{\VAR{\Var}}{\Exp} 
-  \MID \LP\key{Collect} \,\itm{int}\RP }\\
-\Tail &::= & \gray{ \RETURN{\Exp} \MID \SEQ{\Stmt}{\Tail} 
-       \MID \GOTO{\itm{label}} } \\
-    &\MID& \gray{ \IFSTMT{\BINOP{\itm{cmp}}{\Atm}{\Atm}}{\GOTO{\itm{label}}}{\GOTO{\itm{label}}}  }\\
-&\MID& \gray{ \TAILCALL{\Atm}{\Atm\ldots} } 
-  \MID \LP\key{Exit}\RP \\
-\Def &::=& \gray{ \DEF{\itm{label}}{\LP[\Var\key{:}\Type]\ldots\RP}{\Type}{\itm{info}}{\LP\LP\itm{label}\,\key{.}\,\Tail\RP\ldots\RP} }\\
-\LangCAnyM{} & ::= & \gray{ \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP} }
+\LangCAnyM{} & ::= & \PROGRAMDEFS{\itm{info}}{\LP\Def\ldots\RP}
+\end{array}
 \end{array}
 \]
 \fi}
@@ -17958,7 +17915,7 @@ whose syntax is defined in Figure~\ref{fig:c5-syntax}.
 
 
 \section{Select Instructions}
-\label{sec:select-Rany}
+\label{sec:select-Lany}
 
 In the \code{select\_instructions} pass we translate the primitive
 operations on the \ANYTY{} type to x86 instructions that manipulate
@@ -17966,10 +17923,11 @@ the 3 tag bits of the tagged value. In the following descriptions,
 given an atom $e$ we use a primed variable $e'$ to refer to the result
 of translating $e$ into an x86 argument.
 
-\paragraph{\code{make\_any}}
+\paragraph{\racket{\code{make-any}}\python{\code{make\_any}}}
 
-We recommend compiling the \code{make\_any} operation as follows if
-the tag is for \INTTY{} or \BOOLTY{}.  The \key{salq} instruction
+We recommend compiling the
+\racket{\code{make-any}}\python{\code{make\_any}} operation as follows
+if the tag is for \INTTY{} or \BOOLTY{}.  The \key{salq} instruction
 shifts the destination to the left by the number of bits specified its
 source argument (in this case $3$, the length of the tag) and it
 preserves the sign of the integer. We use the \key{orq} instruction to
@@ -18001,12 +17959,16 @@ bits are already zeros so we simply combine the value and the tag
 using \key{orq}.  \\
 %
 {\if\edition\racketEd
+\begin{center}
+\begin{minipage}{\textwidth}
 \begin{lstlisting}
 (Assign |\itm{lhs}| (Prim 'make-any (list |$e$| (Int |$\itm{tag}$|))))
 |$\Rightarrow$|
 movq |$e'$|, |\itm{lhs'}|
 orq $|$\itm{tag}$|, |\itm{lhs'}|
 \end{lstlisting}
+\end{minipage}
+\end{center}
 \fi}
 %
 {\if\edition\pythonEd
@@ -18018,12 +17980,12 @@ orq $|$\itm{tag}$|, |\itm{lhs'}|
 \end{lstlisting}
 \fi}
 
-\paragraph{\code{TagOf}}
+\paragraph{\racket{\code{tag-of-any}}\python{\code{TagOf}}}
 
-Recall that the \code{TagOf} operation extracts the type tag from a
-value of type \ANYTY{}. The type tag is the bottom three bits, so we
-obtain the tag by taking the bitwise-and of the value with $111$ ($7$
-in decimal).
+Recall that the \racket{\code{tag-of-any}}\python{\code{TagOf}}
+operation extracts the type tag from a value of type \ANYTY{}. The
+type tag is the bottom three bits, so we obtain the tag by taking the
+bitwise-and of the value with $111$ ($7$ in decimal).
 %
 {\if\edition\racketEd
 \begin{lstlisting}
@@ -18046,11 +18008,11 @@ andq $7, |\itm{lhs'}|
 
 \paragraph{\code{ValueOf}}
 
-Like \code{make\_any}, the instructions for \key{ValueOf} are
-different depending on whether the type $T$ is a pointer (tuple or
-function) or not (integer or Boolean). The following shows the
-instruction selection for integers and Booleans.  We produce an
-untagged value by shifting it to the right by 3 bits.
+The instructions for \key{ValueOf} also differ depending on whether
+the type $T$ is a pointer (tuple or function) or not (integer or
+Boolean). The following shows the instruction selection for integers
+and Booleans.  We produce an untagged value by shifting it to the
+right by 3 bits.
 %
 {\if\edition\racketEd
 \begin{lstlisting}
@@ -18070,12 +18032,12 @@ sarq $3, |\itm{lhs'}|
 \end{lstlisting}
 \fi}
 %
-In the case for tuples and procedures, we just need to zero-out the
-rightmost 3 bits. We accomplish this by creating the bit pattern
-$\ldots 0111$ ($7$ in decimal) and apply bitwise-not to obtain $\ldots
-11111000$ (-8 in decimal) which we \code{movq} into the destination
-$\itm{lhs'}$.  Finally, we apply \code{andq} with the tagged value to
-get the desired result.
+In the case for tuples and procedures, we zero-out the rightmost 3
+bits. We accomplish this by creating the bit pattern $\ldots 0111$
+($7$ in decimal) and apply bitwise-not to obtain $\ldots 11111000$ (-8
+in decimal) which we \code{movq} into the destination $\itm{lhs'}$.
+Finally, we apply \code{andq} with the tagged value to get the desired
+result.
 %
 {\if\edition\racketEd
 \begin{lstlisting}
@@ -18100,7 +18062,7 @@ andq |$e'$|, |\itm{lhs'}|
 %% devise a sequence of instructions to implement the type predicates
 %% \key{boolean?}, \key{integer?}, \key{vector?}, and \key{procedure?}.
 
-\paragraph{\racket{Any-vector-length}\python{\code{any\_len}}}
+\paragraph{\racket{\code{any-vector-length}}\python{\code{any\_len}}}
 
 The \racket{\code{any-vector-length}}\python{\code{any\_len}}
 operation combines the effect of \code{ValueOf} with accessing the
@@ -18131,7 +18093,7 @@ movq %r11, |$\itm{lhs'}$|
 \end{lstlisting}
 \fi}
 
-\paragraph{\racket{Any-vector-ref}\python{\code{\code{any\_tuple\_load}}}}
+\paragraph{\racket{\code{any-vector-ref}}\python{\code{\code{any\_tuple\_load}}}}
 
 This operation combines the effect of \code{ValueOf} with reading an
 element of the tuple (see
@@ -18171,7 +18133,7 @@ movq 0(%r11) |$\itm{lhs'}$|
 \end{minipage}
 \end{center}
 
-\paragraph{\racket{Any-vector-set!}\python{\code{any\_tuple\_store}}}
+\paragraph{\racket{\code{any-vector-set!}}\python{\code{any\_tuple\_store}}}
 
 The code generation for
 \racket{\code{any-vector-set!}}\python{\code{any\_tuple\_store}} is
@@ -18179,7 +18141,7 @@ analogous to the above translation for reading from a tuple.
 
 
 \section{Register Allocation for \LangAny{}}
-\label{sec:register-allocation-Rany}
+\label{sec:register-allocation-Lany}
 \index{subject}{register allocation}
 
 There is an interesting interaction between tagged values and garbage
@@ -18235,14 +18197,15 @@ completion without error.
 \node (Lfun-2) at (3,4)  {\large \LangDyn{}};
 \node (Lfun-3) at (6,4)  {\large \LangDyn{}};
 \node (Lfun-4) at (9,4)  {\large \LangDynFunRef{}};
-\node (Lfun-5) at (9,2)  {\large \LangAnyFunRef{}};
-\node (Lfun-6) at (12,2)  {\large \LangAnyFunRef{}};
-\node (Lfun-7) at (12,0)  {\large \LangAnyFunRef{}};
-
-\node (F1-2) at (9,0)  {\large \LangAnyFunRef{}};
-\node (F1-3) at (6,0)  {\large \LangAnyFunRef{}};
-\node (F1-4) at (3,0)  {\large \LangAnyAlloc{}};
-\node (F1-5) at (0,0)  {\large \LangAnyAlloc{}};
+\node (Lfun-5) at (12,2)  {\large \LangAnyFunRef{}};
+\node (Lfun-6) at (9,2)  {\large \LangAnyFunRef{}};
+\node (Lfun-7) at (6,2)  {\large \LangAnyFunRef{}};
+
+\node (F1-2) at (3,2)  {\large \LangAnyFunRef{}};
+\node (F1-3) at (0,2)  {\large \LangAnyFunRef{}};
+\node (F1-4) at (0,0)  {\large \LangAnyAlloc{}};
+\node (F1-5) at (3,0)  {\large \LangAnyAlloc{}};
+\node (F1-6) at (6,0)  {\large \LangAnyAlloc{}};
 \node (C3-2) at (3,-2)  {\large \LangCAny{}};
 
 \node (x86-2) at (3,-4)  {\large \LangXIndCallVar{}};
@@ -18258,22 +18221,24 @@ completion without error.
      {\ttfamily\footnotesize uniquify} (Lfun-3);
 \path[->,bend left=15] (Lfun-3) edge [above] node
      {\ttfamily\footnotesize reveal\_functions} (Lfun-4);
-\path[->,bend right=15] (Lfun-4) edge [left] node
+\path[->,bend left=15] (Lfun-4) edge [left] node
      {\ttfamily\footnotesize cast\_insert} (Lfun-5);
-\path[->,bend left=15] (Lfun-5) edge [above] node
+\path[->,bend left=15] (Lfun-5) edge [below] node
      {\ttfamily\footnotesize reveal\_casts} (Lfun-6);
-\path[->,bend left=15] (Lfun-6) edge [left] node
+\path[->,bend left=15] (Lfun-6) edge [below] node
      {\ttfamily\footnotesize convert\_assign.} (Lfun-7);
      
-\path[->,bend left=15] (Lfun-7) edge [below] node
+\path[->,bend right=15] (Lfun-7) edge [above] node
      {\ttfamily\footnotesize convert\_to\_clos.} (F1-2);
 \path[->,bend right=15] (F1-2) edge [above] node
      {\ttfamily\footnotesize limit\_fun.} (F1-3);
-\path[->,bend right=15] (F1-3) edge [above] node
+\path[->,bend right=15] (F1-3) edge [right] node
      {\ttfamily\footnotesize expose\_alloc.} (F1-4);
-\path[->,bend right=15] (F1-4) edge [above] node
-     {\ttfamily\footnotesize remove\_complex.} (F1-5);
-\path[->,bend right=15] (F1-5) edge [right] node
+\path[->,bend right=15] (F1-4) edge [below] node
+     {\ttfamily\footnotesize uncover\_get!} (F1-5);
+\path[->,bend left=15] (F1-5) edge [above] node
+     {\ttfamily\footnotesize remove\_complex.} (F1-6);
+\path[->,bend left=15] (F1-6) edge [right] node
      {\ttfamily\footnotesize explicate\_control} (C3-2);
 \path[->,bend left=15] (C3-2) edge [left] node
      {\ttfamily\footnotesize select\_instr.} (x86-2);
@@ -18286,13 +18251,13 @@ completion without error.
 \path[->,bend left=15] (x86-3) edge [above] node
      {\ttfamily\footnotesize patch\_instr.} (x86-4);
 \path[->,bend left=15] (x86-4) edge [right] node
-     {\ttfamily\footnotesize print\_x86} (x86-5);
+     {\ttfamily\footnotesize prelude\_and\_conc.} (x86-5);
 \end{tikzpicture}
   \caption{Diagram of the passes for \LangDyn{}, a dynamically typed language.}
-\label{fig:Rdyn-passes}
+\label{fig:Ldyn-passes}
 \end{figure}
 
-Figure~\ref{fig:Rdyn-passes} provides an overview of all the passes needed
+Figure~\ref{fig:Ldyn-passes} provides an overview of the passes needed
 for the compilation of \LangDyn{}.
 
 % Further Reading
@@ -19241,7 +19206,7 @@ before the \code{vector-ref}.
 \label{sec:reveal-casts-gradual}
 
 Recall that the \code{reveal-casts} pass
-(Section~\ref{sec:reveal-casts-Rany}) is responsible for lowering
+(Section~\ref{sec:reveal-casts-Lany}) is responsible for lowering
 \code{Inject} and \code{Project} into lower-level operations.  In
 particular, \code{Project} turns into a conditional expression that
 inspects the tag and retrieves the underlying value.  Here we need to
@@ -19336,7 +19301,7 @@ We have another batch of vector operations to deal with, those for the
 \code{any-vector-ref} when there is a \code{vector-ref} on something
 of type \code{Any}, and similarly for \code{any-vector-set!}  and
 \code{any-vector-length} (Figure~\ref{fig:type-check-Rgradual-1}). In
-Section~\ref{sec:select-Rany} we selected instructions for these
+Section~\ref{sec:select-Lany} we selected instructions for these
 operations based on the idea that the underlying value was a real
 vector. But in the current setting, the underlying value is of type
 \code{PVector}. So \code{any-vector-ref} can be translates to
@@ -20322,7 +20287,7 @@ registers.
 %% \section{Concrete Syntax for Intermediate Languages}
 
 %% The concrete syntax of \LangAny{} is defined in
-%% Figure~\ref{fig:Rany-concrete-syntax}.
+%% Figure~\ref{fig:Lany-concrete-syntax}.
 
 %% \begin{figure}[tp]
 %% \centering
@@ -20351,7 +20316,7 @@ registers.
 %% }
 %% \caption{The concrete syntax of \LangAny{}, extending \LangLam{}
 %%   (Figure~\ref{fig:Rlam-syntax}).}
-%% \label{fig:Rany-concrete-syntax}
+%% \label{fig:Lany-concrete-syntax}
 %% \end{figure}
 
 %% The concrete syntax for \LangCVar{}, \LangCIf{}, \LangCVec{} and
@@ -20491,5 +20456,5 @@ registers.
 % LocalWords:  Llambda InterpLlambda AnnAssign Dunfield bodyT str fvs
 % LocalWords:  TypeCheckLlambda annot dereference clos fvts closTy
 % LocalWords:  Minamide AllocateClosure Gilray Milner morphos subtype
-% LocalWords:  polymorphism untyped AnyType dataclass untag Rdyn
+% LocalWords:  polymorphism untyped AnyType dataclass untag Ldyn
 % LocalWords:  lookup

+ 1 - 1
defs.tex

@@ -154,7 +154,7 @@
 \newcommand{\INTTYPE}{{\key{Integer}}}
 \newcommand{\BOOLTY}{{\key{Boolean}}}
 \newcommand{\VECTY}[1]{{\LP\key{Vector}~#1\RP}}
-\newcommand{\ANYTY}{{\key{any}}}
+\newcommand{\ANYTY}{{\key{Any}}}
 \newcommand{\CPROGRAM}[2]{\LP\code{CProgram}~#1~#2\RP}
 \newcommand{\CPROGRAMDEFS}[2]{\LP\code{CProgramDefs}~#1~#2\RP}
 \newcommand{\LET}[3]{\key{(Let}~#1~#2~#3\key{)}}