## ## Simple list-processor that does prefix math, but can be extended ## fairly easily to do more powerful stuff. ## I wrote this to help me learn python better, and exercise some of ## it's more (IMO) interesting and powerful features. ## ## Version: 0.1 alpha (i.e. something i hacked up late one night) ## Last Update: Sep 10, 2004 ## ## By: Scott Hurring (scott @ hurring.com) ## License: GPL: http://www.opensource.org/licenses/gpl-license.php ## class ListProcessor: def __init__(self): self.stack = [] pass def parse(self, s): """ Turn the string into a list of individual chars """ chars = s.split() return chars def eval(self, chars): """ Evaluates a list of characters and calls the necessary objects (see 'decode' for input->object mapping) """ stack = [] while len(chars): c = chars.pop(0) # What does this value mean value = self.decode(c) #print "[read]: ", c if c == "(": #print "[open paren] ", chars stack.append(self.eval(chars)) elif c == ")": #print "[close paren] ", chars, stack try: f = stack.pop(0) v = f( stack ) #print "value = ", v.value return v.value except: raise Exception("There was an error with the stack ", stack) else: stack.append(value) #print "\t[appended to stack] ", value #print "\n[stack] = ", stack return stack.pop(0) def decode(self, s): """ Maps input keyword to the appropriate Python class """ try: return float(s) except: if s == "+": return Add elif s == "-": return Subtract elif s == "*": return Multiply elif s == "/": return Divide elif s == "FortyTwo": return FortyTwo elif s == "Print": return Print elif s == "List": return List else: return s class Add: value = 0.0; def __init__(self, values): for x in values: self.value += x class Subtract: value = 0.0; def __init__(self, values): self.value = values.pop(0) for x in values: self.value -= x class Multiply: value = 1.0; def __init__(self, values): for x in values: self.value *= x class Divide: value = 1.0; def __init__(self, values): for x in values: self.value /= x # Returns "42" no matter what ;-) class FortyTwo: value = 42 def __init__(self, values): pass class Print: value = "" def __init__(self, values): self.value = values print "[[PRINT]]: ", values class List: value = "" def __init__(self, values): self.value = values c = ListProcessor() ## NOTE: Becuase i'm lazy, you must put spaces between *everything* chars = c.parse("( + 5 ( + 2 ( + 9 ( * 5 ( FortyTwo ) ) ) ) )") #chars = c.parse("( + 5 ( - 5 4 ) )"); #chars = c.parse("( Print no ( List xxyz ( FortyTwo ) abc ( Print Hey there ) for this ) )"); try: value = c.eval(chars) print "\nValue of input string = ", value except Exception, e: print e