Add nullptr comparison
This commit is contained in:
parent
e1ac019ecd
commit
1a8535516c
4
examples/nullptr_comparison.reid
Normal file
4
examples/nullptr_comparison.reid
Normal file
@ -0,0 +1,4 @@
|
||||
fn main() -> bool {
|
||||
let ptr = i32::null();
|
||||
return i32::is_null(ptr);
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import triple_import_vec2::Vec2;
|
||||
import triple_import_ship::Ship;
|
||||
|
||||
fn main() -> i32 {
|
||||
return 0;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
//asd
|
||||
import triple_import_vec2::Vec2;
|
||||
|
||||
struct Ship {
|
||||
position: Vec2,
|
||||
velocity: Vec2,
|
||||
}
|
||||
|
||||
|
||||
impl Ship {
|
||||
pub fn foo(&self, vec: Vec2) {
|
||||
let b: Ship = Ship {
|
||||
position: Vec2::zero(),
|
||||
velocity: Vec2::zero(),
|
||||
};
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
|
||||
struct Vec2 { x: f32, y: f32 }
|
||||
|
||||
impl Vec2 {
|
||||
pub fn zero() -> Vec2 { Vec2 { x: 0.0, y: 0.0 } }
|
||||
}
|
@ -3,6 +3,8 @@
|
||||
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use llvm_sys::core::LLVMBuildIsNull;
|
||||
|
||||
use crate::{
|
||||
Block, BlockData, CompileResult, ConstValueKind, CustomTypeKind, ErrorKind, FunctionData, Instr, InstructionData,
|
||||
ModuleData, NamedStruct, TerminatorKind, Type, TypeCategory, TypeData,
|
||||
@ -614,6 +616,14 @@ impl Builder {
|
||||
Instr::ShiftRightArithmetic(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||
Instr::ShiftLeft(lhs, rhs) => match_types(&lhs, &rhs, &self).map(|_| ()),
|
||||
Instr::GetGlobal(_) => Ok(()),
|
||||
Instr::IsNull(val) => {
|
||||
let val_ty = val.get_type(&self)?;
|
||||
if let Type::Ptr(_) = val_ty {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ErrorKind::Null)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -770,6 +780,7 @@ impl InstructionValue {
|
||||
let kind = builder.get_const_kind(constant);
|
||||
Ok(kind.get_type())
|
||||
}
|
||||
IsNull(_) => Ok(Type::Bool),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1051,6 +1051,10 @@ impl InstructionHolder {
|
||||
LLVMBuildShl(module.builder_ref, lhs_val, rhs_val, name.as_ptr())
|
||||
}
|
||||
GetGlobal(global_value) => module.globals.get(global_value).unwrap().clone(),
|
||||
IsNull(instruction_value) => {
|
||||
let val = module.values.get(&*instruction_value).unwrap().value_ref;
|
||||
LLVMBuildIsNull(module.builder_ref, val, name.as_ptr())
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(record) = &self.record {
|
||||
|
@ -393,6 +393,7 @@ impl Debug for Instr {
|
||||
Instr::ShiftRightArithmetic(lhs, rhs) => fmt_binop(f, lhs, &">>a", rhs),
|
||||
Instr::ShiftLeft(lhs, rhs) => fmt_binop(f, lhs, &"<<", rhs),
|
||||
Instr::GetGlobal(global_value) => write!(f, "global {:?}", global_value),
|
||||
Instr::IsNull(_) => write!(f, "is_null"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,6 +298,7 @@ impl Instr {
|
||||
Instr::ShiftRightArithmetic(..) => "ashr",
|
||||
Instr::ShiftLeft(..) => "shl",
|
||||
Instr::GetGlobal(..) => "global",
|
||||
Instr::IsNull(..) => "is_null",
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -491,6 +492,9 @@ pub enum Instr {
|
||||
/// no-op cast because no bits change with this conversion.
|
||||
BitCast(InstructionValue, Type),
|
||||
|
||||
/// Check if the given instruction value is a null pointer
|
||||
IsNull(InstructionValue),
|
||||
|
||||
FunctionCall(FunctionValue, Vec<InstructionValue>),
|
||||
}
|
||||
|
||||
|
@ -388,6 +388,22 @@ pub fn get_intrinsic_assoc_functions(ty: &TypeKind) -> Vec<FunctionDefinition> {
|
||||
signature_meta: Default::default(),
|
||||
});
|
||||
|
||||
intrinsics.push(FunctionDefinition {
|
||||
name: "is_null".to_owned(),
|
||||
linkage_name: None,
|
||||
is_pub: true,
|
||||
is_imported: false,
|
||||
return_type: TypeKind::Bool,
|
||||
parameters: vec![FunctionParam {
|
||||
name: "value".to_string(),
|
||||
ty: TypeKind::UserPtr(Box::new(ty.clone())),
|
||||
meta: Default::default(),
|
||||
}],
|
||||
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicIsNull)),
|
||||
source: None,
|
||||
signature_meta: Default::default(),
|
||||
});
|
||||
|
||||
intrinsics
|
||||
}
|
||||
|
||||
@ -755,6 +771,16 @@ impl IntrinsicFunction for IntrinsicNullPtr {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IntrinsicIsNull;
|
||||
impl IntrinsicFunction for IntrinsicIsNull {
|
||||
fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result<StackValue, ErrorKind> {
|
||||
let val = params.get(0).unwrap().instr();
|
||||
let instr = scope.block.build(Instr::IsNull(val)).unwrap();
|
||||
Ok(StackValue(StackValueKind::Literal(instr), TypeKind::Bool))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct IntrinsicConst(u64);
|
||||
impl IntrinsicFunction for IntrinsicConst {
|
||||
|
Loading…
Reference in New Issue
Block a user