diff --git a/src/ast/visitor.rs b/src/ast/visitor.rs index 5d902c8..88f5d2a 100644 --- a/src/ast/visitor.rs +++ b/src/ast/visitor.rs @@ -74,7 +74,10 @@ pub fn walk_statement(v: &mut V, stmt: &Statement) { for s in &c.body { v.visit_statement(s); } } Statement::Expression(e) => v.visit_expr(&e.node), - Statement::WorkerSpawn(_) | Statement::Complain(_) + Statement::SendMessage(s) => v.visit_expr(&s.message.node), + Statement::WorkerSpawn(_) | Statement::ReceiveMessage(_) + | Statement::AwaitWorker(_) | Statement::CancelWorker(_) + | Statement::Complain(_) | Statement::Break(_) | Statement::Continue(_) => {} Statement::EmoteAnnotated(e) => v.visit_statement(&e.statement), Statement::Decide(d) => { diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index ca6757c..af16915 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -515,6 +515,30 @@ impl Interpreter { Ok(Value::Unit) } + Statement::SendMessage(send) => Err(RuntimeError::new(format!( + "Worker-addressed message passing is not implemented: cannot `send` to worker '{}'. \ + Use a channel created in the main scope and pass it to the worker instead.", + send.target + ))), + + Statement::ReceiveMessage(recv) => Err(RuntimeError::new(format!( + "Worker-addressed message passing is not implemented: cannot `receive` from worker '{}'. \ + Use a channel created in the main scope and pass it to the worker instead.", + recv.source + ))), + + Statement::AwaitWorker(await_worker) => Err(RuntimeError::new(format!( + "Awaiting a worker by name is not implemented: cannot `await` worker '{}'. \ + Workers run detached; synchronise via a channel created in the main scope.", + await_worker.worker_name + ))), + + Statement::CancelWorker(cancel) => Err(RuntimeError::new(format!( + "Cancelling a worker by name is not implemented: cannot `cancel` worker '{}'. \ + Workers run detached and cannot currently be cancelled.", + cancel.worker_name + ))), + Statement::Complain(complain) => Err(RuntimeError { message: complain.message.clone(), }), diff --git a/src/sexpr.rs b/src/sexpr.rs index d47efb8..0d7cb75 100644 --- a/src/sexpr.rs +++ b/src/sexpr.rs @@ -331,6 +331,20 @@ fn stmt_to_sexpr(stmt: &Statement, out: &mut String, indent: usize) { Statement::WorkerSpawn(w) => { out.push_str(&format!("(spawn-worker \"{}\")", w.worker_name)); } + Statement::SendMessage(s) => { + out.push_str(&format!("(send :to \"{}\" ", s.target)); + expr_to_sexpr(&s.message.node, out, indent + 2); + out.push(')'); + } + Statement::ReceiveMessage(r) => { + out.push_str(&format!("(receive :from \"{}\")", r.source)); + } + Statement::AwaitWorker(a) => { + out.push_str(&format!("(await-worker \"{}\")", a.worker_name)); + } + Statement::CancelWorker(c) => { + out.push_str(&format!("(cancel-worker \"{}\")", c.worker_name)); + } Statement::Complain(c) => { out.push_str(&format!("(complain \"{}\")", c.message)); } @@ -710,6 +724,23 @@ fn stmt_to_json(stmt: &Statement) -> serde_json::Value { "type": "spawn_worker", "name": w.worker_name }), + Statement::SendMessage(s) => serde_json::json!({ + "type": "send_message", + "target": s.target, + "message": expr_to_json(&s.message.node) + }), + Statement::ReceiveMessage(r) => serde_json::json!({ + "type": "receive_message", + "source": r.source + }), + Statement::AwaitWorker(a) => serde_json::json!({ + "type": "await_worker", + "name": a.worker_name + }), + Statement::CancelWorker(c) => serde_json::json!({ + "type": "cancel_worker", + "name": c.worker_name + }), Statement::Complain(c) => serde_json::json!({ "type": "complain", "message": c.message