Skip to content

Instantly share code, notes, and snippets.

@Cairnarvon
Created October 4, 2012 01:30
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 Cairnarvon/3830982 to your computer and use it in GitHub Desktop.
Save Cairnarvon/3830982 to your computer and use it in GitHub Desktop.
The original Codan compiler (because Sprunge deletes old pastes).
#!/usr/bin/python2.5
# coding=utf8
"""
Copyright © 2010 Codan Working Group
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
"""
CC = "gcc"
import sys, os
if len(sys.argv) < 2:
print "\033[1mUsage:\033[0m %s" % sys.argv[0],\
"[ \033[4mCFLAGS\033[0m ... ] \033[4minfile\033[0m"
sys.exit(0)
f = open(sys.argv[-1])
codan = filter(lambda n: n in u"«»←→αβΑΒΛא+−×÷↑=≠<≤>≥≮≯≰≱0123456789\n\t ",
unicode("".join(f.readlines()), "utf8"))
f.close()
out = """
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <termios.h>
int main(void)
{
int mem[10000];
int alpha, beta, t;
"""
iomode = False # True = %c; False = %d
i = 0
try:
while i < len(codan):
while codan[i] in u" \n\t":
i += 1
if codan[i] == u'«': # Open loop
out += "for (;;) {\n"
i += 1
elif codan[i] == u'»': # Close loop
out += "}\n"
i += 1
elif codan[i] == u'א': # Output mode toggle
iomode = not iomode
i += 1
else: # Three-part expression
loperand, operator, roperand = None, None, None
# Read left operand
if codan[i] in u"0123456789":
s = i
while codan[i] in u"0123456789":
i += 1
loperand = codan[s:i]
elif codan[i] in u"αβΑΒΛ+−×÷":
loperand = codan[i]
i += 1
else:
print "Syntax error at %d!" % i
sys.exit(1)
# Read operator
while codan[i] in u" \n\t":
i += 1
if codan[i] in u"←→↑=≠<≤>≥≮≯≰≱":
operator = codan[i]
i += 1
else:
print "Syntax error at %d!" % i
sys.exit(1)
# Read right operand
while codan[i] in u" \n\t":
i += 1
if codan[i] in u"0123456789":
s = i
while codan[i] in u"0123456789":
i += 1
roperand = codan[s:i]
elif codan[i] in u"αβΑΒΛ+−×÷":
roperand = codan[i]
i += 1
else:
print "Syntax error at %d!" % i
sys.exit(1)
# Ensure arrow expressions are in x ← y form
if operator == u'→':
loperand, roperand = roperand, loperand
operator = u'←'
# Pase left operand
if loperand in u"αβΑΒ":
loperand = { u'α': "mem[alpha]",
u'β': "mem[beta]",
u'Α': "alpha",
u'Β': "beta" }[loperand]
elif loperand == u'Λ':
loperand, operator = '', loperand
else:
try:
loperand = int(loperand)
if operator == u'←':
loperand = "mem[%d]" % loperand
else:
loperand = str(loperand)
except ValueError:
print "Syntax error!"
raise
# Parse right operand
if roperand in u"+−×÷↑":
roperand = { u'+': "mem[alpha] + mem[beta]",
u'−': "mem[alpha] - mem[beta]",
u'×': "mem[alpha] * mem[beta]",
u'÷': "mem[alpha] / mem[beta]",
u'↑': "(int)pow((int)mem[alpha], " +\
"(int)mem[beta])" }[roperand]
elif roperand == u'Λ':
out += 't = (int) getchar();\n' if iomode else \
'scanf("%d\\n", &t);\n'
roperand = "t"
elif roperand in u'αβΑΒ':
roperand = { u'α': "mem[alpha]",
u'β': "mem[beta]",
u'Α': "alpha",
u'Β': "beta" }[roperand]
else:
try:
roperand = int(roperand)
roperand = str(roperand)
except ValueError:
print "Syntax error!"
raise
# Parse operator and emit
if operator in u"<>=≤≥≠≮≯≰≱":
operator = { u'=': "!=",
u'≠': "==",
u'≤': ">",
u'≯': ">",
u'≥': "<",
u'≮': "<",
u'≰': "<=",
u'>': "<=",
u'≱': ">=",
u'<': ">=" }[operator]
out += "if (%s %s %s) break;\n" % (loperand,
operator,
roperand)
elif operator == u'←':
out += "%s = %s;\n" % (loperand, roperand)
elif operator == u'Λ':
if iomode:
out += 'printf("%%c", %s);\n' % roperand
else:
out += 'printf("%%d\\n", %s);\n' % roperand
except IndexError:
# Source file ends in whitespace
pass
out += """
return 0;
}
"""
# Make temporary C file and compile it
cfile = os.tempnam() + ".c"
f = open(cfile, 'w')
f.write(out)
f.close()
print out
args = [CC]
if len(sys.argv) > 2:
args.extend(sys.argv[1:-1])
args.append(cfile)
os.spawnvpe(os.P_WAIT, CC, args, os.environ)
os.remove(cfile)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment