71 lines
1.8 KiB
Python
71 lines
1.8 KiB
Python
class Tracer():
|
|
def __init__(self):
|
|
raise Exception("Use BaseTracer instead of Tracer")
|
|
|
|
def _push(self, op, obj):
|
|
return CompTracer(self, obj, op)
|
|
|
|
def __add__(self, other):
|
|
return self._push("+", other)
|
|
|
|
def __sub__(self, other):
|
|
return self._push("-", other)
|
|
|
|
def __mul__(self, other):
|
|
return self._push("*", other)
|
|
|
|
def __truediv__(self, other):
|
|
return self._push("/", other)
|
|
|
|
def __pow__(self, other):
|
|
return self._push("**", other)
|
|
|
|
def __pos__(self):
|
|
return self
|
|
|
|
def __neg__(self):
|
|
return self._push("*", -1)
|
|
|
|
def __repr__(self):
|
|
v = self.eval()
|
|
return "<Tracer: "+str(self)+" = "+str(v if v != None else 'Undefined')+">"
|
|
|
|
class BaseTracer(Tracer):
|
|
def __init__(self, name, val=None):
|
|
self.name = name
|
|
self.val = val
|
|
|
|
def eval(self):
|
|
return self.val
|
|
|
|
def __str__(self):
|
|
return self.name
|
|
|
|
class CompTracer(Tracer):
|
|
def __init__(self, lParent, rParent, op):
|
|
if not isinstance(lParent, Tracer):
|
|
lParent = BaseTracer(repr(lParent), lParent)
|
|
if not isinstance(rParent, Tracer):
|
|
rParent = BaseTracer(repr(rParent), rParent)
|
|
self.parents = [lParent, rParent]
|
|
self.op = op
|
|
|
|
def eval(self):
|
|
l = self.parents[0].eval()
|
|
r = self.parents[1].eval()
|
|
if None in [l,r]:
|
|
return None
|
|
if self.op=="+":
|
|
return l + r
|
|
elif self.op=="-":
|
|
return l - r
|
|
elif self.op=="*":
|
|
return l * r
|
|
elif self.op=="/":
|
|
return l / r
|
|
elif self.op=="**":
|
|
return l ** r
|
|
|
|
def __str__(self):
|
|
return "("+str(self.parents[0])+" "+self.op+" "+str(self.parents[1])+")"
|