[Lisp処理系を作る] 08日目 SymbolTable を作る

Symbol に束縛されているオブジェクトの対応表。 Env 絡みで実装する。

特徴

  • 基本的に 1 オブジェクトで1つのスコープとして扱う。
  • ただし、トップレベルへの参照を持つ。これにより 扱う側が変数が無ければトップにアクセスするというのを意識しないで済む、
    • トップレベルからも明示的にトップにアクセスできる。
  • スタックを用意するのは Env 側でそこに SymbolTable を積む感じ。

関数呼び出し時の注意点

関数呼び出しがあった場合はスタックを積み復帰時はスタックを取り除く。

  • 関数内ではその関数ローカルな変数とトップレベルの変数にアクセスできる。
    • xyzzy(Common Lisp) ではそんな感じらしい。
    • つまり Top → foo → bar で呼び出された場合 bar でアクセスできるのは bar のラムダリストの変数と Top のみで、foo の変数にはアクセスできない。
    • 上記の bar で変数を参照する場合ローカル変数 → トップレベルの優先順位で参照される。
    • 逆に束縛する場合は既にローカルに存在すればそれに、無ければトップレベルのテーブルのシンボルに束縛される。

実装するメソッド

  • class Env
    • SymbolTable プロパティ
      • 現在のスタックの一番上の SymbolTable を返す
    • PushStack
      • スタックを積む
    • PopStack
      • スタックを取り除く
  • class SymbolTable
    • this[string key]
      • アクセスはインデクサでアクセスする。
    • Intern( ISymbol value )
      • シンボルテーブルに引数を登録する
    • Unintern( string key )
      • シンボルテーブルから key に該当する Symbol を削除する。