mirror of
https://github.com/Noratrieb/brainfuck.git
synced 2026-01-15 13:55:02 +01:00
interactive brainfuck repl
This commit is contained in:
parent
5cc058267b
commit
c17bea08e0
7 changed files with 168 additions and 43 deletions
|
|
@ -0,0 +1,111 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
use std::fmt;
|
||||
use std::io::{stdin, stdout, Write};
|
||||
use crate::interpreter::{minify, parse, parsed, Memory, MEM_SIZE};
|
||||
use crate::interpreter::optimized::PrintMode;
|
||||
|
||||
pub struct BrainfuckState {
|
||||
pub memory: Memory,
|
||||
pub pointer: usize,
|
||||
}
|
||||
|
||||
impl Display for BrainfuckState {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "{}", display_state(self))
|
||||
}
|
||||
}
|
||||
|
||||
fn display_state(state: &BrainfuckState) -> String {
|
||||
let start = if state.pointer < 5 {
|
||||
0
|
||||
} else if state.pointer > MEM_SIZE - 10 {
|
||||
MEM_SIZE - 10
|
||||
} else {
|
||||
state.pointer - 5
|
||||
};
|
||||
|
||||
format!("{}-\n|{}|\n{}-\n{}|\n{}|\n{}|\n{}-\n {}^^^^",
|
||||
"----------".repeat(10),
|
||||
{
|
||||
let mut out = String::new();
|
||||
let end = start + 10;
|
||||
for i in start..end {
|
||||
out.push_str(&*format!(" {: >5} ", i));
|
||||
}
|
||||
out
|
||||
},
|
||||
"----------".repeat(10),
|
||||
"| ".repeat(10),
|
||||
{
|
||||
let mut out = String::new();
|
||||
let end = start + 10;
|
||||
for i in start..end {
|
||||
out.push_str(&*format!("| {: >3} ", state.memory[i]));
|
||||
}
|
||||
out
|
||||
},
|
||||
"| ".repeat(10),
|
||||
"----------".repeat(10),
|
||||
" ".repeat(state.pointer - start))
|
||||
}
|
||||
|
||||
pub fn start_repl() {
|
||||
println!("Brainfuck REPL");
|
||||
|
||||
let mut state = BrainfuckState {
|
||||
memory: [0; MEM_SIZE],
|
||||
pointer: 0,
|
||||
};
|
||||
|
||||
println!("Enter Brainfuck programs and they will be executed immediatly.");
|
||||
println!("State is kept.");
|
||||
println!("{}", state);
|
||||
loop {
|
||||
print!(">> ");
|
||||
stdout().flush().unwrap();
|
||||
match read_line() {
|
||||
Ok(s) => {
|
||||
match &*s {
|
||||
":q" => break,
|
||||
":?" | "help" | "?" => print_help(),
|
||||
":r" => {
|
||||
reset(&mut state);
|
||||
println!("{}", state);
|
||||
},
|
||||
_ => {
|
||||
print!("Output: ");
|
||||
println!();
|
||||
parse_input(s, &mut state);
|
||||
println!("{}", state);
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(why) => println!("Error reading input: {}\nPlease try again.", why)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(state: &mut BrainfuckState) {
|
||||
state.pointer = 0;
|
||||
state.memory = [0; MEM_SIZE];
|
||||
}
|
||||
|
||||
fn print_help() {
|
||||
println!("Brainfuck REPL help
|
||||
:q => quit
|
||||
:? => help
|
||||
:r => reset state");
|
||||
}
|
||||
|
||||
fn parse_input(pgm: String, state: &mut BrainfuckState) {
|
||||
let pgm = minify(&*pgm);
|
||||
let pgm = parse(pgm.chars(), PrintMode::DirectPrint);
|
||||
parsed::interpret_with_state(&*pgm, state);
|
||||
}
|
||||
|
||||
pub fn read_line() -> Result<String, std::io::Error> {
|
||||
let mut buf = String::new();
|
||||
stdin().read_line(&mut buf)?;
|
||||
buf.pop();
|
||||
Ok(buf)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue