From d55441e5fb5f4a90525a617338e199ec1a05f6eb Mon Sep 17 00:00:00 2001 From: Rerumu Date: Tue, 14 Dec 2021 06:33:39 -0500 Subject: [PATCH] Refactor front end --- README.md | 10 ++++++-- wasm/src/main.rs | 66 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 59 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 02461f4..df24916 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ -This is a WIP (read: absolutely not ready for serious work) tool for translating WebAssembly into Lua. Support is specifically for LuaJIT, with the secondary objective being Lua 5.4 and Roblox's Luau. +This is a WebAssembly to Lua translation tool. The generated code is designed to run without any dependencies past the bundled runtime. -The instructions are minimal; run the program as `program ` to generate the translations into stdout. Editions currently supported are `LuaJIT` and `Luau`. +You can run the tool via `program help` to list command line instructions. + +| | | | +|----------|-----------------|-----------------------| +| LuaJIT | :green_circle: | Minimum version 2.1.0 | +| Luau | :yellow_circle: | | +| Lua 5.4 | :red_circle: | | diff --git a/wasm/src/main.rs b/wasm/src/main.rs index 956a93f..4331008 100755 --- a/wasm/src/main.rs +++ b/wasm/src/main.rs @@ -5,13 +5,8 @@ mod analyzer; mod ast; mod writer; -fn lang_from_string<'a>(name: &str, wasm: &'a Module) -> Box + 'a> { - match name.to_lowercase().as_str() { - "luau" => Box::new(Luau::new(wasm)), - "luajit" => Box::new(LuaJIT::new(wasm)), - _ => panic!("Bad option: {}", name), - } -} +static LUAJIT_RUNTIME: &str = include_str!("../runtime/luajit.lua"); +static LUAU_RUNTIME: &str = include_str!("../runtime/luau.lua"); fn parse_module(name: &str) -> Module { let wasm = deserialize_file(name).expect("Failed to parse Wasm file"); @@ -22,16 +17,57 @@ fn parse_module(name: &str) -> Module { } } -fn main() { - let mut args = std::env::args().skip(1); - let name = args.next().expect("No language specified"); - +fn run_translator<'a, T: Transpiler<'a>>(wasm: &'a Module) { + let module = T::new(wasm); let output = std::io::stdout(); - for v in args { - let wasm = parse_module(&v); - let module = lang_from_string(&name, &wasm); + module + .transpile(&mut output.lock()) + .expect("Failed to transpile"); +} - module.transpile(&mut output.lock()).unwrap(); +fn do_translate(name: &str, file: &str) { + let wasm = &parse_module(file); + + match name.to_lowercase().as_str() { + "luau" => run_translator::(wasm), + "luajit" => run_translator::(wasm), + _ => panic!("Bad language: {}", name), + } +} + +fn do_runtime(name: &str) { + match name.to_lowercase().as_str() { + "luajit" => println!("{}", LUAJIT_RUNTIME), + "luau" => println!("{}", LUAU_RUNTIME), + _ => panic!("Bad runtime: {}", name), + } +} + +fn do_help() { + println!("usage: program translate "); + println!(" or: program runtime "); + println!(" or: program help"); +} + +fn main() { + let mut args = std::env::args().skip(1); + + match args.next().as_deref().unwrap_or("help") { + "help" => do_help(), + "runtime" => { + let lang = args.next().expect("No runtime specified"); + + do_runtime(&lang); + } + "translate" => { + let lang = args.next().expect("No language specified"); + let file = args.next().expect("No file specified"); + + do_translate(&lang, &file); + } + bad => { + eprintln!("Bad action `{}`; try `help`", bad); + } } }