actually get receive working????

This commit is contained in:
Scott Richmond 2025-06-28 16:40:31 -04:00
parent f873be7668
commit f710beff46
6 changed files with 51 additions and 24 deletions

View File

@ -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. 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. 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

View File

@ -1,25 +1,29 @@
fn foo (val) -> receive { fn agent (val) -> receive {
(:report) -> { (:set, new) -> agent (new)
print! ("LUDUS SAYS ==> value is {val}")
foo (val)
}
(:set, x) -> {
print! ("LUDUS SAYS ==> foo! was {val}, now is {x}")
foo (x)
}
(:get, pid) -> { (:get, pid) -> {
print! ("LUDUS SAYS ==> value is {val}")
send (pid, (:response, 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)) fn agent/update (pid, f) -> {
print! (fooer) send (pid, (:update, f))
send (fooer, (:set, 23)) agent/get (pid)
yield! () }
send (fooer, (:get, self ()))
yield! ()
flush! () let myagent = spawn! (fn () -> agent (42))
print! ("incrementing agent value to", agent/update (myagent, inc))

View File

@ -37,7 +37,7 @@ impl Chunk {
| Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic | EmptyString | Mult | Div | Unbox | BoxStore | Assert | Get | At | Not | Panic | EmptyString
| ConcatStrings | Stringify | MatchType | Return | UnconditionalMatch | Print | ConcatStrings | Stringify | MatchType | Return | UnconditionalMatch | Print
| AppendList | ConcatList | PushList | PushDict | AppendDict | ConcatDict | Nothing | AppendList | ConcatList | PushList | PushDict | AppendDict | ConcatDict | Nothing
| PushGlobal | SetUpvalue | LoadMessage | NextMessage | MatchMessage => { | PushGlobal | SetUpvalue | LoadMessage | NextMessage | MatchMessage | ClearMessage => {
println!("{i:04}: {op}") println!("{i:04}: {op}")
} }
Constant | MatchConstant => { Constant | MatchConstant => {

View File

@ -1040,6 +1040,7 @@ impl Compiler {
} }
Receive(clauses) => { Receive(clauses) => {
let tail_pos = self.tail_pos; let tail_pos = self.tail_pos;
self.emit_op(Op::ClearMessage);
let receive_begin = self.len(); let receive_begin = self.len();
self.emit_op(Op::LoadMessage); self.emit_op(Op::LoadMessage);
self.stack_depth += 1; self.stack_depth += 1;
@ -1050,8 +1051,7 @@ impl Compiler {
self.tail_pos = false; self.tail_pos = false;
let mut no_match_jumps = vec![]; let mut no_match_jumps = vec![];
self.enter_scope(); self.enter_scope();
// TODO: should this be self.reset_match()? self.reset_match();
self.match_depth = 0;
self.visit(pattern); self.visit(pattern);
no_match_jumps.push(self.stub_jump(Op::JumpIfNoMatch)); no_match_jumps.push(self.stub_jump(Op::JumpIfNoMatch));
if guard.is_some() { if guard.is_some() {
@ -1060,8 +1060,8 @@ impl Compiler {
self.visit(guard_expr); self.visit(guard_expr);
no_match_jumps.push(self.stub_jump(Op::JumpIfFalse)); no_match_jumps.push(self.stub_jump(Op::JumpIfFalse));
} }
self.tail_pos = tail_pos;
self.emit_op(Op::MatchMessage); self.emit_op(Op::MatchMessage);
self.tail_pos = tail_pos;
self.visit(body); self.visit(body);
self.store(); self.store();
self.leave_scope(); self.leave_scope();

View File

@ -93,6 +93,7 @@ pub enum Op {
LoadMessage, LoadMessage,
NextMessage, NextMessage,
MatchMessage, MatchMessage,
ClearMessage,
// Inc, // Inc,
// Dec, // Dec,
// Gt, // Gt,
@ -227,7 +228,8 @@ impl std::fmt::Display for Op {
LoadMessage => "load_message", LoadMessage => "load_message",
NextMessage => "next_message", NextMessage => "next_message",
MatchMessage => "clear_message", MatchMessage => "match_message",
ClearMessage => "clear_message",
}; };
write!(f, "{rep}") write!(f, "{rep}")
} }

View File

@ -1233,11 +1233,11 @@ impl Creature {
println!("no more messages in {}", self.pid); println!("no more messages in {}", self.pid);
self.msg_idx = 0; self.msg_idx = 0;
self.r#yield = true; self.r#yield = true;
self.ip -= 2;
} }
} }
} }
MatchMessage => { MatchMessage => {
self.msg_idx = 0;
let matched = self.mbx.remove(self.msg_idx).unwrap(); let matched = self.mbx.remove(self.msg_idx).unwrap();
println!( println!(
"matched in {}: @idx {}, msg {matched}", "matched in {}: @idx {}, msg {matched}",
@ -1245,6 +1245,7 @@ impl Creature {
); );
} }
ClearMessage => { ClearMessage => {
println!("clearing messages in {}", self.pid);
self.msg_idx = 0; self.msg_idx = 0;
} }
} }