Initial commit

This commit is contained in:
Sebastian Lohff 2022-01-03 16:19:37 +01:00
commit fdd2fa7361
4 changed files with 149 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
*.swp
*.swo

7
Cargo.lock generated Normal file
View File

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "brainfuck"
version = "0.1.0"

8
Cargo.toml Normal file
View File

@ -0,0 +1,8 @@
[package]
name = "brainfuck"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

131
src/main.rs Normal file
View File

@ -0,0 +1,131 @@
fn check_brainfuck(prog: &str) -> bool {
/*
let valid_bf_chars = "<>+-.,[]";
for (n, c) in prog.char_indices() {
if ! valid_bf_chars.contains(c) {
println!("Invalid character '{}' on pos {}", c, n);
}
}
*/
let mut brackets = 0;
let mut borked = false;
for (n, c) in prog.char_indices() {
match c {
'[' => brackets += 1,
']' => {
if brackets > 0 {
brackets -= 1;
} else {
println!("Closing bracket without matching opening bracket in pos {}", n);
borked = true;
}
},
'<' | '>' | '+' | '-' | '.' | ',' => (),
_ => {
println!("Invalid character '{}' on pos {}", c, n);
borked = true;
},
}
}
return ! borked;
}
fn run_brainfuck(prog: &str, debug: bool) {
println!("Running programm {}", prog);
let mut data = vec![];
data.push(0);
let mut data_ptr = 0;
let mut pc = 0;
loop {
let c = prog.chars().nth(pc).unwrap();
if debug {
println!("At pos {} char {} with data {} at {} (data {:?})", pc, c, data[data_ptr], data_ptr, data);
}
let mut inc_pc = true;
match c {
'+' => data[data_ptr] += 1,
'-' => data[data_ptr] -= 1,
'>' => {
data_ptr += 1;
if data_ptr == data.len() {
data.push(0)
}
},
'<' => {
if data_ptr > 0 {
data_ptr -= 1;
} else {
data.insert(0, 0);
}
},
'.' => print!("{}", std::char::from_u32(data[data_ptr]).unwrap()),
',' => println!("<input not implemented>"),
'[' => {
if data[data_ptr] == 0 {
let mut brackets = 0;
loop {
match prog.chars().nth(pc).unwrap() {
'[' => brackets += 1,
']' => {
brackets -= 1;
if brackets == 0 {
break;
}
},
_ => (),
}
pc += 1;
}
inc_pc = false;
if debug {
println!("Executed conditional [ jump to pos {}", pc);
}
}
},
']' => {
if data[data_ptr] != 0 {
let mut brackets = 1;
loop {
pc -= 1;
match prog.chars().nth(pc).unwrap() {
']' => brackets += 1,
'[' => {
brackets -= 1;
if brackets == 0 {
break;
}
},
_ => (),
}
}
if debug {
println!("Executed conditional ] jump to pos {}", pc + 1);
}
}
}
_ => (),
}
if inc_pc {
pc += 1
}
if pc == prog.len() {
break;
}
}
}
fn main() {
println!("Welcome to rust BF!");
//let prog = "xxx]]";
let prog = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.";
if ! check_brainfuck(prog) {
println!("Invalid program, aborting");
return;
}
run_brainfuck(prog, false);
}