[Lisp処理系を作る] 10日目 Eval を作る

評価は Lisp の中でも中核を担う部分。だけど、以外とシンプルではある。

特徴

  • S 式は評価することで S 式を得ることが出来る。
  • 同じ S 式を評価しても環境が違えば同じ結果になるとは限らない。
  • 評価した場合の処理はその S 式によって異なる。

処理の違いは以下。

List
List の先頭の名前の関数を呼び出す。 List の先頭以外が引数になる。関数の呼び出し結果を返却する。
Symbol
束縛されている S 式を返却する。
Atom
自身を返却する。

実装

  • 環境が S 式を評価すると S 式が得られる。
    • Env.Eval( SymbolicExpression s )
  • しかし、対象とする S 式のオブジェクトのクラスによって処理が異なっている。
    • 通常こういった処理はオーバーライド(やインターフェース)で表現する。
  • virtual SymbolicExpression.ToEvaluated( Env env )

つまり

class Env {
  public SymbolicExpression Eval( SymbolicExpression s ) {
    return s.ToEvaluated( this );
  }
}
class abstract SymbolicExpression {
  public abstract SymbolicExpression ToEvaluated( Env env );
}
// 派生クラスで ToEvaluated をオーバーライドする。

これで通常は Env.Eval のインターフェースを使い S 式を評価する。 実際の処理を記述する場所はそれぞれのクラスで記述できる。

これまでの成果