# we define our own exception for this example class UnknownOperatorExcpetion (Exception) : pass # some helper functions to make the code easier to read def const(c) : return Expr("const",c,c) def add(a,b) : return Expr("add",a,b) def mult(a,b) : return Expr("mult",a,b) class Expr : def __init__(self,op,a,b) : self.operand1 = a self.operand2 = b self.op = op # even the debug function is recursive, so we can see the whole expression def __str__(self) : if self.op == "add" : return "(" + str(self.operand1) + " + " + str(self.operand2) + ")" elif self.op == "mult" : return "(" + str(self.operand1) + " * " + str(self.operand2) + ")" elif self.op == "const" : return str(self.operand1) else : raise UnknownOperatorException # evaluating the expression also needs to be recursive, because # we need to evaluate from the inside of the brackets outwards def eval(self) : if self.op == "add" : return self.operand1.eval() + self.operand2.eval() elif self.op == "mult" : return self.operand1.eval() * self.operand2.eval() elif self.op == "const" : return self.operand1 else : raise UnknownOperatorException