Croissant Runtime
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
crsn/crsn/src/asm/instr/op.rs

76 lines
2.0 KiB

use std::fmt::Debug;
use sexp::{Atom, Sexp, SourcePosition};
use crate::asm::instr::Cond;
use crate::builtin::defs::BuiltinOp;
use crate::module::{EvalRes, OpTrait, SchedSignal};
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<dyn OpTrait>),
}
#[derive(Debug)]
pub struct Op {
pub kind: OpKind,
pub cond: Option<Cond>,
pub pos: SourcePosition,
}
impl OpTrait for Op {
fn execute(&self, ti: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> {
if let Some(cond) = self.cond {
if !state.test_cond(cond) {
return Ok(EvalRes {
cycles: 0,
advance: 1,
sched: SchedSignal::Normal
});
}
}
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()
};
// TODO rewrite to be more readable?
if let Some(cond) = self.cond {
// "true" is used for "else" branches, it has no effect - just omit it
if cond != Cond::True {
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
}
fn is_compile_time_evaluable(&self) -> bool {
match &self.kind {
OpKind::BuiltIn(op) => op.is_compile_time_evaluable(),
OpKind::Ext(op) => op.is_compile_time_evaluable()
}
}
}