experimental pattern matching

This commit is contained in:
nora 2021-04-25 10:35:28 +02:00
parent 42fc197341
commit 329c33f3cb
3 changed files with 47 additions and 6 deletions

View file

@ -24,6 +24,7 @@ enum ExStatement {
Loop(Vec<ExStatement>),
SetNull,
Repeat(Box<ExStatement>, usize),
ForLoop(usize, Box<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)]
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() {

View file

@ -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 {}
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));
}
}

View file

@ -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());