Skip to content

Instantly share code, notes, and snippets.

@PythonJedi
Last active March 26, 2016 17:29
Show Gist options
  • Save PythonJedi/ec3f9956070bdc87caea to your computer and use it in GitHub Desktop.
Save PythonJedi/ec3f9956070bdc87caea to your computer and use it in GitHub Desktop.
Silly little calculator language expressing functions as DAGs of arithmetic expressions.
#! /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)))
# 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