예제 #1
0
파일: pycompile.py 프로젝트: manbaum/Logix
 def stm(x):
     if hasResult(x):
         dis = ast.Discard(topy(x))
         dis.lineno = getmeta(x, 'lineno')
         return dis
     else:
         return topy(x)
예제 #2
0
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])
예제 #3
0
 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)
예제 #4
0
    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)
예제 #5
0
파일: pycompile.py 프로젝트: manbaum/Logix
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])])
예제 #6
0
파일: pycompile.py 프로젝트: manbaum/Logix
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)
예제 #7
0
 def _do_ExpressionStatement(self, node):
     expr = self.transform(node.Expression)
     return ast.Discard(expr)