diff --git a/CHANGELOG.md b/CHANGELOG.md index 562439f..2f38391 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,13 +23,20 @@ - Include the original tokens in the AST +## v0.0.15 + +- [ ] Replace all panics with actual errors +- [ ] Remove all old codegen +- [ ] Test codegen +- [ ] Begin work on the code formatter + + ## v0.0.14 - [x] Define a minimal PHP AST - [x] Transform THP AST into PHP AST -- [ ] Implement minimal codegen for the PHP AST -- [ ] Remove old codegen -- [ ] Finish the workflow for a hello world +- [x] Implement minimal codegen for the PHP AST +- [x] Finish the workflow for a hello world ## v0.0.13 diff --git a/Cargo.toml b/Cargo.toml index 7141c86..28d918b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "thp" -version = "0.0.13" +version = "0.0.14" edition = "2021" diff --git a/src/codegen/php/mod.rs b/src/codegen/php/mod.rs index ed7552c..1676356 100644 --- a/src/codegen/php/mod.rs +++ b/src/codegen/php/mod.rs @@ -1,4 +1,6 @@ -use crate::php_ast::{PhpAst, PhpStatement}; +use std::os::linux::raw::stat; + +use crate::php_ast::{PhpAst, PhpExpression, PhpStatement}; use super::Transpilable; @@ -18,10 +20,31 @@ impl Transpilable for PhpStatement<'_> { fn transpile(&self) -> String { match self { PhpStatement::PhpEchoStatement(expr_list) => { - // TODO: Actually generate parameters from the expr_list - "echo \"\";".into() + let expressions_vec = expr_list.expressions + .iter() + .map(|e| e.transpile()) + .collect::>(); + + let expressions_str = if expressions_vec.is_empty() { + "\"\"".into() + } else { + expressions_vec.join(", ") + }; + + format!("echo {};", expressions_str) } } } } +impl Transpilable for PhpExpression<'_> { + fn transpile(&self) -> String { + match self { + PhpExpression::String(value) => { + format!("{}", value) + } + } + } +} + + diff --git a/src/php_ast/transformers/module_ast.rs b/src/php_ast/transformers/module_ast.rs index a4a5a70..0d9ab6b 100644 --- a/src/php_ast/transformers/module_ast.rs +++ b/src/php_ast/transformers/module_ast.rs @@ -1,5 +1,5 @@ use super::super::PhpAst; -use crate::php_ast::{PhpExpressionList, PhpStatement}; +use crate::php_ast::{PhpExpression, PhpExpressionList, PhpStatement}; use crate::syntax::ast::{Expression, ModuleAST, ModuleMembers}; use super::PHPTransformable; @@ -17,20 +17,31 @@ impl<'a> PHPTransformable<'a> for ModuleAST<'_> { php_statements.push(stmt.into_php_ast()); } ModuleMembers::Expr(expr) => { - // TODO: a print() function call is technically an - // expression in the AST, but PHP expects it to be an statement. - // transform beforehand? - + // TODO: This should be done by the Expression transformer match expr { Expression::FunctionCall(fc) => { let function_expr: &Expression = &*fc.function; match function_expr { Expression::Identifier(id) if *id == "print" => { - // transform to print() expression - // no parameters supported - php_statements.push(PhpStatement::PhpEchoStatement(PhpExpressionList { - expressions: vec![] - })); + // transform to print() expression + // no parameters supported + + // transform parameters, expect them all to be strings + + let mut expressions = Vec::::new(); + + for e in fc.arguments.arguments.iter() { + match e { + Expression::String(v) => { + expressions.push(PhpExpression::String(v)) + }, + _ => panic!("Non string expressions not supported") + } + } + + php_statements.push(PhpStatement::PhpEchoStatement(PhpExpressionList { + expressions + })); }, _ => todo!("Not implemented: AST transformation for function call that is not an identifier") } diff --git a/src/syntax/ast/mod.rs b/src/syntax/ast/mod.rs index a8a67a5..b33e808 100644 --- a/src/syntax/ast/mod.rs +++ b/src/syntax/ast/mod.rs @@ -62,6 +62,8 @@ 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),