Skip to content

Instantly share code, notes, and snippets.

@geraldstanje
Forked from jdp/bf2c.py
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save geraldstanje/24a60bb6ee01eec0967e to your computer and use it in GitHub Desktop.
Save geraldstanje/24a60bb6ee01eec0967e to your computer and use it in GitHub Desktop.
#!/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;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment