From 7f2e49e5234e63c8c7ff05a1d15c0d0ce695a8df Mon Sep 17 00:00:00 2001 From: trivernis Date: Sun, 26 Apr 2020 17:43:25 +0200 Subject: [PATCH] Add assembler --- .gitignore | 5 + Cargo.lock | 359 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 11 ++ src/asm_tokens.rs | 203 +++++++++++++++++++++++++ src/bin/lsambler.rs | 84 +++++++++++ src/lib.rs | 2 + src/registers.rs | 28 ++++ 7 files changed, 692 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/asm_tokens.rs create mode 100644 src/bin/lsambler.rs create mode 100644 src/lib.rs create mode 100644 src/registers.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..587c80a --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/target +**/*.rs.bk +.idea +*.asm +*.sbc \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..ff3874c --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,359 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "clap" +version = "2.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", + "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", + "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", + "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", + "scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "hermit-abi" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "ledstrip_vm" +version = "0.1.0" +dependencies = [ + "rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "libc" +version = "0.2.69" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "memoffset" +version = "0.5.4" +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 = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "hermit-abi 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro-error-attr 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", + "syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", + "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "proc-macro2" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rayon-core" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "structopt" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "structopt-derive 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "structopt-derive" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro-error 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn-mid" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "version_check" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +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 cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" +"checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +"checksum crossbeam-deque 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" +"checksum crossbeam-epoch 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +"checksum crossbeam-queue 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" +"checksum crossbeam-utils 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +"checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" +"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 maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" +"checksum memoffset 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" +"checksum num_cpus 1.13.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +"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" +"checksum quote 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f" +"checksum rayon 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" +"checksum rayon-core 1.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" +"checksum scopeguard 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +"checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +"checksum structopt 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "863246aaf5ddd0d6928dfeb1a9ca65f505599e4e1b399935ef7e75107516b4ef" +"checksum structopt-derive 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "d239ca4b13aee7a2142e6795cbd69e457665ff8037aed33b3effdc430d2f927a" +"checksum syn 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" +"checksum syn-mid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" +"checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +"checksum unicode-segmentation 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" +"checksum unicode-width 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" +"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" +"checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" +"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" +"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..c583320 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "ledstrip_vm" +version = "0.1.0" +authors = ["trivernis "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +structopt = "0.3.9" +rayon = "1.3.0" \ No newline at end of file diff --git a/src/asm_tokens.rs b/src/asm_tokens.rs new file mode 100644 index 0000000..0aae85d --- /dev/null +++ b/src/asm_tokens.rs @@ -0,0 +1,203 @@ +const T_NOP: u8 = 0x00; +const T_EXIT: u8 = 0x01; +const T_SET: u8 = 0x02; +const T_COPY: u8 = 0x03; +const T_LOAD: u8 = 0x04; +const T_CLEAR: u8 = 0x05; +const T_WRITE: u8 = 0x06; +const T_LABEL: u8 = 0x07; +const T_GOTO: u8 = 0x08; +const T_ADD: u8 = 0x10; +const T_SUB: u8 = 0x11; +const T_MUL: u8 = 0x12; +const T_DIV: u8 = 0x13; +const T_MOD: u8 = 0x14; +const T_LSH: u8 = 0x15; +const T_RSH: u8 = 0x16; +const T_JG: u8 = 0x20; +const T_JL: u8 = 0x21; +const T_JE: u8 = 0x22; +const T_PAUSE: u8 = 0xF0; +const T_CMD: u8 = 0xF1; + +pub trait Token { + fn to_bytecode(&self) -> Vec; +} + +pub struct NopToken; + +impl Token for NopToken { + fn to_bytecode(&self) -> Vec { + vec![T_NOP] + } +} + +pub struct ExitToken { + pub register: u8, +} + +impl Token for ExitToken { + fn to_bytecode(&self) -> Vec { + vec![T_EXIT, self.register] + } +} + +pub struct SetToken { + pub value: u8, + pub register: u8, +} + +impl Token for SetToken { + fn to_bytecode(&self) -> Vec { + vec![T_SET, self.value, self.register] + } +} + +pub struct CopyToken { + pub register_1: u8, + pub register_2: u8, +} + +impl Token for CopyToken { + fn to_bytecode(&self) -> Vec { + vec![T_COPY, self.register_1, self.register_2] + } +} + +pub struct LoadToken; + +impl Token for LoadToken { + fn to_bytecode(&self) -> Vec { + vec![T_LOAD] + } +} + +pub struct ClearToken { + pub register: u8, +} + +impl Token for ClearToken { + fn to_bytecode(&self) -> Vec { + vec![T_CLEAR, self.register] + } +} + +pub struct WriteToken; + +impl Token for WriteToken { + fn to_bytecode(&self) -> Vec { + vec![T_WRITE] + } +} + +pub struct LabelToken; + +impl Token for LabelToken { + fn to_bytecode(&self) -> Vec { + vec![T_LABEL] + } +} + +pub struct GotoToken; + +impl Token for GotoToken { + fn to_bytecode(&self) -> Vec { + vec![T_GOTO] + } +} + +pub struct AddToken; + +impl Token for AddToken { + fn to_bytecode(&self) -> Vec { + vec![T_ADD] + } +} + +pub struct SubToken; + +impl Token for SubToken { + fn to_bytecode(&self) -> Vec { + vec![T_SUB] + } +} + +pub struct MulToken; + +impl Token for MulToken { + fn to_bytecode(&self) -> Vec { + vec![T_MUL] + } +} + +pub struct DivToken; + +impl Token for DivToken { + fn to_bytecode(&self) -> Vec { + vec![T_DIV] + } +} + +pub struct ModToken; + +impl Token for ModToken { + fn to_bytecode(&self) -> Vec { + vec![T_MOD] + } +} + +pub struct LshToken; + +impl Token for LshToken { + fn to_bytecode(&self) -> Vec { + vec![T_LSH] + } +} + +pub struct RshToken; + +impl Token for RshToken { + fn to_bytecode(&self) -> Vec { + vec![T_RSH] + } +} + +pub struct JgToken; + +impl Token for JgToken { + fn to_bytecode(&self) -> Vec { + vec![T_JG] + } +} + +pub struct JlToken; + +impl Token for JlToken { + fn to_bytecode(&self) -> Vec { + vec![T_JL] + } +} + +pub struct JeToken; + +impl Token for JeToken { + fn to_bytecode(&self) -> Vec { + vec![T_JE] + } +} + +pub struct PauseToken; + +impl Token for PauseToken { + fn to_bytecode(&self) -> Vec { + vec![T_PAUSE] + } +} + +pub struct CmdToken; + +impl Token for CmdToken { + fn to_bytecode(&self) -> Vec { + vec![T_CMD] + } +} diff --git a/src/bin/lsambler.rs b/src/bin/lsambler.rs new file mode 100644 index 0000000..48a8a38 --- /dev/null +++ b/src/bin/lsambler.rs @@ -0,0 +1,84 @@ +use ledstrip_vm::asm_tokens; +use ledstrip_vm::asm_tokens::{ + AddToken, ClearToken, CmdToken, CopyToken, DivToken, ExitToken, GotoToken, JeToken, JgToken, + JlToken, LabelToken, LoadToken, LshToken, ModToken, MulToken, PauseToken, RshToken, SetToken, + SubToken, Token, WriteToken, +}; +use ledstrip_vm::registers::get_register_by_name; +use rayon::prelude::*; +use std::fs::{read_to_string, File}; +use std::io; +use std::io::{BufRead, BufReader, BufWriter, Read, Write}; +use structopt::StructOpt; + +macro_rules! some_box { + ($expr:expr) => { + Some(Box::new($expr)) + }; +} + +#[derive(StructOpt, Debug)] +struct Opts { + #[structopt(short = "i", name = "input")] + input_file: String, + + #[structopt(short = "o", name = "output")] + output_file: String, +} + +fn main() -> io::Result<()> { + let opts: Opts = Opts::from_args(); + let contents = read_to_string(opts.input_file)?; + let f = File::create(opts.output_file)?; + let mut writer = BufWriter::new(f); + contents + .lines() + .map(|line| get_token(line)) + .filter_map(|token| Some(token?.to_bytecode())) + .for_each(|code| { + writer.write(&code); + }); + + Ok(()) +} + +fn get_token(line: &str) -> Option> { + let mut instr_parts = line.split_whitespace(); + + match instr_parts.next()? { + "exit" => Some(Box::new(ExitToken { + register: get_register_by_name(instr_parts.next()?)?, + })), + "set" => some_box!(SetToken { + value: instr_parts + .next()? + .parse::() + .expect("Failed to parse the value into a u8."), + register: get_register_by_name(instr_parts.next()?)?, + }), + "copy" => some_box!(CopyToken { + register_1: get_register_by_name(instr_parts.next()?)?, + register_2: get_register_by_name(instr_parts.next()?)?, + }), + "load" => some_box!(LoadToken), + "clear" => some_box!(ClearToken { + register: get_register_by_name(instr_parts.next()?)?, + }), + "write" => some_box!(WriteToken), + "label" => some_box!(LabelToken), + "goto" => some_box!(GotoToken), + "add" => some_box!(AddToken), + "sub" => some_box!(SubToken), + "mul" => some_box!(MulToken), + "div" => some_box!(DivToken), + "mod" => some_box!(ModToken), + "lsh" => some_box!(LshToken), + "rsh" => some_box!(RshToken), + "jg" => some_box!(JgToken), + "jl" => some_box!(JlToken), + "je" => some_box!(JeToken), + "pause" => some_box!(PauseToken), + "cmd" => some_box!(CmdToken), + _ => None, + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..fd88f32 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,2 @@ +pub mod asm_tokens; +pub mod registers; diff --git a/src/registers.rs b/src/registers.rs new file mode 100644 index 0000000..eebce69 --- /dev/null +++ b/src/registers.rs @@ -0,0 +1,28 @@ +pub const RCS: u8 = 0x01; +pub const RCR: u8 = 0x02; +pub const RCG: u8 = 0x03; +pub const RCB: u8 = 0x04; +pub const RCD: u8 = 0x05; +pub const RGP: u8 = 0x06; +pub const RGI: u8 = 0x07; +pub const RGO: u8 = 0x08; +pub const RGL: u8 = 0x09; + +/// Maps a register name to the bytecode value +pub fn get_register_by_name(name: &str) -> Option { + let item = [ + ("rcs", RCS), + ("rcr", RCR), + ("rcg", RCG), + ("rcb", RCB), + ("rcd", RCD), + ("rgp", RGP), + ("rgi", RGI), + ("rgo", RGO), + ("rgl", RGL), + ] + .iter() + .find(|(reg, bc)| *reg == name)?; + + Some((*item).1) +}