From 329c33f3cbe353c2fd159d0a4f3c0df351e66169 Mon Sep 17 00:00:00 2001 From: Nilstrieb Date: Sun, 25 Apr 2021 10:35:28 +0200 Subject: [PATCH] experimental pattern matching --- bfi-rust/src/interpreter/optimized/mod.rs | 10 ++++- .../src/interpreter/optimized/patterns.rs | 41 +++++++++++++++++-- bfi-rust/src/main.rs | 2 +- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/bfi-rust/src/interpreter/optimized/mod.rs b/bfi-rust/src/interpreter/optimized/mod.rs index 9745171..7df4ab4 100644 --- a/bfi-rust/src/interpreter/optimized/mod.rs +++ b/bfi-rust/src/interpreter/optimized/mod.rs @@ -24,6 +24,7 @@ enum ExStatement { Loop(Vec), SetNull, Repeat(Box, usize), + ForLoop(usize, Box), } impl From for ExStatement { @@ -177,6 +178,12 @@ fn execute(statement: &ExStatement, mem: &mut Memory, pointer: &mut usize, out: } } } + ExStatement::ForLoop(offset, statement) => { + *pointer += offset; + while mem[*pointer - offset] != 0 { + execute(statement, mem, pointer, out); + } + } }; } @@ -184,8 +191,7 @@ fn execute(statement: &ExStatement, mem: &mut Memory, pointer: &mut usize, out: #[cfg(test)] mod test { use crate::interpreter::optimized::{run, o_repeat}; - use crate::interpreter::optimized::ExStatement::{Inc, Repeat, R, L}; - use crate::interpreter::Statement::Dec; + use crate::interpreter::optimized::ExStatement::{Inc, Repeat, R, L, Dec}; #[test] fn run_loop() { diff --git a/bfi-rust/src/interpreter/optimized/patterns.rs b/bfi-rust/src/interpreter/optimized/patterns.rs index 0d9ebf4..ffe4bb9 100644 --- a/bfi-rust/src/interpreter/optimized/patterns.rs +++ b/bfi-rust/src/interpreter/optimized/patterns.rs @@ -1,8 +1,43 @@ //! //! # Patterns find and replace //! Pattern-match ExStatements and replace them with optimizations like add, multiply etc -//! -//! A pattern might look a bit like this: `Loop(Dec)` -> `SetNull` -struct Pattern {} \ No newline at end of file +use crate::interpreter::optimized::ExStatement; + +/// +/// Replace this: `[>>x<<-]` or `[->>x<<]` with `WhileAdd(2, x)` +fn for_loop(to_test: ExStatement) -> ExStatement { + match to_test { + ExStatement::Loop(v) => { + match v[..] { + [ExStatement::R, ExStatement::Inc, ExStatement::L, ExStatement::Dec] => { + ExStatement::ForLoop(1, Box::from(ExStatement::Inc)) + } + _ => ExStatement::Loop(v) + } + }, + s => s + } +} + + + + +#[cfg(test)] +mod test { + use crate::interpreter::optimized::ExStatement::{Out, Loop, Inc, R, L, Dec, ForLoop}; + use crate::interpreter::optimized::patterns::for_loop; + + #[test] + fn for_loop_false() { + let statement = Loop(vec![Out, Inc]); + assert_eq!(statement.clone(), for_loop(statement)); + } + + #[test] + fn for_loop_simplest() { + let statement = Loop(vec![R, Inc, L, Dec]); + assert_eq!(ForLoop(1, Box::from(Inc)), for_loop(statement)); + } +} \ No newline at end of file diff --git a/bfi-rust/src/main.rs b/bfi-rust/src/main.rs index c6099cd..222a01c 100644 --- a/bfi-rust/src/main.rs +++ b/bfi-rust/src/main.rs @@ -30,7 +30,7 @@ fn run(program: String) { let out = interpreter::o1::run(&*program); let end1 = start1.elapsed().unwrap();*/ let start2 = SystemTime::now(); - let out2 = interpreter::o2::run(&*program, false).unwrap(); + let out2 = interpreter::optimized::run(&*program, false).unwrap(); let end2 = start2.elapsed().unwrap(); //assert_eq!(out, out2); //println!("{}\nFinished execution. Took o1: 18008ms (for hanoi), o2: {}ms", out2/*, end1.as_millis()*/, end2.as_millis());