From 9cd1b7010304a845001bc1815963f15da9454bbe Mon Sep 17 00:00:00 2001 From: Araozu Date: Thu, 1 Aug 2024 15:37:00 -0500 Subject: [PATCH] feat: codegen of top level expressions --- CHANGELOG.md | 4 ++++ src/php_ast/transformers/module_ast.rs | 22 ++++++++++++++++++++ src/semantic/checks/top_level_declaration.rs | 22 +++++--------------- src/syntax/ast/mod.rs | 2 -- 4 files changed, 31 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c5fa4ed..87e3fc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ - Begin work on the code formatter +## v0.1.1 + +- [x] Top level expressions as statements + ## v0.1.0 - [x] Complete workflow for "Hello world" diff --git a/src/php_ast/transformers/module_ast.rs b/src/php_ast/transformers/module_ast.rs index d8c6bde..f85b4ca 100644 --- a/src/php_ast/transformers/module_ast.rs +++ b/src/php_ast/transformers/module_ast.rs @@ -22,6 +22,7 @@ impl<'a> PHPTransformable<'a> for ModuleAST<'_> { // TODO: This should be done by the Expression transformer match expr { Expression::FunctionCall(fc) => { + // TODO: This definitely needs refactoring let function_expr: &Expression = &*fc.function; match function_expr { Expression::Identifier(id) if *id == "print" => { @@ -50,6 +51,27 @@ impl<'a> PHPTransformable<'a> for ModuleAST<'_> { _ => todo!("Not implemented: AST transformation for function call that is not an identifier") } } + Expression::Int(value) => { + php_statements.push(PhpStatement::PhpExpressionStatement( + PhpExpression::Assignment(PhpAssignmentExpression::Primary( + PhpPrimaryExpression::IntegerLiteral(value), + )), + )); + } + Expression::Float(value) => { + php_statements.push(PhpStatement::PhpExpressionStatement( + PhpExpression::Assignment(PhpAssignmentExpression::Primary( + PhpPrimaryExpression::FloatingLiteral(value), + )), + )); + } + Expression::String(value) => { + php_statements.push(PhpStatement::PhpExpressionStatement( + PhpExpression::Assignment(PhpAssignmentExpression::Primary( + PhpPrimaryExpression::StringLiteral(value), + )), + )); + } _ => { todo!("not implemented: AST transform for expression {:?}", expr) } diff --git a/src/semantic/checks/top_level_declaration.rs b/src/semantic/checks/top_level_declaration.rs index 3a2c800..d7e5509 100644 --- a/src/semantic/checks/top_level_declaration.rs +++ b/src/semantic/checks/top_level_declaration.rs @@ -33,22 +33,6 @@ impl SemanticCheck for Statement<'_> { // TODO: Move to its own file when it grows impl SemanticCheck for Expression<'_> { fn check_semantics(&self, scope: &SymbolTable) -> Result<(), MistiError> { - // How to get the global definition into the symbol table? - // maybe just when creating the symbol table inject all - // the global elements at once? - // Store the global elements as binary/JSON - // and load them along with the symbol table - - // then for efficiency they could be grouped by module? - // and stored as binary files? - // then the binary files are searched for and loaded when - // requested? - - // For a function call: - // check that the function exists - // check its signature - // check parameters - match self { Expression::FunctionCall(f) => { let fun = &*f.function; @@ -104,7 +88,11 @@ impl SemanticCheck for Expression<'_> { } } } - _ => todo!("Check semantics for expression other than function call"), + Expression::Int(_) => {}, + Expression::Float(_) => {}, + Expression::String(_) => {}, + Expression::Boolean(_) => {}, + _ => todo!("Check semantics for expression other than function call and primitive"), } Ok(()) diff --git a/src/syntax/ast/mod.rs b/src/syntax/ast/mod.rs index b33e808..a8a67a5 100644 --- a/src/syntax/ast/mod.rs +++ b/src/syntax/ast/mod.rs @@ -62,8 +62,6 @@ pub struct Parameter<'a> { pub enum Expression<'a> { Int(&'a String), Float(&'a String), - // TODO: Specify if this contains or not the original quotes "" - // TODO: After this fix where neccesary String(&'a String), Boolean(bool), Identifier(&'a String),