use std::fmt::Debug; use sexp::{Atom, Sexp, SourcePosition}; use crate::asm::instr::Cond; use crate::builtin::defs::BuiltinOp; use crate::module::{EvalRes, OpTrait}; use crate::runtime::fault::Fault; use crate::runtime::run_thread::{info::ThreadInfo, state::RunState}; /// A higher level simple opration #[derive(Debug)] pub enum OpKind { BuiltIn(BuiltinOp), /// Instruction added by an extension Ext(Box), } #[derive(Debug)] pub struct Op { pub kind: OpKind, pub cond: Option, pub pos: SourcePosition, } impl OpTrait for Op { fn execute(&self, ti: &ThreadInfo, state: &mut RunState) -> Result { if let Some(cond) = self.cond { if !state.test_cond(cond) { return Ok(EvalRes { cycles: 0, advance: 1, }); } } match &self.kind { OpKind::BuiltIn(op) => { op.execute(ti, state) } OpKind::Ext(op) => { op.execute(ti, state) } } } fn to_sexp(&self) -> Sexp { let mut se = match &self.kind { OpKind::BuiltIn(op) => op.to_sexp(), OpKind::Ext(op) => op.to_sexp() }; if let Some(cond) = self.cond { if let Sexp::List(items, _) = &mut se { if let Some(Sexp::Atom(Atom::S(s), _)) = &mut items.get_mut(0) { s.push('.'); s.push_str(&cond.to_string()); } } } se } }