Exemplo n.º 1
0
    def compile(self, module: ir.Module, builder: ir.IRBuilder,
                symbols: SymbolTable) -> ir.Value:
        bop = self.bop

        exprL = self.exprL.compile(module, builder, symbols)
        exprL_type = self.exprL.type_of()
        exprL_int = exprL_type in IntTypes

        exprR = self.exprR.compile(module, builder, symbols)
        exprR_type = self.exprR.type_of()
        exprR_int = exprR_type in IntTypes

        if bop == '+':
            if exprL_int and exprR_int:
                return builder.add(exprL, exprR)

            if exprL_int:
                exprL = builder.sitofp(exprL, exprR_type.ir_type)

            if exprR_int:
                exprR = builder.sitofp(exprR, exprL_type.ir_type)

            return builder.fadd(exprL, exprR)

        if bop == '-':
            if exprL_int and exprR_int:
                return builder.sub(exprL, exprR)

            if exprL_int:
                exprL = builder.sitofp(exprL, exprL_type.ir_type)

            if exprR_int:
                exprR = builder.sitofp(exprL, exprR_type.ir_type)

            return builder.fsub(exprL, exprR)

        if bop == '*':
            if exprL_int and exprR_int:
                return builder.mul(exprL, exprR)

            if exprL_int:
                exprL = builder.sitofp(exprL, exprL_type.ir_type)

            if exprR_int:
                exprR = builder.sitofp(exprL, exprR_type.ir_type)

            return builder.fmul(exprL, exprR)

        if bop == '/':
            if exprL_int:
                exprL = builder.sitofp(exprL, exprL_type.ir_type)

            if exprR_int:
                exprR = builder.sitofp(exprL, exprR_type.ir_type)

            return builder.fdiv(exprL, exprR)

        if bop == '//':
            return builder.sdiv(exprL, exprR)

        if bop == '%':
            if exprL_int and exprR_int:
                return builder.srem(exprL, exprR)

            if exprL_int:
                exprL = builder.sitofp(exprL, exprL_type.ir_type)

            if exprR_int:
                exprR = builder.sitofp(exprL, exprR_type.ir_type)

            return builder.frem(exprL, exprR)

        if bop in ['&', '&&']:
            return builder.and_(exprL, exprR)

        if bop in ['|', '||']:
            return builder.or_(exprL, exprR)

        if bop == '^':
            return builder.xor(exprL, exprR)

        if bop in ['<', '<=', '>=', '>']:
            if exprL_int and exprR_int:
                return builder.icmp_signed(bop, exprL, exprR)

            if exprL_int:
                exprL = builder.sitofp(exprL, exprL_type.ir_type)

            if exprR_int:
                exprR = builder.sitofp(exprL, exprR_type.ir_type)

            return builder.fcmp_ordered(bop, exprL, exprR)

        if bop == '==':
            if exprL_int and exprR_int:
                return builder.icmp_signed(bop, exprL, exprR)

            if exprL_int:
                exprL = builder.sitofp(exprL, exprL_type.ir_type)

            if exprR_int:
                exprR = builder.sitofp(exprL, exprR_type.ir_type)

            return builder.fcmp_ordered(bop, exprL, exprR)

        if bop == '!=':
            if exprL_int and exprR_int:
                return builder.icmp_signed(bop, exprL, exprR)

            if exprL_int:
                exprL = builder.sitofp(exprL, exprL_type.ir_type)

            if exprR_int:
                exprR = builder.sitofp(exprL, exprR_type.ir_type)

            return builder.fcmp_unordered(bop, exprL, exprR)

        # if bop == '**':

        # if bop in ['**', '*', '%', '-', '<<', '>>', '>>>', '<=', '>=', '<',
        #            '>', '&', '^', '|', '==', '!=', '&&', '||', '=', '+=',
        #            '-=', '*=', '&=', '|=', '^=', '<<=', '>>=', '>>>=', '%=']:
        #     data = (exprL, bop, exprR)

        #     if minify:
        #         return "({}{}{})".format(*data)

        #     return "({} {} {})".format(*data)

        # converter = {
        #     '<=>': '<>=',
        #     '===': '==',
        #     '!==': '!=',
        #     '~=': '~==',
        #     '//=': '/='
        # }
        # if bop in converter.keys():
        #     data = (exprL, converter[bop], exprR)

        #     if minify:
        #         return "({}{}{})".format(*data)

        #     return "({} {} {})".format(*data)

        # if bop == '+':
        #     if self.exprL.type_of() == StringType:
        #         return "{}..{}".format(exprL, exprR)

        #     return "{}+{}".format(exprL, exprR)

        # if bop == '/':
        #     return "({}/double({}))".format(exprL, exprR)

        # if bop == '//':
        #     return "floor({}/{})".format(exprL, exprR)

        # if bop == 'is':
        #     return "{} is '{}'".format(exprL, exprR)

        # if bop == '|>':
        #     return "({}({}))".format(exprR, exprL)

        # if bop == '**=':
        #     data = (exprL, exprR)

        #     if minify:
        #         return "({0}={0}**{1})".format(*data)

        #     return "({0} = {0} ** {1})".format(*data)

        # if bop == '/=':
        #     data = (exprL, exprR)

        #     if minify:
        #         return "({0}={0}/double({1}))".format(*data)

        #     return "({0} = {0} / double({1}))".format(*data)

        WappaException(
            "FATAL", "Unhandled Binary Operator {}".format(bop), self.tok)
        return bop