rendered paste bodyimport string,math
delin_debug = 0
exec_debug = 0
def sc(command):
return execute(parse(tokenize(string.strip(command), symbols)))
class scalar:
pass
class vector:
def __str__(self):
return '(' + ','.join(map(str, self.data)) + ')'
def make(self, l):
self.length = len(l)
self.data = []
[self.data.append(component) for component in l]
def set(self, i,s):
self.data[i-1]=s
def get(self, i):
self.data[i-1]
class matrix:
pass
symbols = ['(',')','[',']','<','>','degrees','sin','cos','tan','log','ln','factor','^','*','/','+','-',',','=','_']
# bugs: some whitespace gets through
def tokenize(s, symbols):
parts = [s]
for symbol in symbols:
newparts = []
for part in parts:
for newpart in string.split(part, symbol):
newparts.append(newpart)
newparts.append(symbol)
newparts = newparts[:-1]
newparts = [newpart for newpart in newparts if newpart != '']
parts = newparts
return parts
def parse(tokens):
return numericize(tokens)
def numericize_anon(part):
if part in symbols:
return part
if '.' in part:
return float(part)
return int(part)
def numericize(parts):
return map(numericize_anon, parts)
delin_tokens = {'(': ')',
'[': ']',
'<': '>'}
def delinearizer(tokens, start, matching):
if delin_debug:
print 'delinearizer(%r, %r)'%(tokens, start)
i=start
while i<len(tokens):
if tokens[i] in delin_tokens:
if delin_debug:
print '%r detected- start=%r, i=%r'%(tokens[i], start, i)
(tokens, i) = delinearizer(tokens, i+1, delin_tokens[tokens[i]])
if tokens[i] == matching:
if delin_debug:
print '%r detected- start=%r, i=%r'%(tokens[i], start, i)
tokens[start:i+1] = [tokens[start:i+1]]
if delin_debug:
print 'returning tokens=%r, i=%r'%(tokens, start)
return tokens, start
else:
if delin_debug:
print 'tokens[%r] is not a ( or a ) but a %r'%(i, tokens[i])
i=i+1
return tokens, i
def delinearize(tokens):
tokens = delinearizer(tokens, 0, None)[0]
if delin_debug:
print 'delinearlizer: i think that tokens should be %s'%tokens
return tokens
def noop(tokens, index):
return tokens, index
def add(x,y):
return x+y
def sub(x,y):
return x-y
def mul(x,y):
return x*y
def div(x,y):
return x/y
def pow(x,y):
return x**y
def binop(op, tokens, index):
tokens[index-1:index+2] = [op(tokens[index-1],tokens[index+1])]
return (tokens, index-1)
#def parens(tokens, index):
# tokens[index:index+2] = [execute(tokens[index+1])]
# return tokens, index
def parens(tokens, index):
execute(tokens, index+1)
return (tokens, index)
def prevleftparen(tokens, index):
while tokens[index] != '(':
index=index-1
return index
def endparens(tokens, index):
tokens[prevleftparen(tokens, index):index+1] = [execute(tokens[prevleftparen(tokens, index)+1:index])]
return tokens, index
def leftunop(op, tokens, index):
tokens[index:index+2] = [op(tokens[index+1])]
return tokens, index
def degrees(tokens, index):
tokens[index-1:index+1] = [tokens[index-1]*math.pi/180]
return tokens, index
def logger(tokens, index):
if tokens[index+1] == '_':
tokens[index:index+4] = [math.log(tokens[index+3], tokens[index+2])]
else:
tokens[index:index+2] = [math.log(tokens[index+1])]
return tokens, index
def vectorcollect(tokens, index):
v = vector()
v.make([tokens[index-1],tokens[index+1]])
tokens[index-1:index+2] = [v]
return tokens, index
symbolfunctions = {'+': lambda x,y: binop(add, x, y),
'-': lambda x,y: binop(sub, x, y),
'*': lambda x,y: binop(mul, x, y),
'/': lambda x,y: binop(div, x, y),
'^': lambda x,y: binop(pow, x, y),
'(': parens,
')': endparens,
',': vectorcollect,
'sin': lambda x,y: leftunop(math.sin, x, y),
'cos': lambda x,y: leftunop(math.cos, x, y),
'tan': lambda x,y: leftunop(math.tan, x, y),
'degrees': degrees,
'log': logger,
'ln': lambda x,y: leftunop(math.log, x, y)}
def execute(tokens, start=0):
for symbol in symbols:
index = start
while(index < len(tokens)):
if tokens[index] == symbol:
(tokens, index) = symbolfunctions[symbol](tokens, index)
index = index+1
return tokens[0]