mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-14 21:35:02 +01:00
things that don't work
This commit is contained in:
parent
04dd019806
commit
b8157f2ceb
11 changed files with 368 additions and 104 deletions
|
|
@ -1,6 +1,7 @@
|
|||
use std::fmt::{Debug, Formatter};
|
||||
|
||||
use bumpalo::Bump;
|
||||
use dbg_pls::DebugPls;
|
||||
|
||||
use crate::{
|
||||
parse::{Ast, Instr, Span},
|
||||
|
|
@ -16,7 +17,13 @@ pub struct Hir<'hir> {
|
|||
|
||||
impl Debug for Hir<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
self.stmts.fmt(f)
|
||||
Debug::fmt(&self.stmts, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl DebugPls for Hir<'_> {
|
||||
fn fmt(&self, f: dbg_pls::Formatter<'_>) {
|
||||
DebugPls::fmt(&self.stmts.iter().collect::<Vec<_>>(), f)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -38,11 +45,17 @@ impl<'hir> Stmt<'hir> {
|
|||
|
||||
impl Debug for Stmt<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
self.kind.fmt(f)
|
||||
Debug::fmt(&self.kind, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
impl DebugPls for Stmt<'_> {
|
||||
fn fmt(&self, f: dbg_pls::Formatter<'_>) {
|
||||
DebugPls::fmt(&self.kind, f)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, DebugPls)]
|
||||
pub enum StmtKind<'hir> {
|
||||
Add(i32, u8),
|
||||
Sub(i32, u8),
|
||||
|
|
|
|||
|
|
@ -15,11 +15,13 @@ pub fn optimize<'hir>(alloc: &'hir Bump, hir: &mut Hir<'hir>) {
|
|||
pass_cancel_left_right_add_sub(hir);
|
||||
pass_add_sub_offset(hir);
|
||||
pass_move_add_to(hir);
|
||||
// pass_unroll_loops(hir);
|
||||
// pass_cancel_left_right_add_sub(hir);
|
||||
}
|
||||
|
||||
/// pass that replaces things like `Sub(1) Sub(1)` with `Sub(2)`
|
||||
// TODO: This pass is really slow, speed it up please
|
||||
#[tracing::instrument]
|
||||
#[tracing::instrument(skip(alloc, ir_param))]
|
||||
fn pass_group<'hir>(alloc: &'hir Bump, ir_param: &mut Hir<'hir>) {
|
||||
let empty_ir = Hir {
|
||||
stmts: Vec::new_in(alloc),
|
||||
|
|
@ -85,8 +87,12 @@ fn pass_group<'hir>(alloc: &'hir Bump, ir_param: &mut Hir<'hir>) {
|
|||
}
|
||||
|
||||
/// pass that replaces `Loop([Sub(_)])` to `SetNull`
|
||||
#[tracing::instrument]
|
||||
#[tracing::instrument(skip(ir))]
|
||||
fn pass_find_set_null(ir: &mut Hir<'_>) {
|
||||
pass_find_set_null_inner(ir)
|
||||
}
|
||||
|
||||
fn pass_find_set_null_inner(ir: &mut Hir<'_>) {
|
||||
for stmt in &mut ir.stmts {
|
||||
if let Stmt {
|
||||
kind: StmtKind::Loop(body),
|
||||
|
|
@ -101,16 +107,19 @@ fn pass_find_set_null(ir: &mut Hir<'_>) {
|
|||
trace!(?span, "Replacing Statement with SetNull");
|
||||
*stmt = Stmt::new(StmtKind::SetN(0), *span);
|
||||
} else {
|
||||
pass_find_set_null(body);
|
||||
pass_find_set_null_inner(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// pass that replaces `SetN(n) Add(m)` with `SetN(n + m)`
|
||||
#[tracing::instrument]
|
||||
#[tracing::instrument(skip(ir))]
|
||||
fn pass_set_n(ir: &mut Hir<'_>) {
|
||||
window_pass(ir, pass_set_n, |[a, b]| {
|
||||
pass_set_n_inner(ir)
|
||||
}
|
||||
fn pass_set_n_inner(ir: &mut Hir<'_>) {
|
||||
window_pass(ir, pass_set_n_inner, |[a, b]| {
|
||||
if let StmtKind::SetN(before) = a.kind() {
|
||||
let new = match b.kind() {
|
||||
StmtKind::Add(0, n) => StmtKind::SetN(before.wrapping_add(*n)),
|
||||
|
|
@ -126,9 +135,13 @@ fn pass_set_n(ir: &mut Hir<'_>) {
|
|||
}
|
||||
|
||||
/// pass that replaces `Left(5) Right(3)` with `Left(2)`
|
||||
#[tracing::instrument]
|
||||
#[tracing::instrument(skip(ir))]
|
||||
fn pass_cancel_left_right_add_sub(ir: &mut Hir<'_>) {
|
||||
window_pass(ir, pass_cancel_left_right_add_sub, |[a, b]| {
|
||||
pass_cancel_left_right_add_sub_inner(ir)
|
||||
}
|
||||
|
||||
fn pass_cancel_left_right_add_sub_inner(ir: &mut Hir<'_>) {
|
||||
window_pass(ir, pass_cancel_left_right_add_sub_inner, |[a, b]| {
|
||||
match (a.kind(), b.kind()) {
|
||||
(StmtKind::Right(r), StmtKind::Left(l)) | (StmtKind::Left(l), StmtKind::Right(r)) => {
|
||||
let new = match r.cmp(l) {
|
||||
|
|
@ -159,9 +172,12 @@ fn pass_cancel_left_right_add_sub(ir: &mut Hir<'_>) {
|
|||
}
|
||||
|
||||
/// pass that replaces `Right(9) Add(5) Left(9)` with `AddOffset(9, 5)`
|
||||
#[tracing::instrument]
|
||||
#[tracing::instrument(skip(ir))]
|
||||
fn pass_add_sub_offset(ir: &mut Hir<'_>) {
|
||||
window_pass(ir, pass_add_sub_offset, |[a, b, c]| {
|
||||
pass_add_sub_offset_inner(ir)
|
||||
}
|
||||
fn pass_add_sub_offset_inner(ir: &mut Hir<'_>) {
|
||||
window_pass(ir, pass_add_sub_offset_inner, |[a, b, c]| {
|
||||
match (a.kind(), b.kind(), c.kind()) {
|
||||
(StmtKind::Right(r), StmtKind::Add(0, n), StmtKind::Left(l)) if r == l => {
|
||||
WindowPassAction::Merge(StmtKind::Add(i32::try_from(*r).unwrap(), *n))
|
||||
|
|
@ -181,8 +197,12 @@ fn pass_add_sub_offset(ir: &mut Hir<'_>) {
|
|||
}
|
||||
|
||||
/// pass that replaces `Loop([Sub(1) AddOffset(o, 1)])` with `MoveAddTo(o)`
|
||||
#[tracing::instrument]
|
||||
#[tracing::instrument(skip(ir))]
|
||||
fn pass_move_add_to(ir: &mut Hir<'_>) {
|
||||
pass_move_add_to_inner(ir)
|
||||
}
|
||||
|
||||
fn pass_move_add_to_inner(ir: &mut Hir<'_>) {
|
||||
for stmt in &mut ir.stmts {
|
||||
if let Stmt {
|
||||
kind: StmtKind::Loop(body),
|
||||
|
|
@ -207,22 +227,47 @@ fn pass_move_add_to(ir: &mut Hir<'_>) {
|
|||
trace!(?span, ?offset, "Replacing Statement with MoveAddTo");
|
||||
*stmt = Stmt::new(StmtKind::MoveAddTo { offset: *offset }, *span);
|
||||
} else {
|
||||
pass_move_add_to(body);
|
||||
pass_move_add_to_inner(body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum WindowPassAction<'hir> {
|
||||
#[tracing::instrument(skip(ir))]
|
||||
fn pass_unroll_loops(ir: &mut Hir<'_>) {
|
||||
let alloc = Bump::new();
|
||||
pass_unroll_loops_inner(&alloc, ir);
|
||||
}
|
||||
|
||||
fn pass_unroll_loops_inner(alloc: &Bump, ir: &mut Hir<'_>) {
|
||||
window_pass(ir, pass_unroll_loops, |[a, b]| {
|
||||
if let (StmtKind::SetN(n), StmtKind::Loop(body)) = (a.kind(), b.kind()) {
|
||||
let mut stmts_vec = BumpVec::new_in(alloc);
|
||||
|
||||
let stmts = std::iter::repeat(body.stmts.iter())
|
||||
.take(usize::from(*n))
|
||||
.flatten()
|
||||
.cloned();
|
||||
stmts_vec.extend(stmts);
|
||||
|
||||
WindowPassAction::MergeMany(stmts_vec)
|
||||
} else {
|
||||
WindowPassAction::None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
enum WindowPassAction<'hir, 'pass> {
|
||||
None,
|
||||
Merge(StmtKind<'hir>),
|
||||
MergeMany(BumpVec<'pass, Stmt<'hir>>),
|
||||
RemoveAll,
|
||||
}
|
||||
|
||||
fn window_pass<'hir, P, F, const N: usize>(ir: &mut Hir<'hir>, pass_recur: P, action: F)
|
||||
fn window_pass<'hir, 'pass, P, F, const N: usize>(ir: &mut Hir<'hir>, pass_recur: P, action: F)
|
||||
where
|
||||
P: Fn(&mut Hir<'hir>),
|
||||
F: Fn([&Stmt<'hir>; N]) -> WindowPassAction<'hir>,
|
||||
F: Fn([&Stmt<'hir>; N]) -> WindowPassAction<'hir, 'pass>,
|
||||
{
|
||||
assert!(N > 0);
|
||||
|
||||
|
|
@ -262,6 +307,15 @@ where
|
|||
}
|
||||
stmts[i] = Stmt::new(new, merged_span);
|
||||
}
|
||||
WindowPassAction::MergeMany(new) => {
|
||||
trace!(?elements, ?new, "Merging many");
|
||||
for _ in 0..N {
|
||||
stmts.remove(i);
|
||||
}
|
||||
for stmt in new.into_iter().rev() {
|
||||
stmts.insert(i, stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,8 +23,8 @@ pub mod parse;
|
|||
#[derive(clap::Parser, Default)]
|
||||
#[clap(author, about)]
|
||||
pub struct Args {
|
||||
/// Print colored source code depending on how often it was run.
|
||||
/// Makes the interpreter ~30% slower.
|
||||
/// Print colored source code depending on how often it was run.
|
||||
/// Makes the interpreter ~30% slower.
|
||||
#[clap(short, long)]
|
||||
pub profile: bool,
|
||||
/// Dump the IR info (ast, hir, mir, lir)
|
||||
|
|
@ -85,7 +85,7 @@ where
|
|||
let optimized_hir = hir::optimized_hir(&hir_alloc, &parsed);
|
||||
|
||||
if let Some(DumpKind::Hir) = config.dump {
|
||||
println!("{optimized_hir:#?}");
|
||||
println!("{}", dbg_pls::color(&optimized_hir));
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
use std::{cmp, fmt::Debug};
|
||||
use std::{
|
||||
cmp,
|
||||
fmt::{Debug, Formatter},
|
||||
};
|
||||
|
||||
use bumpalo::Bump;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Default)]
|
||||
pub struct Span {
|
||||
start: u32,
|
||||
len: u32,
|
||||
|
|
@ -62,6 +65,12 @@ impl Span {
|
|||
}
|
||||
}
|
||||
|
||||
impl Debug for Span {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
Debug::fmt(&(self.start..(self.start + self.len)), f)
|
||||
}
|
||||
}
|
||||
|
||||
pub type Ast<'ast> = Vec<(Instr<'ast>, Span), &'ast Bump>;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
|
|
|
|||
|
|
@ -1,95 +1,61 @@
|
|||
---
|
||||
source: src/parse.rs
|
||||
assertion_line: 164
|
||||
expression: instrs
|
||||
---
|
||||
Ok(
|
||||
[
|
||||
(
|
||||
Add,
|
||||
Span {
|
||||
start: 0,
|
||||
len: 1,
|
||||
},
|
||||
0..1,
|
||||
),
|
||||
(
|
||||
Loop(
|
||||
[
|
||||
(
|
||||
Sub,
|
||||
Span {
|
||||
start: 2,
|
||||
len: 1,
|
||||
},
|
||||
2..3,
|
||||
),
|
||||
(
|
||||
Loop(
|
||||
[
|
||||
(
|
||||
Sub,
|
||||
Span {
|
||||
start: 4,
|
||||
len: 1,
|
||||
},
|
||||
4..5,
|
||||
),
|
||||
(
|
||||
Loop(
|
||||
[
|
||||
(
|
||||
Sub,
|
||||
Span {
|
||||
start: 6,
|
||||
len: 1,
|
||||
},
|
||||
6..7,
|
||||
),
|
||||
],
|
||||
),
|
||||
Span {
|
||||
start: 5,
|
||||
len: 3,
|
||||
},
|
||||
5..8,
|
||||
),
|
||||
],
|
||||
),
|
||||
Span {
|
||||
start: 3,
|
||||
len: 6,
|
||||
},
|
||||
3..9,
|
||||
),
|
||||
(
|
||||
Add,
|
||||
Span {
|
||||
start: 9,
|
||||
len: 1,
|
||||
},
|
||||
9..10,
|
||||
),
|
||||
(
|
||||
Right,
|
||||
Span {
|
||||
start: 10,
|
||||
len: 1,
|
||||
},
|
||||
10..11,
|
||||
),
|
||||
(
|
||||
Right,
|
||||
Span {
|
||||
start: 11,
|
||||
len: 1,
|
||||
},
|
||||
11..12,
|
||||
),
|
||||
(
|
||||
Right,
|
||||
Span {
|
||||
start: 12,
|
||||
len: 1,
|
||||
},
|
||||
12..13,
|
||||
),
|
||||
],
|
||||
),
|
||||
Span {
|
||||
start: 1,
|
||||
len: 13,
|
||||
},
|
||||
1..14,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,68 +1,43 @@
|
|||
---
|
||||
source: src/parse.rs
|
||||
assertion_line: 155
|
||||
expression: instrs
|
||||
---
|
||||
Ok(
|
||||
[
|
||||
(
|
||||
Right,
|
||||
Span {
|
||||
start: 0,
|
||||
len: 1,
|
||||
},
|
||||
0..1,
|
||||
),
|
||||
(
|
||||
Add,
|
||||
Span {
|
||||
start: 1,
|
||||
len: 1,
|
||||
},
|
||||
1..2,
|
||||
),
|
||||
(
|
||||
Left,
|
||||
Span {
|
||||
start: 2,
|
||||
len: 1,
|
||||
},
|
||||
2..3,
|
||||
),
|
||||
(
|
||||
Add,
|
||||
Span {
|
||||
start: 3,
|
||||
len: 1,
|
||||
},
|
||||
3..4,
|
||||
),
|
||||
(
|
||||
Add,
|
||||
Span {
|
||||
start: 4,
|
||||
len: 1,
|
||||
},
|
||||
4..5,
|
||||
),
|
||||
(
|
||||
Loop(
|
||||
[
|
||||
(
|
||||
Sub,
|
||||
Span {
|
||||
start: 6,
|
||||
len: 1,
|
||||
},
|
||||
6..7,
|
||||
),
|
||||
],
|
||||
),
|
||||
Span {
|
||||
start: 5,
|
||||
len: 3,
|
||||
},
|
||||
5..8,
|
||||
),
|
||||
(
|
||||
Out,
|
||||
Span {
|
||||
start: 8,
|
||||
len: 1,
|
||||
},
|
||||
8..9,
|
||||
),
|
||||
],
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue