python一个简单的lisp实现,pythonlisp,#coding=utf-


#coding=utf-8import types,sysimport operator as opfrom functools import reducefrom inspect import getargspec##########################def quote(code):    return codedef atom(code):    if type(code) is list and code != []:        return []    return Truedef eq(car, cdr):    if car==cdr:        return True    return []def noteq(car, cdr):    if car != cdr:        return True    return []def and2(car, cdr):#用lisp实现一个and吧    if car!=[] and cdr!=[]:        return True    return []def car(code):    if code == [] or code == '':#fix map func error        return []    return code[0]def cdr(code):    return code[1:]def cons(arg1, arg2):    res = [arg1]    res.extend(arg2);    return resdef cond(code):passdef define():passdef fun():passdef fun_seq():passclass S(str):pass#extradef lt(car, cdr):#<    if car < cdr:        return True    return []def gt(car, cdr):#>    if car > cdr:        return True    return []def mul(*args):#*    return reduce(op.mul, args)def div(*args):#/    return reduce(op.div, args)def sub(*args):#-    return reduce(op.sub, args)def add(*args):#+    return reduce(op.add, args)def mod(car, cdr):#%    return car % cdrdef show(code):    print( code)    return codedef seti(key, val):    pass# def yf():#     pass# def yd():#     passdef nexti(sq, n):    if not hasattr(sq, '__next__'):        sq = iter(sq)    while n:        if n == 1:            return next(sq)        next(sq)        n = n - 1def use(pg, _as=None):    try:        mod = __import__(pg)        return mod, _as    except Exception as e:        print('<No this Package: '+ str(e) +'>')        return None, Nonedef attr(obj, prop):    return getattr(obj, prop)###############################class Env(dict):    def __init__(self, outer, params=None, args=None):        params = params if params else []        args = args if args else []        #for currying        for i in range(len(args),len(params)):            args.append([])        #end        self.update(zip(params,args))#        self.outer = outer    def find(self, key):        ks = key.split('.')        if len(ks) > 1:            if ks[0] in self:                for k in ks[1:]:                    ks[0] = getattr(self[ks[0]], k)                return ks[0]            return self.outer[key]        else:            if key in self:                return self[key]            return self.outer.find(key)    def seti(self, key,value):        if key in self:            self[key] = value        else:            self.outer.seti(key,value)#############################lisp_env = {'quote':quote,'_':quote,'atom':atom,'eq':eq,'car':car, \        'cdr':cdr,'cons':cons,'cond':cond,'define':define,'fun':fun, \        'lt':lt,'mul':mul,'sub':sub,'gt':gt,'div':div,'mod':mod, \        'add':add,'noteq':noteq,'and2':and2, 'next':next, 'nexti':nexti, \        'show':show, 'seti':seti, 'True':True, 'False':False, \        'use':use, 'attr':attr }#############################def run(code,env):    # print '===code===', code, '======'    # print '===env===', env, '======'    # print '===outer===', env.outer, '======'    #return S('val'),变量    if type(code) is S:        try:            return env.find(code)        except:            print( '<Undefined variable %s...>' % code, '')            raise RuntimeError    #常量    #for empty list and no list    elif code==[] or type(code) is not list:        return code    #设置变量的值    elif code[0] is seti:        if type(code[1]) is not S:            print ("<Can't assign a value to %s...>" % code[1], '')            raise RuntimeError        try:            key = env.seti(code[1], run(code[2], env))            return env.find(code[1])        except:            print( "<Can't variable %s...>" % code[1], '')            raise RuntimeError    #变量引用,for quote exp    elif code[0] is quote:        return code[0](*code[1:])    #特别函数,for def, fun, let    elif code[0] is define:        env[ code[1]] = run(code[2],env)        # if code[1] == 'inner' or code[1]=='E':        #     print '--define--', code[1], code[2], env        return env[ code[1]]    #执行function体    elif code[0] is fun_seq:        last = None        codelen = len(code[1:]) - 1        for i, c in enumerate(code[1:]):            res = run(c, env)            if i == codelen:                last = res        return last    elif code[0] is fun:        # if code[1] and code[1][-1] == 'ident' or code[1] and code[1][-1] == '__outer__':        #     print '--eval--', env        if len(code[1]) == 0:            return lambda *args: run([fun_seq]+code[2:], Env(env, ['args'], [list(args)]))        if type(code[1]) is S:            return lambda *args: run( [fun_seq]+code[2:], Env(env, [code[1]], [list(args)]))        return lambda *args: run([fun_seq]+code[2:], Env(env, code[1], list(args)))#name,value    #条件,for cond, [cond [p1,e1],[p2,e2],...]    elif code[0] is cond:        for c in code[1:]:            if run(c[0], env):                res = [run(ii, env) for ii in c[1:]]                return res[-1]    elif code[0] is use:        mod, _as = None,None        if len(code) > 2:            mod, _as = use(code[1], code[2])        else:            mod, _as = use(code[1])        if not mod:            raise RuntimeError        if _as:            env[_as] = mod         else:            env[code[1]] = mod        return env[_as] if _as else env[code[1]]    #[S]    elif type(code[0]) is S and len(code) == 1:        try:            return run(env.find(code[0]), env)        except:            print( '<Undefined variable %s...>' % code[0], '')            raise RuntimeError    else:        exps = [ run(exp, env) for exp in code]        f = exps.pop(0)        if not (type(f) is types.FunctionType) and not (type(f) is types.BuiltinFunctionType) and not f is type:            return [f]+exps        try:            #print f, exps            return f(*exps)        except TypeError as e:#pass arg for next(), if not a iterator            print ('<StopIteration!>')        raise RuntimeError

评论关闭