BrainFuck compiler using Rust proc macro
More precisely, the BrainFuck-to-Rust transpiler using Rust proc macro
Examples:
- Runs on
into
called (usinginto
method to obtain(pc: usize, mem: Vec<u8>)
)let (pc, mem) = brain_fuck!( ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>. >---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. ).into(); println!("{:?}", (pc, mem));
- Runs on
env
called (env
method setspc
andmem
for the block) (env
method also returns(pc: usize, mem: Vec<u8>)
)let mut pc = 0; let mut mem = vec![72, 101, 108, 108, 79, 119, 104, 97, 116, 65, 115, 10, 0]; let (pc, mem) = brain_fuck!( [.>] ).env(pc, mem); println!("{:?}", (pc, mem));
- Runs on drop
brain_fuck!( ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>. >---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++. );
Explaination
The brainfuck code
brainfuck!(
++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[
-<<<[
->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<
]>.>+[>>]>+
]
)
will be transpiled to the following rust code
::bflib::BrainfuckBlock::new(&|pc: &mut usize, mem: &mut Vec<u8>| {
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(8);
while mem[*pc] != 0 {
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(1);
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(4);
if *pc < 2 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 2;
}
mem[*pc] = mem[*pc].wrapping_sub(1);
}
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(2);
*pc += 2;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(1);
if *pc < 1 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 1;
}
while mem[*pc] != 0 {
mem[*pc] = mem[*pc].wrapping_sub(1);
while mem[*pc] != 0 {
*pc += 2;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(1);
if *pc < 2 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 2;
}
mem[*pc] = mem[*pc].wrapping_sub(1);
}
mem[*pc] = mem[*pc].wrapping_add(1);
*pc += 2;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
}
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(1);
while mem[*pc] != 0 {
mem[*pc] = mem[*pc].wrapping_sub(1);
if *pc < 3 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 3;
}
while mem[*pc] != 0 {
mem[*pc] = mem[*pc].wrapping_sub(1);
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
while mem[*pc] != 0 {
mem[*pc] = mem[*pc].wrapping_add(1);
while mem[*pc] != 0 {
mem[*pc] = mem[*pc].wrapping_sub(1);
}
mem[*pc] = mem[*pc].wrapping_add(1);
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(2);
*pc += 3;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_sub(1);
if *pc < 2 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 2;
}
}
if *pc < 1 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 1;
}
while mem[*pc] != 0 {
if *pc < 1 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 1;
}
}
*pc += 2;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(6);
while mem[*pc] != 0 {
if *pc < 2 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 2;
}
mem[*pc] = mem[*pc].wrapping_add(5);
*pc += 2;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_sub(1);
}
mem[*pc] = mem[*pc].wrapping_add(1);
if *pc < 2 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 2;
}
mem[*pc] = mem[*pc].wrapping_add(2);
print!("{}", mem[*pc] as char);
while mem[*pc] != 0 {
mem[*pc] = mem[*pc].wrapping_sub(1);
}
if *pc < 2 {
panic!("BrainFuck Program Counter reduced to below zero !!!");
} else {
*pc -= 2;
}
}
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
print!("{}", mem[*pc] as char);
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(1);
while mem[*pc] != 0 {
*pc += 2;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
}
*pc += 1;
if mem.len() <= *pc {
mem.append(&mut vec![0; *pc - mem.len() + 1]);
}
mem[*pc] = mem[*pc].wrapping_add(1);
}
});