You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.9 KiB
132 lines
3.9 KiB
2 years ago
|
|
||
|
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);
|
||
|
}
|