def compileDeflang(self, name, parentx, body): assert isinstance(name, Symbol) if parentx: assertResult(parentx, "derive language from") parent = topy(parentx) else: parent = logixglobal('langlang') funcname = "#lang:%s" % name body = len(body) > 0 and block(body, False).nodes or [] funcbody = ast.Stmt( body + [ast.CallFunc(ast.Getattr(ast.Getattr(ast.Name(str(name)), '__impl__'), 'addDeflangLocals'), [ast.CallFunc(ast.Name('locals'), [])])]) res = ast.Stmt([ ast.Assign([compilePlace(Symbol(name))], ast.CallFunc(logixglobal('defLanguage'), [ast.Const(str(name)), parent, ast.CallFunc(GlobalName("globals"), [])])), astFunction(funcname, tuple(), tuple(), 0, None, funcbody), ast.CallFunc(ast.Name(funcname), []), ast.AssName(funcname, 'OP_DELETE')]) lineno = getmeta(self, 'lineno') for n in res.nodes: n.lineno = lineno res.lineno = lineno return res
def block(lst, withResult, prepend=None): if len(lst) == 0: if withResult: return ast.Const(None) else: return ast.Pass() def stm(x): if hasResult(x): dis = ast.Discard(topy(x)) dis.lineno = getmeta(x, 'lineno') return dis else: return topy(x) if withResult: stms = [stm(s) for s in lst[:-1]] last = lst[-1] lastpy = topy(last) if hasResult(last): # Insert a pass so pycodegen emits a SET_LINENO p = ast.Pass() p.lineno = getmeta(last, 'lineno') statements = stms + [p, lastpy] else: statements = stms + [lastpy, ast.Const(None)] else: statements = [stm(s) for s in lst] if prepend: return ast.Stmt(prepend + statements) else: return ast.Stmt(statements)
def p_suite(p): """suite : simple_stmt | NEWLINE INDENT stmts DEDENT""" if len(p) == 2: p[0] = ast.Stmt(p[1]) else: p[0] = ast.Stmt(p[3])
def compileCodeObjects(filename, codeobjs): if len(codeobjs) == 0: stmts = [] else: stmts = [ast.For(ast.AssName('[--codeobj--]', 'OP_ASSIGN'), ast.Const(codeobjs), ast.Stmt([ast.Exec(ast.Name('[--codeobj--]'), None, None)]), None), ast.AssName('[--codeobj--]', 'OP_DELETE')] module = ast.Module(None, ast.Stmt(stmts)) compiler.misc.set_filename(filename, module) return pycodegen.ModuleCodeGenerator(module).getCode()
def file_input(self, nodelist): # Add a "from IO_MODULE import IO_CLASS" statement to the # beginning of the module. doc = None # self.get_docstring(nodelist, symbol.file_input) if sys.hexversion >= 0x02050000: io_imp = ast.From(IO_MODULE, [(IO_CLASS, None)], 0) markup_imp = ast.From(MARKUP_MODULE, [(MARKUP_CLASS, None)], 0) else: io_imp = ast.From(IO_MODULE, [(IO_CLASS, None)]) markup_imp = ast.From(MARKUP_MODULE, [(MARKUP_CLASS, None)]) markup_assign = ast.Assign( [ast.AssName(MARKUP_MANGLED_CLASS, OP_ASSIGN)], ast.Name(MARKUP_CLASS)) # Add an IO_INSTANCE binding for module level expressions (like # doc strings). This instance will not be returned. io_instance = ast.CallFunc(ast.Name(IO_CLASS), []) io_assign_name = ast.AssName(IO_INSTANCE, OP_ASSIGN) io_assign = ast.Assign([io_assign_name], io_instance) stmts = [io_imp, io_assign, markup_imp, markup_assign] for node in nodelist: if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: self.com_append_stmt(stmts, node) return ast.Module(doc, ast.Stmt(stmts))
def transform_suite(self, node): if node is None: return None node = self.transform(node) if not isinstance(node, ast.Stmt): node = ast.Stmt([node]) return node
def file_input(self, nodelist): doc = None # self.get_docstring(nodelist, symbol.file_input) if sys.hexversion >= 0x02050000: html_imp = ast.From( 'quixote.html', [('TemplateIO', '_q_TemplateIO'), ('htmltext', '_q_htmltext')], 0) vars_imp = ast.From("__builtin__", [("vars", "_q_vars")], 0) else: html_imp = ast.From( 'quixote.html', [('TemplateIO', '_q_TemplateIO'), ('htmltext', '_q_htmltext')]) vars_imp = ast.From("__builtin__", [("vars", "_q_vars")]) ptl_imports = [ vars_imp, html_imp ] stmts = [] for node in nodelist: if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: self.com_append_stmt(stmts, node) # count __future__ statements i = 0 for stmt in stmts: if isinstance(stmt, ast.From) and stmt.modname == '__future__': i += 1 else: break stmts[i:i] = ptl_imports return ast.Module(doc, ast.Stmt(stmts))
def visitAugAssign(self, node): if isinstance(node.node, ast.Name) and ( not self.locals or node.node.name not in flatten(self.locals)): name = node.node.name node.node = ast.Subscript(ast.Name('data'), 'OP_APPLY', [ast.Const(name)]) node.expr = self.visit(node.expr) return ast.If( [(ast.Compare(ast.Const(name), [('in', ast.Name('data'))]), ast.Stmt([node]))], ast.Stmt([ ast.Raise( ast.CallFunc(ast.Name('UndefinedError'), [ast.Const(name)]), None, None) ])) else: return ASTTransformer.visitAugAssign(self, node)
def block(lst, withResult, prepend=None): if len(lst) == 0: if withResult: return ast.Const(None) else: return ast.Pass() def stm(x): if hasResult(x): dis = ast.Discard(topy(x)) dis.lineno = getattr(x, 'lineno', None) return dis else: return topy(x) if withResult: stms = [stm(s) for s in lst[:-1]] last = lst[-1] lastpy = topy(last) if hasResult(last): # Insert a pass so pycodegen emits a SET_LINENO p = ast.Pass() p.lineno = getattr(last, "lineno", None) statements = stms + [p, lastpy] else: statements = stms + [lastpy, ast.Const(None)] else: statements = [stm(s) for s in lst] # HACK: No lineno info was emitted for "del a[0]" statements # (insert a Pass to fix that) s2 = [] for s in statements: if isinstance(s, ast.Subscript) and s.flags == "OP_DELETE" and hasattr(s, "lineno"): p = ast.Pass() p.lineno = s.lineno s2.append(p) s2.append(s) if prepend: return ast.Stmt(prepend + s2) else: return ast.Stmt(s2)
def sequence(self, exprs): """ Creates a sequence of exprs, returning the value of the last one. """ if len(exprs) > 0: stmtExprs = [ast.Discard(e) for e in exprs[:-1]] + [exprs[-1]] return ast.Stmt(stmtExprs) else: return ast.Const(None)
def quote(obj, depth=1): assert depth > 0 if isinstance(obj, rootops.quote): depth += 1 elif isinstance(obj, rootops.escape): extra = obj.__operands__.get('extra', []) escapelevel = 1 + len(extra) if escapelevel > depth: raise CompileError("invalid quote escape") elif escapelevel == depth: if obj.__operands__.hasField('splice'): raise CompileError("Can't splice here") elif obj.__operands__.hasField("localmodule"): return topy(localModuleQuote()) else: assertResult(obj[0], "insert into quote") return topy(obj[0]) if isinstance(type(obj), OperatorType): # {{{ generate code to build the operator cls = obj.__class__ if cls.__module__ == '%s.rootops' % logixModuleName: classx = ast.Getattr(logixglobal('rootops'), cls.__name__) else: optoken = obj.__class__.__syntax__.token classx = compileGetOp(obj) operands = macros.gensym("operands") return ast.Stmt([ast.Assign([compilePlace(operands)], quotedArgs(obj.__operands__, depth)), ast.CallFunc(classx, [], ast.Getattr(topy(operands), "elems"), ast.Getattr(topy(operands), "fields"))]) # }}} elif isinstance(obj, flist): # {{{ generate code to build the flist return quotedArgs(obj, depth) # }}} elif isinstance(obj, Symbol): # {{{ generate code to build the symbol return ast.CallFunc(logixglobal('Symbol'), [ast.Const(obj.asStr())]) # }}} elif isinstance(obj, (tuple, list, dict)): # Q: Is this ok? assert 0, "didn't expect one of those to be quoted" else: return topy(obj)
def bind(self, expr, name): """ Generates code for binding a name to a value in the rule's locals dict. """ return ast.Stmt([ ast.Assign([ast.Subscript(ast.Name('__locals'), 'OP_ASSIGN', [ast.Const(name)])], expr), ast.Subscript(ast.Name('__locals'), 'OP_APPLY', [ast.Const(name)])])
def run(self, frame): # fall-back for unknown statement nodes try: expr = ast.Module(None, ast.Stmt([self.__obj__])) expr.filename = '<run>' co = pycodegen.ModuleCodeGenerator(expr).getCode() frame.exec_(co) except passthroughex: raise except: raise Failure(self)
def parse(self, needle=()): start_lineno = self.lineno result = [] add = result.append for self.lineno, token, value in self.gen: if token == 'data': add(self.parse_data(value)) elif token == 'code': add(self.parse_code(value.splitlines())) elif token == 'cmd': name, args = value if name in needle: return name, args, ast.Stmt(result, lineno=start_lineno) if name in ('for', 'while'): add(self.parse_loop(args, name)) elif name == 'if': add(self.parse_if(args)) else: self.fail('unknown directive %s' % name) if needle: self.fail('unexpected end of template') return ast.Stmt(result, lineno=start_lineno)
def file_input(self, nodelist): doc = None # self.get_docstring(nodelist, symbol.file_input) html_imp = ast.From('quixote.html', [('TemplateIO', '_q_TemplateIO'), ('htmltext', '_q_htmltext')]) vars_imp = ast.From("__builtin__", [("vars", "_q_vars")]) stmts = [ vars_imp, html_imp ] for node in nodelist: if node[0] != token.ENDMARKER and node[0] != token.NEWLINE: self.com_append_stmt(stmts, node) return ast.Module(doc, ast.Stmt(stmts))
def compilePythonExpr(self, name, expr): """ Compile an embedded Python expression. @param name: The current rule name. @param expr: The Python expression to compile. """ c = python_compile(expr, "<grammar rule %s>" % (name,), "eval") return ast.Stmt([ ast.CallFunc(ast.Name('eval'), [ast.Const(c), ast.Getattr(ast.Name("self"), "globals"), ast.Name('__locals')])])
def run(self, frame): expr = Interpretable(self.expr) expr.eval(frame) self.result = expr.result self.explanation = '... = ' + expr.explanation # fall-back-run the rest of the assignment ass = ast.Assign(self.nodes, ast.Name('__exprinfo_expr')) mod = ast.Module(None, ast.Stmt([ass])) mod.filename = '<run>' co = pycodegen.ModuleCodeGenerator(mod).getCode() try: frame.exec_(co, __exprinfo_expr=expr.result) except passthroughex: raise except: raise Failure(self)
def compileGetops(doc): fromlang = doc[0] targetlang = doc.get("lang") ops = [op.strip() for op in doc[1:]] if targetlang is None: raise CompileError("No target language for getops" "(getops in non-exec parse?)") assertResult(fromlang, "get operators from") lineno = getattr(doc, 'lineno', None) lastdot = targetlang.rfind('.') if lastdot == -1: def targetlangexpr(): return GlobalName(targetlang) else: assert 0, ("PROBE: Why are we getting ops into an imported language?") langname = targetlang[lastdot+1:] langmod = targetlang[:lastdot] def targetlangexpr(): return ast.Getattr(ast.Subscript(logixglobal('lmodules'), 'OP_APPLY', [ast.Const(langmod)]), langname) if len(ops) == 0: # get all operators res = ast.CallFunc(ast.Getattr(ast.Getattr(targetlangexpr(), '__impl__'), 'addAllOperators'), [topy(fromlang)]) else: stmts = [ast.CallFunc(ast.Getattr(ast.Getattr(targetlangexpr(), '__impl__'), 'addOp'), [ast.CallFunc(ast.Getattr(ast.Getattr(topy(fromlang), "__impl__"), "getOp"), [ast.Const(op), ast.Const(False)])]) for op in ops] for s in stmts: s.lineno = lineno res = ast.Stmt(stmts) res.lineno = lineno return res
def compileGetops(self, fromlang, *ops, **kw): targetlang = kw.get("lang") if targetlang is None: raise CompileError("No target language for getops" "(getops in non-exec parse?)") assertResult(fromlang, "get operators from") lineno = getmeta(self, 'lineno') lastdot = targetlang.rfind('.') if lastdot == -1: targetlangexpr = GlobalName(targetlang) else: assert 0, ("PROBE: Why are we getting ops into an imported language?") langname = targetlang[lastdot+1:] langmod = targetlang[:lastdot] targetlangexpr = ast.Getattr(ast.Subscript(logixglobal('lmodules'), 'OP_APPLY', [ast.Const(langmod)]), langname) if len(ops) == 0: # get all operators res = ast.CallFunc(ast.Getattr(ast.Getattr(targetlangexpr, '__impl__'), 'addAllOperators'), [topy(fromlang)]) else: stmts = [ast.CallFunc(ast.Getattr(ast.Getattr(targetlangexpr, '__impl__'), 'addOp'), [compileGetOp(op)]) for op in ops] for s in stmts: s.lineno = lineno res = ast.Stmt(stmts) res.lineno = lineno return res
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 p_file_input_end(p): """file_input_end : file_input ENDMARKER""" p[0] = ast.Stmt(p[1])
def _do_SuiteStatement(self, node): nodes = map(self.transform, node.Statements) return ast.Stmt(nodes)
def compileDefop(self, binding, ruledef, smartspace=None, assoc='left', imp=None, lang=None): if lang is None: raise CompileError("invalid defop") assertResult(ruledef, "use in defop") assertResult(binding, "use in defop") lineno = getmeta(self, 'lineno') # {{{ token = extract from ruledef def islit(x): return x[0][0] == 'LiteralRule' if islit(ruledef): token = ruledef[1] elif ruledef[0][0] == 'SequenceRule': rules = ruledef[1:] if len(rules) > 1 and islit(rules[0]): token = rules[0][1] elif len(rules) > 1 and islit(rules[1]): token = rules[1][1] else: raise CompileError("invalid ruledef") else: raise CompileError("invalid ruledef") # }}} if imp: if imp['kind'] == 'm': funcname = 'macro' elif imp['kind'] == 'f': funcname = 'func' else: assert 0, "invalid implementation kind: %s" % imp.kind impfuncname = 'operator[%s]' % token # {{{ impfunc = argflags, argnames, argdefaults = funcArgs(imp.get('args')) impfunc = astFunction(impfuncname, argnames, argdefaults, argflags, None, #docstring ast.Return(block(imp['body'], True))) impfunc.lineno = lineno # }}} else: funcname = None impfuncname = "None" impfunc = None lastdot = lang.rfind('.') if lastdot == -1: langexpr = GlobalName(lang) else: assert 0, "PROBE: Why are we adding an op to an imported language?" langname = lang[lastdot+1:] langmod = lang[:lastdot] langexpr = ast.Getattr(ast.Subscript(logixglobal('lmodules'), 'OP_APPLY', [ast.Const(langmod)]), langname) newOpCall = ast.CallFunc( ast.Getattr(ast.Getattr(langexpr, '__impl__'), 'newOp'), [ast.Const(token), topy(binding), topy(ruledef), ast.Const(smartspace), ast.Const(assoc), ast.Const(funcname), ast.Name(impfuncname) ]) if impfunc: return ast.Stmt([impfunc, newOpCall]) else: return newOpCall
def funcdef(self, nodelist): if len(nodelist) == 6: assert nodelist[0][0] == symbol.decorators decorators = self.decorators(nodelist[0][1:]) else: assert len(nodelist) == 5 decorators = None lineno = nodelist[-4][2] name = nodelist[-4][1] args = nodelist[-3][2] if not re.match('_q_((html|plain)_)?template_', name): # just a normal function, let base class handle it self.__template_type.append(None) n = transformer.Transformer.funcdef(self, nodelist) else: if name.startswith(PLAIN_TEMPLATE_PREFIX): name = name[len(PLAIN_TEMPLATE_PREFIX):] template_type = "plain" elif name.startswith(HTML_TEMPLATE_PREFIX): name = name[len(HTML_TEMPLATE_PREFIX):] template_type = "html" elif name.startswith(TEMPLATE_PREFIX): name = name[len(TEMPLATE_PREFIX):] template_type = "plain" else: raise RuntimeError, 'unknown prefix on %s' % name self.__template_type.append(template_type) # Add "IO_INSTANCE = IO_CLASS()" statement at the beginning of # the function and a "return IO_INSTANCE" at the end. if args[0] == symbol.varargslist: names, defaults, flags = self.com_arglist(args[1:]) else: names = defaults = () flags = 0 doc = None # self.get_docstring(nodelist[-1]) # code for function code = self.com_node(nodelist[-1]) # create an instance, assign to IO_INSTANCE klass = ast.Name(IO_CLASS) args = [ast.Const(template_type == "html")] instance = ast.CallFunc(klass, args) assign_name = ast.AssName(IO_INSTANCE, OP_ASSIGN) assign = ast.Assign([assign_name], instance) # return the IO_INSTANCE.getvalue(...) func = ast.Getattr(ast.Name(IO_INSTANCE), "getvalue") ret = ast.Return(ast.CallFunc(func, [])) # wrap original function code code = ast.Stmt([assign, code, ret]) if sys.hexversion >= 0x20400a2: n = ast.Function(decorators, name, names, defaults, flags, doc, code) else: n = ast.Function(name, names, defaults, flags, doc, code) n.lineno = lineno self.__template_type.pop() return n
def quotedArgs(operands, depth): """ Generate code from an flist of operand expressions, possibly containing splices. Returns an expression that constructs an flist. """ parts = [] for x in operands.elems: if isinstance(x, rootops.escape): extra = x.__operands__.get('extra', []) escapelevel = 1 + len(extra) if escapelevel > depth: raise CompileError("invalid quote escape") escape = escapelevel == depth else: escape = False if escape: if x.__operands__.hasField("splice"): assertResult(x[0], "insert into quote") parts.append( ('s', topy(x[0])) ) # 's' == splice elif x.__operands__.hasField("localmodule"): parts.append( ('v',topy(localModuleQuote())) ) else: assertResult(x[0], "insert into quote") parts.append( ('v', topy(x[0])) ) # 'v' == plain value else: parts.append( ('v', quote(x, depth)) ) # 'v' == plain value # {{{ expr = reduce parts to a single expression # If there is just a single splice, then that is the expression # otherwise generate: val = ??; val.extend(??); val.extend(??)... def frontSection(parts): vals = list(itools.takewhile(lambda (tag, exp): tag == 'v', parts)) if len(vals) == 0: return parts[0][1], parts[1:] else: return ast.List([v[1] for v in vals]), parts[len(vals):] if len(parts) == 0: expr = ast.List([]) else: first, rest = frontSection(parts) if len(rest) == 0: expr = first else: # Generate: # val = ...; if not hasattr(val, 'extend'): val = list(val) val = macros.gensym("val") statements = [ ast.Assign([compilePlace(val)], first), ast.If([(ast.CallFunc(GlobalName('isinstance'), [topy(val), logixglobal("flist")]), ast.Assign([compilePlace(val)], ast.CallFunc(ast.Getattr(topy(val), "copy"), [])))], #else ast.Assign([compilePlace(val)], ast.CallFunc(GlobalName('list'), [topy(val)])))] while len(rest) > 0: ex, rest = frontSection(rest) statements.append(ast.Discard(ast.CallFunc(ast.Getattr(topy(val), "extend"), [ex]))) statements.append(topy(val)) expr = ast.Stmt(statements) # }}} for v in operands.fields.values(): assertResult(v, "use as operand") keywords = ast.Dict([(ast.Const(n), quote(v, depth)) for n, v in operands.items()]) if isinstance(expr, ast.List): return ast.CallFunc(ast.Getattr(logixglobal("flist"), 'new'), [expr, keywords]) else: return ast.Add([expr, ast.CallFunc(ast.Getattr(logixglobal("flist"), 'new'), [ast.List([]), keywords])])
def quotedDoc(doc, depth): """ Generate code to build a Doc like `doc` with quote-escapes replaced by runtime values. """ # Each element of contentParts is either: # an AST - meaning a spliced value - the resulting content # should be `extend`ed by that value # a list of ASTs - a list of regular elements, the resulting # content should be `extend`ed by an ast.List # with these elements # {{{ contentParts = contentParts = [[]] for x in doc.content(): if isDoc(x, rootops.escape): escapelevel = 1 + len(x.get('extra', [])) if escapelevel > depth: raise CompileError("more quote escapes than quotes") escape = escapelevel == depth else: escape = False if escape: if x.hasProperty("splice"): assertResult(x[0], "insert into quote") contentParts.append(topy(x[0])) contentParts.append([]) elif x.hasProperty("localmodule"): contentParts[-1].append(topy(localModuleQuote())) else: assertResult(x[0], "insert into quote") contentParts[-1].append(topy(x[0])) else: contentParts[-1].append(quote(x, depth)) # }}} # These properties are added to the result doc *after* # any spliced in docs, so they overwrite any spliced properties for v in doc.propertyValues(): assertResult(v, "use as operand") properties = ast.Dict([(compileSymbol(n), quote(v, depth)) for n, v in doc.properties()]) # assert isinstance(contentParts[0], list) if contentParts == [[]]: return ast.CallFunc(logixglobal("Doc"), [compileSymbol(doc.tag), properties]) else: if len(contentParts[0]) > 0: docArg = ast.List(contentParts[0]) rest = contentParts[1:] elif len(contentParts) > 0: docArg = contentParts[1] rest = contentParts[2:] if len(rest) == 0: return ast.CallFunc(logixglobal("Doc"), [compileSymbol(doc.tag), docArg, properties]) else: val = macros.gensym("val") stmts = [ast.Assign([compilePlace(val)], ast.CallFunc(logixglobal("Doc"), [compileSymbol(doc.tag), docArg]))] for part in rest: if isinstance(part, list): if len(part) == 0: continue ext = ast.List(part) else: ext = part stmts.append(ast.Discard(ast.CallFunc(ast.Getattr(topy(val), "extend"), [ext]))) stmts.append(ast.Discard(ast.CallFunc(ast.Getattr(topy(val), "extend"), [properties]))) stmts.append(topy(val)) return ast.Stmt(stmts)
def compileDefop(doc): binding = doc['binding'] ruledef = doc['ruledef'] smartspace = doc.get('smartspace') assoc = doc.get('assoc', 'left') imp = doc.get('imp') lang = doc.get('lang') if lang is None: raise CompileError("invalid defop") assertResult(ruledef, "use in defop") assertResult(binding, "use in defop") lineno = getattr(doc, "lineno", None) # {{{ token = extract from ruledef def islit(x): return x[0][0] == 'LiteralRule' if islit(ruledef): token = ruledef[1] elif ruledef[0][0] == 'SequenceRule': rules = ruledef[1:] if len(rules) > 1 and islit(rules[0]): token = rules[0][1] elif len(rules) > 1 and islit(rules[1]): token = rules[1][1] else: raise CompileError("invalid ruledef") else: raise CompileError("invalid ruledef") # }}} if imp: if imp['kind'] == 'm': impkind = 'macro' elif imp['kind'] == 'f': impkind = 'func' else: assert 0, "invalid implementation kind: %s" % imp.kind impfuncname = 'operator[%s]' % token # {{{ impfunc = argflags, argnames, argdefaults = funcArgs(imp.get('args')) impfunc = astFunction(impfuncname, argnames, argdefaults, argflags, None, #docstring ast.Return(block(imp['body'], True))) impfunc.lineno = lineno # }}} impArgs = [ast.Const(impkind), ast.Name(impfuncname)] else: impArgs = [] lastdot = lang.rfind('.') if lastdot == -1: langexpr = GlobalName(lang) else: assert 0, "PROBE: Why are we adding an op to an imported language?" langname = lang[lastdot+1:] langmod = lang[:lastdot] langexpr = ast.Getattr(ast.Subscript(logixglobal('lmodules'), 'OP_APPLY', [ast.Const(langmod)]), langname) # If unmarshallable objects get into the code-object, you get a # blanket error message, so check these before they go in. assert isinstance(token, str) assert isinstance(smartspace, str) or smartspace == None assert isinstance(assoc, str) newOpCall = ast.CallFunc( ast.Getattr(ast.Getattr(langexpr, '__impl__'), 'newOp'), [ast.Const(token), topy(binding), topy(ruledef), ast.Const(smartspace), ast.Const(assoc)] + impArgs) if impArgs != []: return ast.Stmt([impfunc, newOpCall]) else: return newOpCall
def p_program(p): """program : file_input ENDMARKER""" p[0] = ast.Stmt(p[1])