def _nonarith(self, left, right, il_code): """Check equality of non-arithmetic expressions.""" # If either operand is a null pointer constant, cast it to the # other's pointer type. if left.ctype.is_pointer() and right.null_ptr_const: right = set_type(right, left.ctype, il_code) elif right.ctype.is_pointer() and left.null_ptr_const: left = set_type(left, right.ctype, il_code) # If both operands are not pointer types, quit now if not left.ctype.is_pointer() or not right.ctype.is_pointer(): with report_err(): err = "comparison between incomparable types" raise CompilerError(err, self.op.r) # If one side is pointer to void, cast the other to same. elif left.ctype.arg.is_void(): check_cast(right, left.ctype, self.op.r) right = set_type(right, left.ctype, il_code) elif right.ctype.arg.is_void(): check_cast(left, right.ctype, self.op.r) left = set_type(left, right.ctype, il_code) # If both types are still incompatible, warn! elif not left.ctype.compatible(right.ctype): with report_err(): err = "comparison between distinct pointer types" raise CompilerError(err, self.op.r) # Now, we can do comparison out = ILValue(ctypes.integer) il_code.add(self.eq_il_cmd(out, left, right)) return out
def _get_args_with_prototype(self, func_ctype, il_code, symbol_table, c): """Return list of argument ILValues for function this represents. Use _get_args_with_prototype when the function this represents has a prototype. This function converts all passed arguments to expected types. """ arg_types = func_ctype.args if len(arg_types) != len(self.args): err = ("incorrect number of arguments for function call" f" (expected {len(arg_types)}, have {len(self.args)})") if self.args: raise CompilerError(err, self.args[-1].r) else: raise CompilerError(err, self.r) final_args = [] for arg_given, arg_type in zip(self.args, arg_types): arg = arg_given.make_il(il_code, symbol_table, c) check_cast(arg, arg_type, arg_given.r) final_args.append( set_type(arg, arg_type.make_unqual(), il_code)) return final_args
def _get_args_with_prototype(self, func_ctype, il_code, symbol_table, c): """Return list of argument ILValues for function this represents. Use _get_args_with_prototype when the function this represents has a prototype. This function converts all passed arguments to expected types. """ # if only parameter is of type void, expect no arguments if (len(func_ctype.args) == 1 and func_ctype.args[0].is_void()): arg_types = [] else: arg_types = func_ctype.args if len(arg_types) != len(self.args): err = ("incorrect number of arguments for function call" + " (expected {}, have {})").format(len(arg_types), len(self.args)) if self.args: raise CompilerError(err, self.args[-1].r) else: raise CompilerError(err, self.tok.r) final_args = [] for arg_given, arg_type in zip(self.args, arg_types): arg = arg_given.make_il(il_code, symbol_table, c) check_cast(arg, arg_type, arg_given.r) final_args.append(set_type(arg, arg_type, il_code)) return final_args
def make_il(self, il_code, symbol_table, c): """Make IL code for returning this value.""" il_value = self.return_value.make_il(il_code, symbol_table, c) check_cast(il_value, ctypes.integer, self.return_value.r) ret = set_type(il_value, ctypes.integer, il_code) il_code.add(control_cmds.Return(ret))
def make_il(self, il_code, symbol_table, c): """Make IL code for returning this value.""" if self.return_value and not c.return_type.is_void(): il_value = self.return_value.make_il(il_code, symbol_table, c) check_cast(il_value, c.return_type, self.return_value.r) ret = set_type(il_value, c.return_type, il_code) il_code.add(control_cmds.Return(ret)) elif self.return_value and c.return_type.is_void(): err = "function with void return type cannot return value" raise CompilerError(err, self.r) elif not self.return_value and not c.return_type.is_void(): err = "function with non-void return type must return value" raise CompilerError(err, self.r) else: il_code.add(control_cmds.Return())
def _nonarith(self, left, right, il_code): """Check equality of non-arithmetic expressions.""" # If either operand is a null pointer constant, cast it to the # other's pointer type. if (left.ctype.is_pointer() and getattr(right.literal, "val", None) == 0): right = set_type(right, left.ctype, il_code) elif (right.ctype.is_pointer() and getattr(left.literal, "val", None) == 0): left = set_type(left, right.ctype, il_code) # If both operands are not pointer types, quit now if not left.ctype.is_pointer() or not right.ctype.is_pointer(): with report_err(): err = "comparison between incomparable types" raise CompilerError(err, self.op.r) # If one side is pointer to void, cast the other to same. elif left.ctype.arg.is_void(): check_cast(right, left.ctype, self.op.r) right = set_type(right, left.ctype, il_code) elif right.ctype.arg.is_void(): check_cast(left, right.ctype, self.op.r) left = set_type(left, right.ctype, il_code) # If both types are still incompatible, warn! elif not left.ctype.compatible(right.ctype): with report_err(): err = "comparison between distinct pointer types" raise CompilerError(err, self.op.r) # Now, we can do comparison out = ILValue(ctypes.integer) il_code.add(self.eq_il_cmd(out, left, right)) return out