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 defs; |
||||||
mod parse; |
mod parse; |
||||||
mod exec; |
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::data::{Rd, Wr}; |
||||||
use crsn::asm::error::Error; |
use crsn::asm::error::CrsnError; |
||||||
use crsn::asm::instr::Op; |
use crsn::asm::instr::Op; |
||||||
use crsn::asm::parse::arg_parser::ArgParser; |
use crsn::asm::parse::arg_parser::ArgParser; |
||||||
use crsn::module::{CrsnExtension, ParseOpRes}; |
use crsn::module::{ParseOpRes}; |
||||||
|
|
||||||
use crate::defs::ArithOp; |
use crate::defs::ArithOp; |
||||||
|
|
||||||
#[derive(Debug, Clone)] |
pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { |
||||||
pub struct ArithOps { |
Ok(ParseOpRes::ext(match keyword { |
||||||
_internal: () |
"cmp" => { |
||||||
} |
ArithOp::Compare { |
||||||
|
a: args.next_rd()?, |
||||||
impl ArithOps { |
b: args.next_rd()?, |
||||||
pub fn new() -> Box<dyn CrsnExtension> { |
} |
||||||
Box::new(Self { |
} |
||||||
_internal: () |
|
||||||
}) |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
impl CrsnExtension for ArithOps { |
"tst" => { |
||||||
fn name(&self) -> &'static str { |
let arg = args.next_rd()?; |
||||||
"arith" |
ArithOp::Test { a: arg } |
||||||
} |
} |
||||||
|
|
||||||
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, Error> { |
"inc" => { |
||||||
Ok(ParseOpRes::parsed(match keyword { |
let dst = args.next_wr()?; |
||||||
"cmp" => { |
ArithOp::Add { |
||||||
ArithOp::Compare { |
dst, |
||||||
a: args.next_rd()?, |
a: dst.as_rd(), |
||||||
b: args.next_rd()?, |
b: Rd::immediate(1), |
||||||
} |
|
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"tst" => { |
"dec" => { |
||||||
let arg = args.next_rd()?; |
let dst = args.next_wr()?; |
||||||
ArithOp::Test { a: arg } |
ArithOp::Sub { |
||||||
|
dst, |
||||||
|
a: dst.as_rd(), |
||||||
|
b: Rd::immediate(1), |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"inc" => { |
"add" => { |
||||||
let dst = args.next_wr()?; |
match args.len() { |
||||||
ArithOp::Add { |
3 => { |
||||||
dst, |
ArithOp::Add { |
||||||
a: dst.as_rd(), |
dst: args.next_wr()?, |
||||||
b: Rd::immediate(1), |
a: args.next_rd()?, |
||||||
|
b: args.next_rd()?, |
||||||
|
} |
||||||
} |
} |
||||||
} |
2 => { |
||||||
|
let dst = args.next_wr()?; |
||||||
"dec" => { |
ArithOp::Add { |
||||||
let dst = args.next_wr()?; |
dst, |
||||||
ArithOp::Sub { |
a: dst.as_rd(), |
||||||
dst, |
b: args.next_rd()?, |
||||||
a: dst.as_rd(), |
} |
||||||
b: Rd::immediate(1), |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("Add requires 2 or 3 arguments".into())); |
||||||
} |
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"add" => { |
"sub" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Add { |
ArithOp::Sub { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
b: args.next_rd()?, |
b: args.next_rd()?, |
||||||
} |
} |
||||||
} |
} |
||||||
2 => { |
2 => { |
||||||
let dst = args.next_wr()?; |
let dst = args.next_wr()?; |
||||||
ArithOp::Add { |
ArithOp::Sub { |
||||||
dst, |
dst, |
||||||
a: dst.as_rd(), |
a: dst.as_rd(), |
||||||
b: args.next_rd()?, |
b: args.next_rd()?, |
||||||
} |
|
||||||
} |
|
||||||
_ => { |
|
||||||
return Err(Error::Parse("Add requires 2 or 3 arguments".into())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("Sub requires 2 or 3 arguments".into())); |
||||||
|
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"sub" => { |
"mul" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Sub { |
ArithOp::Mul { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
b: args.next_rd()?, |
b: args.next_rd()?, |
||||||
} |
} |
||||||
} |
} |
||||||
2 => { |
2 => { |
||||||
let dst = args.next_wr()?; |
let dst = args.next_wr()?; |
||||||
ArithOp::Sub { |
ArithOp::Mul { |
||||||
dst, |
dst, |
||||||
a: dst.as_rd(), |
a: dst.as_rd(), |
||||||
b: args.next_rd()?, |
b: args.next_rd()?, |
||||||
} |
|
||||||
} |
|
||||||
_ => { |
|
||||||
return Err(Error::Parse("Sub requires 2 or 3 arguments".into())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("Mul requires 2 or 3 arguments".into())); |
||||||
|
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"mul" => { |
"divr" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Mul { |
let dst = args.next_wr()?; |
||||||
dst: args.next_wr()?, |
let rem = args.next_wr()?; |
||||||
a: args.next_rd()?, |
let div = args.next_rd()?; |
||||||
b: args.next_rd()?, |
ArithOp::Div { |
||||||
} |
dst, |
||||||
} |
rem, |
||||||
2 => { |
a: dst.as_rd(), |
||||||
let dst = args.next_wr()?; |
div, |
||||||
ArithOp::Mul { |
|
||||||
dst, |
|
||||||
a: dst.as_rd(), |
|
||||||
b: args.next_rd()?, |
|
||||||
} |
|
||||||
} |
|
||||||
_ => { |
|
||||||
return Err(Error::Parse("Mul requires 2 or 3 arguments".into())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
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" => { |
"div" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
let dst = args.next_wr()?; |
ArithOp::Div { |
||||||
let rem = args.next_wr()?; |
dst: args.next_wr()?, |
||||||
let div = args.next_rd()?; |
rem: Wr::discard(), |
||||||
ArithOp::Div { |
a: args.next_rd()?, |
||||||
dst, |
div: args.next_rd()?, |
||||||
rem, |
} |
||||||
a: dst.as_rd(), |
} |
||||||
div, |
2 => { |
||||||
} |
let dst = args.next_wr()?; |
||||||
} |
let div = args.next_rd()?; |
||||||
4 => { |
ArithOp::Div { |
||||||
ArithOp::Div { |
dst, |
||||||
dst: args.next_wr()?, |
rem: Wr::discard(), |
||||||
rem: args.next_wr()?, |
a: dst.as_rd(), |
||||||
a: args.next_rd()?, |
div, |
||||||
div: args.next_rd()?, |
|
||||||
} |
|
||||||
} |
|
||||||
_ => { |
|
||||||
return Err(Error::Parse("DivR requires 3 or 4 arguments".into())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("Div requires 2 or 3 arguments".into())); |
||||||
|
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"div" => { |
"mod" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Div { |
ArithOp::Mod { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
rem: Wr::discard(), |
a: args.next_rd()?, |
||||||
a: args.next_rd()?, |
div: args.next_rd()?, |
||||||
div: args.next_rd()?, |
} |
||||||
} |
} |
||||||
} |
2 => { |
||||||
2 => { |
let dst = args.next_wr()?; |
||||||
let dst = args.next_wr()?; |
let div = args.next_rd()?; |
||||||
let div = args.next_rd()?; |
ArithOp::Mod { |
||||||
ArithOp::Div { |
dst, |
||||||
dst, |
a: dst.as_rd(), |
||||||
rem: Wr::discard(), |
div, |
||||||
a: dst.as_rd(), |
|
||||||
div, |
|
||||||
} |
|
||||||
} |
|
||||||
_ => { |
|
||||||
return Err(Error::Parse("Div requires 2 or 3 arguments".into())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("Mod requires 2 or 3 arguments".into())); |
||||||
|
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"mod" => { |
"and" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Mod { |
ArithOp::And { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
div: args.next_rd()?, |
b: args.next_rd()?, |
||||||
} |
} |
||||||
} |
} |
||||||
2 => { |
2 => { |
||||||
let dst = args.next_wr()?; |
let dst = args.next_wr()?; |
||||||
let div = args.next_rd()?; |
ArithOp::And { |
||||||
ArithOp::Mod { |
dst, |
||||||
dst, |
a: dst.as_rd(), |
||||||
a: dst.as_rd(), |
b: args.next_rd()?, |
||||||
div, |
|
||||||
} |
|
||||||
} |
|
||||||
_ => { |
|
||||||
return Err(Error::Parse("Mod requires 2 or 3 arguments".into())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("And requires 2 or 3 arguments".into())); |
||||||
|
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"and" => { |
"or" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::And { |
ArithOp::Or { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
b: 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())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
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" => { |
"xor" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Or { |
ArithOp::Xor { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
b: 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())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
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" => { |
"cpl" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
2 => { |
||||||
ArithOp::Xor { |
ArithOp::Cpl { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
b: args.next_rd()?, |
} |
||||||
} |
} |
||||||
} |
1 => { |
||||||
2 => { |
let dst = args.next_wr()?; |
||||||
let dst = args.next_wr()?; |
ArithOp::Cpl { |
||||||
ArithOp::Xor { |
dst, |
||||||
dst, |
a: dst.as_rd(), |
||||||
a: dst.as_rd(), |
|
||||||
b: args.next_rd()?, |
|
||||||
} |
|
||||||
} |
|
||||||
_ => { |
|
||||||
return Err(Error::Parse("Xor requires 2 or 3 arguments".into())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("Cpl requires 1 or 2 arguments".into())); |
||||||
|
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"cpl" => { |
"rol" => { |
||||||
match args.len() { |
match args.len() { |
||||||
2 => { |
3 => { |
||||||
ArithOp::Cpl { |
ArithOp::Rol { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
} |
n: args.next_rd()?, |
||||||
} |
} |
||||||
1 => { |
} |
||||||
let dst = args.next_wr()?; |
2 => { |
||||||
ArithOp::Cpl { |
let dst = args.next_wr()?; |
||||||
dst, |
ArithOp::Rol { |
||||||
a: dst.as_rd(), |
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" => { |
"ror" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Rol { |
ArithOp::Ror { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
n: 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())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
} |
2 => { |
||||||
|
let dst = args.next_wr()?; |
||||||
"ror" => { |
ArithOp::Ror { |
||||||
match args.len() { |
dst, |
||||||
3 => { |
a: dst.as_rd(), |
||||||
ArithOp::Ror { |
n: args.next_rd()?, |
||||||
dst: args.next_wr()?, |
} |
||||||
a: args.next_rd()?, |
} |
||||||
n: args.next_rd()?, |
1 => { |
||||||
} |
let dst = args.next_wr()?; |
||||||
} |
ArithOp::Ror { |
||||||
2 => { |
dst, |
||||||
let dst = args.next_wr()?; |
a: dst.as_rd(), |
||||||
ArithOp::Ror { |
n: Rd::immediate(1), |
||||||
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())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("Ror requires 1, 2 or 3 arguments".into())); |
||||||
|
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"lsl" | "asl" => { |
"lsl" | "asl" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Lsl { |
ArithOp::Lsl { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
n: args.next_rd()?, |
n: args.next_rd()?, |
||||||
} |
} |
||||||
} |
} |
||||||
2 => { |
2 => { |
||||||
let dst = args.next_wr()?; |
let dst = args.next_wr()?; |
||||||
ArithOp::Lsl { |
ArithOp::Lsl { |
||||||
dst, |
dst, |
||||||
a: dst.as_rd(), |
a: dst.as_rd(), |
||||||
n: args.next_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())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
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" => { |
"lsr" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Lsr { |
ArithOp::Lsr { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
n: args.next_rd()?, |
n: args.next_rd()?, |
||||||
} |
} |
||||||
} |
} |
||||||
2 => { |
2 => { |
||||||
let dst = args.next_wr()?; |
let dst = args.next_wr()?; |
||||||
ArithOp::Lsr { |
ArithOp::Lsr { |
||||||
dst, |
dst, |
||||||
a: dst.as_rd(), |
a: dst.as_rd(), |
||||||
n: args.next_rd()?, |
n: args.next_rd()?, |
||||||
} |
} |
||||||
} |
} |
||||||
1 => { |
1 => { |
||||||
let dst = args.next_wr()?; |
let dst = args.next_wr()?; |
||||||
ArithOp::Lsr { |
ArithOp::Lsr { |
||||||
dst, |
dst, |
||||||
a: dst.as_rd(), |
a: dst.as_rd(), |
||||||
n: Rd::immediate(1), |
n: Rd::immediate(1), |
||||||
} |
|
||||||
} |
|
||||||
_ => { |
|
||||||
return Err(Error::Parse("Lsr requires 1, 2 or 3 arguments".into())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
_ => { |
||||||
|
return Err(CrsnError::Parse("Lsr requires 1, 2 or 3 arguments".into())); |
||||||
|
} |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"asr" => { |
"asr" => { |
||||||
match args.len() { |
match args.len() { |
||||||
3 => { |
3 => { |
||||||
ArithOp::Asr { |
ArithOp::Asr { |
||||||
dst: args.next_wr()?, |
dst: args.next_wr()?, |
||||||
a: args.next_rd()?, |
a: args.next_rd()?, |
||||||
n: 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())); |
|
||||||
} |
} |
||||||
} |
} |
||||||
|
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 => { |
_other => { |
||||||
return Ok(ParseOpRes::Unknown(args)); |
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 defs; |
||||||
mod parse; |
mod parse; |
||||||
mod exec; |
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::instr::Op; |
||||||
use crsn::asm::parse::arg_parser::ArgParser; |
use crsn::asm::parse::arg_parser::ArgParser; |
||||||
use crsn::module::{CrsnExtension, ParseOpRes}; |
use crsn::module::{ParseOpRes}; |
||||||
use crsn::runtime::fault::Fault; |
|
||||||
use crsn::runtime::run_thread::{RunState, ThreadInfo}; |
|
||||||
|
|
||||||
use crate::defs::StackOp; |
|
||||||
|
|
||||||
#[derive(Debug, Clone)] |
|
||||||
pub struct StackOps { |
|
||||||
_internal: () |
|
||||||
} |
|
||||||
|
|
||||||
impl StackOps { |
use crate::defs::StackOp; |
||||||
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()?, |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
"push" => { |
pub(crate) fn parse(keyword: &str, mut args: ArgParser) -> Result<ParseOpRes<Op>, CrsnError> { |
||||||
StackOp::Push { |
Ok(ParseOpRes::ext(match keyword { |
||||||
obj: args.next_rdobj()?, |
"stack" => { |
||||||
src: args.next_rd()?, |
StackOp::NewStack { |
||||||
} |
dst: args.next_wr()?, |
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
"pop" => { |
"push" => { |
||||||
StackOp::Pop { |
StackOp::Push { |
||||||
dst: args.next_wr()?, |
obj: args.next_rdobj()?, |
||||||
obj: args.next_rdobj()?, |
src: args.next_rd()?, |
||||||
} |
|
||||||
} |
} |
||||||
|
} |
||||||
|
|
||||||
_other => { |
"pop" => { |
||||||
return Ok(ParseOpRes::Unknown(args)); |
StackOp::Pop { |
||||||
|
dst: args.next_wr()?, |
||||||
|
obj: args.next_rdobj()?, |
||||||
} |
} |
||||||
})) |
} |
||||||
} |
|
||||||
|
|
||||||
fn drop_obj(&self, _ti: &ThreadInfo, state: &mut RunState, handle: Value) -> Result<Option<()>, Fault> |
_other => { |
||||||
{ |
return Ok(ParseOpRes::Unknown(args)); |
||||||
crate::exec::drop_stack(state, handle) |
} |
||||||
} |
})) |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue