Changes to codegen to move from JS to PHP generation

master
Araozu 2023-09-08 19:34:08 -05:00
parent 94f0b0c92d
commit c61f88aaaa
8 changed files with 41 additions and 22 deletions

22
README.md Normal file
View File

@ -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.

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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<String> = self
@ -36,6 +36,6 @@ mod tests {
let result = module.transpile();
assert_eq!("const identifier = 322;", result);
assert_eq!("$identifier = 322;", result);
}
}

View File

@ -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

View File

@ -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();

View File

@ -40,7 +40,7 @@ fn build_ast(input: &String, tokens: Vec<Token>) {
}
}
/// 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();