番石榴:一个实验性的Go编译器,用Rust编写。
Goiaba: An experimental Go compiler, written in Rust

原始链接: https://github.com/raphamorim/goiaba

## Goiaba:Go 到 WebAssembly 编译器 Goiaba 是一个实验性的、基于 Rust 的编译器,可以将 Go 源代码翻译成 WebAssembly (WASM) 字节码。这使得 Go 程序可以在 Web 浏览器和其他 WASM 环境中运行。它具有一个 Go 解析器,生成抽象语法树 (AST),然后将 Go 函数编译成 WASM 模块。 目前,Goiaba 支持 Go 的基本特性,例如函数、控制流、算术运算和数据结构(结构体、数组、切片、字符串)。函数可以导出用于 JavaScript/WebAssembly 或通过 C ABI 直接在 Rust/Zig 中使用。 一个命令行界面支持带有详细输出选项和生成完整 Web 项目的编译。一个编程 API 允许集成到 Rust 项目中。在优先保证正确性的同时,未来的开发将侧重于优化,例如死代码消除和函数内联。 **限制:** Goiaba 目前缺乏垃圾回收、全面的标准库支持和并发原语。它还仅支持单文件编译。欢迎贡献!

Hacker News新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交登录 Goiaba:一个实验性的Go编译器,用Rust编写 (github.com/raphamorim) 10 分,由 SchwKatze 1小时前发布 | 隐藏 | 过去 | 收藏 | 2 评论 schoen 26分钟前 [–] (葡萄牙语中是“番石榴”的意思。)回复 mariusseufzer 13分钟前 | 父评论 [–] 我喜欢这种水果回复 考虑申请YC冬季2026批次!申请截止日期为11月10日 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

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.

  • Parse Go source code into an Abstract Syntax Tree (AST)
  • Compile Go functions to WebAssembly modules
  • Support for fundamental Go language features (functions, control flow, arithmetic)
  • Export Go functions for use in JavaScript/WebAssembly environments
  • Export Go functions for use in Rust through C ABI
  • Export Go functions for use in Zig through C ABI
  • Command-line interface for compilation
  • Programmatic API for integration into Rust projects

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);
        }
    }
}
  • Function definitions with parameters and return types
  • Integer arithmetic operations (+, -, *, /, %)
  • Comparison operations (<, >, <=, >=, ==, !=)
  • Bitwise operations (&, |, ^, <<, >>)
  • Logical operations (&&, ||, !)
  • Variable declarations and assignments
  • If-else statements and nested conditionals
  • For loops with initialization, condition, and post statements
  • Recursive function calls
  • Function calls with multiple arguments
  • Increment and decrement operators (++, --)
  • Unary operators (-, !)
  • Struct types with field access and assignment
  • Composite literals for struct initialization
  • Arrays and slices
  • String literals and operations
  • Switch statements
  • Pointer operations
  • Methods on types
  • Interfaces
  • Multiple return values
  • Defer statements
  • Panic and recover
  • Goroutines and channels
  • Package imports
  • Standard library support

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.

  • Go source code parsing to Abstract Syntax Tree (AST)
  • Translation of Go constructs to WebAssembly representations
  • WebAssembly bytecode generation
  • Function definitions with parameter and return types
  • Variable declarations and assignments
  • Control flow statements (if/else, for loops)
  • Exportable WASM functions
  • Arithmetic operations (+, -, *, /, %)
  • Comparison operations (<, >, <=, >=, ==, !=)
  • Bitwise operations (&, |, ^, <<, >>)
  • Logical operations (&&, ||, !)
  • Increment/decrement operators (++, --)
  • Recursive function calls
  • Struct types with field access and assignment
  • Command-line interface
  • Unary operators (negation, logical NOT)
  • Arrays and slices
  • String literals and operations
  • Switch statements

Goiaba consists of several key components:

  1. Parser: Lexical analysis and syntax parsing of Go source code
  2. AST: Internal representation of Go program structure
  3. Translator: Conversion from Go AST to WebAssembly IR
  4. Compiler: Generation of WebAssembly bytecode
  5. CLI: Command-line interface for user interaction

Performance Considerations

The generated WebAssembly code prioritizes correctness over optimization. Future versions will include:

  • Dead code elimination
  • Constant folding
  • Register allocation improvements
  • Memory access optimization
  • Function inlining for small functions

Contributions are welcome. Please ensure all tests pass before submitting pull requests:

cargo test
cargo clippy
cargo fmt

Run the test suite:

Current limitations of the compiler, yet to be added:

  • No garbage collection (manual memory management)
  • Limited standard library support
  • No concurrency primitives (goroutines, channels)
  • Single file compilation only
  • No optimizer passes

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.

联系我们 contact @ memedata.com