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