Infer datatype of another identifier
This commit is contained in:
parent
c8d16fc77f
commit
4f7fa0f5e3
@ -8,6 +8,7 @@
|
|||||||
codegen section can focus only in codegen, not in
|
codegen section can focus only in codegen, not in
|
||||||
translation of thp->php.
|
translation of thp->php.
|
||||||
- Parse __more__ binary operators
|
- Parse __more__ binary operators
|
||||||
|
- Store tokens for the semantic analysis phase, to have actual error reporting
|
||||||
- Parse more complex bindings
|
- Parse more complex bindings
|
||||||
- Watch mode
|
- Watch mode
|
||||||
- Improve error messages
|
- Improve error messages
|
||||||
@ -24,8 +25,12 @@
|
|||||||
|
|
||||||
## v0.0.12
|
## v0.0.12
|
||||||
|
|
||||||
|
- [x] Infer datatype of an identifier
|
||||||
|
- [ ] Infer datatype of a binary operatior
|
||||||
|
- [ ] Infer datatype of unary operator
|
||||||
- [ ] Infer datatype of a function call expression
|
- [ ] Infer datatype of a function call expression
|
||||||
- [ ] Infer datatype of binary operators
|
- [ ] Infer datatype of binary operators
|
||||||
|
- [ ] Infer Int & Float as different types
|
||||||
- [ ] Execute semantic analysis on the function's block
|
- [ ] Execute semantic analysis on the function's block
|
||||||
- [ ] Write tests
|
- [ ] Write tests
|
||||||
- [ ] Abstract the parsing of datatypes, such that in the future generics can be implemented in a single place
|
- [ ] Abstract the parsing of datatypes, such that in the future generics can be implemented in a single place
|
||||||
|
@ -28,7 +28,7 @@ impl SemanticCheck for Binding<'_> {
|
|||||||
|
|
||||||
// This gets the datatype of the assigned expression,
|
// This gets the datatype of the assigned expression,
|
||||||
// to compare it later with the declared datatype.
|
// to compare it later with the declared datatype.
|
||||||
let expression_datatype = self.expression.get_type();
|
let expression_datatype = self.expression.get_type(scope)?;
|
||||||
|
|
||||||
let datatype = match self.datatype {
|
let datatype = match self.datatype {
|
||||||
Some(t) => t.value.clone(),
|
Some(t) => t.value.clone(),
|
||||||
|
@ -45,6 +45,11 @@ impl SymbolTable {
|
|||||||
pub fn test(&self, key: &String) -> bool {
|
pub fn test(&self, key: &String) -> bool {
|
||||||
self.node.borrow_mut().test(key)
|
self.node.borrow_mut().test(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets the datatype of a symbol, if it exists
|
||||||
|
pub fn get_type(&self, key: &String) -> Option<String> {
|
||||||
|
self.node.borrow_mut().get_type(key)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SymbolTableNode {
|
impl SymbolTableNode {
|
||||||
@ -83,6 +88,27 @@ impl SymbolTableNode {
|
|||||||
None => false,
|
None => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the symbol's datatype
|
||||||
|
pub fn get_type(&mut self, key: &String) -> Option<String> {
|
||||||
|
// Try to get the type in the current scope
|
||||||
|
if let Some(entry) = self.scope.get(key) {
|
||||||
|
// TODO: Change to allow other types of datatypes: functions, classes, maps
|
||||||
|
return match entry {
|
||||||
|
SymbolEntry::Variable(t) => Some(t.clone()),
|
||||||
|
SymbolEntry::Function(_, _) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to get the type in the parent scope
|
||||||
|
match &self.parent {
|
||||||
|
Some(parent) => {
|
||||||
|
let mut parent = parent.as_ref().borrow_mut();
|
||||||
|
parent.get_type(key)
|
||||||
|
}
|
||||||
|
None => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SymbolEntry {
|
impl SymbolEntry {
|
||||||
|
@ -1,15 +1,34 @@
|
|||||||
use crate::syntax::ast::Expression;
|
use crate::{
|
||||||
|
error_handling::{semantic_error::SemanticError, MistiError},
|
||||||
|
semantic::symbol_table::SymbolTable,
|
||||||
|
syntax::ast::Expression,
|
||||||
|
};
|
||||||
|
|
||||||
use super::Typed;
|
use super::Typed;
|
||||||
|
|
||||||
impl Typed for Expression<'_> {
|
impl Typed for Expression<'_> {
|
||||||
fn get_type(&self) -> String {
|
/// Attempts to get the datatype for an expression.
|
||||||
|
fn get_type(&self, scope: &SymbolTable) -> Result<String, MistiError> {
|
||||||
match self {
|
match self {
|
||||||
// TODO: Distinguish between Int & Float
|
// TODO: Distinguish between Int & Float
|
||||||
Expression::Number(_) => "Int".into(),
|
Expression::Number(_) => Ok("Int".into()),
|
||||||
Expression::String(_) => "String".into(),
|
Expression::String(_) => Ok("String".into()),
|
||||||
Expression::Boolean(_) => "Bool".into(),
|
Expression::Boolean(_) => Ok("Bool".into()),
|
||||||
Expression::Identifier(_) => todo!(),
|
Expression::Identifier(identifier) => {
|
||||||
|
// Attempt to get the datatype of the identifier in the current scope
|
||||||
|
let datatype = match scope.get_type(identifier) {
|
||||||
|
Some(x) => x,
|
||||||
|
None => {
|
||||||
|
return Err(MistiError::Semantic(SemanticError {
|
||||||
|
error_start: 0,
|
||||||
|
error_end: 1,
|
||||||
|
reason: format!("The identifier {} does not exist.", identifier),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(datatype)
|
||||||
|
}
|
||||||
Expression::FunctionCall(_) => todo!(),
|
Expression::FunctionCall(_) => todo!(),
|
||||||
Expression::UnaryOperator(_, _) => todo!(),
|
Expression::UnaryOperator(_, _) => todo!(),
|
||||||
Expression::BinaryOperator(_, _, _) => todo!(),
|
Expression::BinaryOperator(_, _, _) => todo!(),
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
// This crate provides an interface and implementations
|
// This crate provides an interface and implementations
|
||||||
// for determining the datatypes of the language constructs.
|
// for determining the datatypes of the language constructs.
|
||||||
|
|
||||||
|
use crate::error_handling::MistiError;
|
||||||
|
|
||||||
|
use super::symbol_table::SymbolTable;
|
||||||
|
|
||||||
mod expression;
|
mod expression;
|
||||||
|
|
||||||
pub trait Typed {
|
pub trait Typed {
|
||||||
fn get_type(&self) -> String;
|
fn get_type(&self, scope: &SymbolTable) -> Result<String, MistiError>;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user