refactors
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
|
||||
/// Register name
|
||||
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||
@@ -34,6 +34,6 @@ pub fn parse_reg(name: &str) -> anyhow::Result<Register> {
|
||||
let val: u8 = rn.parse()?;
|
||||
Ok(Register::Gen(val))
|
||||
} else {
|
||||
Err(Error::Parse(format!("Bad reg name: {}", name).into()))?
|
||||
Err(CrsnError::Parse(format!("Bad reg name: {}", name).into()))?
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::asm::instr::Cond;
|
||||
|
||||
/// csn_asm unified error type
|
||||
#[derive(Error, Debug)]
|
||||
pub enum Error {
|
||||
pub enum CrsnError {
|
||||
#[error("S-expression syntax error: {0:?}")]
|
||||
PreParse(#[from] Box<sexp::Error>),
|
||||
#[error("Parse error: {0:?}")]
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::fmt::{self, Display, Formatter};
|
||||
use std::ops::Not;
|
||||
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
|
||||
/// Condition flag
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
@@ -45,7 +45,7 @@ pub enum Cond {
|
||||
NotCarry,
|
||||
}
|
||||
|
||||
pub fn parse_cond(text: &str) -> Result<Cond, Error> {
|
||||
pub fn parse_cond(text: &str) -> Result<Cond, CrsnError> {
|
||||
Ok(match text.trim_end_matches('?') {
|
||||
"eq" | "=" | "==" => Cond::Equal,
|
||||
"ne" | "<>" | "!=" | "≠" => Cond::NotEqual,
|
||||
@@ -66,7 +66,7 @@ pub fn parse_cond(text: &str) -> Result<Cond, Error> {
|
||||
"ov" | "^" => Cond::Overflow,
|
||||
"nov" | "!ov" | "!^" => Cond::NotOverflow,
|
||||
_ => {
|
||||
return Err(Error::Parse(format!("Unknown cond: {}", text).into()));
|
||||
return Err(CrsnError::Parse(format!("Unknown cond: {}", text).into()));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -3,17 +3,17 @@ use std::sync::atomic::AtomicU32;
|
||||
|
||||
use crate::asm::data::{Rd, RdData};
|
||||
use crate::asm::data::literal::{Label, Value};
|
||||
use crate::asm::error::{AsmError, Error};
|
||||
use crate::asm::error::{AsmError, CrsnError};
|
||||
use crate::asm::instr::{Cond, Instr, Op, Routine};
|
||||
use crate::builtin::defs::BuiltinOp;
|
||||
|
||||
/// A trait for something that can turn into multiple instructions
|
||||
pub trait Flatten {
|
||||
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, Error>;
|
||||
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError>;
|
||||
}
|
||||
|
||||
impl Flatten for Instr {
|
||||
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, Error> {
|
||||
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError> {
|
||||
let mut ops = vec![self.op];
|
||||
|
||||
if let Some(branches) = self.branches {
|
||||
@@ -22,7 +22,7 @@ impl Flatten for Instr {
|
||||
let end_lbl = Label::unique(label_num);
|
||||
for (cnt, (cond, branch)) in branches.into_iter().enumerate() {
|
||||
if labels.contains_key(&cond) {
|
||||
return Err(Error::Asm(AsmError::ConditionalAlreadyUsed(cond)));
|
||||
return Err(CrsnError::Asm(AsmError::ConditionalAlreadyUsed(cond)));
|
||||
}
|
||||
|
||||
let next_lbl = if cnt == branch_count - 1 {
|
||||
@@ -49,7 +49,7 @@ impl Flatten for Instr {
|
||||
}
|
||||
|
||||
impl Flatten for Routine {
|
||||
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, Error> {
|
||||
fn flatten(self, label_num: &AtomicU32) -> Result<Vec<Op>, CrsnError> {
|
||||
let mut ops = vec![
|
||||
BuiltinOp::Routine(self.name.clone()).into(),
|
||||
];
|
||||
@@ -65,7 +65,7 @@ impl Flatten for Routine {
|
||||
}
|
||||
|
||||
/// Convert jumps to relative skips
|
||||
fn numbered_labels_to_skips(ops: Vec<Op>) -> Result<Vec<Op>, Error> {
|
||||
fn numbered_labels_to_skips(ops: Vec<Op>) -> Result<Vec<Op>, CrsnError> {
|
||||
let mut label_positions = HashMap::<Label, usize>::new();
|
||||
for (n, op) in ops.iter().enumerate() {
|
||||
if let Op::BuiltIn(BuiltinOp::Label(name @ Label::Numbered(_))) = op {
|
||||
@@ -85,7 +85,7 @@ fn numbered_labels_to_skips(ops: Vec<Op>) -> Result<Vec<Op>, Error> {
|
||||
let skip = *dest as isize - n as isize + skipped;
|
||||
cleaned.push(Op::BuiltIn(BuiltinOp::Skip(Rd::new(RdData::Immediate(skip as Value)))));
|
||||
} else {
|
||||
return Err(Error::Asm(AsmError::LabelNotDefined(target)));
|
||||
return Err(CrsnError::Asm(AsmError::LabelNotDefined(target)));
|
||||
}
|
||||
}
|
||||
Op::BuiltIn(BuiltinOp::JumpIf(cond, target @ Label::Numbered(_))) => {
|
||||
@@ -93,7 +93,7 @@ fn numbered_labels_to_skips(ops: Vec<Op>) -> Result<Vec<Op>, Error> {
|
||||
let skip = *dest as isize - n as isize + skipped;
|
||||
cleaned.push(Op::BuiltIn(BuiltinOp::SkipIf(cond, Rd::new(RdData::Immediate(skip as Value)))));
|
||||
} else {
|
||||
return Err(Error::Asm(AsmError::LabelNotDefined(target)));
|
||||
return Err(CrsnError::Asm(AsmError::LabelNotDefined(target)));
|
||||
}
|
||||
}
|
||||
other => {
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ pub mod parse;
|
||||
pub mod patches;
|
||||
|
||||
/// Parse a program from string and assemble a low level instruction sequence from it.
|
||||
pub fn assemble(source: &str, parsers: Arc<Vec<Box<dyn CrsnExtension>>>) -> Result<Arc<Program>, error::Error> {
|
||||
pub fn assemble(source: &str, parsers: Arc<Vec<Box<dyn CrsnExtension>>>) -> Result<Arc<Program>, error::CrsnError> {
|
||||
let ops = parse::parse(source, &parsers)?;
|
||||
|
||||
trace!("--- Compiled program ---");
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::sync::atomic::AtomicU32;
|
||||
pub use parse_instr::parse_instructions;
|
||||
use parse_routines::parse_routines;
|
||||
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
use crate::asm::instr::{Flatten, Op, Routine};
|
||||
use crate::asm::parse::sexp_expect::expect_list;
|
||||
use crate::module::CrsnExtension;
|
||||
@@ -17,7 +17,7 @@ mod parse_op;
|
||||
|
||||
pub mod arg_parser;
|
||||
|
||||
pub fn parse(source: &str, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Op>, Error> {
|
||||
pub fn parse(source: &str, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Op>, CrsnError> {
|
||||
let root = sexp::parse(source)?;
|
||||
|
||||
let subs: Vec<Routine> = parse_routines(expect_list(Some(root), true)?, parsers)?;
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
use sexp::Sexp;
|
||||
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
use crate::asm::instr::{Cond, cond, Instr};
|
||||
use crate::asm::parse::parse_instr::parse_instructions;
|
||||
use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom};
|
||||
use crate::asm::patches::TryRemove;
|
||||
use crate::module::CrsnExtension;
|
||||
|
||||
pub fn parse_cond_branch(tok: Sexp, parsers: &[Box<dyn CrsnExtension>]) -> Result<(Cond, Vec<Instr>), Error> {
|
||||
pub fn parse_cond_branch(tok: Sexp, parsers: &[Box<dyn CrsnExtension>]) -> Result<(Cond, Vec<Instr>), CrsnError> {
|
||||
let mut list = expect_list(Some(tok), false)?;
|
||||
let kw = expect_string_atom(list.try_remove(0))?;
|
||||
|
||||
if !kw.ends_with('?') {
|
||||
return Err(Error::Parse(format!("Condition must end with '?': {}", kw).into()));
|
||||
return Err(CrsnError::Parse(format!("Condition must end with '?': {}", kw).into()));
|
||||
}
|
||||
|
||||
Ok((cond::parse_cond(&kw)?, parse_instructions(list, parsers)?))
|
||||
|
||||
@@ -4,21 +4,21 @@ use sexp::{Atom, Sexp};
|
||||
|
||||
use crate::asm::data::{DataDisp, Rd, RdData, reg, Wr, WrData};
|
||||
use crate::asm::data::literal::Label;
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
use crate::asm::parse::sexp_expect::expect_string_atom;
|
||||
|
||||
/// Parse a label
|
||||
pub fn parse_label(name: Option<Sexp>) -> Result<Label, Error> {
|
||||
pub fn parse_label(name: Option<Sexp>) -> Result<Label, CrsnError> {
|
||||
let name = expect_string_atom(name)?;
|
||||
Ok(Label::Named(name.trim_start_matches(':').into()))
|
||||
}
|
||||
|
||||
/// Parse data disposition (address/value, without the read/write restriction)
|
||||
pub fn parse_data_disp(tok: Option<Sexp>) -> Result<DataDisp, Error> {
|
||||
pub fn parse_data_disp(tok: Option<Sexp>) -> Result<DataDisp, CrsnError> {
|
||||
let tok = if let Some(tok) = tok {
|
||||
tok
|
||||
} else {
|
||||
return Err(Error::Parse("Expected data disposition token".into()));
|
||||
return Err(CrsnError::Parse("Expected data disposition token".into()));
|
||||
};
|
||||
|
||||
// TODO implement masks
|
||||
@@ -41,7 +41,7 @@ pub fn parse_data_disp(tok: Option<Sexp>) -> Result<DataDisp, Error> {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
Err(Error::Parse(format!("bad data disp: {:?}", tok).into()))
|
||||
Err(CrsnError::Parse(format!("bad data disp: {:?}", tok).into()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use sexp::Sexp;
|
||||
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
use crate::asm::instr::Instr;
|
||||
use crate::asm::parse::arg_parser::ArgParser;
|
||||
use crate::asm::parse::parse_cond::parse_cond_branch;
|
||||
@@ -10,7 +10,7 @@ use crate::module::CrsnExtension;
|
||||
|
||||
use super::parse_op::parse_op;
|
||||
|
||||
pub fn parse_instructions(instrs: Vec<Sexp>, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Instr>, Error> {
|
||||
pub fn parse_instructions(instrs: Vec<Sexp>, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Instr>, CrsnError> {
|
||||
let mut parsed = vec![];
|
||||
for expr in instrs {
|
||||
let tokens = expect_list(Some(expr), false)?;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
use crate::asm::instr::Op;
|
||||
use crate::asm::parse::arg_parser::ArgParser;
|
||||
use crate::builtin::parse::BuiltinOps;
|
||||
use crate::module::{CrsnExtension, ParseOpRes};
|
||||
|
||||
pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box<dyn CrsnExtension>]) -> Result<Op, Error> {
|
||||
pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box<dyn CrsnExtension>]) -> Result<Op, CrsnError> {
|
||||
// Include built-in instructions
|
||||
let builtins = [BuiltinOps::new()];
|
||||
|
||||
@@ -23,5 +23,5 @@ pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box<dyn Crs
|
||||
}
|
||||
}
|
||||
|
||||
return Err(Error::Parse(format!("Unknown instruction: {}", keyword).into()));
|
||||
return Err(CrsnError::Parse(format!("Unknown instruction: {}", keyword).into()));
|
||||
}
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
use sexp::Sexp;
|
||||
|
||||
use crate::asm::data::literal::RoutineName;
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
use crate::asm::instr::Routine;
|
||||
use crate::asm::parse::parse_instr::parse_instructions;
|
||||
use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom};
|
||||
use crate::asm::patches::TryRemove;
|
||||
use crate::module::CrsnExtension;
|
||||
|
||||
pub fn parse_routines(routines: Vec<Sexp>, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Routine>, Error> {
|
||||
pub fn parse_routines(routines: Vec<Sexp>, parsers: &[Box<dyn CrsnExtension>]) -> Result<Vec<Routine>, CrsnError> {
|
||||
let mut parsed = vec![];
|
||||
for rt in routines {
|
||||
let mut def = expect_list(Some(rt), false)?;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
use sexp::{Atom, Sexp};
|
||||
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
|
||||
pub fn expect_list(expr: Option<Sexp>, allow_empty: bool) -> Result<Vec<Sexp>, Error> {
|
||||
pub fn expect_list(expr: Option<Sexp>, allow_empty: bool) -> Result<Vec<Sexp>, CrsnError> {
|
||||
if let Some(expr) = expr {
|
||||
match &expr {
|
||||
Sexp::Atom(_) => {
|
||||
return Err(Error::ParseIn("Expected a list".into(), expr));
|
||||
return Err(CrsnError::ParseIn("Expected a list".into(), expr));
|
||||
}
|
||||
Sexp::List(list) => {
|
||||
if !allow_empty && list.is_empty() {
|
||||
return Err(Error::ParseIn("Routine: Empty list".into(), expr));
|
||||
return Err(CrsnError::ParseIn("Routine: Empty list".into(), expr));
|
||||
}
|
||||
|
||||
if let Sexp::List(list) = expr {
|
||||
@@ -22,10 +22,10 @@ pub fn expect_list(expr: Option<Sexp>, allow_empty: bool) -> Result<Vec<Sexp>, E
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::Parse("Expected a list, got nothing".into()))
|
||||
Err(CrsnError::Parse("Expected a list, got nothing".into()))
|
||||
}
|
||||
|
||||
pub fn expect_atom(expr: Option<Sexp>) -> Result<Atom, Error> {
|
||||
pub fn expect_atom(expr: Option<Sexp>) -> Result<Atom, CrsnError> {
|
||||
if let Some(expr) = expr {
|
||||
match &expr {
|
||||
Sexp::Atom(_atom) => {
|
||||
@@ -36,18 +36,18 @@ pub fn expect_atom(expr: Option<Sexp>) -> Result<Atom, Error> {
|
||||
}
|
||||
}
|
||||
Sexp::List(_) => {
|
||||
return Err(Error::ParseIn("Expected atom got list".into(), expr));
|
||||
return Err(CrsnError::ParseIn("Expected atom got list".into(), expr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::Parse("Expected atom, got nothing".into()))
|
||||
Err(CrsnError::Parse("Expected atom, got nothing".into()))
|
||||
}
|
||||
|
||||
pub fn expect_string_atom(expr: Option<Sexp>) -> Result<String, Error> {
|
||||
pub fn expect_string_atom(expr: Option<Sexp>) -> Result<String, CrsnError> {
|
||||
match expect_atom(expr) {
|
||||
Ok(Atom::S(s)) => Ok(s),
|
||||
Ok(atom) => Err(Error::ParseIn("Expected string atom".into(), Sexp::Atom(atom))),
|
||||
Ok(atom) => Err(CrsnError::ParseIn("Expected string atom".into(), Sexp::Atom(atom))),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use sexp::{Atom, Sexp};
|
||||
|
||||
use crate::asm::data::literal::{Label, RoutineName};
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
use crate::asm::instr::cond::parse_cond;
|
||||
use crate::asm::instr::Op;
|
||||
use crate::asm::parse::arg_parser::ArgParser;
|
||||
@@ -28,7 +28,7 @@ impl CrsnExtension for BuiltinOps {
|
||||
"builtin"
|
||||
}
|
||||
|
||||
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, Error> {
|
||||
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> {
|
||||
Ok(ParseOpRes::Parsed(Op::BuiltIn(match keyword {
|
||||
"nop" => {
|
||||
BuiltinOp::Nop
|
||||
|
||||
@@ -4,7 +4,7 @@ pub use eval_res::EvalRes;
|
||||
|
||||
use crate::asm::data::literal::Value;
|
||||
use crate::asm::data::Mask;
|
||||
use crate::asm::error::Error;
|
||||
use crate::asm::error::CrsnError;
|
||||
use crate::asm::instr::Op;
|
||||
use crate::asm::parse::arg_parser::ArgParser;
|
||||
use crate::runtime::fault::Fault;
|
||||
@@ -23,7 +23,7 @@ pub enum ParseOpRes<T> {
|
||||
|
||||
impl ParseOpRes<Op> {
|
||||
/// Helper to construct an extension op
|
||||
pub fn parsed(op : impl OpTrait) -> Self {
|
||||
pub fn ext(op : impl OpTrait) -> Self {
|
||||
Self::Parsed(Op::Ext(Box::new(op)))
|
||||
}
|
||||
}
|
||||
@@ -41,7 +41,7 @@ pub trait CrsnExtension: Debug + Send + Sync + 'static {
|
||||
/// 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<ParseOpRes<Op>, Error>;
|
||||
fn parse_op(&self, keyword: &str, arg_tokens: ArgParser) -> Result<ParseOpRes<Op>, CrsnError>;
|
||||
|
||||
/// Drop an object referenced by a handle
|
||||
fn drop_obj(&self,
|
||||
|
||||
+22
-1
@@ -1,6 +1,27 @@
|
||||
pub use parse::ArithOps;
|
||||
use crsn::module::{CrsnExtension, ParseOpRes};
|
||||
use crsn::asm::parse::arg_parser::ArgParser;
|
||||
use crsn::asm::error::CrsnError;
|
||||
use crsn::asm::instr::Op;
|
||||
|
||||
mod defs;
|
||||
mod parse;
|
||||
mod exec;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ArithOps;
|
||||
|
||||
impl ArithOps {
|
||||
pub fn new() -> Box<dyn CrsnExtension> {
|
||||
Box::new(Self)
|
||||
}
|
||||
}
|
||||
|
||||
impl CrsnExtension for ArithOps {
|
||||
fn name(&self) -> &'static str {
|
||||
"arith"
|
||||
}
|
||||
|
||||
fn parse_op(&self, keyword: &str, args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> {
|
||||
parse::parse(keyword, args)
|
||||
}
|
||||
}
|
||||
|
||||
+20
-38
@@ -1,31 +1,13 @@
|
||||
use crsn::asm::data::{Rd, Wr};
|
||||
use crsn::asm::error::Error;
|
||||
use crsn::asm::error::CrsnError;
|
||||
use crsn::asm::instr::Op;
|
||||
use crsn::asm::parse::arg_parser::ArgParser;
|
||||
use crsn::module::{CrsnExtension, ParseOpRes};
|
||||
use crsn::module::{ParseOpRes};
|
||||
|
||||
use crate::defs::ArithOp;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ArithOps {
|
||||
_internal: ()
|
||||
}
|
||||
|
||||
impl ArithOps {
|
||||
pub fn new() -> Box<dyn CrsnExtension> {
|
||||
Box::new(Self {
|
||||
_internal: ()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl CrsnExtension for ArithOps {
|
||||
fn name(&self) -> &'static str {
|
||||
"arith"
|
||||
}
|
||||
|
||||
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, Error> {
|
||||
Ok(ParseOpRes::parsed(match keyword {
|
||||
pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> {
|
||||
Ok(ParseOpRes::ext(match keyword {
|
||||
"cmp" => {
|
||||
ArithOp::Compare {
|
||||
a: args.next_rd()?,
|
||||
@@ -74,7 +56,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Add requires 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Add requires 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -97,7 +79,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Sub requires 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Sub requires 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -120,7 +102,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Mul requires 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Mul requires 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -147,7 +129,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("DivR requires 3 or 4 arguments".into()));
|
||||
return Err(CrsnError::Parse("DivR requires 3 or 4 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -173,7 +155,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Div requires 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Div requires 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -197,7 +179,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Mod requires 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Mod requires 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,7 +202,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("And requires 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("And requires 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -243,7 +225,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Or requires 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Or requires 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -266,7 +248,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Xor requires 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Xor requires 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -287,7 +269,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Cpl requires 1 or 2 arguments".into()));
|
||||
return Err(CrsnError::Parse("Cpl requires 1 or 2 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -318,7 +300,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Rol requires 1, 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Rol requires 1, 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -349,7 +331,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Ror requires 1, 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Ror requires 1, 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -380,7 +362,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Lsl requires 1, 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Lsl requires 1, 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -411,7 +393,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Lsr requires 1, 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Lsr requires 1, 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -442,7 +424,7 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
return Err(Error::Parse("Asr requires 1, 2 or 3 arguments".into()));
|
||||
return Err(CrsnError::Parse("Asr requires 1, 2 or 3 arguments".into()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,4 +434,4 @@ impl CrsnExtension for ArithOps {
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ impl OpTrait for StackOp {
|
||||
//
|
||||
}
|
||||
|
||||
pub(crate) fn drop_stack(state: &mut RunState, handle: Value) -> Result<Option<()>, Fault> {
|
||||
pub(crate) fn drop_obj(state: &mut RunState, handle: Value) -> Result<Option<()>, Fault> {
|
||||
let stacks: &mut Stacks = state.ext_mut();
|
||||
Ok(stacks.store.remove(&handle).map(|_| ()))
|
||||
}
|
||||
|
||||
+22
-1
@@ -1,6 +1,27 @@
|
||||
pub use parse::StackOps;
|
||||
use crsn::module::{CrsnExtension, ParseOpRes};
|
||||
use crsn::asm::parse::arg_parser::ArgParser;
|
||||
use crsn::asm::instr::Op;
|
||||
use crsn::asm::error::CrsnError;
|
||||
|
||||
mod defs;
|
||||
mod parse;
|
||||
mod exec;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StackOps;
|
||||
|
||||
impl StackOps {
|
||||
pub fn new() -> Box<dyn CrsnExtension> {
|
||||
Box::new(Self)
|
||||
}
|
||||
}
|
||||
|
||||
impl CrsnExtension for StackOps {
|
||||
fn name(&self) -> &'static str {
|
||||
"stacks"
|
||||
}
|
||||
|
||||
fn parse_op(&self, keyword: &str, args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> {
|
||||
parse::parse(keyword, args)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,15 @@
|
||||
use crsn::asm::data::literal::Value;
|
||||
use crsn::asm::error::Error;
|
||||
|
||||
use crsn::asm::error::CrsnError;
|
||||
use crsn::asm::instr::Op;
|
||||
use crsn::asm::parse::arg_parser::ArgParser;
|
||||
use crsn::module::{CrsnExtension, ParseOpRes};
|
||||
use crsn::runtime::fault::Fault;
|
||||
use crsn::runtime::run_thread::{RunState, ThreadInfo};
|
||||
use crsn::module::{ParseOpRes};
|
||||
|
||||
|
||||
|
||||
use crate::defs::StackOp;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct StackOps {
|
||||
_internal: ()
|
||||
}
|
||||
|
||||
impl StackOps {
|
||||
pub fn new() -> Box<dyn CrsnExtension> {
|
||||
Box::new(Self {
|
||||
_internal: ()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl CrsnExtension for StackOps {
|
||||
fn name(&self) -> &'static str {
|
||||
"stacks"
|
||||
}
|
||||
|
||||
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, Error> {
|
||||
Ok(ParseOpRes::parsed(match keyword {
|
||||
pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> {
|
||||
Ok(ParseOpRes::ext(match keyword {
|
||||
"stack" => {
|
||||
StackOp::NewStack {
|
||||
dst: args.next_wr()?,
|
||||
@@ -53,9 +35,3 @@ impl CrsnExtension for StackOps {
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
fn drop_obj(&self, _ti: &ThreadInfo, state: &mut RunState, handle: Value) -> Result<Option<()>, Fault>
|
||||
{
|
||||
crate::exec::drop_stack(state, handle)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user