Skip to content

C0d3N1nja97342/rustcompiler

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rustcompiler — a Rust compiler written in C++

A from-scratch educational Rust compiler. The skeleton mirrors the architecture of rustc itself, just dramatically smaller and in C++17.

source.rs
   │
   ▼
┌──────────┐    ┌────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│  Lexer   │──▶│ Parser │──▶│ Resolver │──▶│ TypeCk   │──▶│ BorrowCk │
└──────────┘    └────────┘    └──────────┘    └──────────┘    └──────────┘
   tokens          AST       name → DefId    typed AST     (validated)
                                                                │
                                                                ▼
                                                       ┌──────────────┐
                                                       │  MIR Lower   │
                                                       └──────────────┘
                                                              │
                                                              ▼
                                                       ┌──────────────┐
                                                       │  x86-64 cg   │──▶ .s
                                                       └──────────────┘

What works end-to-end

  • Items: fn
  • Types: i64, bool, unit ()
  • Statements: let, let mut, expression-statements, return
  • Expressions: integer/bool literals, identifiers, binary + - * / % == != < <= > >= && ||, unary - !, function calls, blocks, if / else, while, assignment.
  • Control flow: recursion, mutation, nested ifs/whiles.
  • A minimal C runtime providing print_i64 and print_bool.

What parses but isn't lowered yet

The parser accepts a much larger Rust surface so the AST is realistic. These constructs report a clean "unsupported in this stage" diagnostic from the resolver/typeck instead of being silently miscompiled:

  • struct, enum, impl, trait, use, mod
  • generics <T, 'a, const N: usize> and trait bounds
  • patterns beyond plain identifiers (match, tuple/struct patterns)
  • references &T, &mut T, lifetimes, Box<T>, Vec<T>
  • closures, ?, ranges, method calls on user types

Each of those is one (often more) follow-up session of work. Hooks are in place.

Build (CMake, any C++17 toolchain)

cmake -S . -B build
cmake --build build

This produces build/rustc (or rustc.exe).

Run

# 1. compile a Rust source to assembly
build/rustc tests/samples/fib.rs -o fib.s

# 2. assemble + link with the tiny C runtime (mingw / gcc)
gcc fib.s runtime/runtime.c -o fib.exe

# 3. run
./fib.exe

Use --emit=tokens|ast|mir|asm to inspect each stage.

Layout

include/rustc/        public headers, one folder per phase
src/                  matching .cpp implementations
runtime/runtime.c     print_i64 / print_bool, linked into compiled programs
tests/samples/*.rs    Rust source the working subset covers

Non-goals (intentional simplifications)

  • No borrow checker beyond a stub. We parse & / &mut but don't enforce aliasing rules. Adding NLL would be a project of its own.
  • No monomorphisation. Generics parse and are stored in the AST but type-checking refuses them.
  • No incremental / on-demand query system. Every phase runs once, top-down.
  • No real cargo — single-file input only. Module loading is a TODO.
  • No optimisation passes between MIR and codegen. Codegen consumes MIR directly with a naïve stack-slot model. Every local lives on the stack; every operation goes through rax.

The point is to be a faithful shape of a real compiler, small enough to read.

About

a Rust compiler written in C++

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages