# 4.1.2表示语句和表达式

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

该评估器让人想起 [2.3.2](36) 部分中讨论的符号微分程序。 这两个程序都对符号表达式进行操作。 在这两个程序中，通过对表达式的各个部分进行递归运算并以取决于表达式类型的方式组合结果，可以确定对复合表达式进行运算的结果。 在这两个程序中，我们都使用数据抽象来将一般操作规则与如何表示表达式的细节分开。 在微分程序中，这意味着相同的微分函数可以处理前缀形式，中缀形式或其他某种形式的代数表达式。 对于评估者，这意味着被评估语言的语法仅由分类和提取表达式的函数确定。

 <split>这是我们语言语法的规范：

*   自我评估项目是数字，字符串和布尔值。

    ```js
    function is_self_evaluating(stmt) {
        return is_number(stmt) ||
               is_string(stmt) || 
               is_boolean(stmt);
    }
    ```

*   函数`is_name`测试给定的语句是否为名称表达式，函数`name_of_name`访问表示该名称的JavaScript字符串。

    ```js
    function is_name(stmt) {
        return is_tagged_list(stmt, "name");
    }
    function name_of_name(stmt) {
        return head(tail(stmt));
    }
    ```

    函数`is_name`是根据函数`is_tagged_list`定义的，该函数标识以指定字符串开头的列表，我们将其称为_标签_：

    ```js
    function is_tagged_list(stmt, the_tag) {
        return is_pair(stmt) && head(stmt) === the_tag;
    }
    ```

*   分配形式为![%5Ctextit%7Bname%7D](img/abe58dbcc6883742e3e0d539cb238bc1.jpg) `=` ![%5Ctextit%7Bvalue%7D](img/8941e10ab9faad8a97352258c597168e.jpg)：

    ```js
    function is_assignment(stmt) {
       return is_tagged_list(stmt, "assignment");
    }
    function assignment_name(stmt) {
       return head(tail(head(tail(stmt))));
    }
    function assignment_value(stmt) {
       return head(tail(tail(stmt)));
    }
    ```

*   声明的形式为`const ![%5Ctextit%7Bname%7D](img/abe58dbcc6883742e3e0d539cb238bc1.jpg) = ![%5Ctextit%7Bvalue%7D](img/8941e10ab9faad8a97352258c597168e.jpg);`或`let ![%5Ctextit%7Bname%7D](img/abe58dbcc6883742e3e0d539cb238bc1.jpg) = ![%5Ctextit%7Bvalue%7D](img/8941e10ab9faad8a97352258c597168e.jpg);`或`function ![%5Ctextit%7Bname%7D](img/abe58dbcc6883742e3e0d539cb238bc1.jpg)(![%5Ctextit%7Bparameter%7D_%7B1%7D](img/69b4a0a75a6d5bd5f15deef47bf51576.jpg), ![%5Cldots](img/9f57fa7487fb5cc87b777f74773ffb74.jpg), ![%5Ctextit%7Bparameter%7D_%7Bn%7D](img/81aaa1c9ff024ef9a6cbb38ea59c377f.jpg)) { ![%5Ctextit%7Bbody%7D](img/37455e5f4ca86663530db456cf71bea8.jpg) }`在这里，我们将后一种形式（函数声明）视为`const ![%5Ctextit%7Bname%7D](img/abe58dbcc6883742e3e0d539cb238bc1.jpg) = (![%5Ctextit%7Bparameter%7D_%7B1%7D](img/69b4a0a75a6d5bd5f15deef47bf51576.jpg), ![%5Cldots](img/9f57fa7487fb5cc87b777f74773ffb74.jpg), ![%5Ctextit%7Bparameter%7D_%7Bn%7D](img/81aaa1c9ff024ef9a6cbb38ea59c377f.jpg)) =&gt; { ![%5Ctextit%7Bbody%7D](img/37455e5f4ca86663530db456cf71bea8.jpg); };`的语法糖 [[1]](75#footnote-1) 。相应的语法函数如下：

    ```js
    function is_constant_declaration(stmt) {
       return is_tagged_list(stmt, "constant_declaration");
    }
    function constant_declaration_name(stmt) {
       return head(tail(head(tail(stmt))));
    }
    function constant_declaration_value(stmt) {
       return head(tail(tail(stmt)));
    }
    function is_variable_declaration(stmt) {
       return is_tagged_list(stmt, "variable_declaration");
    }
    function variable_declaration_name(stmt) {
       return head(tail(head(tail(stmt))));
    }
    function variable_declaration_value(stmt) {
       return head(tail(tail(stmt)));
    }
    ```

*   函数定义是用字符串`function_definition`标记的对象：

    ```js
    function is_function_definition(stmt) {
       return is_tagged_list(stmt, "function_definition");
    }
    function function_definition_parameters(stmt) {
       return head(tail(stmt));
    }
    function function_definition_body(stmt) {
       return head(tail(tail(stmt)));
    }
    ```

*   `return`语句是标记有字符串`"return_statement"`的对象：

    ```js
    function is_return_statement(stmt) {
       return is_tagged_list(stmt, "return_statement");
    }
    function return_statement_expression(stmt) {
       return head(tail(stmt));
    }
    ```

*   条件表达式用`"conditional_expression"`标记，并具有谓词，结果和备选。

    ```js
    function is_conditional_expression(stmt) {
       return is_tagged_list(stmt, 
                    "conditional_expression");
    }
    function cond_expr_pred(stmt) {
       return list_ref(stmt, 1);
    }
    function cond_expr_cons(stmt) {
       return list_ref(stmt, 2);
    }
    function cond_expr_alt(stmt) {
       return list_ref(stmt, 3);
    }
    ```

*   序列是语句列表。

    ```js
    function is_sequence(stmt) {
       return is_tagged_list(stmt, "sequence");
    }
    function make_sequence(stmts) {
       return list("sequence", stmts);
    }
    function sequence_statements(stmt) {   
       return head(tail(stmt));
    }
    function is_empty_sequence(stmts) {
       return is_null(stmts);
    }
    function is_last_statement(stmts) {
       return is_null(tail(stmts));
    }
    function first_statement(stmts) {
       return head(stmts);
    }
    function rest_statements(stmts) {
       return tail(stmts);
    }
    ```

*   块包含其主体语句。

    ```js
    function is_block(stmt) {
        return is_tagged_list(stmt, "block");
    }
    function make_block(stmt) {
       return list("block", stmt);
    }
    function block_body(stmt) {
        return head(tail(stmt));
    }
    ```

*   函数应用程序是带有字符串`"application"`标记的对象。 我们为`operator`，`operands`提供访问功能，并提供三个用于遍历操作数列表的功能：

    ```js
    function is_application(stmt) {
       return is_tagged_list(stmt, "application");
    }
    function operator(stmt) {
       return head(tail(stmt));
    }
    function operands(stmt) {
       return head(tail(tail(stmt)));
    }
    function no_operands(ops) {
       return is_null(ops);
    }
    function first_operand(ops) {
       return head(ops);
    }
    function rest_operands(ops) {
       return tail(ops);
    }
    ```</split> <exercise>Rewrite `evaluate` so that the dispatch is done in data-directed style. Compare this with the data-directed differentiation function of exercise <ref name="ex:data-directed-differentiation">[2.73](42#ex_2.73)</ref>. (You may use the `head` of a compound expression as the type of the expression, as is appropriate for the syntax implemented in this section.)<button class="btn btn-secondary solution_btn" data-toggle="collapse" href="#no_solution_75_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>Recall the definitions of the special forms `&&` and `||` from chapter 1: <split>*   ![%5Ctextit%7Bexpression%7D_1](img/af41029c31183e68ec01b08c614e1295.jpg) `&&` ![%5Ctextit%7Bexpression%7D_2](img/65aa6628b728916b19487b6648d5257c.jpg)：首先评估表达式![%5Ctextit%7Bexpression%7D_1](img/af41029c31183e68ec01b08c614e1295.jpg)。 如果评估为`false`，则返回`false`； 不评估表达式![%5Ctextit%7Bexpression%7D_2](img/65aa6628b728916b19487b6648d5257c.jpg)。 如果其值为`true`，则返回![%5Ctextit%7Bexpression%7D_2](img/65aa6628b728916b19487b6648d5257c.jpg)的值。
*   ![%5Ctextit%7Bexpression%7D_1](img/af41029c31183e68ec01b08c614e1295.jpg) `||` ![%5Ctextit%7Bexpression%7D_2](img/65aa6628b728916b19487b6648d5257c.jpg)：首先评估表达式![%5Ctextit%7Bexpression%7D_1](img/af41029c31183e68ec01b08c614e1295.jpg)。 如果评估为`true`，则返回`true`； 不评估表达式![%5Ctextit%7Bexpression%7D_2](img/65aa6628b728916b19487b6648d5257c.jpg)。 如果其值为`false`，则返回![%5Ctextit%7Bexpression%7D_2](img/65aa6628b728916b19487b6648d5257c.jpg)的值。Include `&&` and `||` expressions by defining appropriate syntax functions and evaluation functions `eval_and` and `eval_or`</split><button class="btn btn-secondary solution_btn" data-toggle="collapse" href="#no_solution_75_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]](75#footnote-link-1) In actual JavaScript, there is a subtle difference between the two forms. The interpretation of function declaration statements involves reordering of sequence statements, a topic which we prefer to skip at this point.

