Example #1
0
def p_class_decl_head(p):
    'class_decl_head : CLASS ID extends'
    global current_class, current_context
    cid = p[2]
    sc = p[3]
    c = ast.lookup(ast.classtable, cid)
    if (c != None):
        signal_error('Class {0} already exists!'.format(cid), p.lineno(2))
    else:
        c = ast.Class(cid, sc)
        ast.addtotable(ast.classtable, cid, c)
    current_class = c
    current_context = 'class'
    pass
Example #2
0
 def p_class_inherits(self, parse):
     '''
     class : CLASS TYPE INHERITS TYPE LBRACE features_list_optional RBRACE
     '''
     parse[0] = AST.Class(name=parse[2], parent=parse[4], features=parse[6])
Example #3
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__))
Example #4
0
 def p_class(self, parse):
     '''
     class : CLASS TYPE LBRACE features_list_optional RBRACE
     '''
     parse[0] = AST.Class(name=parse[2], parent='Object', features=parse[4])
Example #5
0
 def p_class(self, parse):
     """
     class : CLASS TYPE LBRACE features_list_opt RBRACE
     """
     parse[0] = AST.Class(name=parse[2], parent="Object", features=parse[4])