| Crates.io | goiaba |
| lib.rs | goiaba |
| version | 0.0.5 |
| created_at | 2025-09-20 18:29:17.612259+00 |
| updated_at | 2025-10-08 15:19:29.51918+00 |
| description | Experimental Go parser and compiler |
| homepage | |
| repository | https://github.com/raphamorim/goiaba |
| max_upload_size | |
| id | 1848107 |
| size | 483,343 |
An experimental Go parser and WebAssembly compiler written in Rust. Goiaba translates Go source code into WebAssembly bytecode, enabling Go programs to run in web browsers and other WebAssembly environments.
cargo install goiaba
Add to your Cargo.toml:
[dependencies]
goiaba = "*"
Basic compilation:
goiaba main.go -o main.wasm
Compile with verbose output:
goiaba input.go --output output.wasm --verbose
Generate a complete web project with HTML and JavaScript:
goiaba main.go -w ./web-project
Advanced usage with multiple options:
goiaba calculator.go -o calc.wasm -w ./demo --verbose
use goiaba::wasm::compiler::compile_str;
fn main() {
let go_source = r#"
package main
//export add
func add(x int, y int) int {
return x + y
}
"#;
let wasm_bytes = compile_str(go_source)
.expect("Failed to compile Go to WASM");
// Write to file or use with a WASM runtime
std::fs::write("output.wasm", wasm_bytes)
.expect("Failed to write WASM file");
}
use goiaba::wasm::compiler::compile_str;
use wasmtime::{Engine, Instance, Module, Store};
fn main() {
let go_source = r#"
package main
//export add
func add(x int, y int) int {
return x + y
}
"#;
let wasm_bytes = compile_str(go_source)
.expect("Failed to compile Go to WASM");
// Create a WASM runtime
let engine = Engine::default();
let module = Module::from_binary(&engine, &wasm_bytes)
.expect("Failed to load WASM module");
let mut store = Store::new(&engine, ());
// Instantiate the module
let instance = Instance::new(&mut store, &module, &[])
.expect("Failed to instantiate module");
// Get the exported function
let add_func = instance
.get_typed_func::<(i32, i32), i32>(&mut store, "add")
.expect("Failed to get 'add' function");
// Call the function
let result = add_func
.call(&mut store, (5, 3))
.expect("Failed to call 'add' function");
assert_eq!(result, 8);
}
use goiaba::parser::parse_str;
fn main() {
let source = r#"
package main
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}
"#;
match parse_str(source) {
Ok((objects, file)) => {
println!("Successfully parsed Go source code");
// Access AST nodes through objects and file
}
Err(err) => {
eprintln!("Parse error: {}", err);
}
}
}
To make Go functions callable from WebAssembly, use the //export directive:
//export function_name
func function_name(param1 int, param2 int) int {
return param1 + param2
}
The exported name will be used in the WebAssembly module exports.
Goiaba consists of several key components:
The generated WebAssembly code prioritizes correctness over optimization. Future versions will include:
Contributions are welcome. Please ensure all tests pass before submitting pull requests:
cargo test
cargo clippy
cargo fmt
Run the test suite:
make test
Current limitations of the compiler, yet to be added:
BSD-3-Clause
Copyright (c) 2024 Raphael Amorim
This project builds upon concepts from the Go language specification and WebAssembly standards. Parser implementation is adapted from the Goscript project.