Crate bflib

source ·
Expand description

BrainFuck compiler using Rust proc macro

More precisely, the BrainFuck-to-Rust transpiler using Rust proc macro

Examples:

  1. Hello World (run on dropping)
    brain_fuck!(
        ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.
        >---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
    );
  2. using into method to obtain (pc: usize, mem: Vec<u8>) after running (run on into calling)
    let (pc, mem) = brain_fuck!(
        ++++++++[>+>++++<<-]>++>>+<[-[>>+<<-]+>>]>+[
            -<<<[
                ->[+[-]+>++>>>-<<]<[<]>>++++++[<<+++++>>-]+<<++.[-]<<
            ]>.>+[>>]>+
        ]
    ).into();
    println!("{:?}", (pc, mem));
  3. use env method to set Program Counter pc and Memory mem for brainfuck codeblock (run on dropping)
    brain_fuck!(
        [.>]
    ).env(0, vec![79, 75, 10]);
  4. Altogether (run on into calling)
    let (pc, mem) = brain_fuck!(
        [.>]
    ).env(0, vec![72, 101, 108, 108, 79, 119, 104, 97, 116, 65, 115, 10]).into();
    println!("{:?}", (pc, mem));

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);
    }
})

Macros

Structs