Check for trivial expressions that they are >0 when unsigned
This commit is contained in:
		
							parent
							
								
									d65b0153a1
								
							
						
					
					
						commit
						b23577aa18
					
				| @ -395,8 +395,6 @@ impl Builder { | |||||||
|                 Instr::Alloca(_) => Ok(()), |                 Instr::Alloca(_) => Ok(()), | ||||||
|                 Instr::Load(ptr, load_ty) => { |                 Instr::Load(ptr, load_ty) => { | ||||||
|                     let ptr_ty = ptr.get_type(&self)?; |                     let ptr_ty = ptr.get_type(&self)?; | ||||||
|                     dbg!(&self); |  | ||||||
|                     dbg!(&ptr_ty, &load_ty); |  | ||||||
|                     if let Type::Ptr(ptr_ty_inner) = ptr_ty { |                     if let Type::Ptr(ptr_ty_inner) = ptr_ty { | ||||||
|                         if *ptr_ty_inner == load_ty { |                         if *ptr_ty_inner == load_ty { | ||||||
|                             Ok(()) |                             Ok(()) | ||||||
|  | |||||||
| @ -29,6 +29,30 @@ impl TypeKind { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     pub fn signed(&self) -> bool { | ||||||
|  |         match self { | ||||||
|  |             TypeKind::Bool => false, | ||||||
|  |             TypeKind::I8 => true, | ||||||
|  |             TypeKind::I16 => true, | ||||||
|  |             TypeKind::I32 => true, | ||||||
|  |             TypeKind::I64 => true, | ||||||
|  |             TypeKind::I128 => true, | ||||||
|  |             TypeKind::U8 => false, | ||||||
|  |             TypeKind::U16 => false, | ||||||
|  |             TypeKind::U32 => false, | ||||||
|  |             TypeKind::U64 => false, | ||||||
|  |             TypeKind::U128 => false, | ||||||
|  |             TypeKind::Void => false, | ||||||
|  |             TypeKind::StringPtr => false, | ||||||
|  |             TypeKind::Array(type_kind, len) => false, | ||||||
|  |             TypeKind::CustomType(_) => false, | ||||||
|  |             TypeKind::CodegenPtr(_) => false, | ||||||
|  |             TypeKind::Vague(_) => false, | ||||||
|  |             TypeKind::Borrow(_, _) => false, | ||||||
|  |             TypeKind::UserPtr(_) => false, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     pub fn size_of(&self) -> u64 { |     pub fn size_of(&self) -> u64 { | ||||||
|         match self { |         match self { | ||||||
|             TypeKind::Bool => 1, |             TypeKind::Bool => 1, | ||||||
| @ -262,6 +286,33 @@ impl Expression { | |||||||
|             ExprKind::If(_) => None, |             ExprKind::If(_) => None, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     pub fn is_zero(&self) -> Option<bool> { | ||||||
|  |         Some(self.num_value()? == 0) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     pub fn num_value(&self) -> Option<i128> { | ||||||
|  |         match &self.0 { | ||||||
|  |             ExprKind::Variable(_) => None, | ||||||
|  |             ExprKind::Indexed(..) => None, | ||||||
|  |             ExprKind::Accessed(..) => None, | ||||||
|  |             ExprKind::Array(_) => None, | ||||||
|  |             ExprKind::Struct(..) => None, | ||||||
|  |             ExprKind::Literal(literal) => literal.num_value(), | ||||||
|  |             ExprKind::BinOp(op, lhs, rhs) => match op { | ||||||
|  |                 BinaryOperator::Add => Some(lhs.num_value()? + rhs.num_value()?), | ||||||
|  |                 BinaryOperator::Minus => Some(lhs.num_value()? - rhs.num_value()?), | ||||||
|  |                 BinaryOperator::Mult => Some(lhs.num_value()? * rhs.num_value()?), | ||||||
|  |                 BinaryOperator::And => None, | ||||||
|  |                 BinaryOperator::Cmp(_) => None, | ||||||
|  |             }, | ||||||
|  |             ExprKind::FunctionCall(..) => None, | ||||||
|  |             ExprKind::If(_) => None, | ||||||
|  |             ExprKind::Block(_) => None, | ||||||
|  |             ExprKind::Borrow(_, _) => None, | ||||||
|  |             ExprKind::Deref(_) => None, | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl IfExpression { | impl IfExpression { | ||||||
| @ -407,6 +458,26 @@ impl Collapsable for TypeKind { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | impl Literal { | ||||||
|  |     pub fn num_value(&self) -> Option<i128> { | ||||||
|  |         match self { | ||||||
|  |             Literal::I8(val) => Some(*val as i128), | ||||||
|  |             Literal::I16(val) => Some(*val as i128), | ||||||
|  |             Literal::I32(val) => Some(*val as i128), | ||||||
|  |             Literal::I64(val) => Some(*val as i128), | ||||||
|  |             Literal::I128(val) => Some(*val as i128), | ||||||
|  |             Literal::U8(val) => Some(*val as i128), | ||||||
|  |             Literal::U16(val) => Some(*val as i128), | ||||||
|  |             Literal::U32(val) => Some(*val as i128), | ||||||
|  |             Literal::U64(val) => Some(*val as i128), | ||||||
|  |             Literal::U128(val) => Some(*val as i128), | ||||||
|  |             Literal::Bool(_) => None, | ||||||
|  |             Literal::String(_) => None, | ||||||
|  |             Literal::Vague(VagueLiteral::Number(val)) => Some(*val as i128), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| impl Collapsable for ScopeFunction { | impl Collapsable for ScopeFunction { | ||||||
|     fn collapse_into(&self, other: &ScopeFunction) -> Result<ScopeFunction, ErrorKind> { |     fn collapse_into(&self, other: &ScopeFunction) -> Result<ScopeFunction, ErrorKind> { | ||||||
|         Ok(ScopeFunction { |         Ok(ScopeFunction { | ||||||
|  | |||||||
| @ -103,10 +103,10 @@ impl<'map> Pass for LinkerPass<'map> { | |||||||
|             modules.insert(module.name.clone(), Rc::new(RefCell::new((module, tokens)))); |             modules.insert(module.name.clone(), Rc::new(RefCell::new((module, tokens)))); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         modules.insert( |         // modules.insert(
 | ||||||
|             "std".to_owned(), |         //     "std".to_owned(),
 | ||||||
|             Rc::new(RefCell::new(compile_std(&mut self.module_map)?)), |         //     Rc::new(RefCell::new(compile_std(&mut self.module_map)?)),
 | ||||||
|         ); |         // );
 | ||||||
| 
 | 
 | ||||||
|         let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> = |         let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> = | ||||||
|             modules.values().cloned().collect(); |             modules.values().cloned().collect(); | ||||||
|  | |||||||
| @ -183,7 +183,7 @@ impl VagueLiteral { | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #[derive(Debug, Clone, Copy)] | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] | ||||||
| pub enum BinaryOperator { | pub enum BinaryOperator { | ||||||
|     Add, |     Add, | ||||||
|     Minus, |     Minus, | ||||||
| @ -193,7 +193,7 @@ pub enum BinaryOperator { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Specifically the operators that LLVM likes to take in as "icmp" parameters
 | /// Specifically the operators that LLVM likes to take in as "icmp" parameters
 | ||||||
| #[derive(Debug, Clone, Copy)] | #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] | ||||||
| pub enum CmpOperator { | pub enum CmpOperator { | ||||||
|     LT, |     LT, | ||||||
|     LE, |     LE, | ||||||
|  | |||||||
| @ -65,6 +65,8 @@ pub enum ErrorKind { | |||||||
|     ImpossibleMutableBorrow(String), |     ImpossibleMutableBorrow(String), | ||||||
|     #[error("Cannot declare variable {0} as mutable, when it's type is immutable")] |     #[error("Cannot declare variable {0} as mutable, when it's type is immutable")] | ||||||
|     ImpossibleMutLet(String), |     ImpossibleMutLet(String), | ||||||
|  |     #[error("Cannot produce a negative unsigned value of type {0}!")] | ||||||
|  |     NegativeUnsignedValue(TypeKind), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// Struct used to implement a type-checking pass that can be performed on the
 | /// Struct used to implement a type-checking pass that can be performed on the
 | ||||||
| @ -409,6 +411,16 @@ impl Expression { | |||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 let both_t = lhs_type.collapse_into(&rhs_type)?; |                 let both_t = lhs_type.collapse_into(&rhs_type)?; | ||||||
|  | 
 | ||||||
|  |                 dbg!(&op, &both_t, both_t.signed(), lhs.is_zero(), rhs.is_zero()); | ||||||
|  |                 if *op == BinaryOperator::Minus && !lhs_type.signed() { | ||||||
|  |                     if let (Some(lhs_val), Some(rhs_val)) = (lhs.num_value(), rhs.num_value()) { | ||||||
|  |                         if lhs_val < rhs_val { | ||||||
|  |                             return Err(ErrorKind::NegativeUnsignedValue(lhs_type)); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  | 
 | ||||||
|                 Ok(both_t.binop_type(op)) |                 Ok(both_t.binop_type(op)) | ||||||
|             } |             } | ||||||
|             ExprKind::FunctionCall(function_call) => { |             ExprKind::FunctionCall(function_call) => { | ||||||
|  | |||||||
| @ -5,5 +5,5 @@ fn main() -> u32 { | |||||||
|   let value = 6; |   let value = 6; | ||||||
|   let other = 15; |   let other = 15; | ||||||
| 
 | 
 | ||||||
|   return value * other + 7 * (-value); |   return value * other + 7 * -value; | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user