From f710beff46e6e8b26506d91b9f32a33fd2fd0f12 Mon Sep 17 00:00:00 2001 From: Scott Richmond Date: Sat, 28 Jun 2025 16:40:31 -0400 Subject: [PATCH] actually get receive working???? --- may_2025_thoughts.md | 20 ++++++++++++++++++++ sandbox.ld | 40 ++++++++++++++++++++++------------------ src/chunk.rs | 2 +- src/compiler.rs | 6 +++--- src/op.rs | 4 +++- src/vm.rs | 3 ++- 6 files changed, 51 insertions(+), 24 deletions(-) diff --git a/may_2025_thoughts.md b/may_2025_thoughts.md index c957938..f9b32b1 100644 --- a/may_2025_thoughts.md +++ b/may_2025_thoughts.md @@ -1078,3 +1078,23 @@ This is just stepwise logic, and some titchy state management. So the thing that's worth noting is that entering the receive afresh with the whole message queue and entering it with the next message in the queue are _different_ behaviours. This may involve mucking with the instruction pointer on a yield. This is subtle but will give me the feeling of "oh, why didn't I see that immediately" as soon as I get it. + +### Step-by-step +#### 2025-06-28 +Here's some pseudobytecode to get us to where we need to be: + +010 reset the message counter +020 load current message +025 if no more messages, jump to 010 THEN yield +030 test the message against a pattern +040 if no match jump to 090 +050 reset message counter +060 delete current message +070 execute body + # this may be the last instruction executed + # recursive tail calls will jump to 010 +080 jump to 100 +085 increase the message counter +090 jump to 025 (not really in bytecode; this will be unrolled) +100 receive end + diff --git a/sandbox.ld b/sandbox.ld index 1427760..afdd359 100644 --- a/sandbox.ld +++ b/sandbox.ld @@ -1,25 +1,29 @@ -fn foo (val) -> receive { - (:report) -> { - print! ("LUDUS SAYS ==> value is {val}") - foo (val) - } - (:set, x) -> { - print! ("LUDUS SAYS ==> foo! was {val}, now is {x}") - foo (x) - } +fn agent (val) -> receive { + (:set, new) -> agent (new) (:get, pid) -> { - print! ("LUDUS SAYS ==> value is {val}") send (pid, (:response, val)) - foo (val) + agent (val) + } + (:update, f) -> agent (f (val)) +} + +fn agent/set (pid, val) -> { + send (pid, (:set, val)) + val +} + +fn agent/get (pid) -> { + send (pid, (:get, self ())) + receive { + (:response, val) -> val } } -let fooer = spawn! (fn () -> foo (42)) -print! (fooer) -send (fooer, (:set, 23)) -yield! () -send (fooer, (:get, self ())) -yield! () +fn agent/update (pid, f) -> { + send (pid, (:update, f)) + agent/get (pid) +} -flush! () +let myagent = spawn! (fn () -> agent (42)) +print! ("incrementing agent value to", agent/update (myagent, inc)) diff --git a/src/chunk.rs b/src/chunk.rs index 22d7e3b..57c81c1 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -37,7 +37,7 @@ impl Chunk { | Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic | EmptyString | ConcatStrings | Stringify | MatchType | Return | UnconditionalMatch | Print | AppendList | ConcatList | PushList | PushDict | AppendDict | ConcatDict | Nothing - | PushGlobal | SetUpvalue | LoadMessage | NextMessage | MatchMessage => { + | PushGlobal | SetUpvalue | LoadMessage | NextMessage | MatchMessage | ClearMessage => { println!("{i:04}: {op}") } Constant | MatchConstant => { diff --git a/src/compiler.rs b/src/compiler.rs index 0a161b5..134726c 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -1040,6 +1040,7 @@ impl Compiler { } Receive(clauses) => { let tail_pos = self.tail_pos; + self.emit_op(Op::ClearMessage); let receive_begin = self.len(); self.emit_op(Op::LoadMessage); self.stack_depth += 1; @@ -1050,8 +1051,7 @@ impl Compiler { self.tail_pos = false; let mut no_match_jumps = vec![]; self.enter_scope(); - // TODO: should this be self.reset_match()? - self.match_depth = 0; + self.reset_match(); self.visit(pattern); no_match_jumps.push(self.stub_jump(Op::JumpIfNoMatch)); if guard.is_some() { @@ -1060,8 +1060,8 @@ impl Compiler { self.visit(guard_expr); no_match_jumps.push(self.stub_jump(Op::JumpIfFalse)); } - self.tail_pos = tail_pos; self.emit_op(Op::MatchMessage); + self.tail_pos = tail_pos; self.visit(body); self.store(); self.leave_scope(); diff --git a/src/op.rs b/src/op.rs index 278a6a4..3a9911f 100644 --- a/src/op.rs +++ b/src/op.rs @@ -93,6 +93,7 @@ pub enum Op { LoadMessage, NextMessage, MatchMessage, + ClearMessage, // Inc, // Dec, // Gt, @@ -227,7 +228,8 @@ impl std::fmt::Display for Op { LoadMessage => "load_message", NextMessage => "next_message", - MatchMessage => "clear_message", + MatchMessage => "match_message", + ClearMessage => "clear_message", }; write!(f, "{rep}") } diff --git a/src/vm.rs b/src/vm.rs index c496947..ac02ebb 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -1233,11 +1233,11 @@ impl Creature { println!("no more messages in {}", self.pid); self.msg_idx = 0; self.r#yield = true; + self.ip -= 2; } } } MatchMessage => { - self.msg_idx = 0; let matched = self.mbx.remove(self.msg_idx).unwrap(); println!( "matched in {}: @idx {}, msg {matched}", @@ -1245,6 +1245,7 @@ impl Creature { ); } ClearMessage => { + println!("clearing messages in {}", self.pid); self.msg_idx = 0; } }