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