Skip to content

Instantly share code, notes, and snippets.

@rrika
Created September 10, 2019 23:15
Show Gist options
  • Save rrika/bc24d4e57791a6a46be0aab9dc371a5a to your computer and use it in GitHub Desktop.
Save rrika/bc24d4e57791a6a46be0aab9dc371a5a to your computer and use it in GitHub Desktop.
factorial = (
("op", "a", "input"),
("loop",
("phi", "a", "a", "a2"),
("phi", "b", 1, "b2"),
("op", "b2", "mul", "a", "b"),
("op", "a2", "sub", "a", 1),
("op", "loop-condition", "gt", "a", 0),
"loop-condition"
)
)
def translate(program):
rlabel = []
row = []
def atlevel(expr, level):
if isinstance(expr, str) and expr[:2] == "RC" and level != 0:
return "R[{}]{}".format(level, expr[1:])
return expr
def t_phi(scopes, phiindices, selector, x):
if x[0] != "phi":
return
expr = "RC[-1]"
for i, ((level, scope), var) in enumerate(zip(scopes, x[2:])):
subexpr = atlevel(scope.get(var, var), level)
expr = "IF({} = {}, {}, {})".format(selector, i, subexpr, expr)
row[phiindices.pop(0)] = "="+expr
def t_non_phi(scope, phiindices, x):
if x[0] == "loop":
body = x[1:-1]
exit = x[-1]
inner_scope = scope.copy()
inner_phiindices = []
for x2 in body:
t_non_phi(inner_scope, inner_phiindices, x2)
exit = atlevel(inner_scope.get(exit, exit), -1)
for x2 in body:
t_phi([(0, scope), (-1, inner_scope)], inner_phiindices, exit, x2)
elif x[0] == "op":
name = x[1]
opcode = x[2]
args = [scope.get(arg, arg) for arg in x[3:]]
tr = {"mul": "={}*{}", "gt": "={}>{}", "sub": "={}-{}", "input": ""}
expr = tr[opcode].format(*args)
print(name, opcode, args, tr, expr)
rlabel.append(name)
row.append(expr)
scope[name] = "RC{}".format(len(row))
elif x[0] == "phi":
phiindices.append(len(row))
rlabel.append("phi "+x[1])
row.append(None) # placeholder
scope[x[1]] = "RC{}".format(len(row))
else:
assert False
def t_main(x):
scope = {}
for x2 in x:
t_non_phi(scope, None, x2)
t_main(program)
print(";".join(rlabel))
print(";".join("0" for _ in row))
print(";".join(row))
translate(factorial)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment