# 5.4.3条件，赋值和定义

> 译者： [https://sicp.comp.nus.edu.sg/chapters/112](https://sicp.comp.nus.edu.sg/chapters/112)

与元圆评估器一样，特殊形式通过有选择地评估表达式的片段来处理。 对于`if`表达式，我们必须评估谓词并根据谓词的值决定是评估结果项还是替代项。

在评估谓词之前，我们将保存`if`表达式本身，以便稍后可以提取结果或替代项。 我们还保存了稍后需要用来评估结果或替代项的环境，并保存了`continue`以便稍后返回到等待值的表达式的求值。 `if`。

```js
"ev_if",
          save("exp"),                    // save expression for later
          save("env"),
          save("continue"),
          assign("continue", label("ev_if_decide")),
          assign("exp", op("if_predicate"), reg("exp")),
          go_to(label("eval_dispatch")),  // evaluate the predicate
```

当我们从评估谓词返回时，我们测试它是对还是错，并根据结果将结果或替代项放入`eval_dispatch`中，然后再进入`eval_dispatch`。 请注意，此处恢复`env`和`continue`会将`eval_dispatch`设置为具有正确的环境，并在正确的位置继续以接收`if`表达式的值。

```js
"ev_if_decide",
          restore("continue"),
          restore("env"),
          restore("exp"),
          test(op("is_true"), reg("val")),
          branch(label("ev_if_consequent")),

      "ev_if_alternative",
          assign("exp", op("if_alternative"), reg("exp")),
          go_to(label("eval_dispatch")),

      "ev_if_consequent",
          assign("exp", op("if_consequent"), reg("exp")),
          go_to(label("eval_dispatch")),
```

## 分配和定义

分配由`ev_assignment`处理，这是通过`exp`中的分配表达式从`eval_dispatch`到达的。 `ev_assignment`处的代码首先计算表达式的值部分，然后将新值安装到环境中。 假设`Set_variable_value`可作为机器操作使用。

```js
"ev_assignment",
          assign("unev", op("assignment_variable"), reg("exp")),
          save("unev"),                   // save variable for later
          assign("exp", op("assignment_value"), reg("exp")),
          save("env"),
          save("continue"),
          assign("continue", label("ev_assignment_1")),
          go_to(label("eval_dispatch")),  // evaluate the assignment value

      "ev_assignment_1",
          restore("continue"),
          restore("env"),
          restore("unev"),
          perform(op("set_variable_value"), reg("unev"), reg("val"), reg("env")),
          assign("val", const("ok")),
          go_to(reg("continue")),
```

定义的处理方式类似：

```js
"ev-definition",
          assign("unev", op("definition-variable"), reg("exp")),
          save("unev"),                   // save variable for later
          assign("exp", op("definition-value"), reg("exp")),
          save("env"),
          save("continue"),
          assign("continue", label("ev-definition-1")),
          go_to(label("eval-dispatch")),  // evaluate the definition value

      "ev-definition-1",
          restore("continue"),
          restore("env"),
          restore("unev"),
          perform(op("define-variable"), reg("unev"), reg("val"), reg("env")),
          assign("val", const("ok")),
          go_to(reg("continue")),
```

<exercise>Extend the evaluator to handle derived expressions such as `cond`, `let`, and so on (section <ref name="sec:representing-expressions">[4.1.2](75)</ref>). You may <quote>cheat</quote> and assume that the syntax transformers such as `cond->if` are available as machine operations.[[1]](112#footnote-1)<button class="btn btn-secondary solution_btn" data-toggle="collapse" href="#no_solution_112_1_div">Add solution</button>There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in [Github](https://github.com/source-academy/sicp).</exercise><exercise>Implement `cond` as a new basic special form without reducing it to `if`. You will have to construct a loop that tests the predicates of successive `cond` clauses until you find one that is true, and then use `ev-sequence` to evaluate the actions of the clause.<button class="btn btn-secondary solution_btn" data-toggle="collapse" href="#no_solution_112_1_div">Add solution</button>There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in [Github](https://github.com/source-academy/sicp).</exercise><exercise>Modify the evaluator so that it uses normal-order evaluation, based on the lazy evaluator of section <ref name="sec:lazy-evaluation">[4.2](81)</ref>.<button class="btn btn-secondary solution_btn" data-toggle="collapse" href="#no_solution_112_1_div">Add solution</button>There is currently no solution available for this exercise. This textbook adaptation is a community effort. Do consider contributing by providing a solution for this exercise, using a Pull Request in [Github](https://github.com/source-academy/sicp).</exercise>

* * *

[[1]](112#footnote-link-1) This isn't really cheating. In an actual implementation built from scratch, we would use our explicit-control evaluator to interpret a <split>JavaScript</split> program that performs source-level transformations in a syntax phase that runs before execution.

