Environment - akamah/garbanzo GitHub Wiki
環境とフレーム
変数を束縛する対応関係のことを、フレームと呼ぶ。
現在のフレーム
まず最初に、現在のフレームは必ず一つは存在するとする。これは、ファイルシステムで言う所の「.」に当たるものとする。
フレームの拡張
関数を呼び出す時や、スコープをネストさせる時などは、親フレームを指定し、フレームを拡張することができる。 親フレームには、「..」のようにアクセスができるものとする。 親フレームを指定しないこともでき、そうすることで隔離された環境を構成することもできる。 拡張ができるのだから、もちろん破棄することもできる。
これらの操作は、現在の環境フレームを設定する命令(setenv)によって行われる。
フレームへのアクセス
変数のshadowingが嫌だったので、変数へは相対パスでアクセスするようにする。
a = 1
b = 2
{
a = 10
print(a) # => 10
print(../a) # => 1
print(b) # => ERROR!
}
のような感じで。
ルート
特殊なキーとして、ルート('/')を与える。ここに関数やモジュールを定義することで、どこからでもアクセスができるようになる。
フレームにおいては、単にルートを指し示すだけのエントリなので、そのフレームの先祖に必ずしも存在しなくても良い。
スコープ
スコープは以下の手順で作成される。
- 新しいフレーム(単なるStoreオブジェクト)を作成する
- 作成したフレームに、親フレームとして現在のフレームを設定する
- そこにsetenvする
また、脱出する場合は、
- '..'に示されたところへsetenvする
関数
関数は、それが定義された環境(env)と、その内容(body)を含む。 基本的に、外部からそれらの内容を覗くことは許されない。
関数の呼び出しは、次の手順で行う。
- 引数をまとめたデータストアオブジェクトを作成する。ルートが指定されていない場合は、呼び出し元と同じルートを指定。
- そこに、親となる環境(env)を設定させる。
- 作成したデータストアオブジェクトを環境としてsetenvする。
- コードを実行
- 戻り値を値として返す。
注意するべきは、関数の呼び出し元から、関数の定義された環境を取得できないようにすること。