def _compile_call(self, text, attribute_handlers=None): import compiler import types from compiler import ast, misc, pycodegen raise NotImplementedError('Incomplete') # TODO Make this work? def _generate(node): if node.type == node.TERM: return ast.Compare(ast.Const(node.value), [('in', ast.Name('text'))]) elif node.type == node.AND: return ast.And([_generate(node.left), _generate(node.right)]) elif node.type == node.OR: return ast.Or([_generate(node.left), _generate(node.right)]) elif node.type == node.NOT: return ast.Not(_generate(node.left)) elif node.type == node.ATTR: raise NotImplementedError qast = ast.Expression( ast.Lambda(['self', 'text', 'attribute_handlers'], [ast.Name('None')], 0, _generate(self))) misc.set_filename('<%s compiled query>' % self.__class__.__name__, qast) gen = pycodegen.ExpressionCodeGenerator(qast) self.__call__ = types.MethodType(eval(gen.getCode()), self, Query) return self.__call__(text)
def _lambda(self, body, args=None): flags, argnames, defaults = funcArgs(args) basel = self.__language__.__impl__ if not hasResult(body): body = basel.getOp("do:")(body, basel.getOp("return")(None)) return ast.Lambda(argnames, defaults, flags, topy(body))
def listpattern(self, exprs): """ Create a call to self.listpattern(lambda: exprs). """ f = ast.Lambda([], [], 0, exprs) f.filename = self.name return ast.CallFunc(ast.Getattr(ast.Name("self"), "listpattern"), [f], None, None)
def many1(self, expr): """ Create a call to self.many((lambda: expr), expr). """ f = ast.Lambda([], [], 0, expr) f.filename = self.name return ast.CallFunc(ast.Getattr(ast.Name("self"), "many"), [f, expr], None, None)
def _lambda(self, body, args=None): flags, argnames, defaults = funcArgs(args) return_ = Symbol(rootops.base_ns, "return") do = Symbol(rootops.base_ns, "do:") if not hasResult(body): body = Doc(do, [body, Doc(return_, [None])]) return ast.Lambda(argnames, defaults, flags, topy(body))
def pred(self, expr): """ Create a call to self.pred(lambda: expr). """ f = ast.Lambda([], [], 0, expr) f.filename = self.name return ast.CallFunc(ast.Getattr(ast.Name("self"), "pred"), [f], None, None)
def MAKE_FUNCTION(decompiler, argc): if argc: throw(NotImplementedError) tos = decompiler.stack.pop() codeobject = tos.value func_decompiler = Decompiler(codeobject) # decompiler.names.update(decompiler.names) ??? if codeobject.co_varnames[:1] == ('.0',): return func_decompiler.ast # generator argnames = codeobject.co_varnames[:codeobject.co_argcount] defaults = [] # todo flags = 0 # todo return ast.Lambda(argnames, defaults, flags, func_decompiler.ast)
def _or(self, exprs): """ Create a call to self._or([lambda: expr1, lambda: expr2, ... , lambda: exprN]). """ fs = [] for expr in exprs: f = ast.Lambda([], [], 0, expr) f.filename = self.name fs.append(f) return ast.CallFunc(ast.Getattr(ast.Name("self"), "_or"), [ast.List(fs)], None, None)
def function(self, name, expr): """ Create a function of one argument with the given name returning the given expr. @param name: The function name. @param expr: The AST to insert into the function. """ fexpr = ast.Stmt([ast.Assign([ast.AssName('__locals', 'OP_ASSIGN')], ast.Dict([(ast.Const('self'), ast.Name('self'))])), ast.Assign([ast.Subscript(ast.Getattr( ast.Name('self'), 'locals'), 'OP_ASSIGN', [ast.Const( name.split('_',1)[1])])], ast.Name('__locals')), expr]) f = ast.Lambda(['self'], [], 0, fexpr) f.filename = self.name return f
def _do_LambdaExpression(self, node): function = node.Function argnames, defaults, flags = self.function_info(function) code = self.transform(function.Body.Expression) return ast.Lambda(argnames, defaults, flags, code)