[Python] python一个简单的lisp实 →→→→→进入此内容的聊天室

来自 , 2021-03-06, 写在 Python, 查看 125 次.
URL http://www.code666.cn/view/3e10f9cf
  1. #coding=utf-8
  2. import types,sys
  3. import operator as op
  4. from functools import reduce
  5. from inspect import getargspec
  6. ##########################
  7. def quote(code):
  8.     return code
  9. def atom(code):
  10.     if type(code) is list and code != []:
  11.         return []
  12.     return True
  13. def eq(car, cdr):
  14.     if car==cdr:
  15.         return True
  16.     return []
  17. def noteq(car, cdr):
  18.     if car != cdr:
  19.         return True
  20.     return []
  21. def and2(car, cdr):#用lisp实现一个and吧
  22.     if car!=[] and cdr!=[]:
  23.         return True
  24.     return []
  25. def car(code):
  26.     if code == [] or code == '':#fix map func error
  27.         return []
  28.     return code[0]
  29. def cdr(code):
  30.     return code[1:]
  31. def cons(arg1, arg2):
  32.     res = [arg1]
  33.     res.extend(arg2);
  34.     return res
  35. def cond(code):pass
  36. def define():pass
  37. def fun():pass
  38. def fun_seq():pass
  39. class S(str):pass
  40. #extra
  41. def lt(car, cdr):#<
  42.     if car < cdr:
  43.         return True
  44.     return []
  45. def gt(car, cdr):#>
  46.     if car > cdr:
  47.         return True
  48.     return []
  49. def mul(*args):#*
  50.     return reduce(op.mul, args)
  51. def div(*args):#/
  52.     return reduce(op.div, args)
  53. def sub(*args):#-
  54.     return reduce(op.sub, args)
  55. def add(*args):#+
  56.     return reduce(op.add, args)
  57. def mod(car, cdr):#%
  58.     return car % cdr
  59. def show(code):
  60.     print( code)
  61.     return code
  62. def seti(key, val):
  63.     pass
  64.  
  65. # def yf():
  66. #     pass
  67. # def yd():
  68. #     pass
  69. def nexti(sq, n):
  70.     if not hasattr(sq, '__next__'):
  71.         sq = iter(sq)
  72.     while n:
  73.         if n == 1:
  74.             return next(sq)
  75.         next(sq)
  76.         n = n - 1
  77.        
  78. def use(pg, _as=None):
  79.     try:
  80.         mod = __import__(pg)
  81.         return mod, _as
  82.     except Exception as e:
  83.         print('<No this Package: '+ str(e) +'>')
  84.         return None, None
  85.  
  86. def attr(obj, prop):
  87.     return getattr(obj, prop)
  88.        
  89. ###############################
  90. class Env(dict):
  91.     def __init__(self, outer, params=None, args=None):
  92.         params = params if params else []
  93.         args = args if args else []
  94.         #for currying
  95.         for i in range(len(args),len(params)):
  96.             args.append([])
  97.         #end
  98.         self.update(zip(params,args))#
  99.         self.outer = outer
  100.  
  101.     def find(self, key):
  102.         ks = key.split('.')
  103.         if len(ks) > 1:
  104.             if ks[0] in self:
  105.                 for k in ks[1:]:
  106.                     ks[0] = getattr(self[ks[0]], k)
  107.                 return ks[0]
  108.             return self.outer[key]
  109.         else:
  110.             if key in self:
  111.                 return self[key]
  112.             return self.outer.find(key)
  113.  
  114.     def seti(self, key,value):
  115.         if key in self:
  116.             self[key] = value
  117.         else:
  118.             self.outer.seti(key,value)
  119.  
  120. #############################
  121. lisp_env = {'quote':quote,'_':quote,'atom':atom,'eq':eq,'car':car, \
  122.         'cdr':cdr,'cons':cons,'cond':cond,'define':define,'fun':fun, \
  123.         'lt':lt,'mul':mul,'sub':sub,'gt':gt,'div':div,'mod':mod, \
  124.         'add':add,'noteq':noteq,'and2':and2, 'next':next, 'nexti':nexti, \
  125.         'show':show, 'seti':seti, 'True':True, 'False':False, \
  126.         'use':use, 'attr':attr }#
  127.  
  128. ############################
  129. def run(code,env):
  130.     # print '===code===', code, '======'
  131.     # print '===env===', env, '======'
  132.     # print '===outer===', env.outer, '======'
  133.     #return S('val'),变量
  134.     if type(code) is S:
  135.         try:
  136.             return env.find(code)
  137.         except:
  138.             print( '<Undefined variable %s...>' % code, '')
  139.             raise RuntimeError
  140.  
  141.     #常量
  142.     #for empty list and no list
  143.     elif code==[] or type(code) is not list:
  144.         return code
  145.  
  146.     #设置变量的值
  147.     elif code[0] is seti:
  148.         if type(code[1]) is not S:
  149.             print ("<Can't assign a value to %s...>" % code[1], '')
  150.             raise RuntimeError
  151.         try:
  152.             key = env.seti(code[1], run(code[2], env))
  153.             return env.find(code[1])
  154.         except:
  155.             print( "<Can't variable %s...>" % code[1], '')
  156.             raise RuntimeError
  157.  
  158.     #变量引用,for quote exp
  159.     elif code[0] is quote:
  160.         return code[0](*code[1:])
  161.  
  162.     #特别函数,for def, fun, let
  163.     elif code[0] is define:
  164.         env[ code[1]] = run(code[2],env)
  165.         # if code[1] == 'inner' or code[1]=='E':
  166.         #     print '--define--', code[1], code[2], env
  167.         return env[ code[1]]
  168.  
  169.     #执行function体
  170.     elif code[0] is fun_seq:
  171.         last = None
  172.         codelen = len(code[1:]) - 1
  173.         for i, c in enumerate(code[1:]):
  174.             res = run(c, env)
  175.             if i == codelen:
  176.                 last = res
  177.         return last
  178.  
  179.     elif code[0] is fun:
  180.         # if code[1] and code[1][-1] == 'ident' or code[1] and code[1][-1] == '__outer__':
  181.         #     print '--eval--', env
  182.         if len(code[1]) == 0:
  183.             return lambda *args: run([fun_seq]+code[2:], Env(env, ['args'], [list(args)]))
  184.         if type(code[1]) is S:
  185.             return lambda *args: run( [fun_seq]+code[2:], Env(env, [code[1]], [list(args)]))
  186.         return lambda *args: run([fun_seq]+code[2:], Env(env, code[1], list(args)))#name,value
  187.        
  188.     #条件,for cond, [cond [p1,e1],[p2,e2],...]
  189.     elif code[0] is cond:
  190.         for c in code[1:]:
  191.             if run(c[0], env):
  192.                 res = [run(ii, env) for ii in c[1:]]
  193.                 return res[-1]
  194.                
  195.     elif code[0] is use:
  196.         mod, _as = None,None
  197.         if len(code) > 2:
  198.             mod, _as = use(code[1], code[2])
  199.         else:
  200.             mod, _as = use(code[1])
  201.            
  202.         if not mod:
  203.             raise RuntimeError
  204.         if _as:
  205.             env[_as] = mod
  206.         else:
  207.             env[code[1]] = mod
  208.         return env[_as] if _as else env[code[1]]
  209.     #[S]
  210.     elif type(code[0]) is S and len(code) == 1:
  211.         try:
  212.             return run(env.find(code[0]), env)
  213.         except:
  214.             print( '<Undefined variable %s...>' % code[0], '')
  215.             raise RuntimeError
  216.  
  217.     else:
  218.         exps = [ run(exp, env) for exp in code]
  219.         f = exps.pop(0)
  220.  
  221.         if not (type(f) is types.FunctionType) and not (type(f) is types.BuiltinFunctionType) and not f is type:
  222.             return [f]+exps
  223.  
  224.         try:
  225.             #print f, exps
  226.             return f(*exps)
  227.         except TypeError as e:#pass arg for next(), if not a iterator
  228.             print ('<StopIteration!>')
  229.         raise RuntimeError
  230. #//python/5409

回复 "python一个简单的lisp实"

这儿你可以回复上面这条便签

captcha