From 68e6b02c0720fd672fc8a7dc2eaa59016fa2cdae Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 3 May 2020 14:33:20 +0200 Subject: [PATCH] Add and, or, not, xor, pow and nrt tokens --- Cargo.lock | 26 +++++++++++ Cargo.toml | 3 +- README.md | 6 +++ src/bin/lsambler.rs | 13 ++++-- src/runtime.rs | 17 +++++--- src/tokens.rs | 103 ++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 159 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8cbb1de..5dcc704 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18,6 +18,11 @@ dependencies = [ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "bitflags" version = "1.2.1" @@ -62,6 +67,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" name = "ledstrip_vm" version = "0.1.0" dependencies = [ + "num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", "structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -70,6 +76,23 @@ name = "libc" version = "0.2.69" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "proc-macro-error" version = "1.0.2" @@ -212,12 +235,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" "checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +"checksum autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" "checksum hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "61565ff7aaace3525556587bd2dc31d4a07071957be715e63ce7b1eccf51a8f4" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)" = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005" +"checksum num-integer 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" "checksum proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" "checksum proc-macro-error-attr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" "checksum proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3" diff --git a/Cargo.toml b/Cargo.toml index e62a121..cdab9b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -structopt = "0.3.9" \ No newline at end of file +structopt = "0.3.9" +num-integer = "0.1.42" \ No newline at end of file diff --git a/README.md b/README.md index 57199ce..fc3d6b3 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,12 @@ A virtual machine for controlling a wifi led strip. | mod (rgd, rgi, rgo) | applies mod rgd, rgi and writes the result to rgo | 0x14 | | lsh (rgd, rgi, rgo) | bitshifts rgd by rgi to the left and writes the output to rgo | 0x15 | | rsh (rgd, rgi,rgo) | bitshifts rgd by rgi to the right and writes the output to rgo | 0x16 | +| and (rgd, rgi, rgo) | bitwise rgd and rgi -> rgo | 0x17 | +| or (rgd, rgi, rgo) | bitwise rgd or rgi -> rgo | 0x18 | +| not (rgd, rgo) | bitwise not rgd -> rgo | 0x19 | +| xor (rgd, rgi, rgo) | bitwise rgd xor rgi -> rgo | 0x1A | +| pow (rgd, rgi, rgo) | rgo to the power of rgi -> rgo | 0x1B| +| nrt (rgd, rgi, rgo ) | the nth root of rgd (n = rgi) -> rgo | 0x1C | | jg (rgd, rgi, rgl) | jumps to rgl if rgd > rgi | 0x20 | | jl (rgd, rgi, rgl) | jumps to rgl if rgd < rgi | 0x21 | | je (rgd, rgi, rgl) | jumps to rgl if rgd == rgi | 0x22 | diff --git a/src/bin/lsambler.rs b/src/bin/lsambler.rs index e2b764f..7db5d23 100644 --- a/src/bin/lsambler.rs +++ b/src/bin/lsambler.rs @@ -1,8 +1,9 @@ use ledstrip_vm::registers::get_register_code_by_name; use ledstrip_vm::tokens::{ - AddToken, ClearToken, CmdToken, CopyToken, DebugToken, DivToken, ExitToken, GotoToken, JeToken, - JgToken, JlToken, LabelToken, LoadToken, LshToken, ModToken, MulToken, PauseToken, PrintToken, - RshToken, SendToken, SetToken, SubToken, Token, WriteToken, + AddToken, AndToken, ClearToken, CmdToken, CopyToken, DebugToken, DivToken, ExitToken, + GotoToken, JeToken, JgToken, JlToken, LabelToken, LoadToken, LshToken, ModToken, MulToken, + NotToken, NrtToken, OrToken, PauseToken, PowToken, PrintToken, RshToken, SendToken, SetToken, + SubToken, Token, WriteToken, XorToken, }; use std::fs::{read_to_string, File}; use std::io; @@ -95,6 +96,12 @@ fn get_token(line: &str) -> Option> { "mod" => some_box!(ModToken), "lsh" => some_box!(LshToken), "rsh" => some_box!(RshToken), + "and" => some_box!(AndToken), + "or" => some_box!(OrToken), + "not" => some_box!(NotToken), + "xor" => some_box!(XorToken), + "pow" => some_box!(PowToken), + "nrt" => some_box!(NrtToken), "jg" => some_box!(JgToken), "jl" => some_box!(JlToken), "je" => some_box!(JeToken), diff --git a/src/runtime.rs b/src/runtime.rs index ce0ea02..17fbd85 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -3,11 +3,12 @@ use crate::registers::{ Rcb, Rcg, Rcr, Rcs, Register, Rgd, Rgi, Rgl, Rgo, Rgp, RCB, RCG, RCR, RGD, RGI, RGL, RGO, RGP, }; use crate::tokens::{ - AddToken, ClearToken, CmdToken, CopyToken, DebugToken, DivToken, ExitToken, FromBytecode, - GotoToken, JeToken, JgToken, JlToken, LabelToken, LoadToken, LshToken, ModToken, MulToken, - PauseToken, PrintToken, RshToken, SendToken, SetToken, SubToken, Token, WriteToken, T_ADD, - T_CLEAR, T_CMD, T_COPY, T_DEBUG, T_DIV, T_EXIT, T_GOTO, T_JE, T_JG, T_JL, T_LABEL, T_LOAD, - T_LSH, T_MOD, T_MUL, T_PAUSE, T_PRINT, T_RSH, T_SEND, T_SET, T_SUB, T_WRITE, + AddToken, AndToken, ClearToken, CmdToken, CopyToken, DebugToken, DivToken, ExitToken, + FromBytecode, GotoToken, JeToken, JgToken, JlToken, LabelToken, LoadToken, LshToken, ModToken, + MulToken, NopToken, NotToken, NrtToken, OrToken, PauseToken, PowToken, PrintToken, RshToken, + SendToken, SetToken, SubToken, Token, WriteToken, XorToken, T_ADD, T_AND, T_CLEAR, T_CMD, + T_COPY, T_DEBUG, T_DIV, T_EXIT, T_GOTO, T_JE, T_JG, T_JL, T_LABEL, T_LOAD, T_LSH, T_MOD, T_MUL, + T_NOT, T_NRT, T_OR, T_PAUSE, T_POW, T_PRINT, T_RSH, T_SEND, T_SET, T_SUB, T_WRITE, T_XOR, }; use std::cell::RefCell; use std::collections::HashMap; @@ -111,6 +112,12 @@ impl Runtime { T_MOD => text.push(Box::new(ModToken)), T_LSH => text.push(Box::new(LshToken)), T_RSH => text.push(Box::new(RshToken)), + T_AND => text.push(Box::new(AndToken)), + T_OR => text.push(Box::new(OrToken)), + T_NOT => text.push(Box::new(NotToken)), + T_XOR => text.push(Box::new(XorToken)), + T_POW => text.push(Box::new(PowToken)), + T_NRT => text.push(Box::new(NrtToken)), T_JG => text.push(Box::new(JgToken)), T_JL => text.push(Box::new(JlToken)), T_JE => text.push(Box::new(JeToken)), diff --git a/src/tokens.rs b/src/tokens.rs index 03e383b..8d64541 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -1,7 +1,9 @@ use crate::registers::{Register, RCS}; use crate::runtime::Runtime; +use num_integer::Roots; use std::io; use std::mem; +use std::ops::BitXor; use std::thread::sleep; use std::time::Duration; @@ -23,6 +25,12 @@ pub const T_DIV: u8 = 0x13; pub const T_MOD: u8 = 0x14; pub const T_LSH: u8 = 0x15; pub const T_RSH: u8 = 0x16; +pub const T_AND: u8 = 0x17; +pub const T_OR: u8 = 0x18; +pub const T_NOT: u8 = 0x19; +pub const T_XOR: u8 = 0x1A; +pub const T_POW: u8 = 0x1B; +pub const T_NRT: u8 = 0x1C; pub const T_JG: u8 = 0x20; pub const T_JL: u8 = 0x21; pub const T_JE: u8 = 0x22; @@ -449,6 +457,101 @@ impl Token for RshToken { } } +#[derive(Debug, Clone)] +pub struct AndToken; + +impl Token for AndToken { + fn to_bytecode(&self) -> Vec { + vec![T_AND] + } + + fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { + runtime.rgo.set(runtime.rgd.get() & runtime.rgi.get()); + + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct OrToken; + +impl Token for OrToken { + fn to_bytecode(&self) -> Vec { + vec![T_OR] + } + + fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { + runtime.rgo.set(runtime.rgd.get() | runtime.rgi.get()); + + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct NotToken; + +impl Token for NotToken { + fn to_bytecode(&self) -> Vec { + vec![T_NOT] + } + + fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { + runtime.rgo.set(!runtime.rgd.get()); + + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct XorToken; + +impl Token for XorToken { + fn to_bytecode(&self) -> Vec { + vec![T_XOR] + } + + fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { + runtime.rgo.set(runtime.rgd.get().bitxor(runtime.rgi.get())); + + Ok(()) + } +} + +#[derive(Debug, Clone)] +pub struct PowToken; + +impl Token for PowToken { + fn to_bytecode(&self) -> Vec { + vec![T_POW] + } + + fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { + runtime.rgo.set( + (runtime.rgd.get() as f32) + .powi(runtime.rgi.get() as i32) + .round() as u32, + ); + + Ok(()) + } +} + +pub struct NrtToken; + +impl Token for NrtToken { + fn to_bytecode(&self) -> Vec { + vec![T_NRT] + } + + fn invoke(&self, runtime: &mut Runtime) -> io::Result<()> { + runtime + .rgo + .set(runtime.rgd.get().nth_root(runtime.rgi.get())); + + Ok(()) + } +} + #[derive(Debug, Clone)] pub struct JgToken;