Perform type inference for array and indexing expressions
This commit is contained in:
parent
64f07002b4
commit
4f8153643b
@ -40,6 +40,8 @@ pub enum ErrorKind {
|
||||
TypeNotInferrable(TypeKind),
|
||||
#[error("Expected branch type to be {0}, found {1} instead")]
|
||||
BranchTypesDiffer(TypeKind, TypeKind),
|
||||
#[error("Attempted to index a non-array type of {0}")]
|
||||
TriedIndexingNonArray(TypeKind),
|
||||
}
|
||||
|
||||
/// Struct used to implement a type-checking pass that can be performed on the
|
||||
|
@ -4,7 +4,9 @@
|
||||
//! must then be passed through TypeCheck with the same [`TypeRefs`] in order to
|
||||
//! place the correct types from the IDs and check that there are no issues.
|
||||
|
||||
use std::iter;
|
||||
use std::{convert::Infallible, iter};
|
||||
|
||||
use crate::util::try_all;
|
||||
|
||||
use super::{
|
||||
pass::{Pass, PassState, ScopeVariable},
|
||||
@ -261,8 +263,47 @@ impl Expression {
|
||||
ReturnKind::Soft => Ok(block_ref.1),
|
||||
}
|
||||
}
|
||||
ExprKind::Index(expression, _) => todo!("type inference for index expression"),
|
||||
ExprKind::Array(expressions) => todo!("type inference for array expression"),
|
||||
ExprKind::Index(expression, _) => {
|
||||
let expr_ty = expression.infer_types(state, type_refs)?;
|
||||
let kind = unsafe { expr_ty.resolve_type() };
|
||||
match kind {
|
||||
Array(type_kind, _) => Ok(type_refs.from_type(&type_kind).unwrap()),
|
||||
_ => Err(ErrorKind::TriedIndexingNonArray(kind)),
|
||||
}
|
||||
}
|
||||
ExprKind::Array(expressions) => {
|
||||
let mut expr_types_result = try_all(
|
||||
expressions
|
||||
.iter_mut()
|
||||
.map(|e| (*e).infer_types(state, type_refs))
|
||||
.collect(),
|
||||
);
|
||||
match &mut expr_types_result {
|
||||
Ok(expr_types) => {
|
||||
let mut iter = expr_types.iter_mut();
|
||||
if let Some(first) = iter.next() {
|
||||
while let Some(other) = iter.next() {
|
||||
first.narrow(other);
|
||||
}
|
||||
|
||||
Ok(type_refs
|
||||
.from_type(&Array(
|
||||
Box::new(first.as_type()),
|
||||
expressions.len() as u64,
|
||||
))
|
||||
.unwrap())
|
||||
} else {
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
Err(errors) => {
|
||||
for error in errors {
|
||||
state.ok::<_, Infallible>(Err(error.clone()), self.1);
|
||||
}
|
||||
todo!();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,6 +140,11 @@ impl<'outer> ScopeTypeRefs<'outer> {
|
||||
self.types.type_refs.borrow().get(inner_idx).cloned()?
|
||||
}
|
||||
TypeKind::Vague(_) => self.types.new(ty),
|
||||
TypeKind::Array(elem_ty, length) => {
|
||||
let elem_ty = self.from_type(elem_ty)?;
|
||||
self.types
|
||||
.new(&TypeKind::Array(Box::new(elem_ty.as_type()), *length))
|
||||
}
|
||||
_ => {
|
||||
if let Some(ty_ref) = self.types.find(ty) {
|
||||
ty_ref
|
||||
|
Loading…
Reference in New Issue
Block a user