コード例 #1
0
def p_unary_expression_4(p):
    'unary_expression : unary_operator unary_expression'
    if p[1] == '+':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PLUS, line_no=str(p.lineno(1) + __start_line_no - 1))
    elif p[1] == '-':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.MINUS, line_no=str(p.lineno(1) + __start_line_no - 1))
    elif p[1] == '!':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.LNOT, line_no=str(p.lineno(1) + __start_line_no - 1))
    else:
        err('orio.module.loop.parser internal error: unknown unary operator')
コード例 #2
0
ファイル: code_parser.py プロジェクト: zhjp0/Orio
def p_unary_expression_4(p):
    'unary_expression : unary_operator unary_expression'
    if p[1] == '+':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PLUS, getLineNumber(p.lineno(1)))
    elif p[1] == '-':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.MINUS, getLineNumber(p.lineno(1)))
    elif p[1] == '!':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.LNOT, getLineNumber(p.lineno(1)))
    else:
        err('orio.module.ortildriver.code_parser internal error: unknown unary operator')
コード例 #3
0
ファイル: code_parser.py プロジェクト: zhjp0/Orio
def p_unary_expression_4(p):
    'unary_expression : unary_operator unary_expression'
    if p[1] == '+':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PLUS)
    elif p[1] == '-':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.MINUS)
    elif p[1] == '!':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.LNOT)
    else:
        err('orio.module.tilic.code_parser internal error: unknown unary operator')
コード例 #4
0
ファイル: code_parser.py プロジェクト: phrb/Orio
def p_unary_expression_4(p):
    "unary_expression : unary_operator unary_expression"
    if p[1] == "+":
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PLUS)
    elif p[1] == "-":
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.MINUS)
    elif p[1] == "!":
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.LNOT)
    else:
        err("orio.module.tilic.code_parser internal error: unknown unary operator")
コード例 #5
0
def p_unary_expression_4(p):
    'unary_expression : unary_operator unary_expression'
    if p[1] == '+':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PLUS, p.lineno(1) + __start_line_no - 1)
    elif p[1] == '-':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.MINUS, p.lineno(1) + __start_line_no - 1)
    elif p[1] == '!':
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.LNOT, p.lineno(1) + __start_line_no - 1)
    else:
        print 'internal error: unknown unary operator'
        sys.exit(1)
コード例 #6
0
def p_unary_expression_4(p):
    "unary_expression : unary_operator unary_expression"
    if p[1] == "+":
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PLUS,
                            getLineNumber(p.lineno(1)))
    elif p[1] == "-":
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.MINUS,
                            getLineNumber(p.lineno(1)))
    elif p[1] == "!":
        p[0] = ast.UnaryExp(p[2], ast.UnaryExp.LNOT,
                            getLineNumber(p.lineno(1)))
    else:
        err("orio.module.ortil.code_parser internal error:OrTil: unknown unary operator"
            )
コード例 #7
0
def p_unary_expression_4(p):
    "unary_expression : unary_operator unary_expression"
    if p[1] == "+":
        p[0] = ast.UnaryExp(
            p[2], ast.UnaryExp.PLUS, line_no=str(p.lineno(1) + __start_line_no - 1)
        )
    elif p[1] == "-":
        p[0] = ast.UnaryExp(
            p[2], ast.UnaryExp.MINUS, line_no=str(p.lineno(1) + __start_line_no - 1)
        )
    elif p[1] == "!":
        p[0] = ast.UnaryExp(
            p[2], ast.UnaryExp.LNOT, line_no=str(p.lineno(1) + __start_line_no - 1)
        )
    else:
        err("orio.module.loop.parser internal error: unknown unary operator")
コード例 #8
0
ファイル: code_parser.py プロジェクト: phrb/Orio
def p_unary_expression_3(p):
    "unary_expression : MINUSMINUS unary_expression"
    p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PRE_DEC)
コード例 #9
0
ファイル: code_parser.py プロジェクト: phrb/Orio
def p_unary_expression_2(p):
    "unary_expression : PLUSPLUS unary_expression"
    p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PRE_INC)
コード例 #10
0
ファイル: transformation.py プロジェクト: phrb/Orio
    def __normalizeExp(self, exp):
        """
        To convert <list> and <tuple> back to addition and multiplication (respectively), after
        performing constant folding
        """

        if isinstance(exp, ast.NumLitExp):
            if exp.val < 0:
                exp.val *= -1
                return ast.UnaryExp(exp, ast.UnaryExp.MINUS)
            else:
                return exp

        elif isinstance(exp, ast.StringLitExp):
            return exp

        elif isinstance(exp, ast.IdentExp):
            return exp

        elif isinstance(exp, ast.ArrayRefExp):
            exp.exp = self.__normalizeExp(exp.exp)
            exp.sub_exp = self.__normalizeExp(exp.sub_exp)
            return exp

        elif isinstance(exp, ast.FunCallExp):
            exp.exp = self.__normalizeExp(exp.exp)
            exp.args = [self.__normalizeExp(a) for a in exp.args]
            return exp

        elif isinstance(exp, ast.UnaryExp):
            exp.exp = self.__normalizeExp(exp.exp)
            return exp

        elif isinstance(exp, ast.BinOpExp):
            exp.lhs = self.__normalizeExp(exp.lhs)
            exp.rhs = self.__normalizeExp(exp.rhs)
            return exp

        elif isinstance(exp, ast.ParenthExp):
            exp.exp = self.__normalizeExp(exp.exp)
            return exp

        # addition
        elif isinstance(exp, list):
            n_exp = []
            for e in exp:
                n_exp.append(self.__normalizeExp(e))
            exp = n_exp
            lhs = exp[0]
            for e in exp[1:]:
                if isinstance(
                        e, ast.UnaryExp) and e.op_type == ast.UnaryExp.MINUS:
                    lhs = ast.BinOpExp(lhs, e.exp, ast.BinOpExp.SUB)
                else:
                    lhs = ast.BinOpExp(lhs, e, ast.BinOpExp.ADD)
            return lhs

        # multiplication
        elif isinstance(exp, tuple):
            exp = list(exp)
            n_exp = []
            for e in exp:
                n_exp.append(self.__normalizeExp(e))
            exp = n_exp
            sign = 1
            n_exp = []
            for e in exp:
                if isinstance(
                        e, ast.UnaryExp) and e.op_type == ast.UnaryExp.MINUS:
                    n_exp.append(e.exp)
                    sign *= -1
                else:
                    n_exp.append(e)
            exp = n_exp
            lhs = ast.BinOpExp(exp[0], exp[1], ast.BinOpExp.MUL)
            for e in exp[2:]:
                lhs = ast.BinOpExp(lhs, e, ast.BinOpExp.MUL)
            if sign == -1:
                return ast.UnaryExp(lhs, ast.UnaryExp.MINUS)
            return lhs

        else:
            err("orio.module.ortildriver.transformation internal error: unknown type of expression: %s"
                % exp.__class__.__name__)
コード例 #11
0
def p_unary_expression_2(p):
    'unary_expression : PLUSPLUS unary_expression'
    p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PRE_INC, p.lineno(1) + __start_line_no - 1)
コード例 #12
0
def p_postfix_expression_5(p):
    "postfix_expression : postfix_expression MINUSMINUS"
    p[0] = ast.UnaryExp(p[1], ast.UnaryExp.POST_DEC,
                        getLineNumber(p.lineno(1)))
コード例 #13
0
def p_postfix_expression_4(p):
    "postfix_expression : postfix_expression PLUSPLUS"
    p[0] = ast.UnaryExp(p[1], ast.UnaryExp.POST_INC,
                        getLineNumber(p.lineno(1)))
コード例 #14
0
def p_unary_expression_3(p):
    "unary_expression : MINUSMINUS unary_expression"
    p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PRE_DEC, getLineNumber(p.lineno(1)))
コード例 #15
0
def p_unary_expression_2(p):
    "unary_expression : PLUSPLUS unary_expression"
    p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PRE_INC, getLineNumber(p.lineno(1)))
コード例 #16
0
def p_postfix_expression_4(p):
    "postfix_expression : postfix_expression PLUSPLUS"
    p[0] = ast.UnaryExp(
        p[1], ast.UnaryExp.POST_INC, line_no=str(p.lineno(1) + __start_line_no - 1)
    )
コード例 #17
0
ファイル: code_parser.py プロジェクト: phrb/Orio
def p_postfix_expression_4(p):
    "postfix_expression : postfix_expression PLUSPLUS"
    p[0] = ast.UnaryExp(p[1], ast.UnaryExp.POST_INC)
コード例 #18
0
ファイル: code_parser.py プロジェクト: phrb/Orio
def p_postfix_expression_5(p):
    "postfix_expression : postfix_expression MINUSMINUS"
    p[0] = ast.UnaryExp(p[1], ast.UnaryExp.POST_DEC)
コード例 #19
0
def p_postfix_expression_5(p):
    'postfix_expression : postfix_expression MINUSMINUS'
    p[0] = ast.UnaryExp(p[1], ast.UnaryExp.POST_DEC, p.lineno(1) + __start_line_no - 1)
コード例 #20
0
def p_unary_expression_3(p):
    'unary_expression : MINUSMINUS unary_expression'
    p[0] = ast.UnaryExp(p[2], ast.UnaryExp.PRE_DEC, p.lineno(1) + __start_line_no - 1)
コード例 #21
0
def p_unary_expression_2(p):
    "unary_expression : PLUSPLUS unary_expression"
    p[0] = ast.UnaryExp(
        p[2], ast.UnaryExp.PRE_INC, line_no=str(p.lineno(1) + __start_line_no - 1)
    )
コード例 #22
0
def p_postfix_expression_4(p):
    'postfix_expression : postfix_expression PLUSPLUS'
    p[0] = ast.UnaryExp(p[1], ast.UnaryExp.POST_INC, p.lineno(1) + __start_line_no - 1)
コード例 #23
0
def p_unary_expression_3(p):
    "unary_expression : MINUSMINUS unary_expression"
    p[0] = ast.UnaryExp(
        p[2], ast.UnaryExp.PRE_DEC, line_no=str(p.lineno(1) + __start_line_no - 1)
    )
コード例 #24
0
    def getForLoopInfo(self, stmt):
        '''
        Given a for-loop statement, extract information about its loop structure.
        Note that the for-loop must be in the following form:
          for (<id> = <exp>; <id> <= <exp>; <id> += <exp>)
            <stmt>
        Subtraction is not considered at the iteration expression for the sake of
        the implementation simplicity.
        '''

        # get rid of compound statement that contains only a single statement
        while isinstance(stmt, ast.CompStmt) and len(stmt.stmts) == 1:
            stmt = stmt.stmts[0]

        # check if it is a for-loop statement
        if not isinstance(stmt, ast.ForStmt):
            err('orio.module.ortil.ast_util: OrTil:%s: not a for-loop statement'
                % stmt.line_no)

        # check initialization expression
        if stmt.init:
            while True:
                while isinstance(stmt.init, ast.ParenthExp):
                    stmt.init = stmt.init.exp
                if (isinstance(stmt.init, ast.BinOpExp)
                        and stmt.init.op_type == ast.BinOpExp.EQ_ASGN):
                    while isinstance(stmt.init.lhs, ast.ParenthExp):
                        stmt.init.lhs = stmt.init.lhs.exp
                    while isinstance(stmt.init.rhs, ast.ParenthExp):
                        stmt.init.rhs = stmt.init.rhs.exp
                    if isinstance(stmt.init.lhs, ast.IdentExp):
                        break
                err('orio.module.ortil.ast_util:%s: loop initialization expression not in "<id> = <exp>" form'
                    % stmt.init.line_no)

        # check test expression
        if stmt.test:
            while True:
                while isinstance(stmt.test, ast.ParenthExp):
                    stmt.test = stmt.test.exp
                if (isinstance(stmt.test, ast.BinOpExp) and stmt.test.op_type
                        in (ast.BinOpExp.LT, ast.BinOpExp.LE)):
                    while isinstance(stmt.test.lhs, ast.ParenthExp):
                        stmt.test.lhs = stmt.test.lhs.exp
                    while isinstance(stmt.test.rhs, ast.ParenthExp):
                        stmt.test.rhs = stmt.test.rhs.exp
                    if isinstance(stmt.test.lhs, ast.IdentExp):
                        break
                err('orio.module.ortil.ast_util:%s: loop test expression not in "<id> <= <exp>" or '
                    + '"<id> < <exp>"form' % stmt.test.line_no)

        # check iteration expression
        if stmt.iter:
            while True:
                while isinstance(stmt.iter, ast.ParenthExp):
                    stmt.iter = stmt.iter.exp
                if (isinstance(stmt.iter, ast.BinOpExp)
                        and stmt.iter.op_type == ast.BinOpExp.EQ_ASGN):
                    while isinstance(stmt.iter.lhs, ast.ParenthExp):
                        stmt.iter.lhs = stmt.iter.lhs.exp
                    while isinstance(stmt.iter.rhs, ast.ParenthExp):
                        stmt.iter.rhs = stmt.iter.rhs.exp
                    if isinstance(stmt.iter.lhs, ast.IdentExp):
                        if (isinstance(stmt.iter.rhs, ast.BinOpExp)
                                and stmt.iter.rhs.op_type
                                in (ast.BinOpExp.ADD, ast.BinOpExp.SUB)):
                            while isinstance(stmt.iter.rhs.lhs,
                                             ast.ParenthExp):
                                stmt.iter.rhs.lhs = stmt.iter.rhs.lhs.exp
                            while isinstance(stmt.iter.rhs.rhs,
                                             ast.ParenthExp):
                                stmt.iter.rhs.rhs = stmt.iter.rhs.rhs.exp
                            if (isinstance(stmt.iter.rhs.lhs, ast.IdentExp)
                                    and stmt.iter.lhs.name
                                    == stmt.iter.rhs.lhs.name):
                                break
                elif (isinstance(stmt.iter, ast.UnaryExp) and stmt.iter.op_type
                      in (ast.UnaryExp.POST_INC, ast.UnaryExp.PRE_INC,
                          ast.UnaryExp.POST_DEC, ast.UnaryExp.PRE_DEC)):
                    while isinstance(stmt.iter.exp, ast.ParenthExp):
                        stmt.iter.exp = stmt.iter.exp.exp
                    if isinstance(stmt.iter.exp, ast.IdentExp):
                        break
                err((
                    'orio.module.ortil.ast_util:%s: loop iteration expression not in "<id>++" or "<id>--" or '
                    + '"<id> += <exp>" or "<id> = <id> + <exp>" form') %
                    stmt.iter.line_no)

        # check if the control expressions are all empty
        if not stmt.init and not stmt.test and not stmt.iter:
            err('orio.module.ortil.ast_util:%s: a loop with an empty control expression cannot be handled'
                % stmt.line_no)

        # check if the iterator names are all the same
        init_iname = None
        test_iname = None
        iter_iname = None
        if stmt.init:
            init_iname = stmt.init.lhs.name
        if stmt.test:
            test_iname = stmt.test.lhs.name
        if stmt.iter:
            if isinstance(stmt.iter, ast.BinOpExp):
                iter_iname = stmt.iter.lhs.name
            else:
                assert (isinstance(
                    stmt.iter,
                    ast.UnaryExp)), 'internal error:OrTil: not unary'
                iter_iname = stmt.iter.exp.name
        inames = []
        if init_iname:
            inames.append(init_iname)
        if test_iname:
            inames.append(test_iname)
        if iter_iname:
            inames.append(iter_iname)
        if inames.count(inames[0]) != len(inames):
            err('orio.module.ortil.ast_util:%s: iterator names across init, test, and iter exps must be the same'
                % stmt.line_no)

        # extract for-loop structure information
        index_id = ast.IdentExp(inames[0])
        lbound_exp = None
        ubound_exp = None
        stride_exp = None
        if stmt.init:
            lbound_exp = stmt.init.rhs.replicate()
        if stmt.test:
            if stmt.test.op_type == ast.BinOpExp.LT:
                ubound_exp = ast.BinOpExp(stmt.test.rhs.replicate(),
                                          ast.NumLitExp(1, ast.NumLitExp.INT),
                                          ast.BinOpExp.SUB)
            else:
                ubound_exp = stmt.test.rhs.replicate()
        if stmt.iter:
            if isinstance(stmt.iter, ast.BinOpExp):
                stride_exp = stmt.iter.rhs.rhs.replicate()
                if isinstance(stride_exp, ast.BinOpExp):
                    stride_exp = ast.ParenthExp(stride_exp)
                if stmt.iter.rhs.op_type == ast.BinOpExp.SUB:
                    stride_exp = ast.UnaryExp(stride_exp, ast.UnaryExp.MINUS)
            elif isinstance(stmt.iter, ast.UnaryExp):
                if stmt.iter.op_type in (ast.UnaryExp.POST_INC,
                                         ast.UnaryExp.PRE_INC):
                    stride_exp = ast.NumLitExp(1, ast.NumLitExp.INT)
                elif stmt.iter.op_type in (ast.UnaryExp.POST_DEC,
                                           ast.UnaryExp.PRE_DEC):
                    stride_exp = ast.NumLitExp(-1, ast.NumLitExp.INT)
                else:
                    err('orio.module.ortil.ast_util internal error:OrTil: unexpected unary operation type'
                        )
            else:
                err('orio.module.ortil.ast_utilinternal error:OrTil: unexpected type of iteration expression'
                    )

        loop_body = stmt.stmt.replicate()
        for_loop_info = (index_id, lbound_exp, ubound_exp, stride_exp,
                         loop_body)

        # return the for-loop structure information
        return for_loop_info
コード例 #25
0
ファイル: transformation.py プロジェクト: phrb/Orio
    def __foldConstantExp(self, exp, up_sign):
        """
        To perform a simple (not full-fledged) constant folding optimization on the given expression
        A list is used to represent a k-ary addition.
        A tuple is used to represent a k-ary multiplication.
        """

        if isinstance(exp, ast.NumLitExp):
            if up_sign == -1:
                exp.val *= -1
            return exp

        elif isinstance(exp, ast.StringLitExp):
            if up_sign == -1:
                return ast.UnaryExp(exp, ast.UnaryExp.MINUS)
            return exp

        elif isinstance(exp, ast.IdentExp):
            if up_sign == -1:
                return ast.UnaryExp(exp, ast.UnaryExp.MINUS)
            return exp

        elif isinstance(exp, ast.ArrayRefExp):
            exp.exp = self.__foldConstantExp(exp.exp, 1)
            exp.sub_exp = self.__foldConstantExp(exp.sub_exp, 1)
            if up_sign == -1:
                return ast.UnaryExp(exp, ast.UnaryExp.MINUS)
            return exp

        elif isinstance(exp, ast.FunCallExp):
            exp.exp = self.__foldConstantExp(exp.exp, 1)
            exp.args = [self.__foldConstantExp(a, 1) for a in exp.args]
            if up_sign == -1:
                return ast.UnaryExp(exp, ast.UnaryExp.MINUS)
            return exp

        elif isinstance(exp, ast.UnaryExp):
            if exp.op_type == ast.UnaryExp.MINUS:
                up_sign *= -1
            return self.__foldConstantExp(exp.exp, up_sign)

        elif isinstance(exp, ast.BinOpExp):

            if exp.op_type in (ast.BinOpExp.ADD, ast.BinOpExp.SUB):
                if exp.op_type == ast.BinOpExp.ADD:
                    if up_sign == -1:
                        lhs_sign = -1
                        rhs_sign = -1
                    else:
                        lhs_sign = 1
                        rhs_sign = 1
                else:
                    if up_sign == -1:
                        lhs_sign = -1
                        rhs_sign = 1
                    else:
                        lhs_sign = 1
                        rhs_sign = -1
                lhs = self.__foldConstantExp(exp.lhs, lhs_sign)
                rhs = self.__foldConstantExp(exp.rhs, rhs_sign)
                ops = []
                for e in [lhs, rhs]:
                    if isinstance(e, list):
                        ops.extend(e)
                    else:
                        ops.append(e)
                add_num = 0
                n_ops = []
                for o in ops:
                    if isinstance(o, ast.NumLitExp):
                        add_num += o.val
                    else:
                        n_ops.append(o)
                ops = n_ops
                if add_num != 0:
                    ops.append(ast.NumLitExp(add_num, ast.NumLitExp.INT))
                if len(ops) == 0:
                    return ast.NumLitExp(0, ast.NumLitExp.INT)
                elif len(ops) == 1:
                    return ops[0]
                else:
                    return ops

            elif exp.op_type == ast.BinOpExp.MUL:
                lhs = self.__foldConstantExp(exp.lhs, up_sign)
                rhs = self.__foldConstantExp(exp.rhs, 1)
                ops1 = []
                ops2 = []
                if isinstance(lhs, list):
                    ops1.extend(lhs)
                else:
                    ops1.append(lhs)
                if isinstance(rhs, list):
                    ops2.extend(rhs)
                else:
                    ops2.append(rhs)
                ops = []
                for o1 in ops1:
                    if isinstance(o1, tuple):
                        o1 = list(o1)
                    else:
                        o1 = [o1]
                    for o2 in ops2:
                        if isinstance(o2, tuple):
                            o2 = list(o2)
                        else:
                            o2 = [o2]
                        o1 = [o.replicate() for o in o1]
                        o2 = [o.replicate() for o in o2]
                        o = []
                        mul_num = 1
                        for i in o1 + o2:
                            if isinstance(i, ast.NumLitExp):
                                mul_num *= i.val
                            else:
                                o.append(i)
                        if mul_num != 0:
                            if mul_num != 1:
                                o.insert(
                                    0, ast.NumLitExp(mul_num,
                                                     ast.NumLitExp.INT))
                            if len(o) == 0:
                                ops.append(ast.NumLitExp(1, ast.NumLitExp.INT))
                            elif len(o) == 1:
                                ops.append(o[0])
                            else:
                                ops.append(tuple(o))
                add_num = 0
                n_ops = []
                for o in ops:
                    if isinstance(o, ast.NumLitExp):
                        add_num += o.val
                    else:
                        n_ops.append(o)
                ops = n_ops
                if add_num != 0:
                    ops.append(ast.NumLitExp(add_num, ast.NumLitExp.INT))
                if len(ops) == 0:
                    return ast.NumLitExp(0, ast.NumLitExp.INT)
                elif len(ops) == 1:
                    return ops[0]
                else:
                    return ops

            else:
                err("orio.module.ortildriver.transformation: constant folding cannot handle binary operations other "
                    + "than +,-,*")

        elif isinstance(exp, ast.ParenthExp):
            return self.__foldConstantExp(exp.exp, up_sign)

        else:
            err("orio.module.ortildriver.transformation internal error: unknown type of expression: %s"
                % exp.__class__.__name__)