예제 #1
0
def p_if_stmt(p):
    """if_stmt  :   IF test COLON suite elif_expr
                |   IF test COLON suite elif_expr ELSE COLON suite
    """
    if len(p) == 6:
        p[0] = ast.If([(p[2], p[4])], p[5])
    else:
        p[0] = ast.If([(p[2], p[4])], [(p[5], p[8])])
예제 #2
0
 def visitIf(self, node):
     if len(node.tests) == 1:
         self.visitSingleIf(node.tests[0][0], node.tests[0][1], node.else_)
     else:
         test = node.tests[0]
         else_ = ast.If(tests=node.tests[1:], else_=node.else_)
         self.visitSingleIf(test[0], test[1], else_)
예제 #3
0
def p_elif_expr(p):
    """elif_expr    :
                    | ELIF test COLON suite elif_expr
    """
    if (len(p) > 2):
        p[0] = ast.If([(p[2], p[4])], p[5])
    else:
        p[0] = []
예제 #4
0
 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)
예제 #5
0
파일: pycompile.py 프로젝트: manbaum/Logix
    def _if(self, tests, else_=None):
        for test in tests:
                assertResult(test['test'], "use as if test")
                
        tests = [(el['test'], el['body']) for el in tests]

        pytests = []
        for t,b in tests:
            pyt = topy(t)
            pyt.lineno = getattr(t, 'lineno', None)
            pytests.append( (pyt, block(b, True)) )

        # HACK: For line numbers. Workaround for a test with no metadata
        # (e.g. just a symbol)
        # TODO: make this work for elifs (it doesn't)
        if pytests[0][0].lineno is None:
            pytests[0][0].lineno =  getattr(self, 'lineno', None)

        if else_: else_ = block(else_, True)

        return ast.If(pytests, else_ or ast.Const(None))
예제 #6
0
파일: pycompile.py 프로젝트: manbaum/Logix
    def _if(self, test, body, elifs=None, _else=None):
        assertResult(test, "use as if test")

        if elifs:
            for el in elifs:
                assertResult(el['test'], "use as elif test")
            tests = [(test, body)] + [(el['test'], el['body']) for el in elifs]
        else:
            tests = [(test, body)]

        pytests = []
        for t,b in tests:
            pyt = topy(t)
            pyt.lineno = getmeta(t, 'lineno')
            pytests.append( (pyt, block(b, True)) )

        # HACK: For line numbers. Workaround for a test with no metadata
        # (e.g. just a symbol), but this doesn't work for elifs
        if pytests[0][0].lineno is None:
            pytests[0][0].lineno =  getmeta(self, 'lineno')

        if _else: _else = block(_else, True)

        return ast.If(pytests, _else or ast.Const(None))
예제 #7
0
def p_if_stmt(p):
    'if_stmt : IF test COLON suite'
    p[0] = ast.If([(p[2], p[4])], None)
예제 #8
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])])
예제 #9
0
def translate(node, st=None, strings=None, funcName=False):
    if isinstance(node, oast.Add):
        left = translate(node.left, st, strings, funcName)
        right = translate(node.right, st, strings, funcName)

        return ast.Add(left, right)

    elif isinstance(node, oast.And):
        left = translate(node.nodes[0], st, strings, funcName)
        right = translate(node.nodes[1], st, strings, funcName)

        return ast.And(left, right)

    elif isinstance(node, oast.Assign):
        # Translate the right hand side first so it can use the older version
        # of the left hand side.
        exp = translate(node.expr, st, strings, funcName)
        var = node.nodes.pop()

        if isinstance(var, oast.AssAttr):
            string = strings.setdefault(var.attrname, ast.String(var.attrname))
            var = translate(var.expr, st, strings, funcName)

            return ast.SetAttr(var, string, exp)

        else:
            var = translate(var, st, strings, funcName)

            return ast.Assign(var, exp)

    elif isinstance(node, oast.AssName):
        return st.getSymbol(node.name, True)

    elif isinstance(node, oast.CallFunc):
        name = translate(node.node, st, strings, True)
        args = [translate(a, st, strings) for a in node.args]

        return ast.FunctionCall(name, *args)

    elif isinstance(node, oast.Class):
        bases = [translate(base, st, strings, funcName) for base in node.bases]

        body = translate(node.code, st, strings, funcName)
        body = ast.BasicBlock(body)

        sym = st.getSymbol(node.name, True)
        name = st.getName(node.name, True)

        # This is here temporarily.  It will be moved to the typify pass
        # later.
        sym['type'] = 'class'

        klass = ast.Class(name, bases, body)

        return ast.Assign(sym, klass)

    elif isinstance(node, oast.Compare):
        left = translate(node.expr, st, strings, funcName)

        op, right = node.ops[0]

        right = translate(right, st, strings, funcName)

        if op == '==':
            return ast.Eq(left, right)

        elif op == '!=':
            return ast.Ne(left, right)

        elif op == 'is':
            return ast.Is(left, right)

    elif isinstance(node, oast.Const):
        return ast.Integer(node.value)

    elif isinstance(node, oast.Dict):
        pairs = {}

        for pair in node.items:
            key, value = pair

            key = translate(key, st, strings, funcName)
            value = translate(value, st, strings, funcName)

            pairs[key] = value

        return ast.Dictionary(pairs)

    elif isinstance(node, oast.Discard):
        return translate(node.expr, st, strings, funcName)

    elif isinstance(node, oast.Div):
        left = translate(node.left, st, strings, funcName)
        right = translate(node.right, st, strings, funcName)

        return ast.Div(left, right)

    elif isinstance(node, oast.Function):
        sym = st.getSymbol(node.name, True)
        name = st.getName(node.name, True)

        sym['type'] = 'function'

        newST = SymbolTable(st)

        argSymbols = [
            newST.getSymbol(argName, True) for argName in node.argnames
        ]

        body = translate(node.code, newST, strings, funcName)
        body = ast.BasicBlock(body)

        fun = ast.Function(name, argSymbols, body, newST)
        fun['simplified'] = False

        st.update(newST)

        return ast.Assign(sym, fun)

    elif isinstance(node, oast.Getattr):
        exp = translate(node.expr, st, strings, funcName)
        name = strings.setdefault(node.attrname, ast.String(node.attrname))

        return ast.GetAttr(exp, name)

    elif isinstance(node, oast.If):
        tests = node.tests
        cond, then = tests.pop(0)

        # Translate the conditional expression.
        cond = translate(cond, st, strings)

        # Snapshot the SymbolTable
        st.snapshot()

        # Translate the 'then' clause.
        then = translate(then, st, strings, funcName)
        then = ast.BasicBlock(then)

        # Roll-back the SymbolTable for the 'else' clause.
        st.rollback()

        # Translate the 'else' clause.
        if len(tests) > 0:
            els = [translate(oast.If(tests, node.else_), st, funcName)]
        else:
            els = translate(node.else_, st, strings, funcName)

        els = ast.BasicBlock(els)

        return ast.If(cond, then, els, st)

    elif isinstance(node, oast.IfExp):
        cond = translate(node.test, st, strings, funcName)
        then = translate(node.then, st, strings, funcName)
        els = translate(node.else_, st, strings, funcName)

        return ast.IfExp(cond, then, els)

    elif isinstance(node, oast.Lambda):
        name = st.getName('lambda', True)

        newST = SymbolTable(st)

        argSymbols = map(lambda name: newST.getSymbol(name, True),
                         node.argnames)

        code = ast.Return(translate(node.code, newST, strings, funcName))
        block = ast.BasicBlock([code])
        fun = ast.Function(name, argSymbols, block, newST)
        fun['simplified'] = False

        st.update(newST)

        return fun

    elif isinstance(node, oast.List):
        elements = []

        for n in node.nodes:
            elements.append(translate(n, st, strings, funcName))

        return ast.List(elements)

    elif isinstance(node, oast.Module):
        # Create a new SymbolTable for this module.
        st = SymbolTable()
        strings = {}

        children = translate(node.node, st, strings, funcName)

        block = ast.BasicBlock(children)
        fun = ast.Function(st.getBIF('main'), [], block, st)

        # Mark the main function as migrated so that it doesn't get moved
        # later.
        fun['simplified'] = True

        return ast.Module([fun], strings)

    elif isinstance(node, oast.Mul):
        left = translate(node.left, st, strings, funcName)
        right = translate(node.right, st, strings, funcName)

        return ast.Mul(left, right)

    elif isinstance(node, oast.Name):
        ret = 'input_int' if node.name == 'input' else node.name

        if ret == 'input_int':
            ret = st.getBIF(ret)

        else:
            if ret == 'True':
                ret = ast.Tru()

            elif ret == 'False':
                ret = ast.Fals()

            else:
                ret = st.getSymbol(ret)

        return ret

    elif isinstance(node, oast.Not):
        operand = translate(node.expr, st, strings, funcName)

        return ast.Not(operand)

    elif isinstance(node, oast.Or):
        left = translate(node.nodes[0], st, strings, funcName)
        right = translate(node.nodes[1], st, strings, funcName)

        return ast.Or(left, right)

    elif isinstance(node, oast.Printnl):
        children = [
            translate(e, st, strings, funcName) for e in node.getChildNodes()
        ]
        children = util.flatten(children)

        return ast.FunctionCall(st.getBIF('print_any'), *children)

    elif isinstance(node, oast.Return):
        return ast.Return(translate(node.value, st, strings, funcName))

    elif isinstance(node, oast.Stmt):
        stmts = [
            translate(s, st, strings, funcName) for s in node.getChildNodes()
        ]

        return util.flatten(stmts)

    elif isinstance(node, oast.Sub):
        left = translate(node.left, st, strings, funcName)
        right = translate(node.right, st, strings, funcName)

        return ast.Sub(left, right)

    elif isinstance(node, oast.Subscript):
        sym = translate(node.expr, st, strings, funcName)
        sub = translate(node.subs[0], st, strings, funcName)

        return ast.Subscript(sym, sub)

    elif isinstance(node, oast.While):
        cond = translate(node.test, st, strings, funcName)

        body = translate(node.body, st, strings, funcName)
        body = ast.BasicBlock(body)

        return ast.While(cond, body, st)

    elif isinstance(node, oast.UnarySub):
        operand = translate(node.expr, st, strings, funcName)

        return ast.Negate(operand)

    else:
        raise Exception("Unsupported AST node encountered: {}".format(
            node.__class__.__name__))
예제 #10
0
 def _do_IfStatement(self, node):
     tests = map(self.transform, node.Tests)
     else_ = self.transform_suite(node.ElseStatement)
     return ast.If(tests, else_)