def stm(x): if hasResult(x): dis = ast.Discard(topy(x)) dis.lineno = getmeta(x, 'lineno') return dis else: return topy(x)
def p_expr_stmt(p): """expr_stmt : testlist ASSIGN testlist | testlist """ if len(p) == 2: # a list of expressions p[0] = ast.Discard(p[1]) else: p[0] = Assign(p[1], p[3])
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 parse_data(self, text): start_lineno = lineno = self.lineno pos = 0 end = len(text) nodes = [] def match_or_fail(pos): match = token_re.match(text, pos) if match is None: self.fail('invalid syntax') return match.group().strip(), match.end() def write_expr(code): node = self.parse_python(code, 'eval') nodes.append(call_stmt('__to_unicode', [node], lineno)) return code.count('\n') def write_data(value): if value: nodes.append(ast.Const(value, lineno=lineno)) return value.count('\n') return 0 while 1: offset = text.find('$', pos) if offset < 0: break next = text[offset + 1] if next == '{': lineno += write_data(text[pos:offset]) pos = offset + 2 level = 1 while level: token, pos = match_or_fail(pos) if token in ('{', '}'): level += token == '{' and 1 or -1 lineno += write_expr(text[offset + 2:pos - 1]) elif next in namestart_chars: lineno += write_data(text[pos:offset]) token, pos = match_or_fail(offset + 1) while pos < end: if text[pos] == '.' and pos + 1 < end and \ text[pos + 1] in namestart_chars: token, pos = match_or_fail(pos + 1) elif text[pos] in '([': pos += 1 level = 1 while level: token, pos = match_or_fail(pos) if token in ('(', ')', '[', ']'): level += token in '([' and 1 or -1 else: break lineno += write_expr(text[offset + 1:pos]) else: lineno += write_data(text[pos:offset + 1]) pos = offset + 1 + (next == '$') write_data(text[pos:]) return ast.Discard(call_stmt(len(nodes) == 1 and '__write' or '__write_many', nodes, start_lineno), lineno=start_lineno)
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 _do_ExpressionStatement(self, node): expr = self.transform(node.Expression) return ast.Discard(expr)