クロージャ対応

やっとクロージャが使えるようになった。

(define (k x)
  (lambda (y)
    x))

(print ((k 10) 20))

大変だったけれど、できてしまえばたいしたことない。
実現するにあたって、レキシカルスコープの実現方法を変更した。

レキシカルスコープの実現

いままでは、PushScopeでスコープを作っていた。しかし、これだとFindPropertyで探せないので、PushWithを使うようにした。

(let ([x 42])
  (let ([x 10])
    (print x))
  (print x))

with({x:42}){
    with({x:10}){
	print(x);
    }
    print(x);
}

に対応するイメージ。

クロージャの実現

newfunctionがスコープスタックを保存してくれるので、それほど難しくない。
注意する点は2つ。
クロージャの外で定義されている変数(自由変数)は、GetScopeObjectなどでは取得できないので、FindPropertyで取得しないといけない。
それと引数はレジスタに格納されているので、自由変数になっている場合は、自分でスコープスタックにに積む必要がある。本来はこれ用にActivationオブジェクトがあるが、使いかたがよく分からないので使ってない。