6 from util import algorithms
17 def parse_number(userInput):
19 base = __BASE_MAPPINGS.get(userInput[0:2], 10)
21 userInput = userInput[2:] # Remove prefix
22 value = int(userInput, base)
28 value = float(userInput)
34 value = complex(userInput)
39 raise ValueError('Cannot parse "%s" as a number' % userInput)
42 class AbstractHistory(object):
44 Is it just me or is this class name begging for some jokes?
48 raise NotImplementedError
51 raise NotImplementedError
55 for child in node.get_children():
59 raise NotImplementedError
62 raise NotImplementedError
65 raise NotImplementedError
68 raise NotImplementedError
71 class CalcHistory(AbstractHistory):
74 super(CalcHistory, self).__init__()
78 assert node is not None
79 self.__nodeStack.append(node)
83 popped = self.__nodeStack[-1]
84 del self.__nodeStack[-1]
88 return self.__nodeStack[-1]
94 return len(self.__nodeStack)
97 return self.__nodeStack[::-1]
100 class RpnCalcHistory(object):
102 def __init__(self, history, entry, errorReporting, constants, operations):
103 self.history = history
104 self.__entry = weakref.ref(entry)
106 self.__errorReporter = errorReporting
107 self.__constants = constants
108 self.__operations = operations
110 self.__serialRenderer = operation.render_number()
113 def errorReporter(self):
114 return self.__errorReporter
117 def OPERATIONS(self):
118 return self.__operations
122 return self.__constants
126 self.__entry().clear()
128 def push_entry(self):
129 value = self.__entry().get_value()
133 valueNode = self._parse_value(value)
134 self.history.push(valueNode)
136 self.__entry().clear()
139 def apply_operation(self, Node):
143 node = self._apply_operation(Node)
145 except StandardError, e:
146 self.errorReporter.push_exception()
149 def serialize_stack(self):
151 stackNode.serialize(self.__serialRenderer)
152 for stackNode in self.history
154 serialized = list(serialized)
157 def deserialize_stack(self, data):
158 for possibleNode in data:
159 for nodeValue in possibleNode:
160 if nodeValue in self.OPERATIONS:
161 Node = self.OPERATIONS[nodeValue]
162 self._apply_operation(Node)
164 node = self._parse_value(nodeValue)
165 self.history.push(node)
167 def _parse_value(self, userInput):
169 value, base = parse_number(userInput)
170 return operation.Value(value, base)
175 return self.CONSTANTS[userInput]
179 return operation.Variable(userInput)
181 def _apply_operation(self, Node):
182 numArgs = Node.argumentCount
184 if len(self.history) < numArgs:
186 "Not enough arguments. The stack has %d but %s needs %d" % (
187 len(self.history), Node.symbol, numArgs
191 args = [arg for arg in algorithms.func_repeat(numArgs, self.history.pop)]
196 except StandardError:
198 self.history.push(arg)
200 self.history.push(node)