Create a gist now

Instantly share code, notes, and snippets.

@amitdev /interp1.py
Last active Aug 29, 2015

What would you like to do?
from numbers import Number
class M(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return "%s(%r)" % (self.__class__.__name__, self.val)
def __eq__(self, other):
return self.val == other.val
class Error(M):
pass
def unit(v):
return M(v)
def bind(m, f):
if isinstance(m, Error):
return m
return f(m.val)
class Num(object):
def __init__(self, val):
self.val = val
def evaluate(self, env):
if isinstance(self.val, Number):
return unit(self.val)
else:
return Error("%s is not a number" % self.val)
class Var(object):
def __init__(self, name):
self.name = name
def evaluate(self, env):
try:
return unit(env[self.name])
except KeyError:
return Error("Variable %r not defined" % self.name)
class Add(object):
def __init__(self, left, right):
self.left = left
self.right = right
def evaluate(self, env):
return bind(self.left.evaluate(env), lambda x: bind(self.right.evaluate(env), lambda y: unit(x+y)))
assert Num(1).evaluate({}) == M(1)
assert Var("foo").evaluate({"foo":3}) == M(3)
assert Add(Num(1), Num(2)).evaluate({"foo":3}) == M(3)
assert Add(Num(1), Add(Var("foo"), Num(2))).evaluate({"foo":3}) == M(6)
assert Add(Num(1), Add(Var("foo"), Add(Var("foo"), Num(13)))).evaluate({"foo":3}) == M(20)
#Errors
assert Add(Num(1), Num("2")).evaluate({"foo":3}) == Error("2 is not a number")
assert Add(Num(1), Var("fo")).evaluate({"foo":3}) == Error("Variable 'fo' not defined")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment