def _generate_code(self): self.cache = cache = self.static_cache.copy() def callback(*args, **kw): types = tuple( [getattr(arg, '__class__', type(arg)) for arg in args]) key = tuple(map(istype, types)) self.__lock__.acquire() try: action = self.rules.default_action for sig in self.registry: if implies(key, sig): action = combine_actions(action, self.registry[sig]) f = cache[types] = compile_method(action, self) finally: self.__lock__.release() return f(*args, **kw) c = Code.from_function(self.function, copy_lineno=True) types = [ class_or_type_of(Local(name)) for name in flatten(inspect.getargspec(self.function)[0]) ] target = Call(Const(cache.get), (tuple(types), Const(callback))) c.return_(call_thru(self.function, target)) return c.code()
def class_or_type_of(expr): return Suite([ expr, TryExcept( Suite([ Getattr(Code.DUP_TOP, '__class__'), Code.ROT_TWO, Code.POP_TOP ]), [(Const(AttributeError), Call(Const(type), (Code.ROT_TWO, )))]) ])
def _regen_code(self): c = Code.from_function(self.function, copy_lineno=True) c.return_( call_thru( self.function, Call( Getattr( Call(Const(Dispatching), (Const(self.function), ), fold=False), '_regenerate')))) return c.code()
def testBackquoteParsing(self): from peak.rules.predicates import Compare, Call, Const from peak.rules.syntax import Bind self.assertEqual( self.parse('type(`x`) is `y`'), Compare(Call(Const(type), (Bind('x'), ), (), (), (), True), (('is', Bind('y')), )))
def as_abstract(self): for action in self.rules: raise AssertionError("Can't make abstract: rules already exist") c = Code.from_function(self.function, copy_lineno=True) c.return_(call_thru(self.function, Const(self.rules.default_action))) if self.backup is None: setattr(self.function, CODE, c.code()) else: self.backup = c.code() return self.function
def Const(self, value): return Const(value)