Infer datatype of unary operator

master
Araozu 2024-05-30 14:59:45 -05:00
parent 19cba2a7b3
commit ab782b828d
4 changed files with 51 additions and 2 deletions

View File

@ -22,12 +22,13 @@
- Formatter
- 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
## v0.0.12
- [x] Infer datatype of an identifier
- [x] Infer datatype of a binary operatior
- [ ] Infer datatype of unary operator
- [x] Infer datatype of unary operator
- [ ] Infer datatype of a function call expression
- [ ] Infer datatype of binary operators
- [x] Infer Int & Float as different types

View File

@ -11,6 +11,8 @@ mod syntax;
mod lexic;
// Module to handle semantic analysis
mod semantic;
// Defines the PHP AST
mod php_ast;
// Transforms an AST to JS
mod codegen;

7
src/php_ast/mod.rs Normal file
View File

@ -0,0 +1,7 @@
// Follows https://phplang.org/spec/09-lexical-structure.html
struct PhpAst {
}

View File

@ -30,7 +30,46 @@ impl Typed for Expression<'_> {
Ok(datatype)
}
Expression::FunctionCall(_) => todo!(),
Expression::UnaryOperator(_, _) => todo!(),
Expression::UnaryOperator(op, exp) => {
let expr_type = match exp.get_type(scope) {
Ok(t) => t,
Err(_reason) => {
return Err(MistiError::Semantic(SemanticError {
error_start: 0,
error_end: 1,
reason: format!("Error getting type of expression"),
}))
}
};
// Only supported unary operator: - & !
if *op == "-" {
if expr_type != "Int" && expr_type != "Float" {
return Err(MistiError::Semantic(SemanticError {
error_start: 0,
error_end: 1,
reason: format!(
"Expected a Int or Float after unary `-`, got {}",
expr_type
),
}));
} else {
return Ok("Int".into());
}
} else if *op == "!" {
if expr_type != "Bool" {
return Err(MistiError::Semantic(SemanticError {
error_start: 0,
error_end: 1,
reason: format!("Expected a Bool after unary `!`, got {}", expr_type),
}));
} else {
return Ok("Bool".into());
}
}
panic!("Illegal state: Found an unexpected unary operator during semantic analysis: {}", *op);
}
Expression::BinaryOperator(exp1, exp2, operator) => {
let t1 = exp1.get_type(scope)?;
let t2 = exp2.get_type(scope)?;