7 from libraries.recipes import algorithms
18 def parse_number(userInput):
20 base = __BASE_MAPPINGS.get(userInput[0:2], 10)
22 userInput = userInput[2:] # Remove prefix
23 value = int(userInput, base)
29 value = float(userInput)
35 value = complex(userInput)
40 raise ValueError('Cannot parse "%s" as a number' % userInput)
43 class AbstractHistory(object):
45 Is it just me or is this class name begging for some jokes?
49 raise NotImplementedError
52 raise NotImplementedError
56 for child in node.get_children():
60 raise NotImplementedError
63 raise NotImplementedError
66 raise NotImplementedError
69 raise NotImplementedError
72 class CalcHistory(AbstractHistory):
75 super(CalcHistory, self).__init__()
79 assert node is not None
80 self.__nodeStack.append(node)
84 popped = self.__nodeStack[-1]
85 del self.__nodeStack[-1]
89 return self.__nodeStack[-1]
95 return len(self.__nodeStack)
98 return self.__nodeStack[::-1]
101 class RpnCalcHistory(object):
103 def __init__(self, history, entry, errorReporting, constants, operations):
104 self.history = history
105 self.__entry = weakref.ref(entry)
107 self.__errorReporter = errorReporting
108 self.__constants = constants
109 self.__operations = operations
111 self.__serialRenderer = operation.render_number()
114 def errorReporter(self):
115 return self.__errorReporter
118 def OPERATIONS(self):
119 return self.__operations
123 return self.__constants
127 self.__entry().clear()
129 def push_entry(self):
130 value = self.__entry().get_value()
134 valueNode = self._parse_value(value)
135 self.history.push(valueNode)
137 self.__entry().clear()
140 def apply_operation(self, Node):
144 node = self._apply_operation(Node)
146 except StandardError, e:
147 self.errorReporter.push_exception()
150 def serialize_stack(self):
152 stackNode.serialize(self.__serialRenderer)
153 for stackNode in self.history
155 serialized = list(serialized)
158 def deserialize_stack(self, data):
159 for possibleNode in data:
160 for nodeValue in possibleNode:
161 if nodeValue in self.OPERATIONS:
162 Node = self.OPERATIONS[nodeValue]
163 self._apply_operation(Node)
165 node = self._parse_value(nodeValue)
166 self.history.push(node)
168 def _parse_value(self, userInput):
170 value, base = parse_number(userInput)
171 return operation.Value(value, base)
176 return self.CONSTANTS[userInput]
180 return operation.Variable(userInput)
182 def _apply_operation(self, Node):
183 numArgs = Node.argumentCount
185 if len(self.history) < numArgs:
187 "Not enough arguments. The stack has %d but %s needs %d" % (
188 len(self.history), Node.symbol, numArgs
192 args = [arg for arg in algorithms.func_repeat(numArgs, self.history.pop)]
197 except StandardError:
199 self.history.push(arg)
201 self.history.push(node)