関数型言語の勉強にSICPを読もう - (54) 4章 - 超言語的抽象(217ページ) C++でSchemeインタプリタを作ろう2

eval-if

if を評価します。
ここは言語の奥を見るようで楽しいのですが true / false の定義って何?ということを立ち止まって考えることができます。
metacircular であれば、両方の真偽値をあわせるのが良いでしょう。
今回は以下のように実装しました。

bool isTrue(Object* exp)
{
    if (exp->type() == Object::NUMBER)
    {
        Number* n = (Number*)exp;
        if (n->value() == 0) return false;
    }
    return true;
}

数値の 0 以外は真です。すっきり!


isTrueが実装されてしまえば、eval-if は難しくないので割愛。

eval-sequence

これは順に評価して最後の評価の結果を返すだけです。

Object* evalSequence(Objects* exps, Environment* env)
{
    Object* ret = NULL;
    for (Objects::iterator it = exps->begin(); it != exps->end(); it++)
    {
        ret = eval(*it, env);
    }
    return ret;
}

eval-assignment, eval-definition

Environmentにたいして、データを挿入するか、上書きするかの違いがありますがほとんど同じです。
set-variable-value!/define-variableは
Environmentに

    void setVaribale(Variable* variable, Object* value);
    void defineVariable(Variable* variable, Object* value);

のように定義しています。

問題4.1

左側から評価する。

(define list-of-values (exps env)
  (if (no-operands? exps)
      '()
      (let ((value (eval (first-operand exps) env)))
        (cons value (list-of-value (rest-operands exps) env)))))

右側からは略。今日はここまで。
全然関係ないけど、C++でも自然に再帰が書けるようになってうれしい。


※「SICPを読もう」の目次はこちら


計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン ジュリー サスマン ハロルド エイブルソン 和田 英一
ピアソンエデュケーション (2000/02)
売り上げランキング: 56,404