def make_il(self, il_code, symbol_table, c): """ Make code for this node """ left = self.left.make_il(il_code, symbol_table, c) right = self.right.make_il(il_code, symbol_table, c) if self.check_type(left, right): left, right = arith_convert(left, right, il_code) if left.literal and right.literal: # If NotImplementedError is raised, continue with execution. try: val = self.arith_const( shift_into_range(left.literal.val, left.ctype), shift_into_range(right.literal.val, right.ctype), left.ctype) out = ILValue(left.ctype) il_code.register_literal_var(out, val) return out except NotImplementedError: pass return self.arith(left, right, il_code) else: return self.nonarith(left, right, il_code)
def make_il(self, il_code, symbol_table, c): """ Make code for this node """ expr = self.expr.make_il(il_code, symbol_table, c) if not self.check_type(expr): err = f"{self.descr} requires {self.opnd_descr} type operand" raise CompilerError(err, self.expr.r) # perform integer promotion if expr.ctype.size < 4: expr = set_type(expr, ctypes.integer, il_code) if self.cmd: out = ILValue(expr.ctype) # perform constant folding if expr.literal: val = self.arith_const(expr.literal.val, expr.ctype) val = shift_into_range(val, expr.ctype) il_code.register_literal_var(out, val) else: il_code.add(self.cmd(out, expr)) return out return expr
def arith_const(self, expr, ctype): return ~shift_into_range(expr, ctype)
def arith_const(self, left, right, ctype): return shift_into_range(int(left / right), ctype)