Instantly share code, notes, and snippets.

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

 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")