Compare commits

...

2 Commits

Author SHA1 Message Date
e79a0fe458 Update where default value is calculated, fix load type 2025-07-12 23:59:16 +03:00
edb2784f4a Remove unused while-loop 2025-07-12 23:40:49 +03:00
4 changed files with 29 additions and 25 deletions

View File

@ -251,9 +251,10 @@ impl Builder {
Ok(()) Ok(())
} }
Alloca(_, _) => Ok(()), Alloca(_, _) => Ok(()),
Load(ptr, _) => { Load(ptr, load_ty) => {
if let Ok(ty) = ptr.get_type(&self) { if let Ok(ptr_ty) = ptr.get_type(&self) {
if let Type::Ptr(_) = ty { if let Type::Ptr(ptr_ty_inner) = ptr_ty {
if *ptr_ty_inner == load_ty {
Ok(()) Ok(())
} else { } else {
Err(()) Err(())
@ -261,6 +262,9 @@ impl Builder {
} else { } else {
Err(()) Err(())
} }
} else {
Err(())
}
} }
Store(ptr, _) => { Store(ptr, _) => {
if let Ok(ty) = ptr.get_type(&self) { if let Ok(ty) = ptr.get_type(&self) {
@ -332,7 +336,7 @@ impl InstructionValue {
FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret), FunctionCall(function_value, _) => Ok(builder.function_data(function_value).ret),
Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)), Phi(values) => values.first().ok_or(()).and_then(|v| v.get_type(&builder)),
Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))), Alloca(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))),
Load(_, ty) => Ok(Type::Ptr(Box::new(ty.clone()))), Load(_, ty) => Ok(ty.clone()),
Store(_, value) => value.get_type(builder), Store(_, value) => value.get_type(builder),
} }
} }

View File

@ -6,10 +6,11 @@ fn indirection() -> bool {
fn main() -> u16 { fn main() -> u16 {
let mut test = 5; let mut test = 5;
let heehoo = 10;
if indirection() { if indirection() {
test = 11; test = 11;
} }
return test; return test + heehoo;
} }

View File

@ -40,14 +40,15 @@ type TypeIdRef = Rc<RefCell<usize>>;
pub struct TypeHints { pub struct TypeHints {
/// Simple list of types that variables can refrence /// Simple list of types that variables can refrence
hints: RefCell<Vec<TypeKind>>, hints: RefCell<Vec<TypeKind>>,
types: RefCell<Vec<TypeIdRef>>, /// Indirect ID-references, referring to hints-vec
type_refs: RefCell<Vec<TypeIdRef>>,
} }
impl TypeHints { impl TypeHints {
pub fn new(&self, ty: TypeKind) -> TypeIdRef { pub fn new(&self, ty: TypeKind) -> TypeIdRef {
let idx = self.hints.borrow().len(); let idx = self.hints.borrow().len();
let typecell = Rc::new(RefCell::new(idx)); let typecell = Rc::new(RefCell::new(idx));
self.types.borrow_mut().push(typecell.clone()); self.type_refs.borrow_mut().push(typecell.clone());
self.hints.borrow_mut().push(ty); self.hints.borrow_mut().push(ty);
typecell typecell
} }
@ -70,19 +71,13 @@ impl<'outer> ScopeHints<'outer> {
} }
} }
pub fn retrieve_type(&self, mut idx: usize) -> Option<TypeKind> { pub fn retrieve_type(&self, idx: usize) -> Option<TypeKind> {
// Just make sure we have the correct idx let inner_idx = self
let mut inner_idx = self.types.types.borrow().get(idx).map(|i| *i.borrow())?; .types
let mut limit = 50; .type_refs
while inner_idx != idx { .borrow()
idx = inner_idx; .get(idx)
inner_idx = self.types.types.borrow().get(idx).map(|i| *i.borrow())?; .map(|i| *i.borrow())?;
limit -= 1;
if limit < 0 {
// Should never happen, but just to avoid infinite loops
panic!("Limit reached!");
}
}
self.types.hints.borrow().get(inner_idx).copied() self.types.hints.borrow().get(inner_idx).copied()
} }
@ -133,7 +128,7 @@ impl<'outer> ScopeHints<'outer> {
.get_unchecked(*hint2.0.borrow()) .get_unchecked(*hint2.0.borrow())
.clone(); .clone();
self.narrow_to_type(&hint1, &ty)?; self.narrow_to_type(&hint1, &ty)?;
for idx in self.types.types.borrow_mut().iter_mut() { for idx in self.types.type_refs.borrow_mut().iter_mut() {
if *idx == hint2.0 { if *idx == hint2.0 {
*idx.borrow_mut() = *hint1.0.borrow(); *idx.borrow_mut() = *hint1.0.borrow();
} }
@ -198,7 +193,7 @@ impl<'scope> TypeRef<'scope> {
Ok(ty) => TypeRef::Literal(*ty), Ok(ty) => TypeRef::Literal(*ty),
Err(vague) => match &vague { Err(vague) => match &vague {
super::VagueType::Hinted(idx) => TypeRef::Hint(ScopeHint( super::VagueType::Hinted(idx) => TypeRef::Hint(ScopeHint(
unsafe { hints.types.types.borrow().get_unchecked(*idx).clone() }, unsafe { hints.types.type_refs.borrow().get_unchecked(*idx).clone() },
hints, hints,
)), )),
_ => TypeRef::Hint(hints.new_vague(vague)), _ => TypeRef::Hint(hints.new_vague(vague)),

View File

@ -38,6 +38,8 @@ pub enum ErrorKind {
VariableNotMutable(String), VariableNotMutable(String),
#[error("Function {0} was given {1} parameters, but {2} were expected")] #[error("Function {0} was given {1} parameters, but {2} were expected")]
InvalidAmountParameters(String, usize, usize), InvalidAmountParameters(String, usize, usize),
#[error("Unable to infer type {0}")]
TypeNotInferrable(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
@ -194,6 +196,10 @@ impl Block {
); );
let res_t = if res_t.known().is_err() { let res_t = if res_t.known().is_err() {
// state.ok::<_, Infallible>(
// Err(ErrorKind::TypeNotInferrable(res_t)),
// variable_reference.2 + expression.1,
// );
// Unable to infer variable type even from expression! Default it // Unable to infer variable type even from expression! Default it
let res_t = let res_t =
state.or_else(res_t.or_default(), Vague(Unknown), variable_reference.2); state.or_else(res_t.or_default(), Vague(Unknown), variable_reference.2);
@ -552,8 +558,6 @@ impl Literal {
(L::Vague(VagueL::Number(v)), U32) => L::U32(v as u32), (L::Vague(VagueL::Number(v)), U32) => L::U32(v as u32),
(L::Vague(VagueL::Number(v)), U64) => L::U64(v as u64), (L::Vague(VagueL::Number(v)), U64) => L::U64(v as u64),
(L::Vague(VagueL::Number(v)), U128) => L::U128(v as u128), (L::Vague(VagueL::Number(v)), U128) => L::U128(v as u128),
// Default type for number literal if unable to find true type.
(L::Vague(VagueL::Number(v)), Vague(Number)) => L::I32(v as i32),
(_, Vague(_)) => self, (_, Vague(_)) => self,
_ => Err(ErrorKind::LiteralIncompatible(self, hint))?, _ => Err(ErrorKind::LiteralIncompatible(self, hint))?,
}) })