瀏覽代碼

starting on python ch. 2

Jeremy Siek 3 年之前
父節點
當前提交
8dc281a68b
共有 2 個文件被更改,包括 82 次插入22 次删除
  1. 62 19
      book.tex
  2. 20 3
      defs.tex

+ 62 - 19
book.tex

@@ -23,7 +23,7 @@
 
 
 \def\racketEd{0}
 \def\racketEd{0}
 \def\pythonEd{1}
 \def\pythonEd{1}
-\def\edition{0}
+\def\edition{1}
 
 
 % material that is specific to the Racket edition of the book
 % material that is specific to the Racket edition of the book
 \newcommand{\racket}[1]{{\if\edition\racketEd\color{olive}{#1}\fi}}
 \newcommand{\racket}[1]{{\if\edition\racketEd\color{olive}{#1}\fi}}
@@ -838,24 +838,20 @@ defined in Figure~\ref{fig:r0-concrete-syntax}.
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
 {\if\edition\racketEd\color{olive}    
 {\if\edition\racketEd\color{olive}    
 \[
 \[
-\begin{array}{rcl}
 \begin{array}{rcl}
 \begin{array}{rcl}
   \Exp &::=& \Int \mid \LP\key{read}\RP \mid \LP\key{-}\;\Exp\RP \mid \LP\key{+} \; \Exp\;\Exp\RP\\
   \Exp &::=& \Int \mid \LP\key{read}\RP \mid \LP\key{-}\;\Exp\RP \mid \LP\key{+} \; \Exp\;\Exp\RP\\
   \LangInt{} &::=& \Exp
   \LangInt{} &::=& \Exp
 \end{array}
 \end{array}
-\end{array}
 \]
 \]
 \fi}
 \fi}
 
 
 {\if\edition\pythonEd\color{purple}
 {\if\edition\pythonEd\color{purple}
 \[
 \[
-\begin{array}{rcl}
 \begin{array}{rcl}
 \begin{array}{rcl}
   \Exp &::=& \Int \mid \key{input\_int}\LP\RP \mid \key{-}\;\Exp \mid \Exp \; \key{+} \; \Exp\\
   \Exp &::=& \Int \mid \key{input\_int}\LP\RP \mid \key{-}\;\Exp \mid \Exp \; \key{+} \; \Exp\\
   \Stmt &::=& \key{print}\LP \Exp \RP \mid \Exp\\
   \Stmt &::=& \key{print}\LP \Exp \RP \mid \Exp\\
   \LangInt{} &::=& \Stmt^{*}
   \LangInt{} &::=& \Stmt^{*}
 \end{array}
 \end{array}
-\end{array}
 \]
 \]
 \fi}
 \fi}
 
 
@@ -1533,9 +1529,7 @@ def pe_add(r1, r2):
 def pe_exp(e):
 def pe_exp(e):
   match e:
   match e:
     case BinOp(left, Add(), right):
     case BinOp(left, Add(), right):
-      l = pe_exp(left)
-      r = pe_exp(right)
-      return pe_add(l, r)
+      return pe_add(pe_exp(left), pe_exp(right))
     case UnaryOp(USub(), v):
     case UnaryOp(USub(), v):
       return pe_neg(pe_exp(v))
       return pe_neg(pe_exp(v))
     case Constant(value):
     case Constant(value):
@@ -1590,7 +1584,8 @@ Appendix~\ref{appendix:utilities}.\\
 \chapter{Integers and Variables}
 \chapter{Integers and Variables}
 \label{ch:Rvar}
 \label{ch:Rvar}
 
 
-This chapter is about compiling a subset of Racket to x86-64 assembly
+This chapter is about compiling a subset of \racket{Racket}\python{Python}
+to x86-64 assembly
 code~\citep{Intel:2015aa}. The subset, named \LangVar{}, includes
 code~\citep{Intel:2015aa}. The subset, named \LangVar{}, includes
 integer arithmetic and local variable binding.  We often refer to
 integer arithmetic and local variable binding.  We often refer to
 x86-64 simply as x86.  The chapter begins with a description of the
 x86-64 simply as x86.  The chapter begins with a description of the
@@ -1607,20 +1602,22 @@ We hope to give enough hints that the well-prepared reader, together
 with a few friends, can implement a compiler from \LangVar{} to x86 in
 with a few friends, can implement a compiler from \LangVar{} to x86 in
 a couple weeks.  To give the reader a feeling for the scale of this
 a couple weeks.  To give the reader a feeling for the scale of this
 first compiler, the instructor solution for the \LangVar{} compiler is
 first compiler, the instructor solution for the \LangVar{} compiler is
-approximately 500 lines of code.
+approximately \racket{500}\python{300} lines of code.
 
 
 \section{The \LangVar{} Language}
 \section{The \LangVar{} Language}
 \label{sec:s0}
 \label{sec:s0}
 \index{subject}{variable}
 \index{subject}{variable}
 
 
-The \LangVar{} language extends the \LangInt{} language with variable
-definitions.  The concrete syntax of the \LangVar{} language is defined by
-the grammar in Figure~\ref{fig:Rvar-concrete-syntax} and the abstract
-syntax is defined in Figure~\ref{fig:Rvar-syntax}.  The non-terminal
-\Var{} may be any Racket identifier. As in \LangInt{}, \key{read} is a
-nullary operator, \key{-} is a unary operator, and \key{+} is a binary
-operator.  Similar to \LangInt{}, the abstract syntax of \LangVar{} includes the
-\key{Program} struct to mark the top of the program.
+The \LangVar{} language extends the \LangInt{} language with
+variables.  The concrete syntax of the \LangVar{} language is defined
+by the grammar in Figure~\ref{fig:Rvar-concrete-syntax} and the
+abstract syntax is defined in Figure~\ref{fig:Rvar-syntax}.  The
+non-terminal \Var{} may be any Racket identifier. As in \LangInt{},
+\key{read} is a nullary operator, \key{-} is a unary operator, and
+\key{+} is a binary operator.  Similar to \LangInt{}, the abstract
+syntax of \LangVar{} includes the \racket{\key{Program}
+  struct}\python{\key{Module} instance} to mark the top of the
+program.
 %% The $\itm{info}$
 %% The $\itm{info}$
 %% field of the \key{Program} structure contains an \emph{association
 %% field of the \key{Program} structure contains an \emph{association
 %%   list} (a list of key-value pairs) that is used to communicate
 %%   list} (a list of key-value pairs) that is used to communicate
@@ -1632,6 +1629,7 @@ exhibit several compilation techniques.
 \centering
 \centering
 \fbox{
 \fbox{
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
+{\if\edition\racketEd\color{olive}
 \[
 \[
 \begin{array}{rcl}
 \begin{array}{rcl}
   \Exp &::=& \Int{} \mid \CREAD{} \mid \CNEG{\Exp} \mid \CADD{\Exp}{\Exp}\\
   \Exp &::=& \Int{} \mid \CREAD{} \mid \CNEG{\Exp} \mid \CADD{\Exp}{\Exp}\\
@@ -1639,6 +1637,16 @@ exhibit several compilation techniques.
   \LangVarM{} &::=& \Exp
   \LangVarM{} &::=& \Exp
 \end{array}
 \end{array}
 \]
 \]
+\fi}
+{\if\edition\pythonEd\color{purple}
+\[
+\begin{array}{rcl}
+  \Exp &::=& \Int \mid \key{input\_int}\LP\RP \mid \key{-}\;\Exp \mid \Exp \; \key{+} \; \Exp \mid \Var{} \\
+  \Stmt &::=& \key{print}\LP \Exp \RP \mid \Exp \mid \Var\mathop{\key{=}}\Exp\\
+  \LangVarM{} &::=& \Stmt^{*}
+\end{array}
+\]
+\fi}
 \end{minipage}
 \end{minipage}
 }
 }
 \caption{The concrete syntax of \LangVar{}.}
 \caption{The concrete syntax of \LangVar{}.}
@@ -1649,6 +1657,7 @@ exhibit several compilation techniques.
 \centering
 \centering
 \fbox{
 \fbox{
 \begin{minipage}{0.96\textwidth}
 \begin{minipage}{0.96\textwidth}
+{\if\edition\racketEd\color{olive}
 \[
 \[
 \begin{array}{rcl}
 \begin{array}{rcl}
 \Exp &::=& \INT{\Int} \mid \READ{} \\
 \Exp &::=& \INT{\Int} \mid \READ{} \\
@@ -1657,12 +1666,25 @@ exhibit several compilation techniques.
 \LangVarM{} &::=& \PROGRAM{\code{'()}}{\Exp}
 \LangVarM{} &::=& \PROGRAM{\code{'()}}{\Exp}
 \end{array}
 \end{array}
 \]
 \]
+\fi}
+{\if\edition\pythonEd\color{purple}
+\[
+\begin{array}{rcl}
+\Exp{} &::=& \INT{\Int} \mid \READ{} \\
+       &\mid& \NEG{\Exp} \mid  \ADD{\Exp}{\Exp} \mid \VAR{\Var{}} \\
+\Stmt{} &::=& \PRINT{\Exp} \mid \EXPR{\Exp} \\
+        &\mid& \ASSIGN{\VAR{\Var}}{\Exp}\\
+\LangInt{}  &::=& \PROGRAM{}{\Stmt^{*}}
+\end{array}
+\]
+\fi}
 \end{minipage}
 \end{minipage}
 }
 }
 \caption{The abstract syntax of \LangVar{}.}
 \caption{The abstract syntax of \LangVar{}.}
 \label{fig:Rvar-syntax}
 \label{fig:Rvar-syntax}
 \end{figure}
 \end{figure}
 
 
+{\if\edition\racketEd\color{olive}
 Let us dive further into the syntax and semantics of the \LangVar{}
 Let us dive further into the syntax and semantics of the \LangVar{}
 language.  The \key{let} feature defines a variable for use within its
 language.  The \key{let} feature defines a variable for use within its
 body and initializes the variable with the value of an expression.
 body and initializes the variable with the value of an expression.
@@ -1676,6 +1698,26 @@ evaluates the body \code{(+ 10 x)}, producing $42$.
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x (+ 12 20)]) (+ 10 x))
 (let ([x (+ 12 20)]) (+ 10 x))
 \end{lstlisting}
 \end{lstlisting}
+\fi}
+%
+{\if\edition\pythonEd\color{purple}
+The \LangVar{} language adds variables and the assignment statement
+to \LangInt{}.  The assignment statement defines a variable for use by
+later statements and initializes the variable with the value of an expression.
+The abstract syntax for assignment is defined in
+Figure~\ref{fig:Rvar-syntax}.  The concrete syntax for assignment is
+\begin{lstlisting}
+|$\itm{var}$| = |$\itm{exp}$|
+\end{lstlisting}
+For example, the following program initializes \code{x} to $32$ and then
+prints the result of \code{10 + x}, producing $42$.
+\begin{lstlisting}
+x = 12 + 20
+print(10 + x)
+\end{lstlisting}
+\fi}
+
+{\if\edition\racketEd\color{olive}
 When there are multiple \key{let}'s for the same variable, the closest
 When there are multiple \key{let}'s for the same variable, the closest
 enclosing \key{let} is used. That is, variable definitions overshadow
 enclosing \key{let} is used. That is, variable definitions overshadow
 prior definitions. Consider the following program with two \key{let}'s
 prior definitions. Consider the following program with two \key{let}'s
@@ -1698,6 +1740,7 @@ $52$ then $10$, the following produces $42$ (not $-42$).
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x (read)]) (let ([y (read)]) (+ x (- y))))
 (let ([x (read)]) (let ([y (read)]) (+ x (- y))))
 \end{lstlisting}
 \end{lstlisting}
+\fi}
 
 
 \subsection{Extensible Interpreters via Method Overriding}
 \subsection{Extensible Interpreters via Method Overriding}
 \label{sec:extensible-interp}
 \label{sec:extensible-interp}
@@ -1708,7 +1751,7 @@ object-oriented programming, that is, as a collection of methods
 inside of a class. Throughout this book we define many interpreters,
 inside of a class. Throughout this book we define many interpreters,
 one for each of the languages that we study. Because each language
 one for each of the languages that we study. Because each language
 builds on the prior one, there is a lot of commonality between these
 builds on the prior one, there is a lot of commonality between these
-interpreters. We want to write down those common parts just once
+interpreters. We want to write down the common parts just once
 instead of many times. A naive approach would be to have, for example,
 instead of many times. A naive approach would be to have, for example,
 the interpreter for \LangIf{} handle all of the new features in that
 the interpreter for \LangIf{} handle all of the new features in that
 language and then have a default case that dispatches to the
 language and then have a default case that dispatches to the

+ 20 - 3
defs.tex

@@ -5,20 +5,27 @@
 
 
 \if\edition\racketEd
 \if\edition\racketEd
 \newcommand{\LangInt}{\ensuremath{R_{\mathsf{Int}}}} % R0
 \newcommand{\LangInt}{\ensuremath{R_{\mathsf{Int}}}} % R0
+
 \newcommand{\LangVar}{$R_{\mathsf{Var}}$} % R1
 \newcommand{\LangVar}{$R_{\mathsf{Var}}$} % R1
+\newcommand{\LangVarM}{R_{\mathsf{Var}}}
+
+\newcommand{\LangIf}{$R_{\mathsf{If}}$} %R2
 \fi
 \fi
+
 \if\edition\pythonEd
 \if\edition\pythonEd
 \newcommand{\LangInt}{\ensuremath{P_{\mathsf{Int}}}} % R0
 \newcommand{\LangInt}{\ensuremath{P_{\mathsf{Int}}}} % R0
+
 \newcommand{\LangVar}{$P_{\mathsf{Var}}$} % R1
 \newcommand{\LangVar}{$P_{\mathsf{Var}}$} % R1
+\newcommand{\LangVarM}{P_{\mathsf{Var}}}
+
+\newcommand{\LangIf}{$P_{\mathsf{If}}$} %R2
 \fi
 \fi
 
 
-\newcommand{\LangVarM}{R_{\mathsf{Var}}}
 
 
 \newcommand{\LangCVar}{$C_{\mathsf{Var}}$} % C0
 \newcommand{\LangCVar}{$C_{\mathsf{Var}}$} % C0
 \newcommand{\LangCVarM}{C_{\mathsf{Var}}} % C0
 \newcommand{\LangCVarM}{C_{\mathsf{Var}}} % C0
 \newcommand{\LangVarANF}{\ensuremath{R^{\mathsf{ANF}}_{\mathsf{Var}}}}
 \newcommand{\LangVarANF}{\ensuremath{R^{\mathsf{ANF}}_{\mathsf{Var}}}}
 \newcommand{\LangVarANFM}{R^{\mathsf{ANF}}_{\mathsf{Var}}}
 \newcommand{\LangVarANFM}{R^{\mathsf{ANF}}_{\mathsf{Var}}}
-\newcommand{\LangIf}{$R_{\mathsf{If}}$} %R2
 \newcommand{\LangIfM}{\ensuremath{R_{\mathsf{If}}}} %R2
 \newcommand{\LangIfM}{\ensuremath{R_{\mathsf{If}}}} %R2
 \newcommand{\LangCIf}{$C_{\mathsf{If}}$} %C1
 \newcommand{\LangCIf}{$C_{\mathsf{If}}$} %C1
 \newcommand{\LangCIfM}{\ensuremath{C_{\mathsf{If}}}} %C1
 \newcommand{\LangCIfM}{\ensuremath{C_{\mathsf{If}}}} %C1
@@ -110,6 +117,7 @@
 \newcommand{\RP}[0]{\key{)}}
 \newcommand{\RP}[0]{\key{)}}
 \newcommand{\LS}[0]{\key{[}}
 \newcommand{\LS}[0]{\key{[}}
 \newcommand{\RS}[0]{\key{]}}
 \newcommand{\RS}[0]{\key{]}}
+
 \if\edition\racketEd
 \if\edition\racketEd
 \newcommand{\INT}[1]{{\color{olive}\key{(Int}~#1\key{)}}}
 \newcommand{\INT}[1]{{\color{olive}\key{(Int}~#1\key{)}}}
 \newcommand{\READOP}{{\color{olive}\key{read}}}
 \newcommand{\READOP}{{\color{olive}\key{read}}}
@@ -117,7 +125,9 @@
 \newcommand{\NEG}[1]{{\color{olive}\key{(Prim}~\code{-}~\code{(}#1\code{))}}}
 \newcommand{\NEG}[1]{{\color{olive}\key{(Prim}~\code{-}~\code{(}#1\code{))}}}
 \newcommand{\ADD}[2]{{\color{olive}\key{(Prim}~\code{+}~\code{(}#1~#2\code{))}}}
 \newcommand{\ADD}[2]{{\color{olive}\key{(Prim}~\code{+}~\code{(}#1~#2\code{))}}}
 \newcommand{\PROGRAM}[2]{\LP\code{Program}~#1~#2\RP}
 \newcommand{\PROGRAM}[2]{\LP\code{Program}~#1~#2\RP}
+\newcommand{\VAR}[1]{\key{(Var}~#1\key{)}}
 \fi
 \fi
+
 \if\edition\pythonEd
 \if\edition\pythonEd
 \newcommand{\INT}[1]{{\color{purple}\key{Constant(}#1\key{)}}}
 \newcommand{\INT}[1]{{\color{purple}\key{Constant(}#1\key{)}}}
 \newcommand{\READOP}{{\color{purple}\key{input\_int}}}
 \newcommand{\READOP}{{\color{purple}\key{input\_int}}}
@@ -127,7 +137,9 @@
 \newcommand{\PRINT}[1]{{\color{purple}\key{Expr}\LP\key{Call}\LP\key{Name}\LP\key{'print'}\RP\key{,}\LS#1\RS\RP\RP}}
 \newcommand{\PRINT}[1]{{\color{purple}\key{Expr}\LP\key{Call}\LP\key{Name}\LP\key{'print'}\RP\key{,}\LS#1\RS\RP\RP}}
 \newcommand{\EXPR}[1]{{\color{purple}\key{Expr}\LP #1\RP}}
 \newcommand{\EXPR}[1]{{\color{purple}\key{Expr}\LP #1\RP}}
 \newcommand{\PROGRAM}[2]{\code{Module}\LP #2\RP}
 \newcommand{\PROGRAM}[2]{\code{Module}\LP #2\RP}
+\newcommand{\VAR}[1]{\key{Name}\LP #1\RP}
 \fi
 \fi
+
 \newcommand{\BOOL}[1]{\key{(Bool}~#1\key{)}}
 \newcommand{\BOOL}[1]{\key{(Bool}~#1\key{)}}
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\PRIM}[2]{\LP\key{Prim}~#1~\LP #2\RP\RP}
 \newcommand{\CREAD}{\key{(read)}}
 \newcommand{\CREAD}{\key{(read)}}
@@ -156,7 +168,6 @@
 \newcommand{\CBINOP}[3]{\LP #1~#2~#3\RP}
 \newcommand{\CBINOP}[3]{\LP #1~#2~#3\RP}
 \newcommand{\CLET}[3]{\LP\key{let}~\LP\LS#1~#2\RS\RP~#3\RP}
 \newcommand{\CLET}[3]{\LP\key{let}~\LP\LS#1~#2\RS\RP~#3\RP}
 \newcommand{\CIF}[3]{\LP\key{if}~#1~#2~#3\RP}
 \newcommand{\CIF}[3]{\LP\key{if}~#1~#2~#3\RP}
-\newcommand{\VAR}[1]{\key{(Var}~#1\key{)}}
 \newcommand{\LET}[3]{\key{(Let}~#1~#2~#3\key{)}}
 \newcommand{\LET}[3]{\key{(Let}~#1~#2~#3\key{)}}
 \newcommand{\IF}[3]{\key{(If}\,#1~#2~#3\key{)}}
 \newcommand{\IF}[3]{\key{(If}\,#1~#2~#3\key{)}}
 \newcommand{\CAST}[3]{\LP\key{Cast}~#1~#2~#3\RP}
 \newcommand{\CAST}[3]{\LP\key{Cast}~#1~#2~#3\RP}
@@ -189,7 +200,13 @@
 \newcommand{\CPROJECT}[2]{\LP\key{project}~#1~#2\RP}
 \newcommand{\CPROJECT}[2]{\LP\key{project}~#1~#2\RP}
 \newcommand{\VALUEOF}[2]{\LP\key{ValueOf}~#1~#2\RP}
 \newcommand{\VALUEOF}[2]{\LP\key{ValueOf}~#1~#2\RP}
 
 
+\if\edition\racketEd
 \newcommand{\ASSIGN}[2]{\key{(Assign}~#1~#2\key{)}}
 \newcommand{\ASSIGN}[2]{\key{(Assign}~#1~#2\key{)}}
+\fi
+\if\edition\pythonEd
+\newcommand{\ASSIGN}[2]{\key{Assign}\LP\LS #1\RS\key{,}#2\RP}
+\fi
+
 \newcommand{\RETURN}[1]{\key{(Return}~#1\key{)}}
 \newcommand{\RETURN}[1]{\key{(Return}~#1\key{)}}
 \newcommand{\SEQ}[2]{\key{(Seq}~#1~#2\key{)}}
 \newcommand{\SEQ}[2]{\key{(Seq}~#1~#2\key{)}}
 \newcommand{\GOTO}[1]{\key{(Goto}~#1\key{)}}
 \newcommand{\GOTO}[1]{\key{(Goto}~#1\key{)}}