从顺序计算到条件选择

本节阅读量:

写第三章代码之前,先把新增语义说清楚。

第三章加入:

1
2
谓词 eq?
条件表达式 if

程序仍然是一个表达式,每个表达式仍然产生一个整数结果。

用整数表示条件是否成立

本章不另外加入布尔值,直接用整数表示条件是否成立:

1
2
0      表示不成立
非 0   表示成立

eq? 只会返回 01if 则根据结果是否为 0 选择分支。

这类用来提问、并返回成立或不成立的表达式,通常叫做谓词表达式。这里的“谓词”不是新的值类型,只是对 eq? 这类表达式的称呼:它仍然返回整数,只是结果固定为 01

eq? 判断两个结果是否相等

eq? 会先求值左右两个表达式:

1
(eq? (+ 20 22) 42)

左右结果都是 42,所以返回 1

1
(eq? 40 42)

左右结果不同,所以返回 0

判断某个表达式是否等于零也用 eq? 表达:

1
(eq? (+ 1 -1) 0)

因为 (+ 1 -1) 的结果是 0,所以整个表达式返回 1

if 只选择一个分支

if 的形式是:

1
(if condition then-expr else-expr)

求值顺序是:

1
2
3
1. 先求值 condition。
2. condition 不等于 0,只求值 then-expr。
3. condition 等于 0,只求值 else-expr。

例如:

1
(if (eq? 0 0) 42 7)

condition 得到 1,因此结果是 then 分支的 42

1
(if (eq? 5 0) 1 42)

condition 得到 0,因此结果是 else 分支的 42

if 的条件不一定来自谓词。只要结果不是 0,就会选择 then 分支:

1
(if 7 42 0)

写成规则

第三章的表达式规则是:

1
2
3
4
5
6
7
8
9
expr ::= integer
       | identifier
       | "(" "+" expr expr ")"
       | "(" "let" identifier expr expr ")"
       | "(" "eq?" expr expr ")"
       | "(" "if" expr expr expr ")"

integer    ::= "-"? digit+
identifier ::= letter+

identifier 仍然沿用第二章的简单规则。eq? 中的问号属于特殊形式的固定拼写,不表示普通变量名也可以带问号。

合法和非法

合法程序:

1
2
3
4
(eq? -1 0)
(eq? (+ 20 22) 42)
(if 0 1 42)
(let x 0 (if (eq? x 0) 42 7))

非法程序:

1
2
3
4
(eq? 1)
(eq? 1 2 3)
(if 1 42)
(if 1 2 3 4)

前两个程序的 eq? 参数数量不对;后两个 if 分别缺少和多出一个分支。

下一节先看 AST 怎样保存这些结构。


3.0 有无相生,前后相随

上一节

3.2 AST:给条件和分支留位置

下一节