1818 "SET_VAR" ,
1919 "POP" ,
2020 "DEREF_VAR" ,
21- "INSTALL" ]
21+ "INSTALL" ,
22+ "RECUR" ,
23+ "ARG" ,
24+ "PUSH_SELF" ]
2225
2326for x in range (len (BYTECODES )):
2427 globals ()[BYTECODES [x ]] = r_uint (x )
2528
26- class TailCall (object .Object ):
27- _type = object .Type ("TailCall" )
28- __immutable_fields_ = ["_f" , "_args" ]
29- def __init__ (self , f , args ):
30- self ._f = f
31- self ._args = args
32-
33- def run (self ):
34- return self ._f ._invoke (self ._args )
29+ # class TailCall(object.Object):
30+ # _type = object.Type("TailCall")
31+ # __immutable_fields_ = ["_f", "_args"]
32+ # def __init__(self, f, args):
33+ # self._f = f
34+ # self._args = args
35+ #
36+ # def run(self):
37+ # return self._f._invoke(self._args)
3538
3639
3740class BaseCode (object .Object ):
@@ -49,8 +52,6 @@ def get_bytecode(self):
4952
5053 def invoke (self , args ):
5154 result = self ._invoke (args )
52- while isinstance (result , TailCall ):
53- result = result .run ()
5455 return result
5556
5657
@@ -145,9 +146,10 @@ def deref(self):
145146 return self .get_root (rev )
146147
147148
148- class VarRegistry (__builtins__ .object ):
149- def __init__ (self ):
149+ class Namespace (__builtins__ .object ):
150+ def __init__ (self , name ):
150151 self ._registry = {}
152+ self ._name = name
151153
152154 def intern_or_make (self , name ):
153155 assert isinstance (name , str )
@@ -157,19 +159,176 @@ def intern_or_make(self, name):
157159 self ._registry [name ] = v
158160 return v
159161
160- _var_registry = VarRegistry ()
162+ def get (self , name , default ):
163+ return self ._registry .get (name , default )
161164
162- def intern_var (name ):
163- return _var_registry .intern_or_make (name )
165+ class NamespaceRegistry (__builtins__ .object ):
166+ def __init__ (self ):
167+ self ._registry = {}
164168
169+ def find_or_make (self , name ):
170+ assert isinstance (name , str )
171+ v = self ._registry .get (name , None )
172+ if v is None :
173+ v = Namespace (name )
174+ self ._registry [name ] = v
175+ return v
165176
166177
167- def as_var (name ):
168- var = intern_var (name )
169- def with_fn (fn ):
170- inst = type ("W" + fn .__name__ , (NativeFn ,), {"inner_invoke" : fn })()
171- var .set_root (inst )
172- return inst
173- return with_fn
178+ def get (self , name , default ):
179+ return self ._registry .get (name , default )
180+
181+ _ns_registry = NamespaceRegistry ()
182+
183+ def intern_var (ns , name = None ):
184+ if name is None :
185+ name = ns
186+ ns = ""
187+
188+ return _ns_registry .find_or_make (ns ).intern_or_make (name )
189+
190+ def get_var_if_defined (ns , name ):
191+ w_ns = _ns_registry .get (ns , None )
192+ if w_ns is None :
193+ return None
194+ return w_ns .get (name , None )
195+
196+
197+
198+
199+
200+
201+ class Protocol (object .Object ):
202+ _type = object .Type ("Protocol" )
203+
204+ def __init__ (self , name ):
205+ self ._name = name
206+ self ._polyfns = {}
207+ self ._satisfies = {}
208+
209+ def add_method (self , pfn ):
210+ self ._polyfns [pfn ] = pfn
211+
212+ def add_satisfies (self , tp ):
213+ self ._satisfies [tp ] = tp
214+
215+ def satisfies (self , tp ):
216+ return tp in self ._satisfies
174217
175218
219+ class PolymorphicFn (BaseCode ):
220+ _type = object .Type ("PolymorphicFn" )
221+
222+ __immutable_fields__ = ["_rev?" ]
223+ def __init__ (self , name , protocol ):
224+ self ._name = name
225+ self ._dict = {}
226+ self ._rev = 0
227+ self ._protocol = protocol
228+ protocol .add_method (self )
229+
230+ def extend (self , tp , fn ):
231+ self ._dict [tp ] = fn
232+ self ._rev += 1
233+ self ._protocol .add_satisfies (tp )
234+
235+ def _invoke (self , args ):
236+ a = args [0 ].type ()
237+ return self ._dict [a ].invoke (args )
238+
239+ class DoublePolymorphicFn (BaseCode ):
240+ _type = object .Type ("DoublePolymorphicFn" )
241+
242+ __immutable_fields__ = ["_rev?" ]
243+ def __init__ (self , name , protocol ):
244+ BaseCode .__init__ (self )
245+ self ._name = name
246+ self ._dict = {}
247+ self ._rev = 0
248+ self ._protocol = protocol
249+ protocol .add_method (self )
250+
251+ def extend2 (self , tp1 , tp2 , fn ):
252+ d1 = self ._dict .get (tp1 , None )
253+ if d1 is None :
254+ d1 = {}
255+ self ._dict [tp1 ] = d1
256+ d1 [tp2 ] = fn
257+ self ._rev += 1
258+ self ._protocol .add_satisfies (tp1 )
259+
260+
261+ @elidable
262+ def get_fn (self , tp1 , tp2 , _rev ):
263+ d1 = self ._dict .get (tp1 , None )
264+ assert d1
265+ fn = d1 .get (tp2 , None )
266+ return promote (fn )
267+
268+ def _invoke (self , args ):
269+ assert len (args ) >= 2
270+ a = args [0 ].type ()
271+ b = args [1 ].type ()
272+ fn = self .get_fn (a , b , self ._rev )
273+ return fn .invoke (args )
274+
275+ def munge (s ):
276+ return s .replace ("-" , "_" )
277+
278+ import inspect
279+ def defprotocol (ns , name , methods ):
280+ gbls = inspect .currentframe ().f_back .f_globals
281+ proto = Protocol (name )
282+ intern_var (ns , name ).set_root (proto )
283+ gbls [munge (name )] = proto
284+ for method in methods :
285+ poly = PolymorphicFn (method , proto )
286+ intern_var (ns , method ).set_root (poly )
287+ gbls [munge (method )] = poly
288+
289+
290+ ## PYTHON FLAGS
291+ CO_VARARGS = 0x4
292+ def wrap_fn (fn ):
293+ def as_native_fn (f ):
294+ return type ("W" + fn .__name__ , (NativeFn ,), {"inner_invoke" : f })()
295+
296+ code = fn .func_code
297+ if code .co_flags & CO_VARARGS :
298+ pass
299+ else :
300+ argc = code .co_argcount
301+ if argc == 0 :
302+ return as_native_fn (lambda self , args : fn ())
303+ if argc == 1 :
304+ return as_native_fn (lambda self , args : fn (args [0 ]))
305+ if argc == 2 :
306+ return as_native_fn (lambda self , args : fn (args [0 ], args [1 ]))
307+ if argc == 3 :
308+ return as_native_fn (lambda self , args : fn (args [0 ], args [1 ]))
309+
310+
311+ def extend (pfn , tp1 , tp2 = None ):
312+ def extend_inner (fn ):
313+ if tp2 is None :
314+ pfn .extend (tp1 , wrap_fn (fn ))
315+ else :
316+ pfn .extend2 (tp1 , tp2 , wrap_fn (fn ))
317+
318+ return pfn
319+
320+ return extend_inner
321+
322+
323+
324+ def as_var (ns , name = None ):
325+ if name is None :
326+ name = ns
327+ ns = "pixie.stdlib"
328+ var = intern_var (ns , name )
329+ def with_fn (fn ):
330+ if not isinstance (fn , BaseCode ):
331+ fn = wrap_fn (fn )
332+ var .set_root (fn )
333+ return fn
334+ return with_fn
0 commit comments