forked from MightyPork/crsn
parent
2269d759c6
commit
b7345144e0
@ -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) |
||||
} |
||||
} |
||||
|
@ -1,455 +1,437 @@ |
||||
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: () |
||||
}) |
||||
} |
||||
} |
||||
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()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
|
||||
impl CrsnExtension for ArithOps { |
||||
fn name(&self) -> &'static str { |
||||
"arith" |
||||
} |
||||
"tst" => { |
||||
let arg = args.next_rd()?; |
||||
ArithOp::Test { a: arg } |
||||
} |
||||
|
||||
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, Error> { |
||||
Ok(ParseOpRes::parsed(match keyword { |
||||
"cmp" => { |
||||
ArithOp::Compare { |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
"inc" => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Add { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: Rd::immediate(1), |
||||
} |
||||
} |
||||
|
||||
"tst" => { |
||||
let arg = args.next_rd()?; |
||||
ArithOp::Test { a: arg } |
||||
"dec" => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Sub { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: Rd::immediate(1), |
||||
} |
||||
} |
||||
|
||||
"inc" => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Add { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: Rd::immediate(1), |
||||
"add" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Add { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
} |
||||
|
||||
"dec" => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Sub { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: Rd::immediate(1), |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Add { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Add requires 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"add" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Add { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Add { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Add requires 2 or 3 arguments".into())); |
||||
"sub" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Sub { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Sub { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Sub requires 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"sub" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Sub { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Sub { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Sub requires 2 or 3 arguments".into())); |
||||
"mul" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Mul { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Mul { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Mul requires 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"mul" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Mul { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Mul { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Mul requires 2 or 3 arguments".into())); |
||||
"divr" => { |
||||
match args.len() { |
||||
3 => { |
||||
let dst = args.next_wr()?; |
||||
let rem = args.next_wr()?; |
||||
let div = args.next_rd()?; |
||||
ArithOp::Div { |
||||
dst, |
||||
rem, |
||||
a: dst.as_rd(), |
||||
div, |
||||
} |
||||
} |
||||
4 => { |
||||
ArithOp::Div { |
||||
dst: args.next_wr()?, |
||||
rem: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
div: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("DivR requires 3 or 4 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"divr" => { |
||||
match args.len() { |
||||
3 => { |
||||
let dst = args.next_wr()?; |
||||
let rem = args.next_wr()?; |
||||
let div = args.next_rd()?; |
||||
ArithOp::Div { |
||||
dst, |
||||
rem, |
||||
a: dst.as_rd(), |
||||
div, |
||||
} |
||||
} |
||||
4 => { |
||||
ArithOp::Div { |
||||
dst: args.next_wr()?, |
||||
rem: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
div: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("DivR requires 3 or 4 arguments".into())); |
||||
"div" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Div { |
||||
dst: args.next_wr()?, |
||||
rem: Wr::discard(), |
||||
a: args.next_rd()?, |
||||
div: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
let div = args.next_rd()?; |
||||
ArithOp::Div { |
||||
dst, |
||||
rem: Wr::discard(), |
||||
a: dst.as_rd(), |
||||
div, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Div requires 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"div" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Div { |
||||
dst: args.next_wr()?, |
||||
rem: Wr::discard(), |
||||
a: args.next_rd()?, |
||||
div: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
let div = args.next_rd()?; |
||||
ArithOp::Div { |
||||
dst, |
||||
rem: Wr::discard(), |
||||
a: dst.as_rd(), |
||||
div, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Div requires 2 or 3 arguments".into())); |
||||
"mod" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Mod { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
div: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
let div = args.next_rd()?; |
||||
ArithOp::Mod { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
div, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Mod requires 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"mod" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Mod { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
div: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
let div = args.next_rd()?; |
||||
ArithOp::Mod { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
div, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Mod requires 2 or 3 arguments".into())); |
||||
"and" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::And { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::And { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("And requires 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"and" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::And { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::And { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("And requires 2 or 3 arguments".into())); |
||||
"or" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Or { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Or { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Or requires 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"or" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Or { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Or { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Or requires 2 or 3 arguments".into())); |
||||
"xor" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Xor { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Xor { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Xor requires 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"xor" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Xor { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Xor { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
b: args.next_rd()?, |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Xor requires 2 or 3 arguments".into())); |
||||
"cpl" => { |
||||
match args.len() { |
||||
2 => { |
||||
ArithOp::Cpl { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Cpl { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Cpl requires 1 or 2 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"cpl" => { |
||||
match args.len() { |
||||
2 => { |
||||
ArithOp::Cpl { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
} |
||||
"rol" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Rol { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Cpl { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Rol { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Cpl requires 1 or 2 arguments".into())); |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Rol { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Rol requires 1, 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"rol" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Rol { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Rol { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Rol { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Rol requires 1, 2 or 3 arguments".into())); |
||||
"ror" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Ror { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
} |
||||
|
||||
"ror" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Ror { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Ror { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Ror { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Ror requires 1, 2 or 3 arguments".into())); |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Ror { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Ror { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Ror requires 1, 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"lsl" | "asl" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Lsl { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Lsl { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Lsl { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Lsl requires 1, 2 or 3 arguments".into())); |
||||
"lsl" | "asl" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Lsl { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Lsl { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Lsl { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Lsl requires 1, 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"lsr" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Lsr { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Lsr { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Lsr { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Lsr requires 1, 2 or 3 arguments".into())); |
||||
"lsr" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Lsr { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Lsr { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Lsr { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Lsr requires 1, 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
"asr" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Asr { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Asr { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Asr { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(Error::Parse("Asr requires 1, 2 or 3 arguments".into())); |
||||
"asr" => { |
||||
match args.len() { |
||||
3 => { |
||||
ArithOp::Asr { |
||||
dst: args.next_wr()?, |
||||
a: args.next_rd()?, |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
2 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Asr { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: args.next_rd()?, |
||||
} |
||||
} |
||||
1 => { |
||||
let dst = args.next_wr()?; |
||||
ArithOp::Asr { |
||||
dst, |
||||
a: dst.as_rd(), |
||||
n: Rd::immediate(1), |
||||
} |
||||
} |
||||
_ => { |
||||
return Err(CrsnError::Parse("Asr requires 1, 2 or 3 arguments".into())); |
||||
} |
||||
} |
||||
} |
||||
|
||||
_other => { |
||||
return Ok(ParseOpRes::Unknown(args)); |
||||
} |
||||
})) |
||||
} |
||||
_other => { |
||||
return Ok(ParseOpRes::Unknown(args)); |
||||
} |
||||
})) |
||||
} |
||||
|
||||
|
@ -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,61 +1,37 @@ |
||||
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 { |
||||
"stack" => { |
||||
StackOp::NewStack { |
||||
dst: args.next_wr()?, |
||||
} |
||||
} |
||||
use crate::defs::StackOp; |
||||
|
||||
"push" => { |
||||
StackOp::Push { |
||||
obj: args.next_rdobj()?, |
||||
src: args.next_rd()?, |
||||
} |
||||
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()?, |
||||
} |
||||
} |
||||
|
||||
"pop" => { |
||||
StackOp::Pop { |
||||
dst: args.next_wr()?, |
||||
obj: args.next_rdobj()?, |
||||
} |
||||
"push" => { |
||||
StackOp::Push { |
||||
obj: args.next_rdobj()?, |
||||
src: args.next_rd()?, |
||||
} |
||||
} |
||||
|
||||
_other => { |
||||
return Ok(ParseOpRes::Unknown(args)); |
||||
"pop" => { |
||||
StackOp::Pop { |
||||
dst: args.next_wr()?, |
||||
obj: args.next_rdobj()?, |
||||
} |
||||
})) |
||||
} |
||||
} |
||||
|
||||
fn drop_obj(&self, _ti: &ThreadInfo, state: &mut RunState, handle: Value) -> Result<Option<()>, Fault> |
||||
{ |
||||
crate::exec::drop_stack(state, handle) |
||||
} |
||||
_other => { |
||||
return Ok(ParseOpRes::Unknown(args)); |
||||
} |
||||
})) |
||||
} |
||||
|
Loading…
Reference in new issue