|
@@ -1070,12 +1070,12 @@ Appendix~\ref{appendix:utilities}.\\
|
|
\chapter{Integers and Variables}
|
|
\chapter{Integers and Variables}
|
|
\label{ch:int-exp}
|
|
\label{ch:int-exp}
|
|
|
|
|
|
-This chapter is about compiling the subset of Racket that includes
|
|
|
|
-integer arithmetic and local variable binding, which we name $R_1$, to
|
|
|
|
-x86-64 assembly code~\citep{Intel:2015aa}. Henceforth we refer
|
|
|
|
-to x86-64 simply as x86. The chapter begins with a description of the
|
|
|
|
-$R_1$ language (Section~\ref{sec:s0}) followed by a description of x86
|
|
|
|
-(Section~\ref{sec:x86}). The x86 assembly language is large, so we
|
|
|
|
|
|
+This chapter is about compiling a subset of Racket named $R_1$, that
|
|
|
|
+includes integer arithmetic and local variable binding, to x86-64
|
|
|
|
+assembly code~\citep{Intel:2015aa}. Henceforth we refer to x86-64
|
|
|
|
+simply as x86. The chapter begins with a description of the $R_1$
|
|
|
|
+language (Section~\ref{sec:s0}) followed by a description of x86
|
|
|
|
+(Section~\ref{sec:x86}). The x86 assembly language is large so we
|
|
discuss only what is needed for compiling $R_1$. We introduce more of
|
|
discuss only what is needed for compiling $R_1$. We introduce more of
|
|
x86 in later chapters. Once we have introduced $R_1$ and x86, we
|
|
x86 in later chapters. Once we have introduced $R_1$ and x86, we
|
|
reflect on their differences and come up with a plan to break down the
|
|
reflect on their differences and come up with a plan to break down the
|
|
@@ -1085,10 +1085,9 @@ chapter give detailed hints regarding each step
|
|
(Sections~\ref{sec:uniquify-s0} through \ref{sec:patch-s0}). We hope
|
|
(Sections~\ref{sec:uniquify-s0} through \ref{sec:patch-s0}). We hope
|
|
to give enough hints that the well-prepared reader, together with a
|
|
to give enough hints that the well-prepared reader, together with a
|
|
few friends, can implement a compiler from $R_1$ to x86 in a couple
|
|
few friends, can implement a compiler from $R_1$ to x86 in a couple
|
|
-weeks while at the same time leaving room for some fun and creativity.
|
|
|
|
-To give the reader a feeling for the scale of this first compiler, the
|
|
|
|
-instructor solution for the $R_1$ compiler is less than 500 lines of
|
|
|
|
-code.
|
|
|
|
|
|
+weeks. To give the reader a feeling for the scale of this first
|
|
|
|
+compiler, the instructor solution for the $R_1$ compiler is
|
|
|
|
+approximately 500 lines of code.
|
|
|
|
|
|
\section{The $R_1$ Language}
|
|
\section{The $R_1$ Language}
|
|
\label{sec:s0}
|
|
\label{sec:s0}
|
|
@@ -1241,7 +1240,7 @@ provide open recursion in the form of method overriding\index{method
|
|
$R_1$ and $R_2$ using the
|
|
$R_1$ and $R_2$ using the
|
|
\href{https://docs.racket-lang.org/guide/classes.html}{\code{class}}
|
|
\href{https://docs.racket-lang.org/guide/classes.html}{\code{class}}
|
|
\index{class} feature of Racket. We define one class for each
|
|
\index{class} feature of Racket. We define one class for each
|
|
-language and place a method for interpreting expressions inside each
|
|
|
|
|
|
+language and define a method for interpreting expressions inside each
|
|
class. The class for $R_2$ inherits from the class for $R_1$ and the
|
|
class. The class for $R_2$ inherits from the class for $R_1$ and the
|
|
method \code{interp-exp} for $R_2$ overrides the \code{interp-exp} for
|
|
method \code{interp-exp} for $R_2$ overrides the \code{interp-exp} for
|
|
$R_1$. Note that the default case in \code{interp-exp} for $R_2$ uses
|
|
$R_1$. Note that the default case in \code{interp-exp} for $R_2$ uses
|
|
@@ -1404,7 +1403,7 @@ The goal for this chapter is to implement a compiler that translates
|
|
any program $P_1$ written in the $R_1$ language into an x86 assembly
|
|
any program $P_1$ written in the $R_1$ language into an x86 assembly
|
|
program $P_2$ such that $P_2$ exhibits the same behavior when run on a
|
|
program $P_2$ such that $P_2$ exhibits the same behavior when run on a
|
|
computer as the $P_1$ program interpreted by \code{interp-R1}. That
|
|
computer as the $P_1$ program interpreted by \code{interp-R1}. That
|
|
-is, they both output the same integer $n$. We depict this correctness
|
|
|
|
|
|
+is, they output the same integer $n$. We depict this correctness
|
|
criteria in the following diagram.
|
|
criteria in the following diagram.
|
|
\[
|
|
\[
|
|
\begin{tikzpicture}[baseline=(current bounding box.center)]
|
|
\begin{tikzpicture}[baseline=(current bounding box.center)]
|
|
@@ -2600,11 +2599,9 @@ Adapt the partial evaluator from Section~\ref{sec:partial-evaluation}
|
|
(Figure~\ref{fig:pe-arith}) so that it applies to $R_1$ programs
|
|
(Figure~\ref{fig:pe-arith}) so that it applies to $R_1$ programs
|
|
instead of $R_0$ programs. Recall that $R_1$ adds \key{let} binding
|
|
instead of $R_0$ programs. Recall that $R_1$ adds \key{let} binding
|
|
and variables to the $R_0$ language, so you will need to add cases for
|
|
and variables to the $R_0$ language, so you will need to add cases for
|
|
-them in the \code{pe-exp} function. Also, note that the \key{program}
|
|
|
|
-form changes slightly to include an $\itm{info}$ field. Once
|
|
|
|
-complete, add the partial evaluation pass to the front of your
|
|
|
|
-compiler and make sure that your compiler still passes all of the
|
|
|
|
-tests.
|
|
|
|
|
|
+them in the \code{pe-exp} function. Once complete, add the partial
|
|
|
|
+evaluation pass to the front of your compiler and make sure that your
|
|
|
|
+compiler still passes all of the tests.
|
|
\end{exercise}
|
|
\end{exercise}
|
|
|
|
|
|
The next exercise builds on Exercise~\ref{ex:pe-R1}.
|
|
The next exercise builds on Exercise~\ref{ex:pe-R1}.
|