forked from MightyPork/crsn
parent
3e0aaa71e9
commit
0cd800653f
@ -0,0 +1,10 @@ |
|||||||
|
[package] |
||||||
|
name = "crsn_stacks" |
||||||
|
version = "0.1.0" |
||||||
|
authors = ["Ondřej Hruška <ondra@ondrovo.com>"] |
||||||
|
edition = "2018" |
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html |
||||||
|
|
||||||
|
[dependencies] |
||||||
|
crsn = { path = "../crsn" } |
@ -0,0 +1,7 @@ |
|||||||
|
use crsn::asm::data::{Rd, Wr}; |
||||||
|
|
||||||
|
#[derive(Clone, Debug, Eq, PartialEq)] |
||||||
|
pub enum StackOp { |
||||||
|
Push { num: Rd, src: Rd }, |
||||||
|
Pop { dst: Wr, num: Rd }, |
||||||
|
} |
@ -0,0 +1,71 @@ |
|||||||
|
use std::collections::VecDeque; |
||||||
|
|
||||||
|
|
||||||
|
use crsn::asm::data::literal::Value; |
||||||
|
use crsn::asm::instr::op::{EvalRes, OpTrait}; |
||||||
|
use crsn::runtime::fault::Fault; |
||||||
|
|
||||||
|
|
||||||
|
use crsn::runtime::run_thread::{RunState, ThreadInfo}; |
||||||
|
|
||||||
|
use crate::defs::StackOp; |
||||||
|
|
||||||
|
struct Stacks { |
||||||
|
stacks: Vec<VecDeque<Value>>, |
||||||
|
} |
||||||
|
|
||||||
|
impl Default for Stacks { |
||||||
|
fn default() -> Self { |
||||||
|
Stacks { |
||||||
|
stacks: vec![VecDeque::default(); 8], |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl OpTrait for StackOp { |
||||||
|
fn execute(&self, _ti: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> { |
||||||
|
let eres = EvalRes::default(); |
||||||
|
match self { |
||||||
|
StackOp::Push { num, src } => { |
||||||
|
state.frame.status.clear(); |
||||||
|
let stack_num = state.frame.read(*num)?; |
||||||
|
let val = state.frame.read(*src)?; |
||||||
|
|
||||||
|
if stack_num > 8 { |
||||||
|
state.frame.status.invalid = true; |
||||||
|
} else { |
||||||
|
let obj: &mut Stacks = state.ext_mut(); |
||||||
|
obj.stacks[stack_num as usize].push_back(val); |
||||||
|
} |
||||||
|
} |
||||||
|
StackOp::Pop { dst, num } => { |
||||||
|
state.frame.status.clear(); |
||||||
|
let stack_num = state.frame.read(*num)?; |
||||||
|
|
||||||
|
if stack_num > 8 { |
||||||
|
state.frame.status.invalid = true; |
||||||
|
} else { |
||||||
|
let obj: &mut Stacks = state.ext_mut(); |
||||||
|
let val = obj.stacks[stack_num as usize].pop_back(); |
||||||
|
|
||||||
|
let val = match val { |
||||||
|
None => { |
||||||
|
state.frame.status.overflow = true; |
||||||
|
0 |
||||||
|
} |
||||||
|
Some(val) => { |
||||||
|
val |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
state.frame.write(*dst, val)?; |
||||||
|
} |
||||||
|
|
||||||
|
// TODO
|
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Ok(eres) |
||||||
|
} |
||||||
|
//
|
||||||
|
} |
@ -0,0 +1,6 @@ |
|||||||
|
pub use parse::StackOps; |
||||||
|
|
||||||
|
mod defs; |
||||||
|
mod parse; |
||||||
|
mod exec; |
||||||
|
|
@ -0,0 +1,48 @@ |
|||||||
|
|
||||||
|
use crsn::asm::error::Error; |
||||||
|
use crsn::asm::instr::op::{AsmModule, ParseOpResult}; |
||||||
|
use crsn::asm::instr::Op; |
||||||
|
use crsn::asm::parse::arg_parser::ArgParser; |
||||||
|
|
||||||
|
use crate::defs::StackOp; |
||||||
|
|
||||||
|
#[derive(Debug, Clone)] |
||||||
|
pub struct StackOps { |
||||||
|
_internal: () |
||||||
|
} |
||||||
|
|
||||||
|
impl StackOps { |
||||||
|
pub fn new() -> Box<dyn AsmModule> { |
||||||
|
Box::new(Self { |
||||||
|
_internal: () |
||||||
|
}) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
impl AsmModule for StackOps { |
||||||
|
fn name(&self) -> &'static str { |
||||||
|
"stacks" |
||||||
|
} |
||||||
|
|
||||||
|
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpResult, Error> { |
||||||
|
Ok(ParseOpResult::Parsed(Op::Ext(Box::new(match keyword { |
||||||
|
"push" => { |
||||||
|
StackOp::Push { |
||||||
|
num: args.next_rd()?, |
||||||
|
src: args.next_rd()?, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
"pop" => { |
||||||
|
StackOp::Pop { |
||||||
|
dst: args.next_wr()?, |
||||||
|
num: args.next_rd()?, |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
_other => { |
||||||
|
return Ok(ParseOpResult::Unknown(args)); |
||||||
|
} |
||||||
|
})))) |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue