展示 HN:PHP 中的 Rust 编译器,输出 x86-64 可执行文件
Show HN: Rust compiler in PHP emitting x86-64 executables

原始链接: https://github.com/mrconter1/rustc-php

## Rust 编译器在 PHP 中:摘要 该项目使用 PHP 完全实现了一个 Rust 编译器,能够直接生成 x86-64 Linux ELF 二进制文件,*无需* 依赖 LLVM、汇编器或链接器。它专为工具受限的环境(如旧共享主机)设计,支持 Rust 的核心特性,包括所有权和借用检查、类型检查、移动语义、泛型、特征、闭包和迭代器。 该编译器处理基本数据类型(整数、布尔值、字符串)、结构体、枚举、控制流、函数和具有 `pub` 可见性的模块。它包含 `Option` 和 `Result` 的实现,用于错误处理。提供了一个带有预期输出的测试套件,用于验证。 目前,该编译器缺少一些特性,例如复合赋值、元组、`Vec`、浮点数、`?` 运算符、复杂的闭包、生命周期和额外的整数类型。然而,它为在仅 PHP 环境中运行 Rust 代码提供了一个功能基础,尤其是在 Windows 上通过 WSL 实现。

Hacker News 新闻 | 过去 | 评论 | 提问 | 展示 | 工作 | 提交 登录 展示 HN:Rust 编译器在 PHP 中生成 x86-64 可执行文件 (github.com/mrconter1) 5 分,mrconter1 1 小时前 | 隐藏 | 过去 | 收藏 | 4 评论 帮助 nasretdinov 3 分钟前 | 下一个 [–] 我想知道这个编译器是否能在 https://github.com/VKCOM/kphp (一个 PHP->C++ 转换器) 上运行。 replywiseowise 2 分钟前 | 上一个 | 下一个 [–] 所有 PHP 开发者都叫 Rasmus 吗? mike_d 8 分钟前 | 上一个 | 下一个 [–] 有时在进行攻击性安全工作时,你最终会进入最奇怪的环境,工具有限,有奇怪的缺陷,损坏的 shell,以及谁知道还有什么。但你知道什么几乎总是可用并且可以正常工作吗?PHP。 holg 1 小时前 | 上一个 [–] 有趣的 PoC,用 PHP,谁会想到呢 :D 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系方式 搜索:
相关文章

原文

A Rust compiler written in PHP that emits x86-64 Linux ELF binaries directly (no LLVM, no assembler, no linker). Implements ownership checking, borrow checking, type checking, move semantics, generics, traits, closures, and iterators. Useful if you need to compile Rust on a shared hosting server from 2008 where the only installed runtime is PHP.

In order to execute Rust code you of course first need to install PHP. You can do this easily on Windows 11 by running:

winget install PHP.PHP.8.4

This compiler outputs valid machine code for Linux, so the most practical approach if you're on Windows is to use WSL. Start by installing Ubuntu (if you haven't already):

After the install completes, reboot your machine and then open Ubuntu from the Start menu to finish the initial setup.

Compile a .rs file by running:

php rustc.php main.rs -o main

Then execute the compiled binary through WSL:

To see the exit code of the program:

Types

  • i32, bool, u8, u16, u32, u64, u128, usize
  • String (heap string, move semantics)
  • &str and string slice indexing (s[0])
  • &T, &mut T references with borrow checking
  • Structs (named fields, field access, method calls)
  • Enums with optional tuple payloads and match
  • Unit type () in expressions, return types, and generic arguments
  • Generics on functions, structs, and impl blocks
  • Builtin Option<T> and Result<T, E> with Some/None, Ok/Err (no source definitions required)

Control flow

  • if / else (including as expressions)
  • while, loop, break, continue
  • for x in start..end (range iteration)
  • match with enum arms and wildcard _
  • return

Functions and closures

  • Free functions with multiple parameters and explicit return types
  • const fn (accepted and treated as a regular function)
  • impl blocks with self, &self, &mut self
  • Trait definitions and impl Trait for Type
  • Default trait method implementations
  • Closures with capture-by-value (|x: i32| x + captured_var)

Ownership and borrowing

  • Move semantics for non-Copy types
  • Borrow and mutable borrow checking
  • Copy inference for i32, bool, &T, and all-copy structs/enums

Modules and syntax

  • mod name; declarations with file-based module resolution
  • pub visibility on functions, structs, and fields
  • use paths for cross-module imports
  • Attributes #[...] and #![...] (parsed and skipped)

Output

  • println!("{}", expr) — print a single value
  • exit(code) — explicit exit with status code

Run the full test suite:

Test cases live in tests/cases/ organized into fundamentals/valid/, fundamentals/invalid/, modules/, and programs/. Each .rs file declares its expected output in comments at the top:

// exit: 42
// stdout: hello
// error: Use of moved value

What's not yet implemented

Roughly in order of impact:

  1. Compound assignment operators (+=, -=, *=, /=)
  2. Tuples and tuple destructuring
  3. Vec<T> and heap allocation
  4. f32 / f64 floating point
  5. const and static items
  6. The ? operator (Result is supported; ? is not)
  7. Closures as function arguments (fn apply(f: impl Fn(i32) -> i32))
  8. Zero-parameter closures (|| expr)
  9. Pattern matching beyond single-level enum variants
  10. Multi-format println! (only "{}" with one argument is supported)
  11. Lifetimes (borrow checker is simplified — no lifetime annotations)
  12. Additional signed integer types (i8, i16, i64, i128)
联系我们 contact @ memedata.com