2013年5月6日月曜日

[Ruby][Scheme] Micro Schemeの実装(2) lambda式とクロージャの評価

lambda式とクロージャを評価できるようにした。
https://github.com/takeisa/uschemer/tree/v0.02

束縛と環境

lambda式評価時の仮引数と引数の対応を束縛とし、その束縛のリストを環境とする。
束縛はハッシュで管理する。
環境の先頭から束縛のハッシュを順に検索して、束縛した値を取得する。

lambda式の評価方法

評価時の環境をひもづけてクロージャを作成する。

クロージャの評価方法

クロージャの仮引数と引数より束縛を作成し、環境の先頭に追加する。
この環境を利用してクロージャの本体を評価する。

実行例

eval_print([:+, :x, :y], [{:x => 123, :y => 456}] + env)
[:+, :x, :y] #=> 579

eval_print([:lambda, [:x, :y], [:+, :x, :y]], env)
[:lambda, [:x, :y], [:+, :x, :y]] #=> [:closure,
 [:x, :y],
 [:+, :x, :y],
 [{:+=>[:built_in, #<Proc:0xb747bca8@uschemer.rb:6>],
   :/=>[:built_in, #<Proc:0xb747b780@uschemer.rb:9>],
   :-=>[:built_in, #<Proc:0xb747baf0@uschemer.rb:7>],
   :*=>[:built_in, #<Proc:0xb747b938@uschemer.rb:8>]}]]

eval_print([[:lambda, [:x, :y], [:+, :x, :y]], 1, 2], env)
[[:lambda, [:x, :y], [:+, :x, :y]], 1, 2] #=> 3

eval_print(
  [[[:lambda, [:y], [:lambda, [:x], [:+, :x, :y]]], 5], 10],
  env
)
[[[:lambda, [:y], [:lambda, [:x], [:+, :x, :y]]], 5], 10] #=> 15