diff --git a/rust2/.gitignore b/rust2/.gitignore new file mode 100644 index 0000000..5bd05d6 --- /dev/null +++ b/rust2/.gitignore @@ -0,0 +1,2 @@ +target +.idea \ No newline at end of file diff --git a/rust2/Cargo.lock b/rust2/Cargo.lock new file mode 100644 index 0000000..c4c639d --- /dev/null +++ b/rust2/Cargo.lock @@ -0,0 +1,227 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bumpalo" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" + +[[package]] +name = "console" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "terminal_size", + "winapi", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "indexmap" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" +dependencies = [ + "autocfg", + "hashbrown", +] + +[[package]] +name = "insta" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "689960f187c43c01650c805fb6bc6f55ab944499d86d4ffe9474ad78991d8e94" +dependencies = [ + "console", + "once_cell", + "serde", + "serde_json", + "serde_yaml", + "similar", +] + +[[package]] +name = "itoa" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "libc" +version = "0.2.123" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "once_cell" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" + +[[package]] +name = "proc-macro2" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rust2" +version = "0.1.0" +dependencies = [ + "bumpalo", + "insta", +] + +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a521f2940385c165a24ee286aa8599633d162077a54bdcae2a6fd5a7bfa7a0" +dependencies = [ + "indexmap", + "ryu", + "serde", + "yaml-rust", +] + +[[package]] +name = "similar" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e24979f63a11545f5f2c60141afe249d4f19f84581ea2138065e400941d83d3" + +[[package]] +name = "syn" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] diff --git a/rust2/Cargo.toml b/rust2/Cargo.toml new file mode 100644 index 0000000..c4face8 --- /dev/null +++ b/rust2/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rust2" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bumpalo = { version = "3.9.1", features = ["allocator_api"] } + +[dev-dependencies] +insta = "1.14.0" diff --git a/rust2/src/main.rs b/rust2/src/main.rs new file mode 100644 index 0000000..e293ef6 --- /dev/null +++ b/rust2/src/main.rs @@ -0,0 +1,8 @@ +#![feature(allocator_api)] +#![warn(rust_2018_idioms)] + +mod parse; + +fn main() { + println!("Hello, world!"); +} diff --git a/rust2/src/parse.rs b/rust2/src/parse.rs new file mode 100644 index 0000000..57e7600 --- /dev/null +++ b/rust2/src/parse.rs @@ -0,0 +1,104 @@ +use bumpalo::Bump; + +type Instrs<'ast> = Vec, &'ast Bump>; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Instr<'ast> { + Add, + Sub, + Right, + Left, + Out, + In, + Loop(Instrs<'ast>), +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ParseError; + +pub fn parse(alloc: &Bump, mut src: I) -> Result, ParseError> +where + I: Iterator, +{ + let mut instrs = Vec::new_in(alloc); + + loop { + match src.next() { + Some(b'+') => instrs.push(Instr::Add), + Some(b'-') => instrs.push(Instr::Sub), + Some(b'>') => instrs.push(Instr::Right), + Some(b'<') => instrs.push(Instr::Left), + Some(b'.') => instrs.push(Instr::Out), + Some(b',') => instrs.push(Instr::In), + Some(b'[') => { + let loop_instrs = parse_loop(alloc, &mut src, 0)?; + instrs.push(Instr::Loop(loop_instrs)); + } + Some(b']') => return Err(ParseError), + Some(_) => {} // comment + None => break, + } + } + + Ok(instrs) +} + +pub fn parse_loop<'ast, I>( + alloc: &'ast Bump, + src: &mut I, + depth: u16, +) -> Result, ParseError> +where + I: Iterator, +{ + const MAX_DEPTH: u16 = 1000; + + if depth > MAX_DEPTH { + return Err(ParseError); + } + + let mut instrs = Vec::new_in(alloc); + + loop { + match src.next() { + Some(b'+') => instrs.push(Instr::Add), + Some(b'-') => instrs.push(Instr::Sub), + Some(b'>') => instrs.push(Instr::Right), + Some(b'<') => instrs.push(Instr::Left), + Some(b'.') => instrs.push(Instr::Out), + Some(b',') => instrs.push(Instr::In), + Some(b'[') => { + let loop_instrs = parse_loop(alloc, src, depth + 1)?; + instrs.push(Instr::Loop(loop_instrs)); + } + Some(b']') => break, + Some(_) => {} // comment + None => return Err(ParseError), + } + } + + Ok(instrs) +} + +#[cfg(test)] +mod tests { + use bumpalo::Bump; + + #[test] + fn simple() { + let alloc = Bump::new(); + + let bf = ">+<++[-]."; + let instrs = super::parse(&alloc, bf.bytes()); + insta::assert_debug_snapshot!(instrs); + } + + #[test] + fn nested_loop() { + let alloc = Bump::new(); + + let bf = "+[-[-[-]]+>>>]"; + let instrs = super::parse(&alloc, bf.bytes()); + insta::assert_debug_snapshot!(instrs); + } +} diff --git a/rust2/src/snapshots/rust2__parse__tests__nested_loop.snap b/rust2/src/snapshots/rust2__parse__tests__nested_loop.snap new file mode 100644 index 0000000..f10f3e0 --- /dev/null +++ b/rust2/src/snapshots/rust2__parse__tests__nested_loop.snap @@ -0,0 +1,29 @@ +--- +source: src/parse.rs +assertion_line: 102 +expression: instrs +--- +Ok( + [ + Add, + Loop( + [ + Sub, + Loop( + [ + Sub, + Loop( + [ + Sub, + ], + ), + ], + ), + Add, + Right, + Right, + Right, + ], + ), + ], +) diff --git a/rust2/src/snapshots/rust2__parse__tests__simple.snap b/rust2/src/snapshots/rust2__parse__tests__simple.snap new file mode 100644 index 0000000..54ac4ca --- /dev/null +++ b/rust2/src/snapshots/rust2__parse__tests__simple.snap @@ -0,0 +1,20 @@ +--- +source: src/parse.rs +assertion_line: 93 +expression: instrs +--- +Ok( + [ + Right, + Add, + Left, + Add, + Add, + Loop( + [ + Sub, + ], + ), + Out, + ], +)