23
23
24
24
\def\racketEd{0}
25
25
\def\pythonEd{1}
26
- \def\edition{0 }
26
+ \def\edition{1 }
27
27
28
28
% material that is specific to the Racket edition of the book
29
29
\newcommand{\racket}[1]{{\if\edition\racketEd{#1}\fi}}
@@ -1666,11 +1666,11 @@ \section{Example Compiler: A Partial Evaluator}
1666
1666
evaluator for the \LangInt{} language. The output of the partial evaluator
1667
1667
is a program in \LangInt{}. In figure~\ref{fig:pe-arith}, the structural
1668
1668
recursion over $\Exp$ is captured in the \code{pe\_exp} function,
1669
- whereas the code for partially evaluating the negation and addition
1670
- operations is factored into three auxiliary functions:
1671
- \code{pe\_neg}, \code{pe\_add} and \code{pe\_sub }. The input to these
1669
+ whereas the code for partially evaluating the negation, addition,
1670
+ and subtraction operations is factored into two auxiliary functions:
1671
+ \code{pe\_neg} and \code{pe\_add }. The input to these
1672
1672
functions is the output of partially evaluating the children.
1673
- The \code{pe\_neg}, \code{pe\_add} and \code{pe\_sub } functions check whether their
1673
+ The \code{pe\_neg} and \code{pe\_add } functions check whether their
1674
1674
arguments are integers and if they are, perform the appropriate
1675
1675
arithmetic. Otherwise, they create an AST node for the arithmetic
1676
1676
operation.
@@ -1689,18 +1689,13 @@ \section{Example Compiler: A Partial Evaluator}
1689
1689
[((Int n1) (Int n2)) (Int (fx+ n1 n2))]
1690
1690
[(_ _) (Prim '+ (list r1 r2))]))
1691
1691
1692
- (define (pe_sub r1 r2)
1693
- (match* (r1 r2)
1694
- [((Int n1) (Int n2)) (Int (fx- n1 n2))]
1695
- [(_ _) (Prim '- (list r1 r2))]))
1696
-
1697
1692
(define (pe_exp e)
1698
1693
(match e
1699
1694
[(Int n) (Int n)]
1700
1695
[(Prim 'read '()) (Prim 'read '())]
1701
1696
[(Prim '- (list e1)) (pe_neg (pe_exp e1))]
1702
1697
[(Prim '+ (list e1 e2)) (pe_add (pe_exp e1) (pe_exp e2))]
1703
- [(Prim '- (list e1 e2)) (pe_sub (pe_exp e1) (pe_exp e2))]))
1698
+ [(Prim '- (list e1 e2)) (pe_add (pe_exp e1) (pe_neg ( pe_exp e2) ))]))
1704
1699
1705
1700
(define (pe_Lint p)
1706
1701
(match p
@@ -1723,19 +1718,12 @@ \section{Example Compiler: A Partial Evaluator}
1723
1718
case _:
1724
1719
return BinOp(r1, Add(), r2)
1725
1720
1726
- def pe_sub(r1, r2):
1727
- match (r1, r2):
1728
- case (Constant(n1), Constant(n2)):
1729
- return Constant(sub64(n1, n2))
1730
- case _:
1731
- return BinOp(r1, Sub(), r2)
1732
-
1733
1721
def pe_exp(e):
1734
1722
match e:
1735
1723
case BinOp(left, Add(), right):
1736
1724
return pe_add(pe_exp(left), pe_exp(right))
1737
1725
case BinOp(left, Sub(), right):
1738
- return pe_sub (pe_exp(left), pe_exp (right))
1726
+ return pe_add (pe_exp(left), pe_neg (right))
1739
1727
case UnaryOp(USub(), v):
1740
1728
return pe_neg(pe_exp(v))
1741
1729
case Constant(value):
@@ -4204,11 +4192,11 @@ \section{Challenge: Partial Evaluator for \LangVar{}}
4204
4192
%
4205
4193
To accomplish this, the \code{pe\_exp} function should produce output
4206
4194
in the form of the $\itm{residual}$ nonterminal of the following
4207
- grammar. The idea is that when processing an addition expression, we
4208
- can always produce one of the following: (1) an integer constant, (2)
4209
- an addition expression with an integer constant on the left-hand side
4210
- but not the right-hand side, or (3) an addition expression in which
4211
- neither subexpression is a constant.
4195
+ grammar. The idea is that when processing an addition or subtraction
4196
+ expression, we can always produce one of the following: (1) an integer
4197
+ constant, (2) an addition expression with an integer constant on the
4198
+ left-hand side but not the right-hand side, or (3) an addition
4199
+ expression in which neither subexpression is a constant.
4212
4200
%
4213
4201
{\if\edition\racketEd
4214
4202
\[
0 commit comments