浏览代码

subtraction from the beginning

Jeremy Siek 3 年之前
父节点
当前提交
aa77b7434d
共有 1 个文件被更改,包括 29 次插入16 次删除
  1. 29 16
      book.tex

+ 29 - 16
book.tex

@@ -909,13 +909,14 @@ defined in Figure~\ref{fig:r0-concrete-syntax}.
   \begin{array}{rcl}
   \begin{array}{rcl}
     \Type &::=& \key{Integer} \\
     \Type &::=& \key{Integer} \\
     \Exp{} &::=& \Int{} \MID \CREAD \RP \MID \CNEG{\Exp} \MID \CADD{\Exp}{\Exp}
     \Exp{} &::=& \Int{} \MID \CREAD \RP \MID \CNEG{\Exp} \MID \CADD{\Exp}{\Exp}
+      \MID \CSUB{\Exp}{\Exp}
   \end{array}
   \end{array}
 }
 }
 \newcommand{\LintASTRacket}{
 \newcommand{\LintASTRacket}{
   \begin{array}{rcl}
   \begin{array}{rcl}
     \Type &::=& \key{Integer} \\
     \Type &::=& \key{Integer} \\
     \Exp{} &::=& \INT{\Int} \MID \READ{} \\
     \Exp{} &::=& \INT{\Int} \MID \READ{} \\
-           &\MID& \NEG{\Exp} \MID \ADD{\Exp}{\Exp}
+           &\MID& \NEG{\Exp} \MID \ADD{\Exp}{\Exp} \MID \SUB{\Exp}{\Exp}
   \end{array}
   \end{array}
 }
 }
 \newcommand{\LintGrammarPython}{
 \newcommand{\LintGrammarPython}{
@@ -1079,7 +1080,8 @@ several ASTs is shown on the right.
     [(Int n) #t]
     [(Int n) #t]
     [(Prim 'read '()) #t]
     [(Prim 'read '()) #t]
     [(Prim '- (list e1)) #f]
     [(Prim '- (list e1)) #f]
-    [(Prim '+ (list e1 e2)) #f]))
+    [(Prim '+ (list e1 e2)) #f]
+    [(Prim '- (list e1 e2)) #f]))
 
 
 (leaf (Prim 'read '()))
 (leaf (Prim 'read '()))
 (leaf (Prim '- (list (Int 8))))
 (leaf (Prim '- (list (Int 8))))
@@ -1098,6 +1100,8 @@ def leaf(arith):
             return False
             return False
         case BinOp(e1, Add(), e2):
         case BinOp(e1, Add(), e2):
             return False
             return False
+        case BinOp(e1, Sub(), e2):
+            return False
 
 
 print(leaf(Call(Name('input_int'), [])))
 print(leaf(Call(Name('input_int'), [])))
 print(leaf(UnaryOp(USub(), eight)))
 print(leaf(UnaryOp(USub(), eight)))
@@ -1197,6 +1201,8 @@ two examples at the bottom of the figure, the first is in
     [(Prim '- (list e)) (is_exp e)]
     [(Prim '- (list e)) (is_exp e)]
     [(Prim '+ (list e1 e2))
     [(Prim '+ (list e1 e2))
       (and (is_exp e1) (is_exp e2))]
       (and (is_exp e1) (is_exp e2))]
+    [(Prim '- (list e1 e2))
+      (and (is_exp e1) (is_exp e2))]
     [else #f]))
     [else #f]))
 
 
 (define (is_Lint ast)
 (define (is_Lint ast)
@@ -1206,7 +1212,7 @@ two examples at the bottom of the figure, the first is in
 
 
 (is_Lint (Program '() ast1_1)
 (is_Lint (Program '() ast1_1)
 (is_Lint (Program '()
 (is_Lint (Program '()
-       (Prim '- (list (Prim 'read '())
+       (Prim '* (list (Prim 'read '())
                       (Prim '+ (list (Int 8)))))))
                       (Prim '+ (list (Int 8)))))))
 \end{lstlisting}
 \end{lstlisting}
 \fi}
 \fi}
@@ -1333,7 +1339,11 @@ Figure~\ref{fig:interp_Lint}.
     [(Prim '+ (list e1 e2))
     [(Prim '+ (list e1 e2))
      (define v1 (interp_exp e1))
      (define v1 (interp_exp e1))
      (define v2 (interp_exp e2))
      (define v2 (interp_exp e2))
-     (fx+ v1 v2)]))
+     (fx+ v1 v2)]
+    [(Prim '- (list e1 e2))
+     (define v1 ((interp-exp env) e1))
+     (define v2 ((interp-exp env) e2))
+     (fx- v1 v2)]))
 
 
 (define (interp_Lint p)
 (define (interp_Lint p)
   (match p
   (match p
@@ -1566,7 +1576,9 @@ operation.
     [(Int n) (Int n)]
     [(Int n) (Int n)]
     [(Prim 'read '()) (Prim 'read '())]
     [(Prim 'read '()) (Prim 'read '())]
     [(Prim '- (list e1)) (pe_neg (pe_exp e1))]
     [(Prim '- (list e1)) (pe_neg (pe_exp e1))]
-    [(Prim '+ (list e1 e2)) (pe_add (pe_exp e1) (pe_exp e2))]))
+    [(Prim '+ (list e1 e2)) (pe_add (pe_exp e1) (pe_exp e2))]
+    [(Prim '- (list e1 e2)) (pe-add ((pe-exp env) e1)
+                                    (pe-neg ((pe-exp env) e2)))]))
 
 
 (define (pe_Lint p)
 (define (pe_Lint p)
   (match p
   (match p
@@ -1831,12 +1843,13 @@ print(10 + x)
 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
-that define variables named \code{x}. Can you figure out the result?
+that define two variables named \code{x}. Can you figure out the
+result?
 \begin{lstlisting}
 \begin{lstlisting}
 (let ([x 32]) (+ (let ([x 10]) x) x))
 (let ([x 32]) (+ (let ([x 10]) x) x))
 \end{lstlisting}
 \end{lstlisting}
-For the purposes of depicting which variable uses correspond to which
-definitions, the following shows the \code{x}'s annotated with
+For the purposes of depicting which variable occurences correspond to
+which definitions, the following shows the \code{x}'s annotated with
 subscripts to distinguish them. Double check that your answer for the
 subscripts to distinguish them. Double check that your answer for the
 above is the same as your answer for this annotated version of the
 above is the same as your answer for this annotated version of the
 program.
 program.
@@ -1860,12 +1873,12 @@ why we implement it in an object-oriented style. Throughout this book
 we define many interpreters, one for each of language that we
 we define many interpreters, one for each of language that we
 study. Because each language builds on the prior one, there is a lot
 study. Because each language builds on the prior one, there is a lot
 of commonality between these interpreters. We want to write down the
 of commonality between these interpreters. We want to write down the
-common parts just once instead of many times. A naive approach would
-be for the interpreter of \LangVar{} to handle the
+common parts just once instead of many times. A naive 
+interpreter for \LangVar{} would handle the
 \racket{cases for variables and \code{let}}
 \racket{cases for variables and \code{let}}
 \python{case for variables}
 \python{case for variables}
-but dispatch to \LangInt{}
-for the rest of the cases. The following code sketches this idea. (We
+but dispatch to an interpreter for \LangInt{}
+in the rest of the cases. The following code sketches this idea. (We
 explain the \code{env} parameter soon, in
 explain the \code{env} parameter soon, in
 Section~\ref{sec:interp-Lvar}.)
 Section~\ref{sec:interp-Lvar}.)
 
 
@@ -1917,10 +1930,10 @@ def interp_Lvar(e, env):
 \end{minipage}
 \end{minipage}
 \fi}
 \fi}
 \end{center}
 \end{center}
-The problem with this approach is that it does not handle situations
-in which an \LangVar{} feature, such as a variable, is nested inside
-an \LangInt{} feature, like the \code{-} operator, as in the following
-program.
+The problem with this naive approach is that it does not handle
+situations in which an \LangVar{} feature, such as a variable, is
+nested inside an \LangInt{} feature, like the \code{-} operator, as in
+the following program.
 %
 %
 {\if\edition\racketEd
 {\if\edition\racketEd
 \begin{lstlisting}
 \begin{lstlisting}