renaming, cleanup, fmt, move "extension module" traits and structs into a separate mod

pull/21/head
Ondřej Hruška 4 years ago
parent 8222efe6da
commit 79d5aa3cd5
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 108
      Cargo.lock
  2. 1
      crsn/src/asm/data/mod.rs
  3. 50
      crsn/src/asm/instr/op.rs
  4. 3
      crsn/src/asm/mod.rs
  5. 2
      crsn/src/asm/parse/mod.rs
  6. 2
      crsn/src/asm/parse/parse_cond.rs
  7. 2
      crsn/src/asm/parse/parse_data.rs
  8. 2
      crsn/src/asm/parse/parse_instr.rs
  9. 10
      crsn/src/asm/parse/parse_op.rs
  10. 2
      crsn/src/asm/parse/parse_routines.rs
  11. 4
      crsn/src/builtin/defs.rs
  12. 15
      crsn/src/builtin/exec.rs
  13. 22
      crsn/src/builtin/parse.rs
  14. 1
      crsn/src/lib.rs
  15. 18
      crsn/src/module/eval_res.rs
  16. 36
      crsn/src/module/mod.rs
  17. 6
      crsn/src/runtime/exec.rs
  18. 3
      crsn/src/runtime/frame.rs
  19. 21
      crsn/src/runtime/frame/status.rs
  20. 2
      crsn/src/runtime/program.rs
  21. 13
      crsn/src/runtime/run_thread.rs
  22. 20
      crsn/src/runtime/run_thread/state.rs
  23. 2
      crsn_arith/src/exec.rs
  24. 8
      crsn_arith/src/parse.rs
  25. 4
      crsn_stacks/src/exec.rs
  26. 9
      crsn_stacks/src/parse.rs
  27. 48
      launcher/src/main.rs

108
Cargo.lock generated

@ -12,9 +12,9 @@ version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [ dependencies = [
"hermit-abi", "hermit-abi",
"libc", "libc",
"winapi", "winapi",
] ]
[[package]] [[package]]
@ -35,9 +35,9 @@ version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b" checksum = "942f72db697d8767c22d46a598e01f2d3b475501ea43d0db4f16d90259182d0b"
dependencies = [ dependencies = [
"num-integer", "num-integer",
"num-traits", "num-traits",
"time", "time",
] ]
[[package]] [[package]]
@ -46,36 +46,36 @@ version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59" checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
dependencies = [ dependencies = [
"atty", "atty",
"lazy_static", "lazy_static",
"winapi", "winapi",
] ]
[[package]] [[package]]
name = "crsn" name = "crsn"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"dyn-clonable", "dyn-clonable",
"log", "log",
"num-traits", "num-traits",
"sexp", "sexp",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
name = "crsn_arith" name = "crsn_arith"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"crsn", "crsn",
"num-traits", "num-traits",
] ]
[[package]] [[package]]
name = "crsn_stacks" name = "crsn_stacks"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"crsn", "crsn",
] ]
[[package]] [[package]]
@ -84,8 +84,8 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4" checksum = "4e9232f0e607a262ceb9bd5141a3dfb3e4db6994b31989bbfd845878cba59fd4"
dependencies = [ dependencies = [
"dyn-clonable-impl", "dyn-clonable-impl",
"dyn-clone", "dyn-clone",
] ]
[[package]] [[package]]
@ -94,9 +94,9 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5" checksum = "558e40ea573c374cf53507fd240b7ee2f5477df7cfebdb97323ec61c719399c5"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
] ]
[[package]] [[package]]
@ -111,20 +111,20 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151" checksum = "4c30f6d0bc6b00693347368a67d41b58f2fb851215ff1da49e90fe2c5c667151"
dependencies = [ dependencies = [
"libc", "libc",
] ]
[[package]] [[package]]
name = "launcher" name = "launcher"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"crsn", "crsn",
"crsn_arith", "crsn_arith",
"crsn_stacks", "crsn_stacks",
"log", "log",
"simple_logger", "simple_logger",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
@ -145,7 +145,7 @@ version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]] [[package]]
@ -154,8 +154,8 @@ version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b" checksum = "8d59457e662d541ba17869cf51cf177c0b5f0cbf476c66bdc90bf1edac4f875b"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"num-traits", "num-traits",
] ]
[[package]] [[package]]
@ -164,7 +164,7 @@ version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611" checksum = "ac267bcc07f48ee5f8935ab0d24f316fb722d7a1292e2913f0cc196b29ffd611"
dependencies = [ dependencies = [
"autocfg", "autocfg",
] ]
[[package]] [[package]]
@ -173,7 +173,7 @@ version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c" checksum = "36e28516df94f3dd551a587da5357459d9b36d945a7c37c3557928c1c2ff2a2c"
dependencies = [ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]] [[package]]
@ -182,7 +182,7 @@ version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]] [[package]]
@ -197,11 +197,11 @@ version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13a53ed2efd04911c8280f2da7bf9abd350c931b86bc7f9f2386fbafbf525ff9" checksum = "13a53ed2efd04911c8280f2da7bf9abd350c931b86bc7f9f2386fbafbf525ff9"
dependencies = [ dependencies = [
"atty", "atty",
"chrono", "chrono",
"colored", "colored",
"log", "log",
"winapi", "winapi",
] ]
[[package]] [[package]]
@ -210,9 +210,9 @@ version = "1.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b" checksum = "6690e3e9f692504b941dc6c3b188fd28df054f7fb8469ab40680df52fdcc842b"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"unicode-xid", "unicode-xid",
] ]
[[package]] [[package]]
@ -221,7 +221,7 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08" checksum = "7dfdd070ccd8ccb78f4ad66bf1982dc37f620ef696c6b5028fe2ed83dd3d0d08"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl",
] ]
[[package]] [[package]]
@ -230,9 +230,9 @@ version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793" checksum = "bd80fc12f73063ac132ac92aceea36734f04a1d93c1240c6944e23a3b8841793"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
] ]
[[package]] [[package]]
@ -241,9 +241,9 @@ version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255" checksum = "6db9e6914ab8b1ae1c260a4ae7a49b6c5611b40328a735b21862567685e73255"
dependencies = [ dependencies = [
"libc", "libc",
"wasi", "wasi",
"winapi", "winapi",
] ]
[[package]] [[package]]
@ -264,8 +264,8 @@ version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [ dependencies = [
"winapi-i686-pc-windows-gnu", "winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu", "winapi-x86_64-pc-windows-gnu",
] ]
[[package]] [[package]]

@ -2,7 +2,6 @@ use std::convert::TryFrom;
use std::fmt::{Debug, Display, Formatter}; use std::fmt::{Debug, Display, Formatter};
use std::fmt; use std::fmt;
use literal::Addr;
pub use mask::Mask; pub use mask::Mask;
pub use reg::Register; pub use reg::Register;

@ -1,14 +1,8 @@
use std::fmt::Debug; use std::fmt::Debug;
use crate::asm::error::Error;
use crate::asm::parse::arg_parser::ArgParser;
use crate::builtin::defs::BuiltinOp; use crate::builtin::defs::BuiltinOp;
use crate::module::{EvalRes, OpTrait};
use crate::runtime::fault::Fault; use crate::runtime::fault::Fault;
use crate::runtime::run_thread::{state::RunState, ThreadInfo}; use crate::runtime::run_thread::{state::RunState, ThreadInfo};
/// A higher level simple opration /// A higher level simple opration
@ -19,48 +13,8 @@ pub enum Op {
Ext(Box<dyn OpTrait>), Ext(Box<dyn OpTrait>),
} }
pub trait OpTrait: Debug + Send + Sync + 'static {
fn execute(&self, ti : &ThreadInfo, state: &mut RunState) -> 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 { impl OpTrait for Op {
fn execute(&self, ti : &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> { fn execute(&self, ti: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> {
match self { match self {
Op::BuiltIn(op) => { Op::BuiltIn(op) => {
op.execute(ti, state) op.execute(ti, state)

@ -1,7 +1,6 @@
use std::sync::Arc; use std::sync::Arc;
use crate::module::AsmModule;
use crate::asm::instr::op::AsmModule;
use crate::runtime::program::Program; use crate::runtime::program::Program;
pub mod data; pub mod data;

@ -5,8 +5,8 @@ use parse_routines::parse_routines;
use crate::asm::error::Error; use crate::asm::error::Error;
use crate::asm::instr::{Flatten, Op, Routine}; use crate::asm::instr::{Flatten, Op, Routine};
use crate::asm::instr::op::AsmModule;
use crate::asm::parse::sexp_expect::expect_list; use crate::asm::parse::sexp_expect::expect_list;
use crate::module::AsmModule;
mod parse_cond; mod parse_cond;
mod parse_instr; mod parse_instr;

@ -2,10 +2,10 @@ use sexp::Sexp;
use crate::asm::error::Error; use crate::asm::error::Error;
use crate::asm::instr::{Cond, cond, Instr}; use crate::asm::instr::{Cond, cond, Instr};
use crate::asm::instr::op::AsmModule;
use crate::asm::parse::parse_instr::parse_instructions; use crate::asm::parse::parse_instr::parse_instructions;
use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::asm::patches::TryRemove; use crate::asm::patches::TryRemove;
use crate::module::AsmModule;
pub fn parse_cond_branch(tok: Sexp, parsers: &[Box<dyn AsmModule>]) -> Result<(Cond, Vec<Instr>), Error> { pub fn parse_cond_branch(tok: Sexp, parsers: &[Box<dyn AsmModule>]) -> Result<(Cond, Vec<Instr>), Error> {
let mut list = expect_list(Some(tok), false)?; let mut list = expect_list(Some(tok), false)?;

@ -3,7 +3,7 @@ use std::convert::TryFrom;
use sexp::{Atom, Sexp}; use sexp::{Atom, Sexp};
use crate::asm::data::{DataDisp, DstDisp, Rd, reg, SrcDisp, Wr}; use crate::asm::data::{DataDisp, DstDisp, Rd, reg, SrcDisp, Wr};
use crate::asm::data::literal::{Addr, Label}; use crate::asm::data::literal::Label;
use crate::asm::error::Error; use crate::asm::error::Error;
use crate::asm::parse::sexp_expect::expect_string_atom; use crate::asm::parse::sexp_expect::expect_string_atom;

@ -2,11 +2,11 @@ use sexp::Sexp;
use crate::asm::error::Error; use crate::asm::error::Error;
use crate::asm::instr::Instr; use crate::asm::instr::Instr;
use crate::asm::instr::op::AsmModule;
use crate::asm::parse::arg_parser::ArgParser; use crate::asm::parse::arg_parser::ArgParser;
use crate::asm::parse::parse_cond::parse_cond_branch; use crate::asm::parse::parse_cond::parse_cond_branch;
use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::asm::patches::SexpIsA; use crate::asm::patches::SexpIsA;
use crate::module::AsmModule;
use super::parse_op::parse_op; use super::parse_op::parse_op;

@ -1,12 +1,8 @@
use crate::asm::error::Error; use crate::asm::error::Error;
use crate::asm::instr::Op; use crate::asm::instr::Op;
use crate::asm::instr::op::{AsmModule, ParseOpResult};
use crate::asm::parse::arg_parser::ArgParser; use crate::asm::parse::arg_parser::ArgParser;
use crate::builtin::parse::BuiltinOpParser; use crate::builtin::parse::BuiltinOpParser;
use crate::module::{AsmModule, ParseOpRes};
pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box<dyn AsmModule>]) -> Result<Op, Error> { pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box<dyn AsmModule>]) -> Result<Op, Error> {
// Include built-in instructions // Include built-in instructions
@ -14,8 +10,8 @@ pub fn parse_op(keyword: &str, mut arg_tokens: ArgParser, parsers: &[Box<dyn Asm
for p in builtins.iter().chain(parsers) { for p in builtins.iter().chain(parsers) {
arg_tokens = match p.parse_op(keyword, arg_tokens) { arg_tokens = match p.parse_op(keyword, arg_tokens) {
Ok(ParseOpResult::Parsed(op)) => return Ok(op), Ok(ParseOpRes::Parsed(op)) => return Ok(op),
Ok(ParseOpResult::Unknown(to_reuse)) => { Ok(ParseOpRes::Unknown(to_reuse)) => {
if to_reuse.parsing_started() { if to_reuse.parsing_started() {
panic!("Module \"{}\" started parsing {}, but returned Unknown!", p.name(), keyword); panic!("Module \"{}\" started parsing {}, but returned Unknown!", p.name(), keyword);
} }

@ -2,11 +2,11 @@ use sexp::Sexp;
use crate::asm::data::literal::RoutineName; use crate::asm::data::literal::RoutineName;
use crate::asm::error::Error; use crate::asm::error::Error;
use crate::asm::instr::op::AsmModule;
use crate::asm::instr::Routine; use crate::asm::instr::Routine;
use crate::asm::parse::parse_instr::parse_instructions; use crate::asm::parse::parse_instr::parse_instructions;
use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom}; use crate::asm::parse::sexp_expect::{expect_list, expect_string_atom};
use crate::asm::patches::TryRemove; use crate::asm::patches::TryRemove;
use crate::module::AsmModule;
pub fn parse_routines(routines: Vec<Sexp>, parsers: &[Box<dyn AsmModule>]) -> Result<Vec<Routine>, Error> { pub fn parse_routines(routines: Vec<Sexp>, parsers: &[Box<dyn AsmModule>]) -> Result<Vec<Routine>, Error> {
let mut parsed = vec![]; let mut parsed = vec![];

@ -1,6 +1,6 @@
use crate::asm::data::literal::{Label, RoutineName, DebugMsg};
use crate::asm::instr::{Cond, Op};
use crate::asm::data::{Rd, Wr}; use crate::asm::data::{Rd, Wr};
use crate::asm::data::literal::{DebugMsg, Label, RoutineName};
use crate::asm::instr::{Cond, Op};
#[derive(Debug)] #[derive(Debug)]
pub enum BuiltinOp { pub enum BuiltinOp {

@ -1,14 +1,9 @@
use crate::asm::instr::op::{OpTrait, EvalRes};
use crate::runtime::fault::Fault;
use crate::runtime::frame::{StackFrame};
use crate::builtin::defs::BuiltinOp;
use crate::asm::data::literal::Addr; use crate::asm::data::literal::Addr;
use crate::runtime::run_thread::{ThreadInfo, state::RunState}; use crate::builtin::defs::BuiltinOp;
use crate::module::{EvalRes, OpTrait};
use crate::runtime::fault::Fault;
use crate::runtime::frame::StackFrame;
use crate::runtime::run_thread::{state::RunState, ThreadInfo};
impl OpTrait for BuiltinOp { impl OpTrait for BuiltinOp {
fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> { fn execute(&self, info: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault> {

@ -1,14 +1,14 @@
use sexp::{Atom, Sexp};
use crate::asm::error::{Error};
use crate::asm::instr::op::{AsmModule, ParseOpResult};
use crate::asm::parse::arg_parser::ArgParser;
use crate::asm::data::literal::{Label, RoutineName}; use crate::asm::data::literal::{Label, RoutineName};
use crate::asm::parse::sexp_expect::expect_string_atom; use crate::asm::error::Error;
use crate::asm::parse::parse_data::{parse_label, parse_rd};
use crate::asm::instr::cond::parse_cond; use crate::asm::instr::cond::parse_cond;
use crate::asm::instr::Op; use crate::asm::instr::Op;
use crate::asm::parse::arg_parser::ArgParser;
use crate::asm::parse::parse_data::{parse_label, parse_rd};
use crate::asm::parse::sexp_expect::expect_string_atom;
use crate::builtin::defs::BuiltinOp; use crate::builtin::defs::BuiltinOp;
use sexp::{Sexp, Atom}; use crate::module::{AsmModule, ParseOpRes};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct BuiltinOpParser { pub struct BuiltinOpParser {
@ -28,8 +28,8 @@ impl AsmModule for BuiltinOpParser {
"builtin" "builtin"
} }
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpResult, Error> { fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes, Error> {
Ok(ParseOpResult::Parsed(Op::BuiltIn(match keyword { Ok(ParseOpRes::Parsed(Op::BuiltIn(match keyword {
"nop" => { "nop" => {
BuiltinOp::Nop BuiltinOp::Nop
} }
@ -132,10 +132,10 @@ impl AsmModule for BuiltinOpParser {
let label = Label::Named(label.to_string()); let label = Label::Named(label.to_string());
BuiltinOp::FarLabel(label) BuiltinOp::FarLabel(label)
} else { } else {
return Ok(ParseOpResult::Unknown(args)); return Ok(ParseOpRes::Unknown(args));
} }
} else { } else {
return Ok(ParseOpResult::Unknown(args)); return Ok(ParseOpRes::Unknown(args));
} }
} }
@ -144,7 +144,7 @@ impl AsmModule for BuiltinOpParser {
let label = Label::Named(label.to_string()); let label = Label::Named(label.to_string());
BuiltinOp::Label(label) BuiltinOp::Label(label)
} else { } else {
return Ok(ParseOpResult::Unknown(args)); return Ok(ParseOpRes::Unknown(args));
} }
} }
}))) })))

@ -6,4 +6,5 @@ pub use sexp;
pub mod asm; pub mod asm;
pub mod builtin; pub mod builtin;
pub mod runtime; pub mod runtime;
pub mod module;

@ -0,0 +1,18 @@
/// Cycles spent executing an instruction
pub type CyclesSpent = usize;
/// Result of execution evaluation (when Fault is not generated)
#[derive(Debug)]
pub struct EvalRes {
pub cycles: CyclesSpent,
pub advance: i64,
}
impl Default for EvalRes {
fn default() -> Self {
Self {
cycles: 1,
advance: 1,
}
}
}

@ -0,0 +1,36 @@
use std::fmt::Debug;
pub use eval_res::EvalRes;
use crate::asm::error::Error;
use crate::asm::instr::Op;
use crate::asm::parse::arg_parser::ArgParser;
use crate::runtime::fault::Fault;
use crate::runtime::run_thread::state::RunState;
use crate::runtime::run_thread::ThreadInfo;
mod eval_res;
/// Result type returned from the op parser. This is the Ok variant of a Result.
pub enum ParseOpRes {
/// Parsing successful.
Parsed(Op),
/// Instruction not recognized, but there was no error.
Unknown(ArgParser),
}
pub trait OpTrait: Debug + Send + Sync + 'static {
fn execute(&self, ti: &ThreadInfo, state: &mut RunState) -> Result<EvalRes, Fault>;
}
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<ParseOpRes, Error>;
}

@ -1,14 +1,10 @@
use crate::module::{EvalRes, OpTrait};
use crate::asm::instr::op::{EvalRes, OpTrait};
use crate::runtime::fault::Fault; use crate::runtime::fault::Fault;
use crate::runtime::run_thread::RunThread; use crate::runtime::run_thread::RunThread;
impl RunThread { impl RunThread {
// TODO unit tests // TODO unit tests
pub fn eval_op(&mut self) -> Result<EvalRes, Fault> { pub fn eval_op(&mut self) -> Result<EvalRes, Fault> {
let state = &mut self.state; let state = &mut self.state;
let info = &self.info; let info = &self.info;

@ -1,10 +1,7 @@
use status::StatusFlags; use status::StatusFlags;
use crate::asm::data::{DstDisp, Rd, Register, SrcDisp, Wr};
use crate::asm::data::literal::{Addr, Value}; use crate::asm::data::literal::{Addr, Value};
use super::fault::Fault;
pub(crate) mod status; pub(crate) mod status;
pub const REG_COUNT: usize = 8; pub const REG_COUNT: usize = 8;

@ -90,35 +90,36 @@ impl StatusFlags {
match cond { match cond {
Cond::Equal => { Cond::Equal => {
self.equal = true; self.equal = true;
}, }
Cond::Zero => { Cond::Zero => {
self.zero = true; self.zero = true;
}, }
Cond::Lower => { Cond::Lower => {
self.lower = true; self.lower = true;
}, }
Cond::Greater => { Cond::Greater => {
self.lower = false; self.lower = false;
self.equal = false; self.equal = false;
self.greater = true; self.greater = true;
}, }
Cond::Positive => { Cond::Positive => {
self.positive = true; self.positive = true;
}, }
Cond::Negative => { Cond::Negative => {
self.negative = true; self.negative = true;
}, }
Cond::Overflow => { Cond::Overflow => {
self.overflow = true; self.overflow = true;
}, }
Cond::Invalid => { Cond::Invalid => {
self.invalid = true; self.invalid = true;
}, }
Cond::Carry => { Cond::Carry => {
self.carry = true; self.carry = true;
}, }
other => { other => {
panic!("cannot set cond by {:?}", other); error!("Cannot set cond by {:?}", other);
// ...and do nothing. Don't panic, we don't want to crash the runtime!
} }
} }
} }

@ -3,8 +3,8 @@ use std::sync::Arc;
use crate::asm::data::literal::{Addr, Label, RoutineName}; use crate::asm::data::literal::{Addr, Label, RoutineName};
use crate::asm::instr::Op; use crate::asm::instr::Op;
use crate::runtime::fault::Fault;
use crate::builtin::defs::BuiltinOp; use crate::builtin::defs::BuiltinOp;
use crate::runtime::fault::Fault;
#[derive(Debug)] #[derive(Debug)]
pub struct Program { pub struct Program {

@ -1,15 +1,12 @@
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use std::thread::JoinHandle; use std::thread::JoinHandle;
use std::time::Duration; use std::time::Duration;
use crate::asm::data::literal::{Addr, Value}; use crate::asm::data::literal::Addr;
use crate::asm::instr::op::EvalRes; use crate::module::EvalRes;
use crate::runtime::frame::{CallStack, StackFrame, REG_COUNT, status::StatusFlags};
use crate::runtime::program::Program;
use crate::runtime::fault::Fault; use crate::runtime::fault::Fault;
use crate::asm::data::{Rd, SrcDisp, Register, Wr, DstDisp}; use crate::runtime::frame::StackFrame;
use crate::runtime::program::Program;
use crate::runtime::run_thread::state::RunState; use crate::runtime::run_thread::state::RunState;
#[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)] #[derive(Clone, Copy, Eq, PartialEq, Debug, Ord, PartialOrd)]
@ -47,7 +44,7 @@ impl RunThread {
} }
} }
pub fn set_speed(&mut self, cycle_time : Duration) { pub fn set_speed(&mut self, cycle_time: Duration) {
self.info.cycle_time = cycle_time; self.info.cycle_time = cycle_time;
} }

@ -3,12 +3,9 @@ use std::collections::HashMap;
use crate::asm::data::{DstDisp, Rd, Register, SrcDisp, Wr}; use crate::asm::data::{DstDisp, Rd, Register, SrcDisp, Wr};
use crate::asm::data::literal::{Addr, Value}; use crate::asm::data::literal::{Addr, Value};
use crate::asm::instr::op::EvalRes; use crate::asm::instr::Cond;
use crate::runtime::fault::Fault; use crate::runtime::fault::Fault;
use crate::runtime::frame::{CallStack, REG_COUNT, StackFrame}; use crate::runtime::frame::{CallStack, REG_COUNT, StackFrame};
use crate::runtime::program::Program;
use crate::asm::instr::Cond;
use crate::runtime::frame::status::StatusFlags;
pub struct RunState { pub struct RunState {
/// Active stack frame /// Active stack frame
@ -20,6 +17,8 @@ pub struct RunState {
} }
impl RunState { impl RunState {
/// Get an extension's persistent data object for mutation.
/// It will be created using Default if not present before.
pub fn ext_mut<T: Send + Default + 'static>(&mut self) -> &mut T { pub fn ext_mut<T: Send + Default + 'static>(&mut self) -> &mut T {
if !self.ext_data.contains_key(&TypeId::of::<T>()) { if !self.ext_data.contains_key(&TypeId::of::<T>()) {
self.ext_data.insert(TypeId::of::<T>(), Box::new(T::default())); self.ext_data.insert(TypeId::of::<T>(), Box::new(T::default()));
@ -29,32 +28,40 @@ impl RunState {
.downcast_mut().unwrap() .downcast_mut().unwrap()
} }
pub fn set_flag(&mut self, cond : Cond, set : bool) { /// Set a status flag. Only supports simple, positive conds (i.e. not GreaterOrEqual)
pub fn set_flag(&mut self, cond: Cond, set: bool) {
if set { if set {
self.frame.status.set(cond); self.frame.status.set(cond);
} }
} }
pub fn test_cond(&self, cond : Cond) -> bool { /// Check status flags for a condition
pub fn test_cond(&self, cond: Cond) -> bool {
self.frame.status.test(cond) self.frame.status.test(cond)
} }
/// Set program counter - address of the next instruction to run
pub fn set_pc(&mut self, pc: Addr) { pub fn set_pc(&mut self, pc: Addr) {
self.frame.pc = pc; self.frame.pc = pc;
} }
/// Get program counter - address of the next instruction to run
pub fn get_pc(&self) -> Addr { pub fn get_pc(&self) -> Addr {
self.frame.pc self.frame.pc
} }
/// Clear status flags
pub fn clear_status(&mut self) { pub fn clear_status(&mut self) {
self.frame.status.clear(); self.frame.status.clear();
} }
/// Update status flags using a variable.
/// The update is additive - call `clear_status()` first if desired!
pub fn update_status(&mut self, val: Value) { pub fn update_status(&mut self, val: Value) {
self.frame.status.update(val); self.frame.status.update(val);
} }
/// Read a `Rd` value
pub fn read(&mut self, rd: Rd) -> Result<Value, Fault> { pub fn read(&mut self, rd: Rd) -> Result<Value, Fault> {
match rd.d() { match rd.d() {
SrcDisp::Immediate(v) => Ok(v), SrcDisp::Immediate(v) => Ok(v),
@ -88,6 +95,7 @@ impl RunState {
} }
} }
/// Write a value to a `Wr` location
pub fn write(&mut self, wr: Wr, val: Value) -> Result<(), Fault> { pub fn write(&mut self, wr: Wr, val: Value) -> Result<(), Fault> {
trace!("WR {:?} := {}", wr, val); trace!("WR {:?} := {}", wr, val);

@ -3,7 +3,7 @@ use std::ops::Rem;
use num_traits::PrimInt; use num_traits::PrimInt;
use crsn::asm::instr::Cond; use crsn::asm::instr::Cond;
use crsn::asm::instr::op::{EvalRes, OpTrait}; use crsn::module::{EvalRes, OpTrait};
use crsn::runtime::fault::Fault; use crsn::runtime::fault::Fault;
use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; use crsn::runtime::run_thread::{state::RunState, ThreadInfo};

@ -1,8 +1,8 @@
use crsn::asm::data::{Rd, Wr}; use crsn::asm::data::{Rd, Wr};
use crsn::asm::error::Error; use crsn::asm::error::Error;
use crsn::asm::instr::op::{AsmModule, ParseOpResult};
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::{AsmModule, ParseOpRes};
use crate::defs::ArithOp; use crate::defs::ArithOp;
@ -24,8 +24,8 @@ impl AsmModule for ArithOps {
"arith" "arith"
} }
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpResult, Error> { fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes, Error> {
Ok(ParseOpResult::Parsed(Op::Ext(Box::new(match keyword { Ok(ParseOpRes::Parsed(Op::Ext(Box::new(match keyword {
"cmp" => { "cmp" => {
ArithOp::Compare { ArithOp::Compare {
a: args.next_rd()?, a: args.next_rd()?,
@ -448,7 +448,7 @@ impl AsmModule for ArithOps {
} }
_other => { _other => {
return Ok(ParseOpResult::Unknown(args)); return Ok(ParseOpRes::Unknown(args));
} }
})))) }))))
} }

@ -1,12 +1,12 @@
use std::collections::VecDeque; use std::collections::VecDeque;
use crsn::asm::data::literal::Value; use crsn::asm::data::literal::Value;
use crsn::asm::instr::op::{EvalRes, OpTrait}; use crsn::asm::instr::Cond;
use crsn::module::{EvalRes, OpTrait};
use crsn::runtime::fault::Fault; use crsn::runtime::fault::Fault;
use crsn::runtime::run_thread::{state::RunState, ThreadInfo}; use crsn::runtime::run_thread::{state::RunState, ThreadInfo};
use crate::defs::StackOp; use crate::defs::StackOp;
use crsn::asm::instr::Cond;
struct Stacks { struct Stacks {
stacks: Vec<VecDeque<Value>>, stacks: Vec<VecDeque<Value>>,

@ -1,8 +1,7 @@
use crsn::asm::error::Error; use crsn::asm::error::Error;
use crsn::asm::instr::op::{AsmModule, ParseOpResult};
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::{AsmModule, ParseOpRes};
use crate::defs::StackOp; use crate::defs::StackOp;
@ -24,8 +23,8 @@ impl AsmModule for StackOps {
"stacks" "stacks"
} }
fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpResult, Error> { fn parse_op(&self, keyword: &str, mut args: ArgParser) -> Result<ParseOpRes, Error> {
Ok(ParseOpResult::Parsed(Op::Ext(Box::new(match keyword { Ok(ParseOpRes::Parsed(Op::Ext(Box::new(match keyword {
"push" => { "push" => {
StackOp::Push { StackOp::Push {
num: args.next_rd()?, num: args.next_rd()?,
@ -41,7 +40,7 @@ impl AsmModule for StackOps {
} }
_other => { _other => {
return Ok(ParseOpResult::Unknown(args)); return Ok(ParseOpRes::Unknown(args));
} }
})))) }))))
} }

@ -1,14 +1,14 @@
#[macro_use] #[macro_use]
extern crate log; extern crate log;
use std::time::Duration;
use simple_logger::SimpleLogger; use simple_logger::SimpleLogger;
use crsn::asm::data::literal::Addr; use crsn::asm::data::literal::Addr;
use crsn::runtime::run_thread::{RunThread, ThreadToken}; use crsn::runtime::run_thread::{RunThread, ThreadToken};
use crsn_arith::ArithOps; use crsn_arith::ArithOps;
use crsn_stacks::StackOps; use crsn_stacks::StackOps;
use std::time::Duration;
fn main() { fn main() {
SimpleLogger::new().init().unwrap(); SimpleLogger::new().init().unwrap();
@ -44,28 +44,28 @@ fn main() {
) )
";*/ ";*/
/* let program = " /* let program = "
( (
(main (main
(j :lbl) (j :lbl)
(ld _ arg0) (ld _ arg0)
(fault) (fault)
(:lbl) (:lbl)
(call fac 5) (call fac 5)
(ld r0 res0) (ld r0 res0)
) )
(fac (fac
(cmp arg0 2 (cmp arg0 2
(eq? (ret 2))) (eq? (ret 2)))
(ld r0 arg0) (ld r0 arg0)
(dec r0) (dec r0)
(call fac r0) (call fac r0)
(ld r0 arg0) (ld r0 arg0)
(mul r0 res0) (mul r0 res0)
(ret r0) (ret r0)
)
) )
) ";*/
";*/
let program = " let program = "
( (
@ -97,7 +97,7 @@ fn main() {
let mut thread1 = RunThread::new(ThreadToken(0), parsed.clone(), Addr(0), &[]); let mut thread1 = RunThread::new(ThreadToken(0), parsed.clone(), Addr(0), &[]);
thread1.set_speed(Duration::from_millis(250)); thread1.set_speed(Duration::from_millis(250));
let thread2 = RunThread::new(ThreadToken(1), parsed.clone(), Addr(0), &[]); let _thread2 = RunThread::new(ThreadToken(1), parsed.clone(), Addr(0), &[]);
let a = thread1.start(); let a = thread1.start();
//let b = thread2.start(); //let b = thread2.start();

Loading…
Cancel
Save