mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-14 13:35:00 +01:00
parser works
This commit is contained in:
parent
2b1daa55fb
commit
2484fe1f44
7 changed files with 402 additions and 0 deletions
2
rust2/.gitignore
vendored
Normal file
2
rust2/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
target
|
||||
.idea
|
||||
227
rust2/Cargo.lock
generated
Normal file
227
rust2/Cargo.lock
generated
Normal file
|
|
@ -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",
|
||||
]
|
||||
12
rust2/Cargo.toml
Normal file
12
rust2/Cargo.toml
Normal file
|
|
@ -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"
|
||||
8
rust2/src/main.rs
Normal file
8
rust2/src/main.rs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#![feature(allocator_api)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod parse;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
104
rust2/src/parse.rs
Normal file
104
rust2/src/parse.rs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
use bumpalo::Bump;
|
||||
|
||||
type Instrs<'ast> = Vec<Instr<'ast>, &'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<I>(alloc: &Bump, mut src: I) -> Result<Instrs<'_>, ParseError>
|
||||
where
|
||||
I: Iterator<Item = u8>,
|
||||
{
|
||||
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<Instrs<'ast>, ParseError>
|
||||
where
|
||||
I: Iterator<Item = u8>,
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
29
rust2/src/snapshots/rust2__parse__tests__nested_loop.snap
Normal file
29
rust2/src/snapshots/rust2__parse__tests__nested_loop.snap
Normal file
|
|
@ -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,
|
||||
],
|
||||
),
|
||||
],
|
||||
)
|
||||
20
rust2/src/snapshots/rust2__parse__tests__simple.snap
Normal file
20
rust2/src/snapshots/rust2__parse__tests__simple.snap
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
source: src/parse.rs
|
||||
assertion_line: 93
|
||||
expression: instrs
|
||||
---
|
||||
Ok(
|
||||
[
|
||||
Right,
|
||||
Add,
|
||||
Left,
|
||||
Add,
|
||||
Add,
|
||||
Loop(
|
||||
[
|
||||
Sub,
|
||||
],
|
||||
),
|
||||
Out,
|
||||
],
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue