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