Add typechecking for arrays
This commit is contained in:
parent
4f8153643b
commit
b14a62bc34
@ -2,6 +2,7 @@
|
||||
//! passes. Passes can be performed on Reid MIR to e.g. typecheck the code.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::convert::Infallible;
|
||||
use std::error::Error as STDError;
|
||||
|
||||
use super::*;
|
||||
@ -166,6 +167,16 @@ impl<'st, 'sc, TError: STDError + Clone> PassState<'st, 'sc, TError> {
|
||||
self.state.ok(result, meta)
|
||||
}
|
||||
|
||||
pub fn note_errors<TMeta: Into<Metadata> + Clone>(
|
||||
&mut self,
|
||||
errors: &Vec<TError>,
|
||||
meta: TMeta,
|
||||
) {
|
||||
for error in errors {
|
||||
self.ok::<_, Infallible>(Err(error.clone()), meta.clone().into());
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inner(&mut self) -> PassState<TError> {
|
||||
self.inner.push(self.scope.inner());
|
||||
let scope = self.inner.last_mut().unwrap();
|
||||
|
@ -42,6 +42,8 @@ pub enum ErrorKind {
|
||||
BranchTypesDiffer(TypeKind, TypeKind),
|
||||
#[error("Attempted to index a non-array type of {0}")]
|
||||
TriedIndexingNonArray(TypeKind),
|
||||
#[error("Index {0} out of bounds ({1})")]
|
||||
IndexOutOfBounds(u64, u64),
|
||||
}
|
||||
|
||||
/// Struct used to implement a type-checking pass that can be performed on the
|
||||
@ -376,8 +378,42 @@ impl Expression {
|
||||
Ok(collapsed)
|
||||
}
|
||||
ExprKind::Block(block) => block.typecheck(state, &hints, hint_t),
|
||||
ExprKind::Index(expression, _) => todo!("typechecking for index expression"),
|
||||
ExprKind::Array(expressions) => todo!("typechecking for array expression"),
|
||||
ExprKind::Index(expression, idx) => {
|
||||
let expr_t = expression.typecheck(state, hints, hint_t)?;
|
||||
if let TypeKind::Array(elem_t, len) = expr_t {
|
||||
if len >= *idx {
|
||||
return Err(ErrorKind::IndexOutOfBounds(*idx, len));
|
||||
}
|
||||
Ok(*elem_t)
|
||||
} else {
|
||||
Err(ErrorKind::TriedIndexingNonArray(expr_t))
|
||||
}
|
||||
}
|
||||
ExprKind::Array(expressions) => {
|
||||
let mut expr_result = try_all(
|
||||
expressions
|
||||
.iter_mut()
|
||||
.map(|e| e.typecheck(state, hints, hint_t))
|
||||
.collect(),
|
||||
);
|
||||
match &mut expr_result {
|
||||
Ok(expr_types) => {
|
||||
let mut iter = expr_types.iter_mut();
|
||||
if let Some(first) = iter.next() {
|
||||
for other in iter {
|
||||
state.ok(first.collapse_into(other), self.1);
|
||||
}
|
||||
Ok(first.clone())
|
||||
} else {
|
||||
Ok(Array(Box::new(Void), 0))
|
||||
}
|
||||
}
|
||||
Err(errors) => {
|
||||
state.note_errors(errors, self.1);
|
||||
Ok(Array(Box::new(Vague(Unknown)), expressions.len() as u64))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
use std::{convert::Infallible, iter};
|
||||
|
||||
use crate::util::try_all;
|
||||
use crate::{mir::TypeKind, util::try_all};
|
||||
|
||||
use super::{
|
||||
pass::{Pass, PassState, ScopeVariable},
|
||||
@ -293,14 +293,19 @@ impl Expression {
|
||||
))
|
||||
.unwrap())
|
||||
} else {
|
||||
todo!();
|
||||
Ok(type_refs
|
||||
.from_type(&Array(Box::new(TypeKind::Void), 0))
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
Err(errors) => {
|
||||
for error in errors {
|
||||
state.ok::<_, Infallible>(Err(error.clone()), self.1);
|
||||
}
|
||||
todo!();
|
||||
state.note_errors(errors, self.1);
|
||||
Ok(type_refs
|
||||
.from_type(&TypeKind::Array(
|
||||
Box::new(TypeKind::Vague(Unknown)),
|
||||
expressions.len() as u64,
|
||||
))
|
||||
.unwrap())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user