calc.py

changeset 135
ad27ab7e6fb6
parent 134
7316dc5f61ef
child 136
3812bfce21e0
equal deleted inserted replaced
134:7316dc5f61ef 135:ad27ab7e6fb6
118 'compl': { 'symbol': '~', 'operands': 1, 'priority': 5, 'function': intf (operator.inv) }, 118 'compl': { 'symbol': '~', 'operands': 1, 'priority': 5, 'function': intf (operator.inv) },
119 'neg': { 'symbol': '-', 'operands': 1, 'priority': 5, 'function': lambda x: -x }, 119 'neg': { 'symbol': '-', 'operands': 1, 'priority': 5, 'function': lambda x: -x },
120 'pow': { 'symbol': '**', 'operands': 2, 'priority': 10, 'function': lambda x, y: x ** y }, 120 'pow': { 'symbol': '**', 'operands': 2, 'priority': 10, 'function': lambda x, y: x ** y },
121 'mul': { 'symbol': '*', 'operands': 2, 'priority': 50, 'function': lambda x, y: x * y }, 121 'mul': { 'symbol': '*', 'operands': 2, 'priority': 50, 'function': lambda x, y: x * y },
122 'div': { 'symbol': '/', 'operands': 2, 'priority': 50, 'function': lambda x, y: x / y }, 122 'div': { 'symbol': '/', 'operands': 2, 'priority': 50, 'function': lambda x, y: x / y },
123 'mod': { 'symbol': '%', 'operands': 2, 'priority': 50, 'function': lambda x, y: math.fmod (x, y) }, 123 'mod': { 'symbol': '%', 'operands': 2, 'priority': 50, 'function': realf (math.fmod) },
124 'add': { 'symbol': '+', 'operands': 2, 'priority': 100, 'function': lambda x, y: x + y }, 124 'add': { 'symbol': '+', 'operands': 2, 'priority': 100, 'function': lambda x, y: x + y },
125 'sub': { 'symbol': '-', 'operands': 2, 'priority': 100, 'function': lambda x, y: x - y }, 125 'sub': { 'symbol': '-', 'operands': 2, 'priority': 100, 'function': lambda x, y: x - y },
126 'eq': { 'symbol': '==', 'operands': 2, 'priority': 500, 'function': lambda x, y: x == y }, 126 'eq': { 'symbol': '==', 'operands': 2, 'priority': 500, 'function': lambda x, y: x == y },
127 'neq': { 'symbol': '!=', 'operands': 2, 'priority': 500, 'function': lambda x, y: x != y }, 127 'neq': { 'symbol': '!=', 'operands': 2, 'priority': 500, 'function': lambda x, y: x != y },
128 'lt': { 'symbol': '<', 'operands': 2, 'priority': 500, 'function': lambda x, y: x < y }, 128 'lt': { 'symbol': '<', 'operands': 2, 'priority': 500, 'function': lambda x, y: x < y },
147 else: 147 else:
148 OperatorSymbols[op.symbol] = [op] 148 OperatorSymbols[op.symbol] = [op]
149 149
150 def sgn (x): 150 def sgn (x):
151 return cmp (x, 0) 151 return cmp (x, 0)
152
153 def integerclamp (x, bits, signed):
154 x = x % (2 ** bits)
155
156 if signed and x >= (2 ** (bits - 1)):
157 x = -(2 ** bits) + x
158
159 return x
152 160
153 Constants = { 161 Constants = {
154 'pi': cmath.pi, 162 'pi': cmath.pi,
155 'e': cmath.e, 163 'e': cmath.e,
156 'phi': 1.6180339887498948482, 164 'phi': 1.6180339887498948482,
193 're': { 'function': lambda x: x.real }, 201 're': { 'function': lambda x: x.real },
194 'im': { 'function': lambda x: x.imag }, 202 'im': { 'function': lambda x: x.imag },
195 'conjugate':{ 'function': lambda x: x.conjugate() }, 203 'conjugate':{ 'function': lambda x: x.conjugate() },
196 'rand': { 'function': random.random }, 204 'rand': { 'function': random.random },
197 'sgn': { 'function': realf (sgn) }, 205 'sgn': { 'function': realf (sgn) },
206 'byte': { 'function': intf (lambda x: integerclamp (x, bits=8, signed=False)) },
207 'sbyte': { 'function': intf (lambda x: integerclamp (x, bits=8, signed=True)) },
208 'word': { 'function': intf (lambda x: integerclamp (x, bits=16, signed=False)) },
209 'sword': { 'function': intf (lambda x: integerclamp (x, bits=16, signed=True)) },
210 'dword': { 'function': intf (lambda x: integerclamp (x, bits=32, signed=False)) },
211 'sdword': { 'function': intf (lambda x: integerclamp (x, bits=32, signed=True)) },
212 'qword': { 'function': intf (lambda x: integerclamp (x, bits=64, signed=False)) },
213 'sqword': { 'function': intf (lambda x: integerclamp (x, bits=64, signed=True)) },
198 } 214 }
199 215
200 Tokens = ['(', ')'] 216 Tokens = ['(', ')']
201 217
202 # Symbol table 218 # Symbol table
241 } 257 }
242 258
243 Attributes['bin'] = Attributes['binary'] 259 Attributes['bin'] = Attributes['binary']
244 Attributes['dec'] = Attributes['decimal'] 260 Attributes['dec'] = Attributes['decimal']
245 AttributeNames = sorted ([key for key in Attributes], key=lambda x:len(x), reverse=True) 261 AttributeNames = sorted ([key for key in Attributes], key=lambda x:len(x), reverse=True)
262
263 def is_int (x):
264 return math.fabs (x - math.floor(x)) < epsilon
246 265
247 class Calculator (object): 266 class Calculator (object):
248 def __init__ (self): 267 def __init__ (self):
249 self.preferred_base = None 268 self.preferred_base = None
250 269
518 self.tabs = self.tabs[:-1] 537 self.tabs = self.tabs[:-1]
519 538
520 printFunc (self.tabs + 'Evaluating function call: %s' % (sym)) 539 printFunc (self.tabs + 'Evaluating function call: %s' % (sym))
521 expr[i] = Functions[sym.funcname]['function'] (*sym.args) 540 expr[i] = Functions[sym.funcname]['function'] (*sym.args)
522 printFunc (self.tabs + '-> %s' % expr[i]) 541 printFunc (self.tabs + '-> %s' % expr[i])
523 542
524 i += 1 543 i += 1
525 544
526 printFunc (self.tabs + 'Evaluate: %s' % expr) 545 printFunc (self.tabs + 'Evaluate: %s' % expr)
527 runaway = 0 546 runaway = 0
528 while True: 547 while True:
557 return expr[0] 576 return expr[0]
558 577
559 def repr_number (self, x): 578 def repr_number (self, x):
560 """Returns a string representation for a real number""" 579 """Returns a string representation for a real number"""
561 base = self.preferred_base if self.preferred_base else 10 580 base = self.preferred_base if self.preferred_base else 10
562 if math.fabs (x - math.floor(x)) < epsilon and base != 10: 581 if is_int (x) and base != 10:
563 digits='0123456789abcdef' 582 digits='0123456789abcdef'
564 assert base <= len (digits), '''base %d is too large''' % base 583 assert base <= len (digits), '''base %d is too large''' % base
565 584
566 divisor = base 585 divisor = base
567 rep = '' 586 rep = ''
568 x = int (x) 587 x = int (x)
569 runaway = 0 588 runaway = 0
589
590 if not x:
591 return '0x0'
592
593 if x < 0:
594 return '-' + self.repr_number (abs (x))
570 595
571 while x > 0: 596 while x > 0:
572 runaway += 1 597 runaway += 1
573 if runaway > 1000: 598 if runaway > 1000:
574 raise ValueError('runaway triggered') 599 raise ValueError('runaway triggered')

mercurial