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.
|
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
|
||||||
|
|
||||||
|
|
40
sandbox.ld
40
sandbox.ld
|
@ -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))
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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}")
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user