diff --git a/content/mimiumの中間表現を考える.md b/content/mimiumの中間表現を考える.md index 288272df..4e5f3e1c 100644 --- a/content/mimiumの中間表現を考える.md +++ b/content/mimiumの中間表現を考える.md @@ -110,17 +110,6 @@ fn dsp (input){ delayはどうしておくかというと、最初の8バイトは現在のリングバッファの位置、残りをメモリという扱いにすれば良い。ただメモリのサイズを決定すんのがなあ〜 -中間表現では関数呼び出し、即値の読み込みはラベル使ってやるので十分かあ -そうなるとローカルの名前リネームは必要 - -VM自体のstate_sizeの保存には結局コールツリーを辿る必要が出てくる? -pushfeedoffsetでバイトオフセットの値をトレースするためには結局applyの式を辿る必要はある -コールツリーのトラバースをし始めるとワンパスコンパイラとしての旨みがなくなる - -feedはlambdaに閉じ込められてletrecにbindされてるのがちょっと面倒 - -まあでも結局ユーザー層に隠蔽するにはここで静的解析するしかないのか -あれ、でもこの静的解析って結局多段階でいうところのstage 0 の評価に相当するやつなのでは ```rust fn fbdelay(input:float,fb:float,dtime:float)->float{ @@ -135,4 +124,83 @@ fn dsp (input:float)->float{ return twodelay(input,400)+twodelay(input,800) } -``` \ No newline at end of file +``` + +### だめかも + +関数型を受け取って関数を返す`filterbank`的な例がこれだとダメなことに気がついた。少なくともリニアでフラットな内部状態ストレージでは実現無理。 + +```rust +fn onepole(x,g){ + x*(1.0-g) + self*g +} +fn filterbank(n,filter){ + let next = filterbank(n-1,filter); + if (n>0){ + |x,freq| filter(x,freq+n*100) +next(x,freq) + }else{ + |x,freq| filter(x,freq+n) + } + +} +let myfilter = filterbank(3,onepole) +``` + +みたいな感じだとすると +``` +fn onepole(x,g){ + movc 2 "1" + mov 3 1 + sub 2 2 3 + mul 2 0 2 + mov 3 1 + getstate 4 0 + mul 3 3 4 + add 3 2 3 + +} +fn lambda_true(x,freq){ // x:0 freq:1 + getupvalue 2 0 //get n + movc 3 "100" + mul 2 2 3 + add 1 1 2 + getupvalue 2 1 //get filter + mov 4 0 + mov 3 1 + callcls 2 2 1 + getupvalue 3 2 //get next + mov 4 0 + mov 5 1 + callcls 3 2 1 + movc 3 "1" + add 3 3 4 + ret 3 1 +} +fn lambda_false(x,freq){// x:0 freq:1 + getupvalue 2 0 //get n + add 2 2 1 + getupvalue 3 1 //get filter + mov 4 0 + mov 5 2 + callcls 3 2 1 + ret 3 1 +} +fn filterbank (n,filter){ //n:0 filter: 1 + movc 2 "-1" + sub 2 0 2 + mov 3 "filterbank" + mov 4 1 + mov 5 2 + call "filterbank" 2 1 //now stack 2 is a closure "next" + mov 3 0 + movc 4 "0" + eq 3 3 4 + jmpifneg 3 :_else: + closure 3 "lambda_true" + jmp :return: +:else: + closure 3 "lambda_false" +:return: + ret 3 1 +} +``` diff --git a/content/private b/content/private index 809b7bc1..8342ed7e 160000 --- a/content/private +++ b/content/private @@ -1 +1 @@ -Subproject commit 809b7bc1171c14667e40a226697cda9decd8677f +Subproject commit 8342ed7e3554540a6412c4182134d0e8b96b1be1