bench setup that works

This commit is contained in:
nora 2022-04-12 21:20:16 +02:00
parent 7b88c99039
commit e82b14b09a
11 changed files with 302 additions and 19 deletions

View file

@ -6,14 +6,27 @@ const MEM_SIZE: usize = 32_000;
type Memory = [Wrapping<u8>; MEM_SIZE];
pub fn run(instrs: &[Stmt<'_>]) {
pub fn run<W, R>(instrs: &[Stmt<'_>], mut stdout: W, mut stdin: R)
where
W: Write,
R: Read,
{
let mut mem = [Wrapping(0u8); MEM_SIZE];
let mut ptr = 0;
execute(&mut mem, &mut ptr, instrs);
execute(&mut mem, &mut ptr, instrs, &mut stdout, &mut stdin);
}
fn execute(mem: &mut Memory, ptr: &mut usize, instrs: &[Stmt<'_>]) {
fn execute<W, R>(
mem: &mut Memory,
ptr: &mut usize,
instrs: &[Stmt<'_>],
stdout: &mut W,
stdin: &mut R,
) where
W: Write,
R: Read,
{
for instr in instrs {
match instr {
Stmt::Add(n) => {
@ -38,17 +51,17 @@ fn execute(mem: &mut Memory, ptr: &mut usize, instrs: &[Stmt<'_>]) {
}
Stmt::Out => {
let char = mem[*ptr].0 as char;
print!("{char}");
std::io::stdout().flush().unwrap();
write!(stdout, "{char}").unwrap();
stdout.flush().unwrap();
}
Stmt::In => {
let mut buf = [0; 1];
std::io::stdin().read_exact(&mut buf).unwrap();
stdin.read_exact(&mut buf).unwrap();
mem[*ptr] = Wrapping(buf[0]);
}
Stmt::Loop(body) => {
while mem[*ptr] != Wrapping(0) {
execute(mem, ptr, body);
execute(mem, ptr, body, stdout, stdin);
}
}
Stmt::SetNull => {

View file

@ -1,3 +1,6 @@
#![feature(allocator_api, let_else)]
#![warn(rust_2018_idioms)]
pub mod ir_interpreter;
pub mod opts;
pub mod parse;

View file

@ -2,7 +2,7 @@
#![warn(rust_2018_idioms)]
use bumpalo::Bump;
use std::{env, fs, process};
use std::{env, fs, io, process};
use brainfuck::{ir_interpreter, opts, parse};
@ -31,5 +31,10 @@ fn main() {
drop(parsed);
drop(ast_alloc);
ir_interpreter::run(&optimized_ir);
let stdout = io::stdout();
let stdout = stdout.lock();
let stdin = io::stdin();
let stdin = stdin.lock();
ir_interpreter::run(&optimized_ir, stdout, stdin);
}

View file

@ -72,8 +72,9 @@ fn pass_find_set_null(ir: &mut Ir<'_>) {
for stmt in ir {
if let Stmt::Loop(body) = stmt {
if let [Stmt::Sub(_)] = body.as_slice() {
println!("REPLACE");
*stmt = Stmt::SetNull;
} else {
pass_find_set_null(body);
}
}
}