Skip to content

Instantly share code, notes, and snippets.

@sfan5
Created August 31, 2014 15:05
Show Gist options
  • Save sfan5/eb434fbbee83d8b7ddad to your computer and use it in GitHub Desktop.
Save sfan5/eb434fbbee83d8b7ddad to your computer and use it in GitHub Desktop.
Compiles Brainfuck to C || Warning: This not the best code I have written.
#!/usr/bin/env python2
import sys
def multstr(n,st):
o = ""
for i in range(0,n):
o += st
return o
def unpack_opts(s, t):
s = s.split(" ")
o = {}
for opt in s:
if opt[0] != "-":
raise Exception("Option does not start with a -")
if opt[1:] in t:
o[t[opt[1:]]] = True
return o
def sopen(p, m='r'):
return [open(p, m), 0]
def sread(f, n, unsafe=False):
b = f[0].read(n)
if len(b) < n and not unsafe:
b += " " * (n - len(b))
f[1] += (n - len(b))
return b
def sseek(f, n):
if f[1] > 0:
n -= f[1]
f[1] = 0
f[0].seek(n, 1)
def sclose(f):
f[0].close()
options = {
'O': 'optimize',
}
default_opts = {
'optimize': False,
}
tabchar = "\t"
tapesize = 16384
if len(sys.argv) <= 2:
print("Usage: %s <input> <output> [options]" % sys.argv[0])
print("Valid options:")
print("\t-O\t\tEnable optimization")
else:
if len(sys.argv) > 3:
opts = unpack_opts(sys.argv[3], options)
else:
opts = default_opts
fi = sopen(sys.argv[1])
fi2 = open(sys.argv[2], 'w')
fi2.write('#include <stdio.h>\n#include <stdlib.h>\n#include <inttypes.h>\n\nuint8_t* ptr;\n\n')
fi2.write('int main(void)\n{\n%sptr = malloc(%d * sizeof(uint8_t));\n%sif(!ptr)\n%s%sabort();\n' % (tabchar, tapesize, tabchar, tabchar, tabchar))
s = " "
ind = 1
while s != "":
s = sread(fi, 1, True)
if s == "+":
if opts['optimize'] and sread(fi, 1) == "+": # apply optimisation if possible
n = 1 # actually 2, will be incremented in while loop
b = '+'
while b == "+":
n += 1
b = sread(fi, 1)
sseek(fi, -1) # undo last read
fi2.write(multstr(ind, tabchar) + "*ptr += " + str(n) + ";\n")
continue
else:
if opts['optimize']: sseek(fi, -1) # undo read
fi2.write(multstr(ind, tabchar) + "++*ptr;\n")
elif s == "-":
if opts['optimize'] and sread(fi, 1) == "-": # apply optimisation if possible
n = 1 # actually 2, will be incremented in while loop
b = '-'
while b == "-":
n += 1
b = sread(fi, 1)
sseek(fi, -1) # undo last read
fi2.write(multstr(ind, tabchar) + "*ptr -= " + str(n) + ";\n")
continue
else:
if opts['optimize']: sseek(fi, -1) # undo read
fi2.write(multstr(ind, tabchar) + "--*ptr;\n")
elif s == ">":
if opts['optimize'] and sread(fi, 1) == ">": # apply optimisation if possible
n = 1 # actually 2, will be incremented in while loop
b = '>'
while b == ">":
n += 1
b = sread(fi, 1)
sseek(fi, -1) # undo last read
fi2.write(multstr(ind, tabchar) + "ptr += " + str(n) + ";\n")
continue
else:
if opts['optimize']: sseek(fi, -1) # undo read
fi2.write(multstr(ind, tabchar) + "++ptr;\n")
elif s == "<":
if opts['optimize'] and sread(fi, 1) == "<": # apply optimisation if possible
n = 1 # actually 2, will be incremented in while loop
b = '<'
while b == "<":
n += 1
b = sread(fi, 1)
sseek(fi, -1) # undo last read
fi2.write(multstr(ind, tabchar) + "ptr -= " + str(n) + ";\n")
continue
else:
if opts['optimize']: sseek(fi, -1) # undo read
fi2.write(multstr(ind, tabchar) + "--ptr;\n")
elif s == ".":
fi2.write(multstr(ind, tabchar) + "putchar(*ptr);\n")
elif s == ",":
fi2.write(multstr(ind, tabchar) + "*ptr = getchar();\n")
elif s == "[":
if opts['optimize'] and sread(fi, 1) == "-": # apply optimisation if possible
if sread(fi, 1) == "]":
fi2.write(multstr(ind, tabchar) + "*ptr = 0;\n")
continue
else:
sseek(fi, -2) # undo reads
else:
if opts['optimize']: sseek(fi, -1) # undo read
fi2.write(multstr(ind, tabchar) + "while(*ptr) {\n")
ind += 1
elif s == "]":
ind -= 1
fi2.write(multstr(ind, tabchar) + "}\n")
sclose(fi)
fi2.write('\n%sreturn 0;\n}\n' % tabchar)
fi2.close()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment