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
|
||||
translation of thp->php.
|
||||
- Parse __more__ binary operators
|
||||
- Store tokens for the semantic analysis phase, to have actual error reporting
|
||||
- Parse more complex bindings
|
||||
- Watch mode
|
||||
- Improve error messages
|
||||
@ -24,8 +25,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 binary operators
|
||||
- [ ] 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
|
||||
|
@ -28,7 +28,7 @@ impl SemanticCheck for Binding<'_> {
|
||||
|
||||
// This gets the datatype of the assigned expression,
|
||||
// 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 {
|
||||
Some(t) => t.value.clone(),
|
||||
|
@ -45,6 +45,11 @@ impl SymbolTable {
|
||||
pub fn test(&self, key: &String) -> bool {
|
||||
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 {
|
||||
@ -83,6 +88,27 @@ impl SymbolTableNode {
|
||||
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 {
|
||||
|
@ -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;
|
||||
|
||||
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 {
|
||||
// TODO: Distinguish between Int & Float
|
||||
Expression::Number(_) => "Int".into(),
|
||||
Expression::String(_) => "String".into(),
|
||||
Expression::Boolean(_) => "Bool".into(),
|
||||
Expression::Identifier(_) => todo!(),
|
||||
Expression::Number(_) => Ok("Int".into()),
|
||||
Expression::String(_) => Ok("String".into()),
|
||||
Expression::Boolean(_) => Ok("Bool".into()),
|
||||
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::UnaryOperator(_, _) => todo!(),
|
||||
Expression::BinaryOperator(_, _, _) => todo!(),
|
||||
|
@ -1,8 +1,12 @@
|
||||
// This crate provides an interface and implementations
|
||||
// for determining the datatypes of the language constructs.
|
||||
|
||||
use crate::error_handling::MistiError;
|
||||
|
||||
use super::symbol_table::SymbolTable;
|
||||
|
||||
mod expression;
|
||||
|
||||
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