todo: typechecking, then ensure placeness and IR still work as expected

This commit is contained in:
Janis 2025-03-08 12:22:53 +01:00
parent 4c7813aa98
commit aeab786fe3

View file

@ -10,6 +10,7 @@ use super::{
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum ErrorKind { enum ErrorKind {
MismatchingTypes, MismatchingTypes,
DerefNonPointer,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -247,6 +248,15 @@ impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> {
Ok(Some(ty)) Ok(Some(ty))
} }
fn visit_interned_type_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
intern: intern::Index,
) -> Result<Self::Value, Self::Error> {
Ok(Some(intern))
}
fn visit_any( fn visit_any(
&mut self, &mut self,
ast: &'a mut Ast, ast: &'a mut Ast,
@ -257,7 +267,7 @@ impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> {
let _ty = match tag { let _ty = match tag {
Tag::Root => unreachable!(), Tag::Root => unreachable!(),
Tag::InternedType => Some(data.as_intern()), Tag::InternedType => Some(data.as_intern()),
Tag::File => self.visit_children(ast, idx)?, Tag::File => self.visit_file(ast, idx)?,
Tag::ArrayType => self.visit_array_type(ast, idx)?, Tag::ArrayType => self.visit_array_type(ast, idx)?,
Tag::PointerType => self.visit_pointer_type(ast, idx)?, Tag::PointerType => self.visit_pointer_type(ast, idx)?,
Tag::TypeDeclRef => self.visit_type_decl_ref(ast, idx)?, Tag::TypeDeclRef => self.visit_type_decl_ref(ast, idx)?,
@ -265,18 +275,13 @@ impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> {
Tag::FunctionProto => self.visit_function_proto(ast, idx)?, Tag::FunctionProto => self.visit_function_proto(ast, idx)?,
Tag::Parameter => self.visit_parameter(ast, idx)?, Tag::Parameter => self.visit_parameter(ast, idx)?,
Tag::StructDecl => self.visit_struct_decl(ast, idx)?, Tag::StructDecl => self.visit_struct_decl(ast, idx)?,
Tag::StructDeclInterned => { Tag::StructDeclInterned => self.visit_struct_decl_interned(ast, idx)?,
let (_, ty) = data.as_two_interns();
Some(ty)
}
Tag::FunctionDecl => self.visit_function_decl(ast, idx)?, Tag::FunctionDecl => self.visit_function_decl(ast, idx)?,
Tag::ParameterList => todo!(), Tag::ParameterList => todo!(),
Tag::Block => todo!(), Tag::Block | Tag::BlockTrailingExpr => self.visit_block(ast, idx)?,
Tag::BlockTrailingExpr => todo!(), Tag::Constant => self.visit_constant(ast, idx)?,
Tag::Constant => todo!(), Tag::ExprStmt => self.visit_expr_stmt(ast, idx)?,
Tag::ExprStmt => todo!(), Tag::ReturnStmt => self.visit_return_stmt(ast, idx)?,
Tag::ReturnStmt => todo!(),
Tag::ReturnExprStmt => todo!(), Tag::ReturnExprStmt => todo!(),
Tag::VarDecl => todo!(), Tag::VarDecl => todo!(),
Tag::MutVarDecl => todo!(), Tag::MutVarDecl => todo!(),
@ -292,39 +297,203 @@ impl<'a> AstVisitorTrait<&'a mut Ast> for TypeChecker<'_> {
Tag::ArgumentList => todo!(), Tag::ArgumentList => todo!(),
Tag::Argument => todo!(), Tag::Argument => todo!(),
Tag::NamedArgument => todo!(), Tag::NamedArgument => todo!(),
Tag::ExplicitCast => todo!(), Tag::ExplicitCast => self.visit_explicit_cast(ast, idx)?,
Tag::Deref => todo!(), Tag::Deref => self.visit_deref(ast, idx)?,
Tag::AddressOf => todo!(), Tag::AddressOf => self.visit_address_of(ast, idx)?,
Tag::Not => todo!(), Tag::Not | Tag::Negate => {
Tag::Negate => todo!(), let ty = self.visit_any(ast, data.as_index())?;
Tag::PlaceToValueConversion => todo!(), ty
Tag::ValueToPlaceConversion => todo!(), }
Tag::Or => todo!(), Tag::PlaceToValueConversion => self.visit_place_to_value_conversion(ast, idx)?,
Tag::And => todo!(), Tag::ValueToPlaceConversion => self.visit_value_to_place_conversion(ast, idx)?,
Tag::BitOr => todo!(), Tag::Or
Tag::BitXOr => todo!(), | Tag::And
Tag::BitAnd => todo!(), | Tag::BitOr
Tag::Eq => todo!(), | Tag::BitXOr
Tag::NEq => todo!(), | Tag::BitAnd
Tag::Lt => todo!(), | Tag::Eq
Tag::Gt => todo!(), | Tag::NEq
Tag::Le => todo!(), | Tag::Lt
Tag::Ge => todo!(), | Tag::Gt
Tag::Shl => todo!(), | Tag::Le
Tag::Shr => todo!(), | Tag::Ge
Tag::Add => todo!(), | Tag::Shl
Tag::Sub => todo!(), | Tag::Shr
Tag::Mul => todo!(), | Tag::Add
Tag::Div => todo!(), | Tag::Sub
Tag::Rem => todo!(), | Tag::Mul
Tag::Assign => todo!(), | Tag::Div
Tag::SubscriptExpr => todo!(), | Tag::Rem => {
Tag::IfExpr => todo!(), let (lhs, rhs) = data.as_two_indices();
Tag::IfElseExpr => todo!(), let lhs = self.visit_any(ast, lhs)?.unwrap();
let rhs = self.visit_any(ast, rhs)?.unwrap();
if lhs != rhs {
self.errors.push(Error {
idx,
kind: ErrorKind::MismatchingTypes,
});
}
Some(lhs)
}
Tag::Assign => self.visit_assign(ast, idx)?,
Tag::SubscriptExpr => self.visit_subscript_expr(ast, idx)?,
Tag::IfExpr => self.visit_if_expr(ast, idx)?,
Tag::IfElseExpr => self.visit_if_else_expr(ast, idx)?,
Tag::Error => todo!(), Tag::Error => todo!(),
Tag::Undefined => todo!(), Tag::Undefined => todo!(),
}; };
todo!() todo!()
} }
fn visit_explicit_cast_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
expr: Index,
ty: Index,
) -> Result<Self::Value, Self::Error> {
_ = self.visit_any(ast, expr)?;
// TODO: make sure this cast is legal
let ty = self.visit_any(ast, ty)?;
Ok(ty)
}
fn visit_address_of_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
expr: Index,
) -> Result<Self::Value, Self::Error> {
self.visit_any(ast, expr)
}
fn visit_deref_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
expr: Index,
) -> Result<Self::Value, Self::Error> {
let ty = self.visit_any(ast, expr)?.unwrap();
if let intern::Key::PointerType { pointee, .. } = self.ip.get_key(ty) {
Ok(Some(pointee))
} else {
Ok(None)
}
}
fn visit_place_to_value_conversion_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
expr: Index,
) -> Result<Self::Value, Self::Error> {
let ty = self.visit_any(ast, expr)?;
if let Some(ty) = ty {
Ok(self.ip.try_get_pointee_type(ty))
} else {
self.errors.push(Error {
idx,
kind: ErrorKind::DerefNonPointer,
});
Ok(None)
}
}
fn visit_value_to_place_conversion_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
expr: Index,
) -> Result<Self::Value, Self::Error> {
let ty = self.visit_any(ast, expr)?;
if let Some(ty) = ty {
Ok(Some(self.ip.get_pointer_type(ty, None)))
} else {
Ok(None)
}
}
fn visit_if_else_expr_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
cond: Index,
a: Index,
b: Index,
) -> Result<Self::Value, Self::Error> {
self.visit_any(ast, cond)?;
let a = self.visit_block(ast, a)?;
let b = self.visit_block(ast, b)?;
if a != b {
self.errors.push(Error {
idx,
kind: ErrorKind::MismatchingTypes,
});
}
Ok(a)
}
fn visit_if_expr_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
cond: Index,
body: Index,
) -> Result<Self::Value, Self::Error> {
self.visit_any(ast, cond)?;
self.visit_block(ast, body)?;
Ok(None)
}
fn visit_subscript_expr_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
lhs: Index,
index: Index,
) -> Result<Self::Value, Self::Error> {
let lhs = self.visit_any(ast, lhs)?.unwrap();
let index = self.visit_any(ast, index)?.unwrap();
if index != intern::Index::USIZE {
self.errors.push(Error {
idx,
kind: ErrorKind::MismatchingTypes,
});
}
let pointee = self.ip.try_get_pointee_type(lhs).unwrap();
let pointer = self.ip.get_pointer_type(pointee, None);
Ok(Some(pointer))
}
fn visit_assign_impl(
&mut self,
ast: &'a mut Ast,
idx: Index,
lhs: Index,
rhs: Index,
) -> Result<Self::Value, Self::Error> {
let lhs = self.visit_any(ast, lhs)?.unwrap();
let rhs = self.visit_any(ast, rhs)?.unwrap();
if self.ip.try_get_pointee_type(lhs) != Some(rhs) {
self.errors.push(Error {
idx,
kind: ErrorKind::MismatchingTypes,
});
}
Ok(None)
}
} }