mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-14 13:35:00 +01:00
add cancel_left_right_add_sub pass
This commit is contained in:
parent
904356eb4e
commit
3eb9486a8c
2 changed files with 62 additions and 1 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
use crate::parse::{Instr, Span};
|
use crate::parse::{Instr, Span};
|
||||||
use crate::BumpVec;
|
use crate::BumpVec;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
use std::cmp::Ordering;
|
||||||
use std::fmt::{Debug, Formatter};
|
use std::fmt::{Debug, Formatter};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -53,6 +54,7 @@ pub fn optimize<'ir>(alloc: &'ir Bump, instrs: &[(Instr<'_>, Span)]) -> Ir<'ir>
|
||||||
let mut ir = pass_group(alloc, ir);
|
let mut ir = pass_group(alloc, ir);
|
||||||
pass_find_set_null(&mut ir);
|
pass_find_set_null(&mut ir);
|
||||||
pass_set_n(&mut ir);
|
pass_set_n(&mut ir);
|
||||||
|
pass_cancel_left_right_add_sub(&mut ir);
|
||||||
ir
|
ir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,3 +187,62 @@ fn pass_set_n(ir: &mut Ir<'_>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// pass that replaces `Left(5) Right(3)` with `Left(2)`
|
||||||
|
fn pass_cancel_left_right_add_sub(ir: &mut Ir<'_>) {
|
||||||
|
let stmts = &mut ir.stmts;
|
||||||
|
let mut i = 0;
|
||||||
|
while i < stmts.len() {
|
||||||
|
let a = &mut stmts[i];
|
||||||
|
if let StmtKind::Loop(body) = &mut a.kind {
|
||||||
|
pass_cancel_left_right_add_sub(body);
|
||||||
|
}
|
||||||
|
|
||||||
|
if i >= stmts.len() - 1 {
|
||||||
|
break; // we are the last element
|
||||||
|
}
|
||||||
|
|
||||||
|
let a = &stmts[i];
|
||||||
|
let b = &stmts[i + 1];
|
||||||
|
|
||||||
|
match (a.kind(), b.kind()) {
|
||||||
|
(StmtKind::Right(r), StmtKind::Left(l)) | (StmtKind::Left(l), StmtKind::Right(r)) => {
|
||||||
|
let new = match r.cmp(l) {
|
||||||
|
Ordering::Equal => {
|
||||||
|
// remove both
|
||||||
|
stmts.remove(i + 1);
|
||||||
|
stmts.remove(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Ordering::Less => StmtKind::Left(l - r),
|
||||||
|
Ordering::Greater => StmtKind::Right(r - l),
|
||||||
|
};
|
||||||
|
|
||||||
|
let span = a.span.merge(b.span);
|
||||||
|
stmts.remove(i + 1);
|
||||||
|
stmts[i] = Stmt::new(new, span);
|
||||||
|
// don't increment i, maybe the next one matches as well (<><)
|
||||||
|
}
|
||||||
|
(StmtKind::Add(r), StmtKind::Sub(l)) | (StmtKind::Sub(l), StmtKind::Add(r)) => {
|
||||||
|
let new = match r.cmp(l) {
|
||||||
|
Ordering::Equal => {
|
||||||
|
// remove both
|
||||||
|
stmts.remove(i + 1);
|
||||||
|
stmts.remove(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Ordering::Less => StmtKind::Sub(l - r),
|
||||||
|
Ordering::Greater => StmtKind::Add(r - l),
|
||||||
|
};
|
||||||
|
|
||||||
|
let span = a.span.merge(b.span);
|
||||||
|
stmts.remove(i + 1);
|
||||||
|
stmts[i] = Stmt::new(new, span);
|
||||||
|
// don't increment i, maybe the next one matches as well (<><)
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
++++++++++[>[-]++++++++++++++++++[>[-]+++++++++[-]<-]<-]
|
<<<>>>>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue