Initial commit
This commit is contained in:
commit
fdd2fa7361
|
@ -0,0 +1,3 @@
|
|||
/target
|
||||
*.swp
|
||||
*.swo
|
|
@ -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"
|
|
@ -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]
|
|
@ -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);
|
||||
}
|
Loading…
Reference in New Issue