Instantly share code, notes, and snippets.

@jdp /bf2c.py
Created Mar 29, 2012

Embed
What would you like to do?
Naive brainfuck-to-C compiler
#!/usr/bin/env python
import argparse
import sys
def tokenize(source):
return list(source)
def parse(tokens):
depth = 0
ast = []
stack = [ast]
node = ast
for token in tokens:
if token == '[':
node.append([])
stack.append(node)
node = node[-1]
depth += 1
elif token == ']':
node = stack.pop()
depth -= 1
elif token in "+-<>,.":
node.append(token)
if not depth == 0:
raise SyntaxError("Unmatched opening bracket")
return ast
def compile_to_c(tree):
buf = ""
for node in tree:
if isinstance(node, list):
buf += "while (*p) { "
buf += compile_to_c(node)
buf += "} "
elif node == '+':
buf += "++*p; "
elif node == '-':
buf += "--*p; "
elif node == '>':
buf += "++p; "
elif node == '<':
buf += "--p; "
elif node == ",":
buf += "*p = getchar(); "
elif node == ".":
buf += "putchar(*p); "
return buf
if __name__ == '__main__':
ap = argparse.ArgumentParser(description="Transpile a Brainfuck program to a different host language")
ap.add_argument('infile', nargs='?', type=argparse.FileType('r'), \
default='-', help="File to read source from, defaults to stdin")
ap.add_argument('-t', '--target', action='store', type=str, \
choices=set(['c']), default='c', help="Output language to target")
args = ap.parse_args()
code = args.infile.read()
tokens = tokenize(code)
ast = parse(tokens)
if args.target == 'c':
print "#include <stdio.h>"
print "#include <stdlib.h>"
print "int main(int argc, char **argv) {"
print " int *p = (int *)malloc(30000 * sizeof(int));"
print " ", compile_to_c(ast)
print " return 0;"
print "}"
>+++++++++
[<++++++++>-]
<.>+++++++
[<++++>-]
<+.+++++++..+++.>>>++++++++
[<++++>-]
<.>>>++++++++++
[<+++++++++>-]
<---.<<<<.+++.------.--------.>>+.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {
int *p = (int *)malloc(30000 * sizeof(int));
++p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
while (*p) {
--p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++p;
--*p;
}
--p;
putchar(*p);
++p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
while (*p) {
--p;
++*p;
++*p;
++*p;
++*p;
++p;
--*p;
}
--p;
++*p;
putchar(*p);
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
putchar(*p);
putchar(*p);
++*p;
++*p;
++*p;
putchar(*p);
++p;
++p;
++p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
while (*p) {
--p;
++*p;
++*p;
++*p;
++*p;
++p;
--*p;
}
--p;
putchar(*p);
++p;
++p;
++p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
while (*p) {
--p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++*p;
++p;
--*p;
}
--p;
--*p;
--*p;
--*p;
putchar(*p);
--p;
--p;
--p;
--p;
putchar(*p);
++*p;
++*p;
++*p;
putchar(*p);
--*p;
--*p;
--*p;
--*p;
--*p;
--*p;
putchar(*p);
--*p;
--*p;
--*p;
--*p;
--*p;
--*p;
--*p;
--*p;
putchar(*p);
++p;
++p;
++*p;
putchar(*p);
return 0;
}
@augustohp

This comment has been minimized.

Show comment
Hide comment
@keyle

This comment has been minimized.

Show comment
Hide comment
@keyle

keyle Jul 23, 2014

Thanks for your article Justin.

keyle commented Jul 23, 2014

Thanks for your article Justin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment