Browse Source

update to interp-R1

Jeremy Siek 6 years ago
parent
commit
032558d98e
1 changed files with 35 additions and 34 deletions
  1. 35 34
      book.tex

+ 35 - 34
book.tex

@@ -907,7 +907,7 @@ and then a description of x86 (Section~\ref{sec:x86}). The
 x86 assembly language is quite large, so we only discuss what is
 needed for compiling $R_1$. We introduce more of x86 in later
 chapters. Once we have introduced $R_1$ and x86, we reflect on
-their differences and come up with a plan breaking down the
+their differences and come up with a plan to break down the
 translation from $R_1$ to x86 into a handful of steps
 (Section~\ref{sec:plan-s0-x86}).  The rest of the sections in this
 Chapter give detailed hints regarding each step
@@ -924,15 +924,16 @@ The $R_1$ language extends the $R_0$ language
 the $R_1$ language is defined by the grammar in
 Figure~\ref{fig:r1-syntax}.  The non-terminal \Var{} may be any Racket
 identifier. As in $R_0$, \key{read} is a nullary operator, \key{-} is
-a unary operator, and \key{+} is a binary operator. In addition to
-variable definitions, the $R_1$ language includes the \key{program}
-form to mark the top of the program, which is helpful in some of the
-compiler passes.  The $R_1$ language is rich enough to exhibit several
-compilation techniques but simple enough so that the reader can
-implement a compiler for it in a week of part-time work.  To give the
-reader a feeling for the scale of this first compiler, the instructor
-solution for the $R_1$ compiler consists of 6 recursive functions and
-a few small helper functions that together span 256 lines of code.
+a unary operator, and \key{+} is a binary operator.  Similar to $R_0$,
+the $R_1$ language includes the \key{program} form to mark the top of
+the program, which is helpful in some of the compiler passes.  The
+$R_1$ language is rich enough to exhibit several compilation
+techniques but simple enough so that the reader, together with couple
+friends, can implement a compiler for it in a week or two of part-time
+work.  To give the reader a feeling for the scale of this first
+compiler, the instructor solution for the $R_1$ compiler consists of 6
+recursive functions and a few small helper functions that together
+span 256 lines of code.
 
 \begin{figure}[btp]
 \centering
@@ -951,10 +952,11 @@ R_1  &::=& (\key{program} \; \Exp)
 \label{fig:r1-syntax}
 \end{figure}
 
-The \key{let} construct defines a variable for use within its body
-and initializes the variable with the value of an expression.  So the
-following program initializes \code{x} to \code{32} and then evaluates
-the body \code{(+ 10 x)}, producing \code{42}.
+Let us dive into the description of the $R_1$ language.  The \key{let}
+construct defines a variable for use within its body and initializes
+the variable with the value of an expression.  So the following
+program initializes \code{x} to \code{32} and then evaluates the body
+\code{(+ 10 x)}, producing \code{42}.
 \begin{lstlisting}
    (program
       (let ([x (+ 12 20)]) (+ 10 x)))
@@ -1003,31 +1005,30 @@ to the variable, then evaluates the body of the \key{let}.
 \begin{figure}[tbp]
 \begin{lstlisting}
    (define (interp-R1 env)
-     (lambda (e)
-       (define recur (interp-R1 env))
-       (match e
-         [(? symbol?) (lookup e env)]
-         [`(let ([,x ,(app recur v)]) ,body)
-          (define new-env (cons (cons x v) env))
-          ((interp-R1 new-env) body)]
-         [(? fixnum?) e]
-         [`(read)
-          (define r (read))
-          (cond [(fixnum? r) r]
-                [else (error 'interp-R1 "expected an integer" r)])]
-         [`(- ,(app recur v))
-          (fx- 0 v)]
-         [`(+ ,(app recur v1) ,(app recur v2))
-          (fx+ v1 v2)]
-         [`(program ,e) ((interp-R1 '()) e)]
-         )))
+     (define (exp env)
+       (lambda (e)
+         (match e
+           [(? symbol?) (lookup e env)]
+           [`(let ([,x ,(app (exp env) v)]) ,body)
+            (define new-env (cons (cons x v) env))
+            ((exp new-env) body)]
+           [(? fixnum?) e]
+           [`(read)
+            (define r (read))
+            (cond [(fixnum? r) r]
+                  [else (error 'interp-R1 "expected an integer" r)])]
+           [`(- ,(app (exp env) v))
+            (fx- 0 v)]
+           [`(+ ,(app (exp env) v1) ,(app (exp env) v2))
+             (fx+ v1 v2)])))
+     (lambda (p)
+       (match p
+         [`(program ,e) ((exp '()) e)])))
 \end{lstlisting}
 \caption{Interpreter for the $R_1$ language.}
 \label{fig:interp-R1}
 \end{figure}
 
-
-
 The goal for this chapter is to implement a compiler that translates
 any program $P_1$ in the $R_1$ language into an x86 assembly
 program $P_2$ such that $P_2$ exhibits the same behavior on an x86