diff --git a/sw/trashernet-as/.gitignore b/sw/trashernet-as/.gitignore new file mode 100644 index 0000000..90f0431 --- /dev/null +++ b/sw/trashernet-as/.gitignore @@ -0,0 +1 @@ +target/** diff --git a/sw/trashernet-as/Cargo.lock b/sw/trashernet-as/Cargo.lock new file mode 100644 index 0000000..ff014cb --- /dev/null +++ b/sw/trashernet-as/Cargo.lock @@ -0,0 +1,491 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "cactus" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf034765b7d19a011c6d619e880582bf95e8186b580e6fab56589872dd87dcf5" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfgrammar" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41879646bd1fbd55efdb9e2c1ac85e63856ad951e4e14b2e3086374802a13e9b" +dependencies = [ + "indexmap", + "lazy_static", + "num-traits", + "regex", + "serde", + "vob", +] + +[[package]] +name = "deranged" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "filetime" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "hashbrown" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" + +[[package]] +name = "indexmap" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" + +[[package]] +name = "lrlex" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d3c956ecfc913cb0e89575c5dd74d2558ec6e12c18f23baabc2985dc48ead28" +dependencies = [ + "cfgrammar", + "getopts", + "lazy_static", + "lrpar", + "num-traits", + "quote", + "regex", + "regex-syntax", + "serde", + "vergen", +] + +[[package]] +name = "lrpar" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f2acdd7023dc9f0eb51b13a615477c245519f593537667116874d2c699972d" +dependencies = [ + "bincode", + "cactus", + "cfgrammar", + "filetime", + "indexmap", + "lazy_static", + "lrtable", + "num-traits", + "packedvec", + "regex", + "serde", + "static_assertions", + "vergen", + "vob", +] + +[[package]] +name = "lrtable" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310933a066b41ed437844d548c5972b02b407e63a8254d08204082a05f7a1b34" +dependencies = [ + "cfgrammar", + "fnv", + "num-traits", + "serde", + "sparsevec", + "vob", +] + +[[package]] +name = "memchr" +version = "2.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" + +[[package]] +name = "num-traits" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] +name = "packedvec" +version = "1.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde3c690ec20e4a2b4fb46f0289a451181eb50011a1e2acc8d85e2fde9062a45" +dependencies = [ + "num-traits", + "serde", +] + +[[package]] +name = "proc-macro2" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b1106fec09662ec6dd98ccac0f81cef56984d0b49f75c92d8cbad76e20c005c" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "semver" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad977052201c6de01a8ef2aa3378c4bd23217a056337d1d6da40468d267a4fb0" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "sparsevec" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35df5d2e580b29f3f7ec5b4ed49b0ab3acf7f3624122b3e823cafb9630f293b8" +dependencies = [ + "num-traits", + "packedvec", + "serde", + "vob", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "syn" +version = "2.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "time" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" +dependencies = [ + "deranged", + "itoa", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ad70d68dba9e1f8aceda7aa6711965dfec1cac869f311a51bd08b3a2ccbce20" +dependencies = [ + "time-core", +] + +[[package]] +name = "trashernet-as" +version = "0.1.0" +dependencies = [ + "cfgrammar", + "lrlex", + "lrpar", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "vergen" +version = "8.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85e7dc29b3c54a2ea67ef4f953d5ec0c4085035c0ae2d325be1c0d2144bd9f16" +dependencies = [ + "anyhow", + "rustversion", + "time", +] + +[[package]] +name = "vob" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c058f4c41e71a043c67744cb76dcc1ae63ece328c1732a72489ccccc2dec23e6" +dependencies = [ + "num-traits", + "rustc_version", + "serde", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/sw/trashernet-as/Cargo.toml b/sw/trashernet-as/Cargo.toml new file mode 100644 index 0000000..9a6020b --- /dev/null +++ b/sw/trashernet-as/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "trashernet-as" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[build-dependencies] +cfgrammar = "0.13" +lrlex = "0.13" +lrpar = "0.13" + +[dependencies] +cfgrammar = "0.13" +lrlex = "0.13" +lrpar = "0.13" diff --git a/sw/trashernet-as/build.rs b/sw/trashernet-as/build.rs new file mode 100644 index 0000000..f0c9221 --- /dev/null +++ b/sw/trashernet-as/build.rs @@ -0,0 +1,15 @@ +use cfgrammar::yacc::YaccKind; +use lrlex::CTLexerBuilder; + +fn main() { + CTLexerBuilder::new() + .lrpar_config(|ctp| { + ctp.yacckind(YaccKind::Grmtools) + .grammar_in_src_dir("calc.y") + .unwrap() + }) + .lexer_in_src_dir("calc.l") + .unwrap() + .build() + .unwrap(); +} diff --git a/sw/trashernet-as/notes.md b/sw/trashernet-as/notes.md new file mode 100644 index 0000000..b7b2a6a --- /dev/null +++ b/sw/trashernet-as/notes.md @@ -0,0 +1,186 @@ +# Trashernet Command Processor + +Commands: + +* MATCH (length, matches, jump), followed by match-jump-addresses if , followed by match bytes interleaved: Match incoming data against. Set to zero for unconditional jump. If no match, abort reception. +* FORWARD (length): Output bytes of data on the output port +* IGNORE (length): Ignore bytes +* OUTPUT: Output following byte on the special port + + +Command format: + +2b 4b 3b 1b +[Opcode] [length] [matches] [jump] + + + +Example program: + +# MAC frame +MATCH (6, 2, false) AA.BB.CC.DD.EE.FF FF.FF.FF.FF.FF.FF +IGNORE (6) + +# Protocol MUX +MATCH ( + +# IPv4 +MATCH (4, 1, false) 192.168.178.1 + + + +# IDEA 2 +Okay, I need a new idea. The problem with the first is that I almost always need access to parameters from the past. E.g. ARP requires the sender MAC address for the response. In the current design, I would've already discarded that because what do I care about it for a data packet. + +So, new approach: A packet is received into a RAM ring buffer, and then the script is started with the CRC OK. + +New scripting language: + +* SET_CURSOR (position): Set cursor to position in received telegram +* MATCH[!]
: Jump to address if pattern matches; else continue after pattern and reset cursor to before match (without !), or stop receiving (with !) +* FORWARD +* OUTPUT +* DIE + +COMMAND formatting: + +general : [3 bit opcode] +MATCH : [1b deathflag] [4 bit length] + +Example program: + +MAC_DST: MATCH AA.BB.CC.DD.EE.FF -> ETHERTYPE +MAC_BCAST: MATCH! FF.FF.FF.FF.FF.FF -> ETHERTYPE +ETHERTYPE_ARP: MATCH 08.06 -> ARP +ETHERTYPE_IP: MATCH! 08.00 -> IP +ARP: MATCH! 00.01.08.00.06.04 -> ARP_HDR_OK +ARP_HDR_OK: MATCH 01 -> ARP_REQUEST + MATCH! 02 -> ARP_REPLY +ARP_REQUEST: SET_CURSOR +10 + MATCH! AA.BB.CC.DD.EE.FF -> ARP_REQUEST_OK +ARP_REQUEST_OK: OUTPUT 01 + SET_CURSOR -16 + FORWARD 10 + DONE + + +This program generates an interrupt for + * ARP (01) with 10 user bytes SHA+SPA + + +## Now, on the sender side. + +* TX processor runs on shared memory with receiver, possibly even shared with the receive buffer + So that receiver can write "program memory" of transmitter, this is relevant for example for IP TX, which checks that some memory address is the target TX address. + + +Idea for an IP TX with ARP. + +* Destination IP is written to address in memory +* Start IP TX program +* ARP_CHECK: SET_CURSOR(ARP RX address buffer) +* MATCH FOUND_IP +* WRITE_MEM +* SET_CURSOR(ARP TX address buffer) +* MATCH -> ARP_CHECK +* !!! TBD: Assemble and send out ARP request +* JUMP ARP_CHECK + +* !!! TBD: Loop until MATCH +* FOUND_IP: Assemble and send out IP frame + +ideas for improvement: +* have two cursors for the TX engine + -> basically to select between static data and dynamic + + + + +# Final (TM) Idea + +* We build one processor. It handles both TX and RX +* It runs code from a shared memory space with the RX buffer +* It has multiple pointer registers (at least two) + +Commands: + +* Match -> : Compare len characters from ptr1 and ptr2, jump to dest if all match, go to next instruction if not; if len=zero, it's an unconditional jump. `poll_flag` keeps looping here until the condition is met. `abort_flag` will abort command execution on mismatch. +* SetPtr , +* Write : Write data from ptr2 to ptr1 +* Output : Push data from to output FIFO +* Input : Read bytes from input FIFO into +* Return: TBD: Single-level return to caller (last match?) +* Jump : Pseudo-command, will translate to other instructions. Set location of ptr1 and ptr2 (opt.), then jump (empty match) to that address. + +## Example to send an IP frame + +* Write destination IP to +* Start TX IP program + +SendUDP: + +CheckARP: + SetPtr ptr1, + SetPtr ptr2, + Match 4 -> FOUND_ARP + NeedARPRequest: + Jump SendMAC, ptr1="FF:FF:FF:FF:FF:FF", ptr2="08:06" + Jump SendARP, ptr1= + Match 4, poll -> FOUND_ARP + FOUND_ARP: + + +// ## SendMAC: Send MAC frame. ptr1: Destination MAC, ptr2: Ethertype +SendMAC: + Output ptr1, 6 + SetPtr ptr1, + Output ptr1, 6 + Output ptr2, 2 + Return + +SendARPRequest: + Output // TODO + Output // SHA + Output // SPA + Output FF:FF:FF:FF:FF:FF // THA + Output // TPA + Return + + + +## Maybe change concept + +Idea is: We pretty much have a template for each frame in memory. The program will assemble the data in place, and then TX the entire block + +// Variables will be defined in order! + +// Ethernet frame +Def ETH-DEST-MAC:6 +Def ETH-SOURCE-MAC:6=00:DE:AD:BE:EF:00 +Def ETH-ETHERTYPE:2 + +// ARP frame +Def ARP-HEADER:?=0001:0800:0604:0001 +Def ARP-SHA:0=Ð-SOURCE-MAC +Def ARP-SPA:4 +Def ARP-THA:6 +Def ARP-TPA:4 + +CheckARP: + SetPtr ptr1, + SetPtr ptr2, + Match 4 -> FOUND_ARP + NeedARPRequest: + // Build Ethernet header + Write Ð-DEST-MAC, "FF:FF:FF:FF:FF:FF" + Write Ð-ETHERTYPE, "0806" + Output Ð-DEST-MAC, 18 + // Build ARP header + Write &ARP_TPA, , 4 + Output &ARP-HEADER, 8 + Output &ARP_SHA, 6 + Output &ARP_SPA, 4 + Output &ARP-THA, 10 // +ARP-TPA + // todo: set up match + Match 4, poll -> FOUND_ARP + FOUND_ARP: diff --git a/sw/trashernet-as/src/calc.l b/sw/trashernet-as/src/calc.l new file mode 100644 index 0000000..11a4d2b --- /dev/null +++ b/sw/trashernet-as/src/calc.l @@ -0,0 +1,9 @@ +%% +SetPtr "SetPtr" +[0-9]+ "NUM-DEC" +0x[0-9a-fA-F]+ "NUM-HEX" +0b[0-1]+ "NUM-BIN" +[\n] "NEWLINE" +[\t ]+ ; +&[0-9a-zA-Z_]+ "Reference" +[0-9a-zA-Z ] "text" \ No newline at end of file diff --git a/sw/trashernet-as/src/calc.y b/sw/trashernet-as/src/calc.y new file mode 100644 index 0000000..257ac08 --- /dev/null +++ b/sw/trashernet-as/src/calc.y @@ -0,0 +1,95 @@ +%start CommandSequence +%% + +CommandSequence -> Result >, CompilerError>: + CommandLine CommandSequence + { + let mut list = $2?; + list.push_front($1); + Ok(list) + } + | CommandLine + { + let mut list : LinkedList> = LinkedList::new(); + list.push_front($1); + Ok(list) + } + ; + +CommandLine -> Result: + Command 'NEWLINE' + { + Ok(LineOfCode{line : 42, code: $1}) + } + | 'NEWLINE' + { + Err(CompilerError {pos: $1.unwrap().span(), description: CompilerErrorType::MiscError}) + } + ; + +/*Comment -> Result<(), ()>: + ';' 'text': + { + Ok(()) + } + ;*/ + +Command -> Result : + 'SetPtr' PointerId Symbol + { + Ok(Code::Instruction(InstructionType::SetPtr{which: $2?, address: $3?})) + } + ; + +PointerId -> Result: + Literal + { + let num = $1?; + if num > 0 && num <= 1 { + Ok(num) + } else { + //Err(CompilerError {pos: $lexer.line_col($1.unwrap().span()), description: CompilerErrorType::MiscError}) + Ok(42) // TODO: This should raise an error, but I don't know the span anymore -.- + } + } + ; + +Symbol -> Result: + Literal + { + Ok(Symbol::ResolvedSymbol{address: $1?}) + } + | Reference + { + Ok(Symbol::UnresolvedSymbol{symbol: $1?}) + } + ; + +Reference -> Result: + 'Reference' + { + Ok($lexer.span_str($1.unwrap().span())[1..].to_string()) + } + ; + +Literal -> Result: + 'NUM-HEX' + { + parse_number(16, $1.unwrap().span(), &$lexer.span_str($1.unwrap().span())[2..]) // TODO: Change error to include line/col etc. + } + | 'NUM-DEC' + { + parse_number(10, $1.unwrap().span(), &$lexer.span_str($1.unwrap().span())) + } + ; + +%% + +use crate::compiler_types::*; +use std::collections::LinkedList; + +fn parse_number(radix: u32, span: lrpar::Span, s: &str) -> Result { + //Ok(u16::from_str_radix(s, radix)?) + //u16::from_str_radix(s, radix).map_err(CompilerError{description: CompilerErrorType::MiscError}) + u16::from_str_radix(s, radix).map_err(|e| CompilerError{pos: span, description: e.into()}) +} diff --git a/sw/trashernet-as/src/compiler_types.rs b/sw/trashernet-as/src/compiler_types.rs new file mode 100644 index 0000000..e79d30f --- /dev/null +++ b/sw/trashernet-as/src/compiler_types.rs @@ -0,0 +1,73 @@ +use std::num; + +#[derive(Debug)] +pub enum Symbol { + UnresolvedSymbol{symbol: String}, + ResolvedSymbol{address: u16} +} + +#[derive(Debug)] +pub enum JumpCondition { + Always, + OnMatch, + OnTimer +} + +#[derive(Debug)] +pub enum InstructionType { + SetPtr{which: u16, address: Symbol}, + Output{length: Symbol}, + Match{length: Symbol}, + Write{length: Symbol}, + Timer{time: Symbol}, + Page{page: Symbol}, + Return, + Input{length: Symbol}, + Jump{address: Symbol, condition: JumpCondition} +} + +#[derive(Debug)] +pub enum Code { + Instruction(InstructionType), + Comment(String) +} + +#[derive(Debug)] +pub struct LineOfCode { + pub line: usize, + pub code: Result +} + +#[derive(Debug)] +pub struct CompilerError { + pub pos: lrpar::Span, + pub description: CompilerErrorType +} + +#[derive(Debug)] +pub enum CompilerErrorType { + LiteralError(num::ParseIntError), + LexerError(lrlex::DefaultLexeme), + MiscError +} + + +impl From for CompilerErrorType { + fn from(e: num::ParseIntError) -> Self { + CompilerErrorType::LiteralError(e) + } +} + +impl From for CompilerErrorType { + fn from(e: lrlex::DefaultLexeme) -> Self { + CompilerErrorType::LexerError(e) + } +} + +/* +impl fmt::Debug for LineOfCode { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Line = {}", self.line) + } +} +*/ diff --git a/sw/trashernet-as/src/main.rs b/sw/trashernet-as/src/main.rs new file mode 100644 index 0000000..3ee9627 --- /dev/null +++ b/sw/trashernet-as/src/main.rs @@ -0,0 +1,25 @@ +mod compiler_types; + +use std::env; +use std::fs; + +use lrlex::lrlex_mod; +use lrpar::lrpar_mod; + +lrlex_mod!("calc.l"); +lrpar_mod!("calc.y"); + +fn main() { + let lexerdef = calc_l::lexerdef(); + let args: Vec = env::args().collect(); + let code = fs::read_to_string(&args[1]).unwrap(); + let lexer = lexerdef.lexer(&code); + let (res, errs) = calc_y::parse(&lexer); + for e in errs { + println!("{}", e.pp(&lexer, &calc_y::token_epp)); + } + match res { + Some(r) => println!("Result: {:#?}", r), + _ => eprintln!("Unable to evaluate expression.") + } +} diff --git a/sw/trashernet-as/test.tas b/sw/trashernet-as/test.tas new file mode 100644 index 0000000..4ffb0c5 --- /dev/null +++ b/sw/trashernet-as/test.tas @@ -0,0 +1,4 @@ +SetPtr 1 22 +SetPtr 2 0x42 +SetPtr 3 &Ref +SetPtr 4 99999