actually get receive working????
This commit is contained in:
parent
f873be7668
commit
f710beff46
|
@ -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
|
||||
|
||||
|
|
40
sandbox.ld
40
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))
|
||||
|
|
|
@ -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 => {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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}")
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user