Typecheck function block
This commit is contained in:
parent
ab782b828d
commit
18f3f21eec
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
target
|
target
|
||||||
examples
|
examples
|
||||||
|
tarpaulin-report.html
|
||||||
|
18
CHANGELOG.md
18
CHANGELOG.md
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
|
- Implement functions as first class citizens
|
||||||
- Implement AST transformation before codegen:
|
- Implement AST transformation before codegen:
|
||||||
Create a new AST to represent PHP source code
|
Create a new AST to represent PHP source code
|
||||||
and a THP ast -> PHP ast process, so that the
|
and a THP ast -> PHP ast process, so that the
|
||||||
@ -23,18 +24,25 @@
|
|||||||
- Simple language server
|
- Simple language server
|
||||||
- Decide how to handle comments in the syntax (?)(should comments mean something like in rust?)
|
- Decide how to handle comments in the syntax (?)(should comments mean something like in rust?)
|
||||||
- Not ignore comments & whitespace, for code formatting
|
- 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
|
## v0.0.12
|
||||||
|
|
||||||
- [x] Infer datatype of an identifier
|
- [x] Infer datatype of an identifier
|
||||||
- [x] Infer datatype of a binary operatior
|
- [x] Infer datatype of a binary operatior
|
||||||
- [x] Infer datatype of unary operator
|
- [x] Infer datatype of unary operator
|
||||||
- [ ] Infer datatype of a function call expression
|
- [x] Infer datatype of binary operators
|
||||||
- [ ] Infer datatype of binary operators
|
|
||||||
- [x] Infer Int & Float as different types
|
- [x] Infer Int & Float as different types
|
||||||
- [ ] Execute semantic analysis on the function's block
|
- [x] Execute semantic analysis on the function's block
|
||||||
- [ ] Write tests
|
- [x] Write tests
|
||||||
- [ ] Abstract the parsing of datatypes, such that in the future generics can be implemented in a single place
|
|
||||||
|
|
||||||
|
|
||||||
## v0.0.11
|
## v0.0.11
|
||||||
|
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -20,7 +20,7 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thp"
|
name = "thp"
|
||||||
version = "0.0.11"
|
version = "0.0.12"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"colored",
|
"colored",
|
||||||
]
|
]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "thp"
|
name = "thp"
|
||||||
version = "0.0.11"
|
version = "0.0.12"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error_handling::{semantic_error::SemanticError, MistiError},
|
error_handling::{semantic_error::SemanticError, MistiError},
|
||||||
semantic::{impls::SemanticCheck, symbol_table::SymbolEntry},
|
semantic::{impls::SemanticCheck, symbol_table::{SymbolEntry, SymbolTable}},
|
||||||
syntax::ast::FunctionDeclaration,
|
syntax::ast::{statement::Statement, FunctionDeclaration},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl SemanticCheck for FunctionDeclaration<'_> {
|
impl SemanticCheck for FunctionDeclaration<'_> {
|
||||||
@ -25,8 +25,23 @@ impl SemanticCheck for FunctionDeclaration<'_> {
|
|||||||
return Err(MistiError::Semantic(error));
|
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
|
// 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(
|
scope.insert(
|
||||||
function_name,
|
function_name,
|
||||||
|
@ -29,7 +29,13 @@ impl Typed for Expression<'_> {
|
|||||||
|
|
||||||
Ok(datatype)
|
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) => {
|
Expression::UnaryOperator(op, exp) => {
|
||||||
let expr_type = match exp.get_type(scope) {
|
let expr_type = match exp.get_type(scope) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
|
@ -10,6 +10,7 @@ pub struct ModuleAST<'a> {
|
|||||||
pub declarations: Vec<TopLevelDeclaration<'a>>,
|
pub declarations: Vec<TopLevelDeclaration<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: this and Statement should merge
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum TopLevelDeclaration<'a> {
|
pub enum TopLevelDeclaration<'a> {
|
||||||
Binding(var_binding::Binding<'a>),
|
Binding(var_binding::Binding<'a>),
|
||||||
@ -27,6 +28,7 @@ pub struct FunctionDeclaration<'a> {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Block<'a> {
|
pub struct Block<'a> {
|
||||||
|
// TODO: this should be a Vec of Statement|Expression
|
||||||
pub statements: Vec<statement::Statement<'a>>,
|
pub statements: Vec<statement::Statement<'a>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use super::{functions::FunctionCall, var_binding::Binding};
|
use super::{functions::FunctionCall, var_binding::Binding};
|
||||||
|
|
||||||
|
// TODO: this and TopLevelDeclaration should merge
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Statement<'a> {
|
pub enum Statement<'a> {
|
||||||
FunctionCall(FunctionCall<'a>),
|
FunctionCall(FunctionCall<'a>),
|
||||||
|
Loading…
Reference in New Issue
Block a user