linklist.py
Go to the documentation of this file.00001 '''
00002 (single) linked lists. Different from python 'lists' because
00003 need real links. Want to implement mutation operations with
00004 nodes having efficient delete, splice methods:
00005 eg self.del() will use self._prev to adjust links
00006 self.splice(a,b,c,d...) will create a linked list of nodes,
00007 and use self._prev to adjust pointers
00008
00009 Nil singleton is created by creating 1 instance of local __Nil class
00010 '''
00011 from struct import Struct
00012
00013 class __Nil(object):
00014 'effectively, the nil object'
00015 def set_prev(self,node): pass
00016 def rm_prev(self): pass
00017 def nilp(self): return True
00018 def rm(self): pass
00019 def repl(self,*v,**kw): pass
00020 def splice(self,*v,**kw):pass
00021 def mutate(self):
00022 'nothing happens here'
00023 pass
00024 def __repr__(self): return 'Nil'
00025
00026 class Node(object):
00027 def __init__(self,val,lst):
00028 '''like lisp "cons": takes a val and a node:
00029 returns a node = (val . lst) in lisp notation
00030 '''
00031 self.val = val
00032 self.link = lst
00033
00034 def __repr__(self): return 'Node(%s)' % repr(self.val)
00035 def __str__(self): return 'Node(%s)' % str(self.val)
00036
00037 def nilp(self):return False
00038
00039 def set_prev(self,node):
00040 'set the _prev field of node'
00041 self._prev = node
00042
00043 def rm_prev(self):
00044 'remove the _prev attribute from a node'
00045 del self._prev
00046
00047 def rm(self):
00048 'remove self from the list'
00049 self._prev.link = self.link
00050
00051 def repl(self,v):
00052 v.link = self.link
00053 self._prev.link = v
00054
00055 def splice(self,*vals):
00056 p = self._prev
00057 l = self.link
00058 p.link = l
00059 for v in vals:
00060 nn = Node(v,l)
00061 p.link = nn
00062 p = nn
00063
00064 def mutate(self,oth=None):
00065 '''expects that mutator and _prev attrs are set:
00066 applies mutator to self
00067 sets _prev.link to new self ??
00068 sets self.link._prev to new self
00069 deletes self._prev
00070 '''
00071 self.mutator(oth)
00072 self.link.set_prev(self)
00073 self.rm_prev()
00074
00075 Nil = __Nil()
00076
00077 class LList(object):
00078 '''creates a list head:
00079 This exists only so that mutate can be the major op of lists
00080 '''
00081 def __init__(self,*args):
00082 'create a list from a seq of args'
00083 p = self
00084 p.link = Nil
00085 for n in args:
00086 v = Node(n,Nil)
00087 p.link = v
00088 p = v
00089
00090 def nilp(self): return self.link.nilp()
00091
00092 @staticmethod
00093 def from_iter(iter):
00094 'create LList from single iterator'
00095 rv = LList()
00096 p = rv
00097 for n in iter:
00098 v = Node(n,Nil)
00099 p.link = v
00100 p = v
00101 return rv
00102
00103 def __iter__(self):
00104 'LList implements next, so is self-iterating'
00105 return self.nextn()
00106
00107 def nextn(self):
00108 '''start with 1st node of the LList, cdr down the list
00109 stop iteration is node is Nil
00110 '''
00111 p = self.link
00112 while(True):
00113 if p.nilp():
00114 raise StopIteration
00115 yield p
00116 p = p.link
00117
00118 def mutate(self,mutator,arg=None):
00119 '''
00120 set up the mutator (if it needs it)
00121 'cdr' down the list, mutating each node
00122 clr mutator (if it needs it)
00123 '''
00124 mutator.setup()
00125 cur = self.link
00126 if not cur.nilp():
00127 cur._prev = self
00128 while not cur.nilp():
00129 cur.mutate(arg)
00130 cur = cur.link
00131 mutator.clr()
00132
00133 def __cdrn__(self,fn):
00134 if self.nilp(): return 'Nil'
00135
00136 return 'LList(%s)' % ','.join([fn(n) for n in self])
00137
00138 def __repr__(self): return self.__cdrn__(repr)
00139
00140 def __str__(self): return self.__cdrn__(str)
00141
00142 import fval as fv
00143
00144 class _LLMutator(object):
00145 def __init__(self,*a,**kw): pass
00146 def setup(self,*a,**kw): pass
00147 def clr(self,*a,**kw): pass
00148 def mutate(self,*a,**kw) : pass
00149
00150 def vmutate(self,arg=None):
00151 '''use the value mutating function, but pass self so that
00152 list mutating actions take place there
00153 '''
00154 if not arg: arg = Struct()
00155 arg.lines = self
00156 rv = self.val.mutate(arg)
00157 return rv
00158
00159 class LLMutatorVal(_LLMutator):
00160 def __init__(self,vmutator,*a,**kw):
00161 self.vm = vmutator
00162 self.vm_a = a
00163 self.vm_kw = kw
00164
00165 def setup(self):
00166 self.vm.setup(*self.vm_a,**self.vm_kw)
00167 Node.mutator = vmutate
00168
00169 def clr(self):
00170 self.vm.restore(*self.vm_a,**self.vm_kw)
00171 del Node.mutator
00172
00173 class LLMutatorTriv(_LLMutator):
00174 def __init__(self,fn):
00175 self.triv = fn
00176 def setup(self):
00177 Node.mutator = self.triv
00178 def clr(self):
00179 del Node.mutator