ローカル関数
なんとかローカル関数を実装した。
無理矢理っぽくてあんまり納得いかないけど。
自由変数を本物の引数の前に並べるような
lambda-liftingしただけなので、
関数が定義されたスコープを抜けたらコール不能になる。
(引数として使う自由変数の存在が保証できなくなるから)
従ってfirst classの関数はまだできない。
まあ、ここまでやってあればそう難しくはないと思うけど。
自由変数とスタブ関数(シグネチャがユーザの定義通りの関数)を組にした構造体
(すなわちこれがクロージャ)を作って
スタブ関数の中から本物の関数(シグネチャが自由変数込みのもの)を
呼び出すようにすれば
あとはLLVMのオプティマイザが
そこそこよろしくやってくれるんじゃないかと思う。
つまりこうすると言いたい:
int foo_internal( int l, int m, int n ) { do something } struct closure { int foo( int n ) { foo_internal( l, m, n ); } int l; int m; };
ちなみに現状では、
require leaf; fun main(): int { var m = 3 + 2; fun foo( n: int ): int { m * n ; } puti( foo(4) ); 0; }
こんなソースが
define i32 @main() { ENTRY: %reg28 = add i32 3, 2 %ret50 = call i32 @foo( i32 %reg28, i32 4 ) %ret55 = call i32 @puti( i32 %ret50 ) ret i32 0 } define i32 @foo(i32 %env_m, i32 %arg_n) { ENTRY: %reg41 = mul i32 %env_m, %arg_n ret i32 %reg41 }
こんな風になって出てきます。