From 99963a8643c10c251a3fa338f436e0890f41aca9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=BE=E6=B5=A6=20=E7=9F=A5=E4=B9=9F=20Matsuura=20Tomoy?= =?UTF-8?q?a?= Date: Wed, 30 Oct 2024 17:32:47 +0900 Subject: [PATCH] [obsidian] vault backup: 2024-10-30 17:32:47 --- content/mimiumでMIDIインプットを実装.md | 26 ++++++++++++++++---- content/mimiumの中間表現を考える.md | 32 +++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/content/mimiumでMIDIインプットを実装.md b/content/mimiumでMIDIインプットを実装.md index c6a2f537..86217f94 100644 --- a/content/mimiumでMIDIインプットを実装.md +++ b/content/mimiumでMIDIインプットを実装.md @@ -59,20 +59,38 @@ ChuckもボイスごとにShredを生やす方向で対応してるからちょ Noteのバインドの記法 ```rust -let channel:()->float = bind_midi_note_mono(channel) +let cell:()->float = bind_midi_note_mono(channel) -channel() //値の取り出し +let (note,vel) = cell(); //値の取り出し ``` ```rust //rust -fn bind_midi_note_mono(vm:&mut Machine)->ReturnCode{ - let ch = vm.get_stack(0) +fn bind_midi_note_mono(&mut self ,vm:&mut Machine)->ReturnCode{ + let ch = Machine::get_as::(vm.get_stack(0)); + let cell = Arc::new((AtomicF64::new(),AtomicF64::new() )); + self.add_midi_listener(ch,|note,vel|{ + let (note_c,vel_c) = cell.clone(); + note_c.write(note); + vel_c.write(vel); + }); + let cls = |vm:&mut Machine|->ReturnCode{ + let (note_c,vel_c) = cell.clone(); + vm.set_stack(0,Machine::to_value(note_c)); + vm.set_stack(1,Machine::to_value(vel_c)); + 2 + } + vm::set_stack(0, wrap_rust_closure(cls)) + 1 } ``` +あとは頑張って`add_midi_listener`相当の何かを作ろうって感じだな(関数型っぽくはないけども) + + + --- diff --git a/content/mimiumの中間表現を考える.md b/content/mimiumの中間表現を考える.md index a0c0d0d5..286c4cbc 100644 --- a/content/mimiumの中間表現を考える.md +++ b/content/mimiumの中間表現を考える.md @@ -209,3 +209,35 @@ fn filterbank (n,filter){ //n:0 filter: 1 あ、でも`callcls`命令実行の時だけ、最初にgetstateを実行、暗黙的に読み出して、その中身のポインタへ飛べばいいのか Closureを作った時にどうやってstateのメモリを拡張するかというと、ヒープ上のクロージャのデータ構造自体にstateへのポインタを持たせないと無理? + +--- + +最小限の表現としてはCall(Stateポインタをいじる可能性がある)とCallClsの2種類で対応可能なんだろうけど、最適化を考えると + +- Call (ほぼ純粋な関数) +- CallState (後々SelfとかDelayを呼び出しうる関数) +- CallClosure +- CallExtFunction + +ここにTailCallとか加えると、それぞれに一つずつTailCall用の命令が映えるみたいな感じになるのだろうか + +コンパイル時ifが使える想定として + +```rust +call_function(&mut self,f:F){ + ifc !is_tailcall{ + self.stack.push_return_address(); + } + ifc is_closure{ + self.stateptr_stack.push(f.state_stack_ptr) + } + let nret = f(self); + ifc is_closure{ + self.stateptr_stack.pop() + } + ifc !is_tailcall{ + self.stack.push_return_address(); + } +} + +```