r/Compilers 12h ago

I built Uranium: A statically typed language with a hand-rolled x86_64 JIT (no LLVM) and generational GC in modern C++

0 Upvotes

Hey everyone,

I wanted to share a major milestone on my hobby language project called Uranium, written from scratch in modern C++ (C++17/20).

I deliberately avoided LLVM because I wanted to learn and build the execution pipeline myself from the metal up.

Architecture Highlights:

  • Lexer & Parser: Emits .urc bytecode with peephole optimization. Supports strict static typing, generic syntax, pattern matching (match/case), nested f-strings (f"Outer: {f"Inner: {x}"}"), and async/await with a cooperative task scheduler.

  • Custom Native JIT: In src/native_jit_x64.cpp, I implemented a small assembler (X64Assembler) that directly emits raw x86_64 opcodes for hot loops and arithmetic routines into executable memory pages.

  • Generational GC: Two-tier Mark & Sweep (HEAP_COLLECT_YOUNG vs HEAP_COLLECT_FULL) with write barriers (writeBarrier(owner, value)) tracking remembered sets, plus object pooling.

  • Standard Library & Tooling: Includes raw TCP sockets, native cryptography (SHA256/Base64), embedded SQLite3, Godot engine bindings, its own build tool (omake), and a preview VS Code LSP extension.

The codebase is completely open-source. I'd really appreciate any code review or architecture critiques from other compiler authors:

https://github.com/bruhgit/Uranium-Programming-Language

What do you think of the tiered JIT / Loop Broker approach?


r/Compilers 8h ago

Write the legacy into anothers somewhat hard.

0 Upvotes

Then , rust , how to save its previous edition codes? I wonder how to rust accept its particled edition's codes on futures seamlessly . This is about the maintanence, not just about shovelling the previous codes.

It must invest the a plenty of management assets. However, the resources are restricted. So rewrite in their language is not hopefull.

And the billions lines of codes are not as seamlessely transpiled adjustly. And over, the rust's editions politics are accelerarate their own fragments.

The fragments are must become accumulates debts of the managements and mantainences.

When it comes to persist, the one-shot must cut-down the whole.

"REWRITE IN RUST" is somewhat

brave sentences, nontheless its realities. The truth unveil on real world, is not easy .

The legacy, a plenty of softwares were written by others(by other person, with other languages, so on).

It is nonsense to write software in rust wholy.

The intent of the developer is exist. This not fair , while the codes are not have memory-safety features. All codes have reasons. Tortue the codes to become memory-safety codes are not justice.

As it transpiled automatically or by-hand, the intent is might not same as origin's.

We must have to know "context" of the legacy codes.

It has its own history, innate algorithms, the intents.

We are not must to preserve the origin's intents, but, the understanding the its own scripts are also important.

Because of the developers are such as like as artists.

Their intents are might can be interpreted on many ways.

However, we must do acknowledge to precisely : why the author descripted this and what is its intents?

It is also similiar as using the ai to transpile the previous legacy codes into newer version of codes. Thats are not seamlessely to translate naturally.

Rust's codes are can be the legacy codes too. Whenever what written in, those are legacy.

Ai-derived codes, or manually handled, whichever, the codes can be legacy.

You must intend the logic or algorithm to write down the programs, nontheless the logic is not complete, and also the origin-thoughts are already exists.

We think why the ai-based automatic transpilation is might be dangerous or harmful: this is because the overall programs context is not fully understand by aritificial-intelligence. That is the much greater problems occurs.

Partial knowledge is might become to be dangerous ,

so the misleading to be misinterpretings.

And also, ai could not understand the entire codes contexts.

In addition, to understanding full program's context by ai, are much consume energy.

Such as electrical energy, and noise can occurs, this is not good to environments and vice versa to mankinds(entire employees, and companies , etc.).

It is must cause maintaneance fatigues.

Suppose to : While the all codes are transpiled to rust, it is might cause more problems.

When the rust version and edition updates to latest , the management problems are huger then before.


r/Compilers 17h ago

Built a multi-target systems language with AI assistance. Not trying to hype it, just looking for architecture feedback on Typed HIR lowering.

0 Upvotes

Hey everyone,

I know the community is flooded with toy languages and AI-generated wrappers, so I want to be 100% transparent upfront: I built this project, Nyx, with heavy AI assistance as a pair programmer.

However, my goal wasn't to generate a quick gimmick or dump unverified code on GitHub. I wanted to deeply learn compiler engineering from the ground up, and I treated the design and testing with extreme rigor.

What the project actually is:

  • A statically typed systems language focused on developer ergonomics and zero-cost safety (no garbage collector, RAII scope guards, and deterministic defer).
  • Architecture:
    • Frontend: Recursive descent parser -> AST -> Semantic TypeChecker.
    • Middle-end: An authoritative Typed HIR (High-level Intermediate Representation) pass pipeline with reachability-based dead code elimination and deterministic constant evaluation.
    • Backends: Multi-target codegen emitting modern C++20 for native performance, and a direct WebAssembly binary emitter (wasm_ir) with linear memory alignment.
  • Verification: 138-case end-to-end regression test battery running on Linux, Windows, and macOS GitHub Actions runners, plus a self-hosting verification stage.

Why I’m posting here: I'm not here to claim this will "replace C++" or compete with production languages. I genuinely want feedback from experienced compiler engineers on the architecture:

  1. C++20 vs Direct LLVM: Right now, lowering Typed HIR to C++20 allows me to leverage existing battle-tested optimizers without spending a decade writing machine code generators. For those who built production compilers: at what point does transpiling to modern C++ become a hindrance compared to targeting LLVM IR directly?
  2. WASM Linear Memory Alignment: In the WASM backend, I map Nyx structs with an 8-byte deterministic layout to mirror native offsets for zero-copy buffer sharing. Are there subtle edge cases or padding traps with WebAssembly linear memory that I should watch out for?

The repo is open source here if anyone wants to inspect the HIR or test suite: https://github.com/justsomeone-e/nyx

Any constructive critique, architectural roast, or advice on the middle-end design is very welcome. Thanks for your time ;)


r/Compilers 18h ago

What sort of tests do people use for compilers?

27 Upvotes

I am working on my own compiled programming language, and I figured that a decent test suite would save many headaches down the line (especially as my current code is in desperate need of refactoring). The problem is, I am not sure how to test a compiler without just mindlessly writing a bunch of end-to-end tests as that would be slow and unlikely to catch obscure bugs


r/Compilers 21h ago

Can better language semantics simplify compilers?

21 Upvotes

While implementing the OO part of my language (AET), I ran into a performance problem: OO method calls have overhead. So I started looking into devirtualization.

At first, I treated it as a compiler problem: how can the compiler determine that a method call has only one possible target?

But then I started thinking from a different angle: what if the language itself could tell the compiler that the target is unique?

This made me realize that the relationship between language semantics and compiler shouldn't be one-directional. They should influence each other during the design phase:

Language Semantics ↔ Compiler ↔ Optimization

For example, AET has:

private$ foo();
final$ foo();
final$ class A { ... };

These are language semantics that restrict inheritance and overriding. But they also provide the compiler with clear semantic guarantees: the call target is unique.

A final$ method cannot be overridden by subclasses.

A final$ class has no subclasses that could override the method.

A private$ method does not participate in overriding at all.

Different language rules, but from the compiler's perspective, they all provide the same useful fact: the call target is unique. So AET can use this semantic information to transform an OO call into a direct call to the corresponding FUNCTION_DECL in GCC's intermediate representation.

Of course, a compiler could also discover the same information through type analysis, call graph analysis, devirtualization, LTO, etc. But if these facts can be determined directly by language semantics, could it in turn make the compiler simpler?

This led me to a more general question. Essentially, it's a "who does more, who does less" problem. If language semantics provide more explicit guarantees, the compiler may need to do less inference. If the language keeps weaker semantic constraints, more work falls on compiler analysis.

So the question becomes: what should be left to language semantics, and what should be left to compiler analysis? Are there any methods or theories to guide this division of labor, to make it more scientific and reasonable?

I think this is also a boundary worth discussing between language design and compiler design. AET is my exploration of this question while actually implementing it.

Would love to hear your thoughts.