-
Notifications
You must be signed in to change notification settings - Fork 27
/
Copy pathbrainfuck.rs
74 lines (72 loc) · 2.47 KB
/
brainfuck.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#![feature(custom_attribute)]
#![feature(unboxed_closures)]
#[macro_use] extern crate holyjit_lib as hj;
jit!{ fn eval(jc: hj::JitContext, program: String) -> Result<(), ()> = eval_impl in jc; }
fn eval_impl(_jc: hj::JitContext, program: String) -> Result<(), ()> {
let prog = program.as_bytes();
let mut pc : usize = 0;
let mut ptr : usize = 0;
let mut mem : Vec<u8> = Vec::with_capacity(256);
mem.resize(256, 0);
loop {
if pc >= prog.len() {
return Ok(());
}
match prog[pc] {
b'>' => {
ptr += 1;
if ptr >= mem.len() {
mem.push(0);
}
}
b'<' => { ptr = ptr.saturating_sub(1); }
b'-' => { mem[ptr] = mem[ptr].wrapping_sub(1); }
b'+' => { mem[ptr] = mem[ptr].wrapping_add(1); }
b'.' => { panic!("putchar: NYI"); }
b',' => { panic!("getchar: NYI"); }
b'[' => {
if mem[ptr] == 0 {
let mut iter = (pc + 1, 0);
loop {
iter = match (iter, prog[iter.0]) {
((p, 0), b']') => {
pc = p + 1;
break;
},
((p, d), b'[') => (p + 1, d + 1),
((p, d), b']') => (p + 1, d - 1),
((p, d), _) => (p + 1, d)
}
}
continue; // skip pc increment
}
}
b']' => {
let mut iter = (pc - 1, 0);
loop {
iter = match (iter, prog[iter.0]) {
((p, 0), b'[') => {
pc = p;
break;
},
((p, d), b'[') => (p - 1, d + 1),
((p, d), b']') => (p - 1, d - 1),
((p, d), _) => (p - 1, d)
}
}
continue; // skip pc increment
}
_ => { panic!("Unknown Symbol"); }
}
pc += 1;
}
}
fn main() {
let prog = "++";
// Run without the Jit.
let jc : hj::JitContext = Default::default();
eval_impl(jc, prog.into()).unwrap();
// Run with the Jit.
let jc : hj::JitContext = Default::default();
eval(jc, prog.into()).unwrap();
}