mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-14 13:35:00 +01:00
add opt that doesn't make anything faster but might allow better opts later
This commit is contained in:
parent
6575e09957
commit
c3c24c73fe
7 changed files with 59 additions and 24 deletions
|
|
@ -31,6 +31,7 @@ pub enum Stmt {
|
||||||
Out,
|
Out,
|
||||||
In,
|
In,
|
||||||
SetNull,
|
SetNull,
|
||||||
|
SetN(u8),
|
||||||
JmpIfZero(u32),
|
JmpIfZero(u32),
|
||||||
JmpIfNonZero(u32),
|
JmpIfNonZero(u32),
|
||||||
End,
|
End,
|
||||||
|
|
@ -84,6 +85,7 @@ fn ir_to_stmt<'c>(code: &mut Code<'c>, ir_stmt: &IrStmt<'_>) {
|
||||||
StmtKind::Out => Stmt::Out,
|
StmtKind::Out => Stmt::Out,
|
||||||
StmtKind::In => Stmt::In,
|
StmtKind::In => Stmt::In,
|
||||||
StmtKind::SetNull => Stmt::SetNull,
|
StmtKind::SetNull => Stmt::SetNull,
|
||||||
|
StmtKind::SetN(n) => Stmt::SetN(*n),
|
||||||
StmtKind::Loop(instr) => {
|
StmtKind::Loop(instr) => {
|
||||||
let skip_jmp_idx = code.stmts.len();
|
let skip_jmp_idx = code.stmts.len();
|
||||||
code.stmts.push(Stmt::JmpIfZero(0)); // placeholder
|
code.stmts.push(Stmt::JmpIfZero(0)); // placeholder
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,9 @@ where
|
||||||
Stmt::SetNull => {
|
Stmt::SetNull => {
|
||||||
*self.elem_mut() = Wrapping(0);
|
*self.elem_mut() = Wrapping(0);
|
||||||
}
|
}
|
||||||
|
Stmt::SetN(n) => {
|
||||||
|
*self.elem_mut() = Wrapping(n);
|
||||||
|
}
|
||||||
Stmt::JmpIfZero(pos) => {
|
Stmt::JmpIfZero(pos) => {
|
||||||
if self.elem() == 0 {
|
if self.elem() == 0 {
|
||||||
self.ip = pos as usize;
|
self.ip = pos as usize;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
#![feature(allocator_api, let_else)]
|
#![feature(allocator_api, let_else)]
|
||||||
#![deny(unsafe_op_in_unsafe_fn)]
|
#![deny(unsafe_op_in_unsafe_fn)]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use crate::parse::ParseError;
|
use crate::parse::ParseError;
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,12 @@ fn main() {
|
||||||
let stdin = io::stdin();
|
let stdin = io::stdin();
|
||||||
let stdin = stdin.lock();
|
let stdin = stdin.lock();
|
||||||
|
|
||||||
brainfuck::run(&file, stdout, stdin, UseProfile::Yes).unwrap_or_else(|_| {
|
let profile = env::args()
|
||||||
|
.any(|a| a == "--profile")
|
||||||
|
.then(|| UseProfile::Yes)
|
||||||
|
.unwrap_or(UseProfile::No);
|
||||||
|
|
||||||
|
brainfuck::run(&file, stdout, stdin, profile).unwrap_or_else(|_| {
|
||||||
eprintln!("error: Failed to parse brainfuck code");
|
eprintln!("error: Failed to parse brainfuck code");
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -14,11 +14,12 @@ pub struct Stmt<'ir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'ir> Stmt<'ir> {
|
impl<'ir> Stmt<'ir> {
|
||||||
fn lol(kind: StmtKind<'ir>) -> Stmt<'ir> {
|
fn new(kind: StmtKind<'ir>, span: Span) -> Stmt<'ir> {
|
||||||
Self {
|
Self { kind, span }
|
||||||
kind,
|
|
||||||
span: Span::default(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn kind(&self) -> &StmtKind<'ir> {
|
||||||
|
&self.kind
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,12 +33,14 @@ pub enum StmtKind<'ir> {
|
||||||
Out,
|
Out,
|
||||||
In,
|
In,
|
||||||
SetNull,
|
SetNull,
|
||||||
|
SetN(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn optimize<'ir>(alloc: &'ir Bump, instrs: &[(Instr<'_>, Span)]) -> Ir<'ir> {
|
pub fn optimize<'ir>(alloc: &'ir Bump, instrs: &[(Instr<'_>, Span)]) -> Ir<'ir> {
|
||||||
let ir = ast_to_ir(alloc, instrs);
|
let ir = ast_to_ir(alloc, instrs);
|
||||||
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);
|
||||||
ir
|
ir
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +60,7 @@ fn ast_to_ir<'ir>(alloc: &'ir Bump, ast: &[(Instr<'_>, Span)]) -> Ir<'ir> {
|
||||||
StmtKind::Loop(ir_body)
|
StmtKind::Loop(ir_body)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Stmt { kind, span: *span }
|
Stmt::new(kind, *span)
|
||||||
});
|
});
|
||||||
|
|
||||||
stmts.extend(stmts_iter);
|
stmts.extend(stmts_iter);
|
||||||
|
|
@ -65,6 +68,7 @@ fn ast_to_ir<'ir>(alloc: &'ir Bump, ast: &[(Instr<'_>, Span)]) -> Ir<'ir> {
|
||||||
Ir { stmts }
|
Ir { stmts }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// pass that replaces things like `Sub(1) Sub(1)` with `Sub(2)`
|
||||||
fn pass_group<'ir>(alloc: &'ir Bump, ir: Ir<'ir>) -> Ir<'ir> {
|
fn pass_group<'ir>(alloc: &'ir Bump, ir: Ir<'ir>) -> Ir<'ir> {
|
||||||
let new_stmts = Vec::new_in(alloc);
|
let new_stmts = Vec::new_in(alloc);
|
||||||
let stmts = ir
|
let stmts = ir
|
||||||
|
|
@ -74,10 +78,10 @@ fn pass_group<'ir>(alloc: &'ir Bump, ir: Ir<'ir>) -> Ir<'ir> {
|
||||||
let Some(old) = stmts.last_mut() else {
|
let Some(old) = stmts.last_mut() else {
|
||||||
if let StmtKind::Loop(body) = next.kind {
|
if let StmtKind::Loop(body) = next.kind {
|
||||||
let new_body = pass_group(alloc, body);
|
let new_body = pass_group(alloc, body);
|
||||||
stmts.push(Stmt {
|
stmts.push(Stmt::new(
|
||||||
span: next.span,
|
StmtKind::Loop(new_body),
|
||||||
kind: StmtKind::Loop(new_body),
|
next.span,
|
||||||
});
|
));
|
||||||
} else {
|
} else {
|
||||||
stmts.push(next);
|
stmts.push(next);
|
||||||
}
|
}
|
||||||
|
|
@ -109,10 +113,7 @@ fn pass_group<'ir>(alloc: &'ir Bump, ir: Ir<'ir>) -> Ir<'ir> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
(_, kind) => {
|
(_, kind) => {
|
||||||
stmts.push(Stmt {
|
stmts.push(Stmt::new(kind, next.span));
|
||||||
span: next.span,
|
|
||||||
kind,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -122,6 +123,7 @@ fn pass_group<'ir>(alloc: &'ir Bump, ir: Ir<'ir>) -> Ir<'ir> {
|
||||||
Ir { stmts }
|
Ir { stmts }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// pass that replaces `Loop([Sub(_)])` to `SetNull`
|
||||||
fn pass_find_set_null(ir: &mut Ir<'_>) {
|
fn pass_find_set_null(ir: &mut Ir<'_>) {
|
||||||
for stmt in &mut ir.stmts {
|
for stmt in &mut ir.stmts {
|
||||||
if let Stmt {
|
if let Stmt {
|
||||||
|
|
@ -131,13 +133,37 @@ fn pass_find_set_null(ir: &mut Ir<'_>) {
|
||||||
{
|
{
|
||||||
if let [Stmt {
|
if let [Stmt {
|
||||||
kind: StmtKind::Sub(_),
|
kind: StmtKind::Sub(_),
|
||||||
..
|
span,
|
||||||
}] = body.stmts.as_slice()
|
}] = body.stmts.as_slice()
|
||||||
{
|
{
|
||||||
*stmt = Stmt::lol(StmtKind::SetNull);
|
*stmt = Stmt::new(StmtKind::SetNull, *span);
|
||||||
} else {
|
} else {
|
||||||
pass_find_set_null(body);
|
pass_find_set_null(body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// pass that replaces `SetNull Add(5)` with `SetN(5)`
|
||||||
|
fn pass_set_n(ir: &mut Ir<'_>) {
|
||||||
|
let stmts = &mut ir.stmts;
|
||||||
|
let mut i = 0;
|
||||||
|
while i < stmts.len() - 1 {
|
||||||
|
let a = &stmts[i];
|
||||||
|
if let StmtKind::SetNull = a.kind() {
|
||||||
|
let b = &stmts[i + 1];
|
||||||
|
let new = match b.kind() {
|
||||||
|
StmtKind::Add(n) => StmtKind::SetN(*n),
|
||||||
|
StmtKind::Sub(n) => StmtKind::SetN(0u8.wrapping_sub(*n)),
|
||||||
|
_ => {
|
||||||
|
i += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let span = a.span.merge(b.span);
|
||||||
|
stmts.remove(i + 1);
|
||||||
|
stmts[i] = Stmt::new(new, span);
|
||||||
|
}
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: src/parse.rs
|
source: src/parse.rs
|
||||||
assertion_line: 132
|
assertion_line: 164
|
||||||
expression: instrs
|
expression: instrs
|
||||||
---
|
---
|
||||||
Ok(
|
Ok(
|
||||||
|
|
@ -46,14 +46,14 @@ Ok(
|
||||||
),
|
),
|
||||||
Span {
|
Span {
|
||||||
start: 5,
|
start: 5,
|
||||||
len: 2,
|
len: 3,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Span {
|
Span {
|
||||||
start: 3,
|
start: 3,
|
||||||
len: 5,
|
len: 6,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
@ -88,7 +88,7 @@ Ok(
|
||||||
),
|
),
|
||||||
Span {
|
Span {
|
||||||
start: 1,
|
start: 1,
|
||||||
len: 12,
|
len: 13,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
source: src/parse.rs
|
source: src/parse.rs
|
||||||
assertion_line: 123
|
assertion_line: 155
|
||||||
expression: instrs
|
expression: instrs
|
||||||
---
|
---
|
||||||
Ok(
|
Ok(
|
||||||
|
|
@ -54,7 +54,7 @@ Ok(
|
||||||
),
|
),
|
||||||
Span {
|
Span {
|
||||||
start: 5,
|
start: 5,
|
||||||
len: 2,
|
len: 3,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue