|
@@ -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
|