From 3036c73983f7a61b82f34f0613160149ca020926 Mon Sep 17 00:00:00 2001 From: MilkeeyCat Date: Sun, 8 Sep 2024 14:51:32 +0300 Subject: [PATCH] fix: show error when recursive type occurs closes #24 --- src/passes/type_checker.rs | 21 +++++++++++++++++++++ src/scope.rs | 4 ++++ src/type_table.rs | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/passes/type_checker.rs b/src/passes/type_checker.rs index 1a75a87..f24ce42 100644 --- a/src/passes/type_checker.rs +++ b/src/passes/type_checker.rs @@ -2,6 +2,8 @@ use super::Pass; use crate::{ parser::{Block, Expr, Expression, ParserError, Stmt, UnOp}, scope::Scope, + type_table as tt, + type_table::TypeTable, types::{Type, TypeError}, }; use std::collections::HashSet; @@ -13,6 +15,7 @@ impl Pass for TypeChecker { type Output = Result<()>; fn proccess(stmts: &mut Vec, scope: &mut Scope) -> Self::Output { + Self::check_type_table(scope.type_table(), scope)?; for stmt in stmts { Self::check_stmt(stmt, scope)?; } @@ -24,6 +27,7 @@ impl Pass for TypeChecker { impl TypeChecker { fn check_block(block: &Block, scope: &mut Scope) -> Result<()> { scope.enter(block.scope.clone()); + Self::check_type_table(scope.type_table(), scope)?; for stmt in &block.statements { Self::check_stmt(stmt, scope)?; } @@ -175,4 +179,21 @@ impl TypeChecker { _ => {} }) } + + fn check_type_table(type_table: &TypeTable, scope: &Scope) -> Result<()> { + for type_ in &type_table.0 { + match type_ { + tt::Type::Struct(type_struct) => { + for (_, type_) in &type_struct.fields { + Self::check_type(type_, scope)?; + if type_ == &Type::Struct(type_struct.name.clone()) { + panic!("Recursize type {type_} has infinite size"); + } + } + } + } + } + + Ok(()) + } } diff --git a/src/scope.rs b/src/scope.rs index a9b82a4..c35a585 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -85,6 +85,10 @@ impl Scope { &mut self.0.last_mut().unwrap().symbol_table } + pub fn type_table(&self) -> &TypeTable { + &self.0.last().unwrap().type_table + } + pub fn type_table_mut(&mut self) -> &mut TypeTable { &mut self.0.last_mut().unwrap().type_table } diff --git a/src/type_table.rs b/src/type_table.rs index 18fa900..e344147 100644 --- a/src/type_table.rs +++ b/src/type_table.rs @@ -65,7 +65,7 @@ impl TypeStruct { } #[derive(Debug, Clone, PartialEq)] -pub struct TypeTable(Vec); +pub struct TypeTable(pub Vec); impl TypeTable { pub fn new() -> Self {