remove naive interpreter

This commit is contained in:
nora 2022-04-12 20:21:54 +02:00
parent 2d854539aa
commit 66bd69e674
5 changed files with 73 additions and 28 deletions

16
rust2/Cargo.lock generated
View file

@ -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"

View file

@ -1,5 +1,5 @@
[package] [package]
name = "rust2" name = "brainfuck"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"

View file

@ -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);
}
} }
} }
} }

View file

@ -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
View 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
}