diff --git a/.gitignore b/.gitignore index c33a7d7..fbe6850 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ target examples +tarpaulin-report.html diff --git a/CHANGELOG.md b/CHANGELOG.md index 79648f6..31dad7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## TODO +- Implement functions as first class citizens - Implement AST transformation before codegen: Create a new AST to represent PHP source code and a THP ast -> PHP ast process, so that the @@ -23,18 +24,25 @@ - Simple language server - Decide how to handle comments in the syntax (?)(should comments mean something like in rust?) - Not ignore comments & whitespace, for code formatting +- Abstract the parsing of datatypes, such that in the future generics can be implemented in a single place + +## v0.0.13 + +- [ ] Define a formal grammar +- [ ] Define the top level constructs +- [ ] Implement a hello world until semantic analysis +- [ ] Refactor code + ## v0.0.12 - [x] Infer datatype of an identifier - [x] Infer datatype of a binary operatior - [x] Infer datatype of unary operator -- [ ] Infer datatype of a function call expression -- [ ] Infer datatype of binary operators +- [x] Infer datatype of binary operators - [x] Infer Int & Float as different types -- [ ] Execute semantic analysis on the function's block -- [ ] Write tests -- [ ] Abstract the parsing of datatypes, such that in the future generics can be implemented in a single place +- [x] Execute semantic analysis on the function's block +- [x] Write tests ## v0.0.11 diff --git a/Cargo.lock b/Cargo.lock index 03bf7a2..1013e7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,7 +20,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "thp" -version = "0.0.11" +version = "0.0.12" dependencies = [ "colored", ] diff --git a/Cargo.toml b/Cargo.toml index f2ec7d1..01c3bec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thp" -version = "0.0.11" +version = "0.0.12" edition = "2021" diff --git a/src/semantic/checks/function_declaration.rs b/src/semantic/checks/function_declaration.rs index 97cb697..cbd6e3d 100644 --- a/src/semantic/checks/function_declaration.rs +++ b/src/semantic/checks/function_declaration.rs @@ -1,7 +1,7 @@ use crate::{ error_handling::{semantic_error::SemanticError, MistiError}, - semantic::{impls::SemanticCheck, symbol_table::SymbolEntry}, - syntax::ast::FunctionDeclaration, + semantic::{impls::SemanticCheck, symbol_table::{SymbolEntry, SymbolTable}}, + syntax::ast::{statement::Statement, FunctionDeclaration}, }; impl SemanticCheck for FunctionDeclaration<'_> { @@ -25,8 +25,23 @@ impl SemanticCheck for FunctionDeclaration<'_> { return Err(MistiError::Semantic(error)); } - // TODO: Check the return type of the function + // Create a new scope and use it in the function block + let function_scope = SymbolTable::new_from_parent(scope); + // TODO: Check the return type of the function body + // This should be the last expression in the block + for stmt in self.block.statements.iter() { + match stmt { + Statement::Binding(b) => { + if let Err(err) = b.check_semantics(&function_scope) { + return Err(err) + } + } + Statement::FunctionCall(_) => panic!("FunctionCall semantic check not implemented") + } + } + + // TODO: Check the return type of the function scope.insert( function_name, diff --git a/src/semantic/types/expression.rs b/src/semantic/types/expression.rs index 167d6c6..ca4c4ab 100644 --- a/src/semantic/types/expression.rs +++ b/src/semantic/types/expression.rs @@ -29,7 +29,13 @@ impl Typed for Expression<'_> { Ok(datatype) } - Expression::FunctionCall(_) => todo!(), + Expression::FunctionCall(_f) => { + // TODO: Must implement functions as first class citizens + // for this to work + + // TODO: check the parameter types + panic!("Not implemented: Get datatype of function call") + } Expression::UnaryOperator(op, exp) => { let expr_type = match exp.get_type(scope) { Ok(t) => t, diff --git a/src/syntax/ast/mod.rs b/src/syntax/ast/mod.rs index c1c473a..6c80c14 100644 --- a/src/syntax/ast/mod.rs +++ b/src/syntax/ast/mod.rs @@ -10,6 +10,7 @@ pub struct ModuleAST<'a> { pub declarations: Vec>, } +// TODO: this and Statement should merge #[derive(Debug)] pub enum TopLevelDeclaration<'a> { Binding(var_binding::Binding<'a>), @@ -27,6 +28,7 @@ pub struct FunctionDeclaration<'a> { #[derive(Debug)] pub struct Block<'a> { + // TODO: this should be a Vec of Statement|Expression pub statements: Vec>, } diff --git a/src/syntax/ast/statement.rs b/src/syntax/ast/statement.rs index d72386a..77637af 100644 --- a/src/syntax/ast/statement.rs +++ b/src/syntax/ast/statement.rs @@ -1,5 +1,6 @@ use super::{functions::FunctionCall, var_binding::Binding}; +// TODO: this and TopLevelDeclaration should merge #[derive(Debug)] pub enum Statement<'a> { FunctionCall(FunctionCall<'a>),