[Lisp処理系を作る] 01日目 全体のクラス構成を考える

まずは大まかなクラス構成を考える。 あとでちょこちょこ変えるだろうけど、とりあえず考える。

Lisp 内で扱うオブジェクトのクラス群

  • SymbolicExpression
    • List
      • Nil(もし作るなら)
    • Atom
      • True
      • Symbol
      • Numeric
        • Integer
      • LString
      • Function
        • Lambda
        • SpecialForm
        • Macro

ポイント

  • 全ては S 式(SymbolicExpression)。
    • Nil の判定用のプロパティを持つ。
    • 評価すると評価された S 式を得ることが出来る。
public abstract class SymbolicExpression {
  public abstract bool IsNil { get; }
  public bool IsNotNil { get { return !this.IsNil; } }
  public abstract SymbolicExpression ToEvaluated( Env env );
}
  • Nil クラスは無しかな
    • Nil は List であり Atom であり Symbol であので表現が難しい
    • とりあえず List のうち car cdr 共に nil であるものは nil である。なんじゃそりゃ
    • Symbol で名前が nil のものは nil である。
    • List を継承して Nil クラスにするかも。
  • String ではなくて LString なのは .NET の String クラスと明確に区別するため。

他に必要なクラス

  • Env
    • Lisp 環境を表現する
    • SymbolTable と FunctionTable を持つ。
    • 環境が S 式を評価すると S 式を得ることが出来る
public class Env {
  SymbolTable        Symbols { get; }
  FunctionTable      Functions { get; }
  SymbolicExpression Eval( SymbolicExpression form );
}
  • SymbolTable
    • シンボル名とシンボルオブジェクトの対応表
    • いわゆるスタック?っていうのかな
    • 関数呼び出し時の処理は気を付ける必要あり。
  • FunctionTable
    • 関数名と関数オブジェクトの対応表
    • Lisp ではシンボル(変数)の名前空間と関数の名前空間は独立しているので別に作る
  • Parser
    • パーサは必要になるけど詳しい構成はその時考える
  • LispException
    • 例外クラスは必要になったその時にこれを継承して適当な名前を付けて作成する。