use std::sync::Arc;
use arcstr::ArcStr;
use nanoid::nanoid;
use serde::{Deserialize, Serialize};
use crate::{model::Graph, runtime::{instruction::{Instruction, Instructions}, instructions::{Base, ConsumeStack, DUPLICATE, IS_NULL, POP_STACK}, proc::ProcEnv, Error}};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NullcheckIns {
pub ins: Arc<dyn Instruction>,
pub ifnull: Arc<dyn Instruction>,
}
#[typetag::serde(name = "NullcheckIns")]
impl Instruction for NullcheckIns {
fn exec(&self, _env: &mut ProcEnv, _graph: &mut Graph) -> Result<Option<Instructions>, Error> {
let mut instructions = Instructions::default();
instructions.push(self.ins.clone());
let end_tag: ArcStr = nanoid!(10).into();
instructions.push(DUPLICATE.clone());
instructions.push(IS_NULL.clone());
instructions.push(Arc::new(Base::CtrlForwardToIfNotTruthy(end_tag.clone(), ConsumeStack::Consume)));
instructions.push(POP_STACK.clone());
instructions.push(self.ifnull.clone());
instructions.push(Arc::new(Base::Tag(end_tag)));
Ok(Some(instructions))
}
}