[Lisp処理系を作る] 07日目 Function を作る

まだ書き途中

残りの Lisp のオブジェクトで残った Function を作っていく。

Function の特徴

  • 3 種類ある
    • 通常の関数(Lambda とする)
      • 引数を全て評価してからその値を引数リストに束縛する。
      • その後 body に従い式を評価した結果を返却する。
    • 特別式(SpecialForm とする)
      • それぞれのルールで引数を評価したりしなかったりしてから引数リストに束縛する。
      • その後 body に従い式を評価した結果を返却する。
    • マクロ(Macroとする)
      • 引数を全て評価しないでそのまま引数リストに束縛する。
      • その後 body に従い式を評価した結果をもう一度評価した結果を返却する。
  • 引数リスト(lambda-list)を持つ
  • 実行の為の body を持つ。
  • Env と引数を与えて呼び出して実行することが出来る。

Lambda SpecialForm Macro の処理

  1. 個別処理
    • List の処理。
      1. 与えられた引数を全て評価した List を得る。
      2. 得た List の長さと 引数リストの長さのチェック。
    • SpecialForm の処理。
      1. 与えられた引数を自身のルールで評価したりして List を得る。
      2. 得た List の長さと 引数リストの長さのチェック。
    • Macro の処理
      1. 与えられた引数をそのまま共通の処理に渡す。
      2. 共通の処理の後の S 式を評価してその結果を返却する。
  2. 全て共通の処理。
    1. Env のスタックを積む。
    2. 引数リストの Symbol に評価した List の各値を束縛する。
    3. その環境で body を評価する。
    4. Env に積んだスタックを取り除く。
    5. body の評価した結果を返却する。

実装

クラス構成は以下

  • abstract class Function
    • class Lambda
    • abstract class SpecialForm
      • abstract なのは個別のルールなどで共通化が難しい為。継承して使う。
    • class Macro

主なメソッド

  • Function
    • abstract Call( Env env, List args )
      • 引数を与えて呼び出す。
      • ここをオーバーライドして個別の処理を行う
    • Yield( Env env, List evaledArgs )
      • 上記の全ての共通の処理にあたる部分。

これまでの成果