diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index ee0c5aed2fcc0282a9526d5b434bc963a111f434..fbe0fca45345572d5c03507ce1147e34341b357e 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -165,10 +165,10 @@ impl ProtocolDescription { // TODO: @temp Should just become a concrete thing that is passed in pub trait RunContext { - fn did_put(&self, port: PortId) -> bool; - fn get(&self, port: PortId) -> Option; // None if still waiting on message - fn fires(&self, port: PortId) -> Option; // None if not yet branched - fn get_channel(&self) -> Option<(Value, Value)>; // None if not yet prepared + fn did_put(&mut self, port: PortId) -> bool; + fn get(&mut self, port: PortId) -> Option; // None if still waiting on message + fn fires(&mut self, port: PortId) -> Option; // None if not yet branched + fn get_channel(&mut self) -> Option<(Value, Value)>; // None if not yet prepared } #[derive(Debug)] @@ -207,7 +207,7 @@ impl ComponentState { EC::SyncBlockStart => return RR::ComponentAtSyncStart, EC::SyncBlockEnd => return RR::BranchAtSyncEnd, EC::NewComponent(definition_id, monomorph_idx, args) => - return RR::NewComponent(definition_id, monomorph_idx, arg), + return RR::NewComponent(definition_id, monomorph_idx, args), EC::NewChannel => return RR::NewChannel, EC::BlockFires(port_id) => return RR::BranchMissingPortState(port_id), @@ -271,7 +271,14 @@ impl ComponentState { context.new_component(moved_ports, init_state); // Continue stepping continue; - } + }, + EvalContinuation::NewChannel => { + // Because of the way we emulate the old context for now, we can safely + // assume that this will never happen. The old context thingamajig always + // creates a channel, it never bubbles a "need to create a channel" message + // to the runtime + unreachable!(); + }, // Outside synchronous blocks, no fires/get/put happens EvalContinuation::BlockFires(_) => unreachable!(), EvalContinuation::BlockGet(_) => unreachable!(), @@ -304,23 +311,12 @@ impl ComponentState { EvalContinuation::SyncBlockEnd => return SyncBlocker::SyncBlockEnd, // Not possible to create component in sync block EvalContinuation::NewComponent(_, _, _) => unreachable!(), - EvalContinuation::BlockFires(port) => match port { - Value::Output(port) => { - return SyncBlocker::CouldntCheckFiring(port); - } - Value::Input(port) => { - return SyncBlocker::CouldntCheckFiring(port); - } - _ => unreachable!(), + EvalContinuation::NewChannel => unreachable!(), + EvalContinuation::BlockFires(port) => { + return SyncBlocker::CouldntCheckFiring(port); }, - EvalContinuation::BlockGet(port) => match port { - Value::Output(port) => { - return SyncBlocker::CouldntReadMsg(port); - } - Value::Input(port) => { - return SyncBlocker::CouldntReadMsg(port); - } - _ => unreachable!(), + EvalContinuation::BlockGet(port) => { + return SyncBlocker::CouldntReadMsg(port); }, EvalContinuation::Put(port, message) => { let payload; @@ -346,6 +342,72 @@ impl ComponentState { } } } + +impl RunContext for EvalContext<'_> { + fn did_put(&mut self, port: PortId) -> bool { + match self { + EvalContext::None => unreachable!(), + EvalContext::Nonsync(_) => unreachable!(), + EvalContext::Sync(ctx) => { + ctx.did_put_or_get(port) + } + } + } + + fn get(&mut self, port: PortId) -> Option { + match self { + EvalContext::None => unreachable!(), + EvalContext::Nonsync(_) => unreachable!(), + EvalContext::Sync(ctx) => { + let payload = ctx.read_msg(port); + if payload.is_none() { + return None; + } + + let payload = payload.unwrap(); + let mut transformed = Vec::with_capacity(payload.len()); + for byte in payload.0.iter() { + transformed.push(Value::UInt8(*byte)); + } + + let value_group = ValueGroup{ + values: vec![Value::Message(0)], + regions: vec![transformed], + }; + + return Some(value_group); + } + } + } + + fn fires(&mut self, port: PortId) -> Option { + match self { + EvalContext::None => unreachable!(), + EvalContext::Nonsync(_) => unreachable!(), + EvalContext::Sync(context) => { + match context.is_firing(port) { + Some(did_fire) => Some(Value::Bool(did_fire)), + None => None, + } + } + } + } + + fn get_channel(&mut self) -> Option<(Value, Value)> { + match self { + EvalContext::None => unreachable!(), + EvalContext::Nonsync(context) => { + let [from, to] = context.new_port_pair(); + let from = Value::Output(from); + let to = Value::Input(to); + return Some((from, to)); + }, + EvalContext::Sync(_) => unreachable!(), + } + } +} + +// TODO: @remove once old runtime has disappeared impl EvalContext<'_> { // fn random(&mut self) -> LongValue { // match self {