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