diff --git a/CHANGELOG.md b/CHANGELOG.md index bf3241f..79648f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/src/main.rs b/src/main.rs index 3852a10..d524ba7 100755 --- a/src/main.rs +++ b/src/main.rs @@ -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; diff --git a/src/php_ast/mod.rs b/src/php_ast/mod.rs new file mode 100644 index 0000000..d1f1486 --- /dev/null +++ b/src/php_ast/mod.rs @@ -0,0 +1,7 @@ + +// Follows https://phplang.org/spec/09-lexical-structure.html + +struct PhpAst { + +} + diff --git a/src/semantic/types/expression.rs b/src/semantic/types/expression.rs index 1572a80..167d6c6 100644 --- a/src/semantic/types/expression.rs +++ b/src/semantic/types/expression.rs @@ -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)?;