mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-14 13:35:00 +01:00
remove naive interpreter
This commit is contained in:
parent
2d854539aa
commit
66bd69e674
5 changed files with 73 additions and 28 deletions
16
rust2/Cargo.lock
generated
16
rust2/Cargo.lock
generated
|
|
@ -8,6 +8,14 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brainfuck"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bumpalo",
|
||||||
|
"insta",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.9.1"
|
version = "3.9.1"
|
||||||
|
|
@ -105,14 +113,6 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "rust2"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"bumpalo",
|
|
||||||
"insta",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.9"
|
version = "1.0.9"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[package]
|
[package]
|
||||||
name = "rust2"
|
name = "brainfuck"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::parse::Instr;
|
use crate::opts::IrInstr;
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::num::Wrapping;
|
use std::num::Wrapping;
|
||||||
|
|
||||||
|
|
@ -6,50 +6,54 @@ const MEM_SIZE: usize = 32_000;
|
||||||
|
|
||||||
type Memory = [Wrapping<u8>; MEM_SIZE];
|
type Memory = [Wrapping<u8>; MEM_SIZE];
|
||||||
|
|
||||||
pub fn run(instrs: &[Instr<'_>]) {
|
pub fn run(instrs: &[IrInstr<'_>]) {
|
||||||
let mut mem = [Wrapping(0u8); MEM_SIZE];
|
let mut mem = [Wrapping(0u8); MEM_SIZE];
|
||||||
let mut ptr = 0;
|
let mut ptr = 0;
|
||||||
|
|
||||||
execute(&mut mem, &mut ptr, instrs);
|
execute(&mut mem, &mut ptr, instrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn execute(mem: &mut Memory, ptr: &mut usize, instrs: &[Instr<'_>]) {
|
fn execute(mem: &mut Memory, ptr: &mut usize, instrs: &[IrInstr<'_>]) {
|
||||||
for instr in instrs {
|
for instr in instrs {
|
||||||
match instr {
|
match instr {
|
||||||
Instr::Add => {
|
IrInstr::Add(n) => {
|
||||||
mem[*ptr] += 1;
|
mem[*ptr] += n;
|
||||||
}
|
}
|
||||||
Instr::Sub => {
|
IrInstr::Sub(n) => {
|
||||||
mem[*ptr] -= 1;
|
mem[*ptr] -= n;
|
||||||
}
|
}
|
||||||
Instr::Right => {
|
IrInstr::Right(n) => {
|
||||||
*ptr += 1;
|
*ptr += n;
|
||||||
if *ptr >= MEM_SIZE {
|
if *ptr >= MEM_SIZE {
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::Left => {
|
IrInstr::Left(n) => {
|
||||||
if *ptr == 0 {
|
if *ptr < *n {
|
||||||
*ptr = MEM_SIZE - 1;
|
let diff = *n - *ptr;
|
||||||
|
*ptr = MEM_SIZE - 1 - diff;
|
||||||
} else {
|
} else {
|
||||||
*ptr -= 1;
|
*ptr -= n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Instr::Out => {
|
IrInstr::Out => {
|
||||||
let char = mem[*ptr].0 as char;
|
let char = mem[*ptr].0 as char;
|
||||||
print!("{char}",);
|
print!("{char}");
|
||||||
std::io::stdout().flush().unwrap();
|
std::io::stdout().flush().unwrap();
|
||||||
}
|
}
|
||||||
Instr::In => {
|
IrInstr::In => {
|
||||||
let mut buf = [0; 1];
|
let mut buf = [0; 1];
|
||||||
std::io::stdin().read_exact(&mut buf).unwrap();
|
std::io::stdin().read_exact(&mut buf).unwrap();
|
||||||
mem[*ptr] = Wrapping(buf[0]);
|
mem[*ptr] = Wrapping(buf[0]);
|
||||||
}
|
}
|
||||||
Instr::Loop(body) => {
|
IrInstr::Loop(body) => {
|
||||||
while mem[*ptr] != Wrapping(0) {
|
while mem[*ptr] != Wrapping(0) {
|
||||||
execute(mem, ptr, body);
|
execute(mem, ptr, body);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
IrInstr::SetNull => {
|
||||||
|
mem[*ptr] = Wrapping(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,7 +4,8 @@
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
use std::{env, fs, process};
|
use std::{env, fs, process};
|
||||||
|
|
||||||
mod naive_interpreter;
|
mod ir_interpreter;
|
||||||
|
mod opts;
|
||||||
mod parse;
|
mod parse;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
@ -25,5 +26,12 @@ fn main() {
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
naive_interpreter::run(&parsed);
|
let ir_alloc = Bump::new();
|
||||||
|
|
||||||
|
let optimized_ir = opts::optimize(&ir_alloc, &parsed);
|
||||||
|
|
||||||
|
drop(parsed);
|
||||||
|
drop(ast_alloc);
|
||||||
|
|
||||||
|
ir_interpreter::run(&optimized_ir);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
33
rust2/src/opts.rs
Normal file
33
rust2/src/opts.rs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
use crate::parse::Instr;
|
||||||
|
use bumpalo::Bump;
|
||||||
|
|
||||||
|
pub type Ir<'ir> = Vec<IrInstr<'ir>, &'ir Bump>;
|
||||||
|
|
||||||
|
pub enum IrInstr<'ir> {
|
||||||
|
Add(u8),
|
||||||
|
Sub(u8),
|
||||||
|
Right(usize),
|
||||||
|
Left(usize),
|
||||||
|
Loop(Ir<'ir>),
|
||||||
|
Out,
|
||||||
|
In,
|
||||||
|
SetNull,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn optimize<'ir>(alloc: &'ir Bump, instrs: &[Instr<'_>]) -> Ir<'ir> {
|
||||||
|
ast_to_ir(alloc, instrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn ast_to_ir<'ir>(alloc: &'ir Bump, ast: &[Instr<'_>]) -> Ir<'ir> {
|
||||||
|
let mut vec = Vec::new_in(alloc);
|
||||||
|
vec.extend(ast.iter().map(|instr| match instr {
|
||||||
|
Instr::Add => IrInstr::Add(1),
|
||||||
|
Instr::Sub => IrInstr::Sub(1),
|
||||||
|
Instr::Right => IrInstr::Right(1),
|
||||||
|
Instr::Left => IrInstr::Left(1),
|
||||||
|
Instr::Out => IrInstr::Out,
|
||||||
|
Instr::In => IrInstr::In,
|
||||||
|
Instr::Loop(body) => IrInstr::Loop(ast_to_ir(alloc, body)),
|
||||||
|
}));
|
||||||
|
vec
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue