cp-16 · Capstone Compiler Suite (minilangc)

A complete ahead-of-time compiler that puts everything from cp-01…cp-15 together. minilangc lexes → parses → typechecks → emits LLVM IR → shells out to llc + clang to produce a native executable.

Build & run

cmake -S src/cpp -B build
cmake --build build
./build/tests/test_suite              # → 28/28 checks passed

cat > hello.ml <<'PROG'
fn fib(n) {
    if (n < 2) { return n; }
    return fib(n - 1) + fib(n - 2);
}
fn main() {
    print fib(10);
}
PROG

./build/minilangc emit-ir hello.ml > hello.ll
./build/minilangc build   hello.ml -o hello
./build/minilangc run     hello.ml      # → 55
./build/minilangc check   hello.ml      # silent if clean

CLI:

minilangc <command> [options] <file|->
  emit-ir         lex+parse+typecheck and print LLVM IR
  build           compile to executable (-o path, -O0..3, -v verbose)
  run             build then execute
  check           lex+parse+typecheck only

Language

program := func+
func    := "fn" Ident "(" params? ")" block
block   := "{" stmt* "}"
stmt    := "let" Ident "=" expr ";"
         | "print" expr ";"
         | "return" expr ";"
         | "if" "(" expr ")" block ("else" block)?
         | "while" "(" expr ")" block
         | Ident "=" expr ";"
         | expr ";"
expr    := cmp
cmp     := add (("=="|"!="|"<"|"<="|">"|">=") add)*
add     := mul (("+"|"-") mul)*
mul     := unary (("*"|"/"|"%") unary)*
unary   := "-" unary | call
call    := primary ("(" args? ")")*
primary := Number | Ident | "(" expr ")"

Every value is i64. print lowers to printf("%lld\n", v). Must have fn main() { ... }.

Layout

src/cpp/src/
    source.hpp/.cpp     SourceFile + line index
    diag.hpp/.cpp       Diagnostic + renderer
    lex.hpp/.cpp        tokenizer
    parse.hpp/.cpp      recursive-descent parser
    typecheck.hpp/.cpp  scope + arity + main checks
    llvm_emit.hpp/.cpp  AST → textual LLVM IR
    driver.hpp/.cpp     llc + clang shell-out
    main.cpp            `minilangc` CLI
tests/
    test_suite.cpp      frontend + IR + end-to-end (9 tests / 28 checks)

Reading order

  1. steps/01-pipeline-overview.md
  2. steps/02-frontend-reuse.md
  3. steps/03-multi-function-language.md
  4. steps/04-typecheck-and-scope.md
  5. steps/05-emitting-llvm-ir.md
  6. steps/06-driving-the-toolchain.md
  7. steps/07-from-here-to-production.md