todo: typechecking, then ensure placeness and IR still work as expected
This commit is contained in:
parent
4c7813aa98
commit
aeab786fe3
|
@ -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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue