use alloc::{sync::Arc, vec::Vec};
use miden_core::{
Program,
mast::{MastForest, MastNodeId},
};
const CONTINUATION_STACK_SIZE_HINT: usize = 64;
#[derive(Debug, Clone)]
pub enum Continuation {
StartNode(MastNodeId),
FinishJoin(MastNodeId),
FinishSplit(MastNodeId),
FinishLoop(MastNodeId),
FinishCall(MastNodeId),
FinishDyn(MastNodeId),
FinishExternal(MastNodeId),
EnterForest(Arc<MastForest>),
}
#[derive(Debug, Default, Clone)]
pub struct ContinuationStack {
stack: Vec<Continuation>,
}
impl ContinuationStack {
pub fn new(program: &Program) -> Self {
let mut stack = Vec::with_capacity(CONTINUATION_STACK_SIZE_HINT);
stack.push(Continuation::StartNode(program.entrypoint()));
Self { stack }
}
pub fn push_enter_forest(&mut self, forest: Arc<MastForest>) {
self.stack.push(Continuation::EnterForest(forest));
}
pub fn push_finish_join(&mut self, node_id: MastNodeId) {
self.stack.push(Continuation::FinishJoin(node_id));
}
pub fn push_finish_split(&mut self, node_id: MastNodeId) {
self.stack.push(Continuation::FinishSplit(node_id));
}
pub fn push_finish_loop(&mut self, node_id: MastNodeId) {
self.stack.push(Continuation::FinishLoop(node_id));
}
pub fn push_finish_call(&mut self, node_id: MastNodeId) {
self.stack.push(Continuation::FinishCall(node_id));
}
pub fn push_finish_dyn(&mut self, node_id: MastNodeId) {
self.stack.push(Continuation::FinishDyn(node_id));
}
pub fn push_finish_external(&mut self, node_id: MastNodeId) {
self.stack.push(Continuation::FinishExternal(node_id));
}
pub fn push_start_node(&mut self, node_id: MastNodeId) {
self.stack.push(Continuation::StartNode(node_id));
}
pub fn pop_continuation(&mut self) -> Option<Continuation> {
self.stack.pop()
}
}