init repo
This commit is contained in:
commit
c547d90d0b
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
/Cargo.lock
|
|
@ -0,0 +1,8 @@
|
||||||
|
[package]
|
||||||
|
name = "brainrust"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
|
@ -0,0 +1,16 @@
|
||||||
|
use brainrust::*;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let eval = eval(
|
||||||
|
&(
|
||||||
|
"+++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if eval.is_err() {
|
||||||
|
let err = eval.unwrap_err();
|
||||||
|
if err == "Stdin closed" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
eprintln!("Program failed: {}", err);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,94 @@
|
||||||
|
#![forbid(unsafe_code)]
|
||||||
|
|
||||||
|
use std::io::{stdout, Write, Read, stdin};
|
||||||
|
|
||||||
|
// struct BrainFuckProgram {
|
||||||
|
// memory: [u8; 30000],
|
||||||
|
// pointer: usize,
|
||||||
|
// source: String
|
||||||
|
// }
|
||||||
|
|
||||||
|
pub fn eval_mem(bf_str: &&str, mem: &mut [u8], pointer: &mut usize) -> Result<(), String> {
|
||||||
|
|
||||||
|
let mut pos = 0 as usize;
|
||||||
|
let progsize = bf_str.len();
|
||||||
|
let chars = bf_str.chars().collect::<Vec<char>>();
|
||||||
|
|
||||||
|
let mut loop_stack: Vec<usize> = vec![];
|
||||||
|
|
||||||
|
loop {
|
||||||
|
if pos == progsize {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let char = chars[pos];
|
||||||
|
|
||||||
|
pos += 1;
|
||||||
|
|
||||||
|
if char == '>' {
|
||||||
|
*pointer += 1;
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if char == '<' {
|
||||||
|
*pointer -= 1;
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if char == '+' {
|
||||||
|
mem[*pointer] += 1;
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if char == '-' {
|
||||||
|
mem[*pointer] -= 1;
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if char == '.' {
|
||||||
|
print!("{}", mem[*pointer] as char);
|
||||||
|
stdout().flush().unwrap();
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if char == ',' {
|
||||||
|
let byte = stdin().bytes().next();
|
||||||
|
if byte.is_none() {
|
||||||
|
return Err("Stdin closed".into());
|
||||||
|
}
|
||||||
|
let byte = byte.unwrap();
|
||||||
|
if byte.is_err() {
|
||||||
|
return Err(byte.unwrap_err().to_string());
|
||||||
|
}
|
||||||
|
mem[*pointer] = byte.unwrap();
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if char == '[' {
|
||||||
|
loop_stack.push(pos);
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if char == ']' {
|
||||||
|
|
||||||
|
if loop_stack.len() == 0 {
|
||||||
|
return Err(format!("Invalid loop at position {pos}"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if mem[*pointer] == 0 {
|
||||||
|
loop_stack.pop();
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
pos = loop_stack.last().unwrap().clone();
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn eval(bf_str: &&str) -> Result<[u8; 30000], String> {
|
||||||
|
let mut memory: [u8; 30000] = core::array::from_fn(|_| 0);
|
||||||
|
let mut pointer = 0 as usize;
|
||||||
|
|
||||||
|
let e = eval_mem(bf_str, &mut memory, &mut pointer);
|
||||||
|
if e.is_err() {
|
||||||
|
return Err(e.unwrap_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(memory)
|
||||||
|
}
|
Loading…
Reference in New Issue