Last active
March 26, 2016 17:29
-
-
Save PythonJedi/ec3f9956070bdc87caea to your computer and use it in GitHub Desktop.
Silly little calculator language expressing functions as DAGs of arithmetic expressions.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/python3 | |
""" Silly little dag calculator language on ints. """ | |
# ops are defined to return lists for a very good reason | |
ops = {"I": lambda a:[a], \ | |
"A": lambda b:[b,b], \ | |
"X": lambda c, d: [d,c], \ | |
"+": lambda e, f: [e+f], \ | |
"-": lambda g, h: [g-h], \ | |
"*": lambda i, j: [i*j], \ | |
"/": lambda k, l: [k//l], \ | |
"%": lambda m, n: [m%n], \ | |
"^": lambda o, p: [o**p]} | |
def lex_line(line): | |
# throw away everything after the first # and split on whitespace | |
return line.split("#", 1)[0].split() | |
def slices(sizes): | |
# produce a sequence of consecutive slices from a list of lengths | |
j = 0 | |
for s in sizes: | |
yield slice(j, j+s) | |
j += s | |
def run(prog, arg): | |
val = [] | |
ctr = 1 | |
for line in map(lex_line, prog.splitlines()): | |
assert [n in ops for n in line] == [True]*len(line) | |
if line: | |
expecting = sum([ops[n].__code__.co_argcount for n in line]) # yay, reflection! | |
operations = [ops[n] for n in line] | |
else: | |
continue | |
assert expecting == len(arg) | |
# accumulate the indicies, so that the n+1 op pulls from after n's args | |
# and match it to the lambdas that must be called. also link to the name | |
# for pretty printing | |
calls = tuple(zip(operations, slices(map(lambda l: l.__code__.co_argcount, operations)), line)) | |
for c in calls: | |
# usually don't keep these around, but it looks really pretty | |
#print(str(arg[c[1]])+"\t -> "+c[2]+" -> "+str(c[0](*arg[c[1]]))) | |
val = val + c[0](*arg[c[1]]) | |
arg, val = val, [] | |
ctr += 1 | |
return arg | |
if __name__ == "__main__": | |
import sys | |
if len(sys.argv) >= 3: | |
f = open(sys.argv[1]) | |
prog = ''.join(f.readlines()) | |
f.close() | |
args = list(map(int, sys.argv[2:])) | |
print(' '.join(run(prog, args))) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# quotient and remainder calculator | |
A A | |
I X I | |
/ % |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment