# operators: the docstrings contain the # symbol associated to each operator def op_add(x, y): '+' return x+y def op_sub(x, y): '-' return x-y # entry-point def main(argv): try: print calculate(argv[1:]) return 0 except SyntaxError: print 'Invalid expression' return 1 # evaluate a list of string def calculate(lst): stack = [] for token in lst: try: val = int(token) except ValueError: op = OPCODES.get(token, None) if op is None: raise SyntaxError y, x = stack.pop(), stack.pop() val = op(x, y) stack.append(val) if len(stack) != 1: raise SyntaxError return stack[0] # INIT-TIME only: automatically build the # table of opcodes by inspecting all the # functions declared and their docstrings OPCODES = {} def build_opcodes(): 'NOT_RPYTHON' for name, value in globals().items(): if name.startswith('op_'): OPCODES[value.__doc__] = value build_opcodes()