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),
|
TypeNotInferrable(TypeKind),
|
||||||
#[error("Expected branch type to be {0}, found {1} instead")]
|
#[error("Expected branch type to be {0}, found {1} instead")]
|
||||||
BranchTypesDiffer(TypeKind, TypeKind),
|
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
|
/// 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
|
//! 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.
|
//! 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::{
|
use super::{
|
||||||
pass::{Pass, PassState, ScopeVariable},
|
pass::{Pass, PassState, ScopeVariable},
|
||||||
@ -261,8 +263,47 @@ impl Expression {
|
|||||||
ReturnKind::Soft => Ok(block_ref.1),
|
ReturnKind::Soft => Ok(block_ref.1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExprKind::Index(expression, _) => todo!("type inference for index expression"),
|
ExprKind::Index(expression, _) => {
|
||||||
ExprKind::Array(expressions) => todo!("type inference for array 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()?
|
self.types.type_refs.borrow().get(inner_idx).cloned()?
|
||||||
}
|
}
|
||||||
TypeKind::Vague(_) => self.types.new(ty),
|
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) {
|
if let Some(ty_ref) = self.types.find(ty) {
|
||||||
ty_ref
|
ty_ref
|
||||||
|
Loading…
Reference in New Issue
Block a user