mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-16 14:25:03 +01:00
experimental pattern matching
This commit is contained in:
parent
42fc197341
commit
329c33f3cb
3 changed files with 47 additions and 6 deletions
|
|
@ -24,6 +24,7 @@ enum ExStatement {
|
||||||
Loop(Vec<ExStatement>),
|
Loop(Vec<ExStatement>),
|
||||||
SetNull,
|
SetNull,
|
||||||
Repeat(Box<ExStatement>, usize),
|
Repeat(Box<ExStatement>, usize),
|
||||||
|
ForLoop(usize, Box<ExStatement>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Statement> for ExStatement {
|
impl From<Statement> 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)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::interpreter::optimized::{run, o_repeat};
|
use crate::interpreter::optimized::{run, o_repeat};
|
||||||
use crate::interpreter::optimized::ExStatement::{Inc, Repeat, R, L};
|
use crate::interpreter::optimized::ExStatement::{Inc, Repeat, R, L, Dec};
|
||||||
use crate::interpreter::Statement::Dec;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn run_loop() {
|
fn run_loop() {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,43 @@
|
||||||
//!
|
//!
|
||||||
//! # Patterns find and replace
|
//! # Patterns find and replace
|
||||||
//! Pattern-match ExStatements and replace them with optimizations like add, multiply etc
|
//! 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 {}
|
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));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -30,7 +30,7 @@ fn run(program: String) {
|
||||||
let out = interpreter::o1::run(&*program);
|
let out = interpreter::o1::run(&*program);
|
||||||
let end1 = start1.elapsed().unwrap();*/
|
let end1 = start1.elapsed().unwrap();*/
|
||||||
let start2 = SystemTime::now();
|
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();
|
let end2 = start2.elapsed().unwrap();
|
||||||
//assert_eq!(out, out2);
|
//assert_eq!(out, out2);
|
||||||
//println!("{}\nFinished execution. Took o1: 18008ms (for hanoi), o2: {}ms", out2/*, end1.as_millis()*/, end2.as_millis());
|
//println!("{}\nFinished execution. Took o1: 18008ms (for hanoi), o2: {}ms", out2/*, end1.as_millis()*/, end2.as_millis());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue