Compiler
Hew compiles through a Rust frontend and MLIR progressive lowering to native code.
Overview
The Hew compiler has a Rust frontend and a C++20 MLIR backend. The frontend (hew-lexer, hew-parser, hew-types) handles lexing, parsing, and type checking. The typed AST is serialized via MessagePack (crate hew-serialize, using rmp-serde) and passed to the C++ backend (hew-codegen), which generates native code through progressive lowering: Hew MLIR dialect → standard MLIR dialects → LLVM IR → machine code.
Compilation pipeline
Source code passes through the Rust frontend for lexing, parsing, and type checking. The typed AST is serialized with MessagePack and read by the C++ MLIR backend (msgpack_reader.cpp), which generates MLIR and lowers to native code:
The custom Hew MLIR dialect defines 12 operations in 4 categories that map directly to Hew language constructs. Enum construction uses LLVM dialect operations (llvm.mlir.undef, llvm.insertvalue) directly — no dedicated Hew dialect op is needed.
MLIR enables progressive lowering — the Hew dialect is lowered through increasingly lower-level standard MLIR dialects before reaching LLVM IR:
- Hew dialect →
arith,scf,func,memref(standard MLIR dialects) - Standard dialects →
cf(ControlFlow dialect) - ControlFlow → LLVM dialect → native code
The project currently passes 225 end-to-end tests and 993 Rust unit tests, covering the core language features: functions, structs, enums, traits, generics, actors, generators, error handling, dynamic dispatch, string interpolation, and more.
Runtime library
The Hew runtime provides the infrastructure that actors depend on at execution time:
- M:N work-stealing scheduler — A configurable worker pool with one OS thread per core. Each worker has a local run queue; idle workers steal from busy workers using lock-free operations.
- Message budget / fairness — Each actor processes up to 1,000 messages per dispatch before yielding. Cooperative preemption at message boundaries and await points prevents starvation.
- Actor state machine — Actors transition through well-defined states: Init → Idle → Runnable → Running → Blocked → Stopping → Stopped (or Crashed). All state transitions use CAS (compare-and-swap) for lock-free safety.
- Memory management — Per-actor heaps for memory isolation. RAII-based resource management with no garbage collector.
- IO integration — Platform-specific event loops (epoll on Linux, kqueue on macOS, IOCP on Windows).
- Timer wheels — Efficient timeouts for supervision windows and scheduled operations.
Current status
The Rust frontend and C++ MLIR backend form a single compilation pipeline. The same Rust lexer and parser also power the language server (LSP) for editor integration, providing diagnostics, completion, hover, and semantic tokens.