Topaz – A small Unicode-first language that compiles to Rust
Unicode-first from the lexer up, not just supported as an afterthought.
A small, closed, Unicode-first language that emits Rust.
Transpiles to Rust for native binaries without the borrow checker headache.
Backend developers wanting Rust performance without Rust syntax
Nim · Carbon · V
Topaz reads like Python or TypeScript, runs on a reference interpreter (topaz run), and builds a self-contained native binary by lowering to Rust, then handing off to the Rust toolchain (topaz build).
function factorial(n: int) -> int { if n < 2 { return 1 } return n * factorial(n - 1) } print("10! = {factorial(10)}") // 10! = 3628800
The idea: application logic should have a small, fixed surface with one obvious way to write each thing, and the compiler does the hard part underneath. Writing glue in Python and TS, I kept re-making the same policy decisions — errors, absence, cleanup. Topaz decides those once: Result for recoverable failure, optionals for absence, defer for cleanup.Identifiers are Unicode from the lexer up, with no implicit normalization — names compare by scalar sequence, so what you typed is what matches. Deliberate, not an oversight: NFC and NFD forms aren't silently merged, and the module resolver rejects imports that would collide under NFC/NFD or case folding.
function 인사하기(이름: string) -> string { return "안녕하세요, {이름}님!" } print(인사하기("토파즈")) // 안녕하세요, 토파즈님!
sql, sh, and path strings are tagged templates: interpolations stay structurally separate from the literal text, so a value is never spliced into the query as raw SQL. Below, a classic injection attempt; the printed value is the template's structure, not a concatenated string:let user = "'; DROP TABLE t; --" let q = sql"SELECT * FROM t WHERE name = {user}" print("{q}") // <sql template, 2 part(s), 1 interpolation(s)>
To be clear on scope: this is a representation, not a database driver — there's no query-execution or parameter-binding layer yet. Injection is impossible by construction at this layer; a driver that consumes the value safely is future work.Why compile through Rust instead of C or LLVM? I'm not trying to replace Rust — if you want to write Rust, write Rust. It's just a good thing to land on: I inherit its memory safety and a mature backend for free, the build is reproducible, and the binary needs no Topaz runtime. Topaz is what you write; Rust is what it becomes.
Every fixture runs through both the interpreter and the compiler, and their stdout and exit status must agree; the moment they diverge, a test goes red. Both engines share the same runtime value model, so agreement is structural, not coincidental. cargo test --workspace is green at 635 tests. CI runs on Linux, macOS, and Windows, and every commit clears clippy -D warnings and cargo fmt --check.
Implementation notes:
- Whole toolchain (lexer, parser, checker, interpreter, emitter) is pure Rust, zero crates.io dependencies, forbid(unsafe_code). - The module resolver rejects path collisions from platform-specific case folding or normalization, keeping imports unambiguous across OSes.
Some history, since opening at v5.2 looks odd: v1 was a Lisp dialect (now separate), v2 a Python-like surface, v3 and v4 an internal tool we ran next to Rust in our products. v5.2 is the first version I'm comfortable showing.The honest catch: it's early, with basically no ecosystem yet. The topaz binary runs, checks, and emits on its own, but topaz build shells out to cargo, so that command needs a working Rust toolchain. This is not "easy Rust." It's a small application surface that happens to compile through Rust.
Docs at https://topaz.ooo. License Apache-2.0. Try it with:
topaz run examples/hello.tpz topaz build examples/hello.tpz --out-dir out --run
I'd love feedback on the diagnostics, the generated Rust, the module semantics, and Unicode edge cases. Please tear into it.Unicode-first from the lexer up, not just supported as an afterthought.
Python-to-Nim transpiler with ctypes-backed types when Cython and Numba already exist.
Full Rust compiler in 2.5K lines of PHP—technically impressive but niche hobby project.
Python syntax + native codegen, but the language itself solves no real problem.
Better Bash alternative with proper error handling and compilation, but why not Go or Rust?
AI Python-to-C transpilation when Nuitka and Cython already exist.