SICP 読書ノート#43 - RubyでSchemeインタプリタをつくろう(2)
引き続きRubyでSchemeインタプリタを書き起こして行きます。
手続きの引数
引数exps
にある式リストからひとつずつ式を取り出し評価したリストを返す。
def list_of_values(exps, env) if no_operands?(exps) nil else cons(_eval(first_operand(exps), env), list_of_values(rest_operand(exps), env)) end end
条件文
述語式の結果が真ならconsequent
(結果)を、偽ならalternative
(代替)を評価する。
def eval_if(exp, env) if true?(_eval(if_predicate(exp), env)) _eval(if_consequent(exp), env) else _eval(if_alternative(exp), env) end end
並び
applyで適用された手続きの本体body
から取り出した一連の式を順次評価する。
def eval_sequence(exps, env) if last_exp?(exps) _eval(first_exp(exps), env) else _eval(first_exp(exps), env) eval_sequence(rest_exps(exps), env) end end
代入と定義
代入(assignment)も定義(definition)のどちらも環境へ変数をセットするため、似たような実装になっている。
代入は環境から変数を探し出し、evalした結果をその変数に割り当てる。
def eval_assignment(exp, env) var = assignment_variable(exp) value = _eval(assignment_value(exp), env) set_variable_value!(var, value, env) :ok end
定義は環境に新しい束縛を追加するはず。
def eval_definition(exp, env) var = definition_variable(exp) value = _eval(definition_value(exp), env) define_variable!(var, value, env) :ok end
次回は「§4.1.2 式の表現」から。