jcc is an experimental C compiler written in Rust, targeting AMD64.
It implements the traditional stages of a C compiler, from lexing to semantic analysis, SSA construction, and assembly generation.
The project is modular and instrumented with profiling support, making it suitable for experimentation and learning about compiler internals.
-
Preprocessing Uses
gcc -E -Pfor preprocessing source files before compilation. -
Lexing Converts source text into tokens with diagnostics and error reporting.
-
Parsing Builds an Abstract Syntax Tree (AST) from tokens. Supports optional Graphviz DOT output for visualizing the AST.
-
Semantic Analysis (Sema)
- Name resolution (
ResolverPass) - Control flow analysis (
ControlPass) - Type checking (
TyperPass) - AST lowering into an intermediate form
- Name resolution (
-
SSA Generation Builds a Static Single Assignment (SSA) representation for optimization and code generation.
-
Code Generation
- AMD64 instruction selection
- Assembly emission
- Assembly fixing (final tweaks for correctness)
-
Backend Emits
.sassembly,.oobject files, or full executables viagcc. -
Profiling Built-in timing and profiling of each compiler stage.
-
Verbose Output Optionally print tokens, SSA, or assembly to stdout.
cargo build --releaseThis produces the jcc binary in target/release/.
./target/release/jcc path/to/file.cBy default, this will:
- Preprocess the C file (
gcc -E -P). - Compile down through lexing, parsing, semantic analysis, SSA, and code generation.
- Emit AMD64 assembly.
- Assemble and link with
gcc, producing an executable.
| Flag | Description |
|---|---|
--verbose |
Print additional information (tokens, SSA, assembly). |
--profile |
Time each compiler stage and print a report. |
--lex |
Stop after lexing. |
--parse |
Stop after parsing. |
--emit-ast-graphviz |
Emit the AST as a Graphviz DOT file. |
--validate |
Stop after semantic analysis. |
--tacky |
Stop after SSA generation. |
--codegen |
Stop after AMD64 code generation (before assembly emission). |
-S, --assembly |
Emit an assembly file (.s) but no executable. |
-c, --no-link |
Emit an object file (.o) but do not link. |
Compile and link a program:
./jcc examples/hello.c
./examples/hello # Run the output programGenerate and view the AST as a graph:
./jcc examples/hello.c --emit-ast-graphviz --parse
dot -Tpng examples/hello.dot -o ast.pngProduce assembly only:
./jcc examples/hello.c -S
cat examples/hello.sCompile to object file only:
./jcc examples/hello.c -c
ls examples/hello.oProfile each stage:
./jcc examples/hello.c --profile- Rust toolchain (Rust 1.70+ recommended)
- GCC (used for preprocessing, assembling, and linking)
ast/– AST definition, parser, Graphviz emissionlower/– AST lowering passessema/– Semantic analysis (resolver, typer, control flow checks)ssa/– SSA builder and optimizationsamd64/– Code generation backend (instruction selection, emitter, fixer)sourcemap/– Diagnostics and source mappingtok/– Lexer and token definitionsprofile/– Profiler utilities
This compiler is work-in-progress and not production-ready. The goal is to experiment with compiler construction and gradually expand language coverage, optimizations, and backends.