From c61f88aaaa4a8338942d453d36bbfbac0fa8c465 Mon Sep 17 00:00:00 2001 From: Araozu Date: Fri, 8 Sep 2023 19:34:08 -0500 Subject: [PATCH] Changes to codegen to move from JS to PHP generation --- README.md | 22 ++++++++++++++++++++++ src/codegen/binding.rs | 8 ++++---- src/codegen/expression.rs | 2 +- src/codegen/mod.rs | 8 ++++---- src/codegen/module_ast.rs | 4 ++-- src/file/mod.rs | 9 +++++---- src/main.rs | 8 ++------ src/repl/mod.rs | 2 +- 8 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..88a499c --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# THP: Typed Hypertext Processor + +Types and a new syntax for PHP, because I'm forced to use it at work. + +## Usage + +### Singular files + +Inside an existing PHP codebase, files are converted to THP +one at a time, or new files are written in THP. + +There must be a thp.config.yaml at the root of the project, +which configures the compiler. + +Every file is compiled in place. + + +### Project mode + +The whole project uses THP. Work in progress. + + diff --git a/src/codegen/binding.rs b/src/codegen/binding.rs index 3d44c33..fdb41bc 100644 --- a/src/codegen/binding.rs +++ b/src/codegen/binding.rs @@ -2,18 +2,18 @@ use super::Transpilable; use crate::syntax::ast::Binding; impl Transpilable for Binding { - /// Transpiles val and var bindings into JS. + /// Transpiles val and var bindings into PHP. fn transpile(&self) -> String { match self { Binding::Val(val_binding) => { let expression_str = val_binding.expression.transpile(); - format!("const {} = {};", val_binding.identifier, expression_str) + format!("${} = {};", val_binding.identifier, expression_str) } Binding::Var(var_binding) => { let expression_str = var_binding.expression.transpile(); - format!("let {} = {};", var_binding.identifier, expression_str) + format!("${} = {};", var_binding.identifier, expression_str) } } } @@ -36,6 +36,6 @@ mod tests { let result = binding.transpile(); - assert_eq!("const identifier = 322;", result); + assert_eq!("$identifier = 322;", result); } } diff --git a/src/codegen/expression.rs b/src/codegen/expression.rs index f4d01a3..c6d15f6 100644 --- a/src/codegen/expression.rs +++ b/src/codegen/expression.rs @@ -2,7 +2,7 @@ use super::Transpilable; use crate::syntax::ast::Expression; impl Transpilable for Expression { - /// Transpiles an Expression to JS + /// Transpiles an Expression to PHP /// /// Right now the expressions in the grammar are: /// - Number diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index db897b7..d5f3a17 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -4,13 +4,13 @@ mod binding; mod expression; mod module_ast; -/// Trait that the AST and its nodes implement to support transformation to JavaScript +/// Trait that the AST and its nodes implement to support transformation to PHP trait Transpilable { - /// Transforms this struct into JavaScript + /// Transforms this struct into PHP fn transpile(&self) -> String; } -/// Transforms an AST to its representation in JavaScript +/// Transforms an AST to its representation in PHP pub fn codegen<'a>(ast: &'a ModuleAST) -> String { ast.transpile() } @@ -29,6 +29,6 @@ mod tests { let out_str = codegen(&ast); - assert_eq!("const id = 322;", out_str); + assert_eq!("$id = 322;", out_str); } } diff --git a/src/codegen/module_ast.rs b/src/codegen/module_ast.rs index 87d0581..e72c01f 100644 --- a/src/codegen/module_ast.rs +++ b/src/codegen/module_ast.rs @@ -2,7 +2,7 @@ use super::Transpilable; use crate::syntax::ast::ModuleAST; impl Transpilable for ModuleAST { - /// Transpiles the whole AST into JS, using this same trait on the + /// Transpiles the whole AST into PHP, using this same trait on the /// nodes and leaves of the AST fn transpile(&self) -> String { let bindings_str: Vec = self @@ -36,6 +36,6 @@ mod tests { let result = module.transpile(); - assert_eq!("const identifier = 322;", result); + assert_eq!("$identifier = 322;", result); } } diff --git a/src/file/mod.rs b/src/file/mod.rs index d011745..44784b3 100644 --- a/src/file/mod.rs +++ b/src/file/mod.rs @@ -3,7 +3,7 @@ use std::{fs, path::Path}; use crate::lexic::token::Token; use crate::{codegen, error_handling::PrintableError, lexic, syntax}; -pub fn compile_file(input: &String, output: &String) { +pub fn compile_file(input: &String) { let input_path = Path::new(input); if !input_path.is_file() { @@ -13,10 +13,11 @@ pub fn compile_file(input: &String, output: &String) { let bytes = fs::read(input_path).expect("INPUT_PATH should be valid"); let contents = String::from_utf8(bytes).expect("INPUT_PATH's encoding MUST be UTF-8"); - let js_code = compile(&contents); + let out_code = compile(&contents); - let output_path = Path::new(output); - fs::write(output_path, js_code).expect("Error writing to output path"); + let mut output_path = Path::new(input).canonicalize().unwrap(); + output_path.set_extension("php"); + fs::write(output_path, out_code).expect("Error writing to output path"); } /// Executes Lexical analysis, handles errors and calls build_ast for the next phase diff --git a/src/main.rs b/src/main.rs index 9c3f627..2f25c66 100755 --- a/src/main.rs +++ b/src/main.rs @@ -27,9 +27,6 @@ enum Commands { C { /// File to compile file: String, - - /// File to write the JS code to - output: String, }, /// Starts the REPL R {}, @@ -49,15 +46,14 @@ fn get_copyright() -> String { /// Usage: /// - `misti` : Starts the compiler in watch mode /// - `misti w, --watch, -w` : Starts the compiler in watch mode -/// - `misti -c FILE -o OUTPUT` : Compiles FILE and writes the result in OUTPUT +/// - `misti c FILE` : Compiles FILE and writes the result in the same directory fn main() { let cli = Cli::parse(); match &cli.command { Some(Commands::C { file: input, - output, - }) => file::compile_file(input, output), + }) => file::compile_file(input), Some(Commands::R {}) => { println!("{}", get_copyright()); let _ = repl::run(); diff --git a/src/repl/mod.rs b/src/repl/mod.rs index b09386f..4c9a7e2 100755 --- a/src/repl/mod.rs +++ b/src/repl/mod.rs @@ -40,7 +40,7 @@ fn build_ast(input: &String, tokens: Vec) { } } -/// Executes the REPL, reading from stdin, compiling and emitting JS to stdout +/// Executes the REPL, reading from stdin, compiling and emitting PHP to stdout pub fn run() -> io::Result<()> { let stdin = io::stdin(); let mut buffer = String::new();