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

91 lines
2.7 KiB

use std::fmt::Debug;
use crate::asm::data::{
literal::DebugMsg, literal::Label,
literal::RoutineName,
Rd,
Wr,
};
use crate::asm::error::Error;
use crate::asm::instr::Cond;
use crate::asm::parse::arg_parser::ArgParser;
use crate::runtime::fault::Fault;
use crate::runtime::frame::{CallStack, StackFrame};
use crate::runtime::program::Program;
/// A higher level simple opration
#[derive(Debug)]
pub enum OpWrapper {
/// Mark a jump target.
Label(Label),
/// Jump to a label
Jump(Label),
/// Jump to a label if a flag is set
JumpIf(Cond, Label),
/// Low level op
Op(Op),
}
/// A low level instruction
#[derive(Debug)]
pub enum Op {
/// Do nothing
Nop,
/// Mark a far jump target (can be jumped to from another routine).
/// This label is preserved in optimized code.
FarLabel(Label),
/// Jump to a label that can be in another function
FarJump(Label),
/// Call a routine with arguments.
/// The arguments are passed as argX. Return values are stored in resX registers.
Call(RoutineName, Vec<Rd>),
/// Exit the current routine with return values
Ret(Vec<Rd>),
/// Mark a routine entry point (call target).
/// Kept in the low level instruction file for position-independent code
Routine(RoutineName),
/// Skip backward or forward
Skip(Rd),
/// Skip if a flag is set
SkipIf(Cond, Rd),
/// Deny jumps, skips and run across this address, producing a run-time fault with a message.
Barrier(Option<DebugMsg>),
/// Generate a run-time fault with a debugger message
Fault(Option<DebugMsg>),
/// Copy value
Move { dst: Wr, src: Rd },
/// Store runtime status to a register
StoreStatus { dst: Wr },
/// Load runtime status from a register
LoadStatus { src: Rd },
Extension(Box<dyn OpTrait>),
}
/// Make "into" work
impl From<Op> for OpWrapper {
fn from(op: Op) -> Self {
OpWrapper::Op(op)
}
}
pub trait OpTrait: Debug + Send + Sync + 'static {
fn execute(&self, program: &Program, call_stack: &mut CallStack, frame: &mut StackFrame) -> Result<(), Fault>;
}
pub enum ParseOpResult {
Parsed(Box<dyn OpTrait + Send>),
Unknown(ArgParser),
}
pub trait AsmModule: Debug + Send + 'static {
/// Get name of the module
fn name(&self) -> &'static str;
/// Parse an op.
/// If the keyword matches and the function decides to parse the instruction, it must consume
/// the argument list and either return Ok or Err.
///
/// If the instruction keyword is not recognized, return Unknown with the unchanged argument list.
fn parse_op(&self, keyword: &str, arg_tokens: ArgParser) -> Result<ParseOpResult, Error>;
}