From 527b1b4af69856c8c4fbf8a518fb2c855a4206f7 Mon Sep 17 00:00:00 2001 From: Araozu Date: Sat, 4 May 2024 12:28:15 -0500 Subject: [PATCH] Organize files for semantic analysis --- src/semantic/checks/binding.rs | 7 +- src/semantic/checks/mod.rs | 1 + src/semantic/checks/top_level_declaration.rs | 12 +++ src/semantic/impls.rs | 80 +------------------- src/semantic/mod.rs | 1 + src/semantic/types/expression.rs | 10 +++ src/semantic/types/mod.rs | 11 +++ 7 files changed, 41 insertions(+), 81 deletions(-) create mode 100644 src/semantic/checks/top_level_declaration.rs create mode 100644 src/semantic/types/expression.rs create mode 100644 src/semantic/types/mod.rs diff --git a/src/semantic/checks/binding.rs b/src/semantic/checks/binding.rs index a00b7ec..c242e52 100644 --- a/src/semantic/checks/binding.rs +++ b/src/semantic/checks/binding.rs @@ -1,6 +1,6 @@ use crate::{ error_handling::{semantic_error::SemanticError, MistiError}, - semantic::{impls::SemanticCheck, symbol_table::SymbolEntry}, + semantic::{impls::SemanticCheck, symbol_table::SymbolEntry, types::Typed}, syntax::ast::var_binding::Binding, }; @@ -26,8 +26,8 @@ impl SemanticCheck for Binding<'_> { return Err(MistiError::Semantic(error)); } - todo!(""); - /* + // This gets the datatype of the assigned expression, + // to compare it later with the declared datatype. let expression_datatype = self.expression.get_type(); let datatype = match self.datatype { @@ -53,6 +53,5 @@ impl SemanticCheck for Binding<'_> { scope.insert(binding_name.clone(), SymbolEntry::new_variable(datatype)); Ok(()) - */ } } diff --git a/src/semantic/checks/mod.rs b/src/semantic/checks/mod.rs index 959ff3d..02de27b 100644 --- a/src/semantic/checks/mod.rs +++ b/src/semantic/checks/mod.rs @@ -1,2 +1,3 @@ pub mod binding; pub mod function_declaration; +pub mod top_level_declaration; diff --git a/src/semantic/checks/top_level_declaration.rs b/src/semantic/checks/top_level_declaration.rs new file mode 100644 index 0000000..a48e28a --- /dev/null +++ b/src/semantic/checks/top_level_declaration.rs @@ -0,0 +1,12 @@ +use crate::{semantic::impls::SemanticCheck, syntax::ast::TopLevelDeclaration}; + +impl SemanticCheck for TopLevelDeclaration<'_> { + fn check_semantics(&self, scope: &crate::semantic::symbol_table::SymbolTable) -> Result<(), crate::error_handling::MistiError> { + match self { + TopLevelDeclaration::Binding(binding) => binding.check_semantics(scope), + TopLevelDeclaration::FunctionDeclaration(function) => function.check_semantics(scope), + _ => panic!("Not implemented"), + } + } +} + diff --git a/src/semantic/impls.rs b/src/semantic/impls.rs index 437a59f..c33f23b 100644 --- a/src/semantic/impls.rs +++ b/src/semantic/impls.rs @@ -1,11 +1,8 @@ -use crate::{ - error_handling::semantic_error::SemanticError, - error_handling::MistiError, - syntax::ast::{ModuleAST, TopLevelDeclaration}, -}; +use crate::{error_handling::MistiError, syntax::ast::ModuleAST}; -use super::symbol_table::{SymbolEntry, SymbolTable}; +use super::symbol_table::SymbolTable; +/// Allows this type to have it's semantics checked. pub trait SemanticCheck { fn check_semantics(&self, scope: &SymbolTable) -> Result<(), MistiError>; } @@ -20,74 +17,3 @@ impl SemanticCheck for ModuleAST<'_> { Ok(()) } } - -impl SemanticCheck for TopLevelDeclaration<'_> { - fn check_semantics(&self, scope: &SymbolTable) -> Result<(), MistiError> { - match self { - TopLevelDeclaration::Binding(binding) => { - let binding_name = &binding.identifier.value; - - if scope.test(binding_name) { - let error = SemanticError { - error_start: binding.identifier.position, - error_end: binding.identifier.get_end_position(), - reason: format!( - "Duplicated: A symbol with name {} was already defined", - binding_name - ), - }; - - return Err(MistiError::Semantic(error)); - } - - let datatype = match binding.datatype { - Some(t) => t, - None => { - let error = SemanticError { - error_start: binding.identifier.position, - error_end: binding.identifier.get_end_position(), - reason: format!( - "The variable `{}` didn't define a datatype. Datatype inference is not implemented.", - binding_name - ), - }; - - return Err(MistiError::Semantic(error)); - } - }; - - scope.insert( - binding_name.clone(), - SymbolEntry::new_variable(datatype.value.clone()), - ); - - Ok(()) - } - TopLevelDeclaration::FunctionDeclaration(function) => { - let function_name = function.identifier.value.clone(); - - // Check that the function is not already defined - if scope.test(&function_name) { - let error = SemanticError { - error_start: function.identifier.position, - error_end: function.identifier.get_end_position(), - reason: format!( - "Duplicated: A symbol with name {} was already defined", - function_name - ), - }; - - return Err(MistiError::Semantic(error)); - } - - scope.insert( - function_name, - SymbolEntry::new_function(vec![], "Unit".into()), - ); - - Ok(()) - } - _ => panic!("Not implemented"), - } - } -} diff --git a/src/semantic/mod.rs b/src/semantic/mod.rs index a90af5c..5dd63d2 100644 --- a/src/semantic/mod.rs +++ b/src/semantic/mod.rs @@ -3,6 +3,7 @@ use crate::{error_handling::MistiError, syntax::ast::ModuleAST}; mod impls; mod symbol_table; mod checks; +mod types; use impls::SemanticCheck; diff --git a/src/semantic/types/expression.rs b/src/semantic/types/expression.rs new file mode 100644 index 0000000..770fc6d --- /dev/null +++ b/src/semantic/types/expression.rs @@ -0,0 +1,10 @@ +use crate::syntax::ast::Expression; + +use super::Typed; + + +impl Typed for Expression<'_> { + fn get_type(&self) -> String { + todo!() + } +} diff --git a/src/semantic/types/mod.rs b/src/semantic/types/mod.rs new file mode 100644 index 0000000..f85ac29 --- /dev/null +++ b/src/semantic/types/mod.rs @@ -0,0 +1,11 @@ +// This crate provides an interface and implementations +// for determining the datatypes of the language constructs. + +use crate::lexic::token::Token; + +mod expression; + + +pub trait Typed { + fn get_type(&self) -> String; +}