class nil(object):
"""The empty list"""
def __len__(self):
return 0
def map(self,fn):
return self
def __repr__(self):
return 'nil'
nil=nil() # nil now refers to a single instance of nil class
class Pair(object):
def __init__(self,first,second=nil):
self.first=first
self.second=second
def __repr__(self):
return 'Pair({0},{1})'.format(repr(self.first),repr(self.second))
def __len__(self):
n,second=1,self.second
while isinstance(second,Pair):
n+=1
second=second.second
if second is not nil:
raise TypeError("length attempted on improper list")
return n
def __getitem__(self,k):
if k<0:
raise IndexError("negative index into list")
j,y=0,self
while j<k:
if y.second is nil:
raise IndexError("list index out of bounds")
elif not isinstance(y.second,Pair):
raise TypeError("ill-formed list")
j,y=j+1,y.second
return y.first
def map(self,fn):
"""Return a Scheme list after mapping Python function fn over self."""
mapped=fn(self.first)
if self.second is nil or isinstance(self.second,Pair):
return Pair(mapped,self.second.map(fn))
else:
raise TypeError("ill-formed list")
def to_py_list(self):
"""Return a python list containing the elements of this Scheme list"""
y,result=self,[]
while y is not nil:
result+=[y.first]
if not isinstance(y.second,Pair) and y.second is not nil:
raise TypeError("ill-formed list")
y=y.second
return result
def calc_eval(exp):
if not isinstance(exp,Pair):
return exp
else:
operator,operands=exp.first,exp.second
args=operands.map(calc_eval).to_py_list()
return calc_apply(operator,args)
def calc_apply(operator,args):
if operator=='+':
return sum(args)
elif operator=='-':
if len(args)==1:
return -args[0]
else:
return sum(args[0],[-args for args in args[1:]])
elif operator=='*':
return reduce(mul,args,1)
elif operato=='/':
if len(args)==1:
raise ValueError("args must bigger than 2")
elif 0 in args:
raise ZeroDivisionError("division by zero")
else:
reduce(mul,args,1)
exp=Pair('+',Pair(1,Pair(2,Pair(3,Pair(4,nil)))))
a=calc_eval(exp)
print(a)
简单scheme计算器-python实现
最新推荐文章于 2024-01-05 13:33:33 发布