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.
77 lines
1.9 KiB
77 lines
1.9 KiB
use std::fmt::Debug;
|
|
|
|
use crate::asm::data::{
|
|
literal::DebugMsg, literal::Label,
|
|
literal::RoutineName,
|
|
Rd,
|
|
Wr,
|
|
};
|
|
use crate::asm::data::literal::Addr;
|
|
use crate::asm::error::Error;
|
|
use crate::asm::instr::Cond;
|
|
use crate::asm::parse::arg_parser::ArgParser;
|
|
use crate::builtin::defs::BuiltinOp;
|
|
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 Op {
|
|
BuiltIn(BuiltinOp),
|
|
/// Instruction added by an extension
|
|
Ext(Box<dyn OpTrait>),
|
|
}
|
|
|
|
pub trait OpTrait: Debug + Send + Sync + 'static {
|
|
fn execute(&self, program: &Program, call_stack: &mut CallStack, frame: &mut StackFrame) -> Result<EvalRes, Fault>;
|
|
}
|
|
|
|
pub enum ParseOpResult {
|
|
Parsed(Op),
|
|
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>;
|
|
}
|
|
|
|
|
|
pub type CyclesSpent = usize;
|
|
|
|
#[derive(Debug)]
|
|
pub struct EvalRes {
|
|
pub cycles: CyclesSpent,
|
|
pub advance: i64,
|
|
}
|
|
|
|
impl Default for EvalRes {
|
|
fn default() -> Self {
|
|
Self {
|
|
cycles: 1,
|
|
advance: 1,
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
impl OpTrait for Op {
|
|
fn execute(&self, program: &Program, call_stack: &mut CallStack, frame: &mut StackFrame) -> Result<EvalRes, Fault> {
|
|
match self {
|
|
Op::BuiltIn(op) => {
|
|
op.execute(&program, call_stack, frame)
|
|
}
|
|
Op::Ext(op) => {
|
|
op.execute(&program, call_stack, frame)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|