関数型言語の勉強に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++でも自然に再帰が書けるようになってうれしい。
計算機プログラムの構造と解釈
posted with amazlet on 06.05.31