mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-14 21:35:02 +01:00
parser works
This commit is contained in:
parent
2b1daa55fb
commit
2484fe1f44
7 changed files with 402 additions and 0 deletions
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