PitchHut logo
A specialized compiler for a subset of C inspired by a renowned guide.
Pitch

This project offers an implementation of a C compiler based on the book 'Writing a C Compiler' by Nora Sandler. Focused on a specific subset of C, it integrates unique code design while optimizing for performance using Zig's design principles. Ideal for those interested in compiler construction and language design.

Description

C Compiler Implementation in Zig

This repository features a compiler implementation for a subset of the C programming language, based on the book Writing a C Compiler by Nora Sandler. Unlike traditional compilers, this project focuses exclusively on the features covered in the book, and incorporates additional functionalities defined by the author. The compiler is designed to generate assembly for Linux systems.

Design Philosophy

The implementation adopts a data-oriented design philosophy, leveraging the efficiency of Zig. Development was a personal project completed over a period of 10 months, with consistent work during evenings and weekends. The final month and a half involved a more intense focus on development.

Project Structure

The compiler is systematically organized into key components, each responsible for a specific phase of the compilation process:

src/
├── main.zig         - Main entry point and compilation pipeline orchestration
├── driver.zig       - Compiler driver handling file I/O and process management
├── lexer.zig        - Lexical analysis (tokenization)
├── Ast.zig          - Abstract Syntax Tree (AST) definitions and operations
├── Parser.zig       - Syntax analysis and AST construction
├── Sema.zig         - Semantic analysis
├── Tacky.zig        - Tacky Intermediate Representation (IR) definitions
├── TackyGen.zig     - Intermediate code generation (Tacky IR)
├── Optimizer        - Optimizer for Tacky IR
├── codegen.zig      - x86_64 assembly code generation
├── RegAllocator.zig - Register allocation and coalescing on assembly instructions
└── emit.zig         - Assembly code emission

Abstract Syntax Tree (AST)

The AST structure is heavily inspired by the Zig compiler. Each AST node is designed to encapsulate relevant properties in a compact manner, ensuring efficient data management. For example:

pub const Node = struct {
    tag: Tag,
    main_token: TokenIndex,
    data: Data = .{},

    pub const Data = struct {
        lhs: Index = Index.empty,
        rhs: Index = Index.empty,
    };

    pub const Index = enum(u32) {
        empty = 0,
        _,
    };

    pub const Tag = enum(u8) {
        program,
        func_decl,
        func_def,
        func_call,
        block,
        return_stmt,
        ...
    }
}

Tacky Intermediate Representation (IR)

Tacky IR instructions are similarly structured:

pub const Instr = struct {
    tag: Tag,
    data: Data,

    pub const Data = packed struct(u64) {
        lhs: Index = Index.empty,
        rhs: Index = Index.empty,
    };

    pub const Index = enum(u32) {
        empty = 0,
        _,
    };

    pub const Tag = enum(u8) {
        constant,
        string_constant,
        copy,
        copyf,
        get_local,
        ...
    }
}

Code Generation

In codegen.zig, assembly instructions are rigorously defined:

pub const Instr = struct {
    tag: Tag,
    data: Data = .{},

    pub const Data = struct {
        dst: Operand = .empty,
        src: Operand = .empty,
    };

    pub const Index = enum(u32) { empty = 0, _ };

    pub const OperandTag = enum(u8) {
        none,
        val,
        val_index,
        reg,
        stack,
        ...
    };
  
    pub const OperandWidth = enum(u8) {
        none,
        byte,
        word,
        dword,
        qword,
        ...
    };

    pub const Operand = struct {
        tag: OperandTag,
        width: OperandWidth = .none,
        val: u32,

        pub const empty = Operand{ .tag = .none, .val = 0 };
    }
}

Development Tools

Configurations for popular code editors, such as VS Code and Zed, are included to facilitate building and running the compiler. Commands for compiling the project and running tests can be executed directly from the configured environment.

Knowledge and AI Usage

Throughout the development process, all coding was executed independently, with the only assistance from AI being in debugging and understanding complex issues related to compiler behavior. This balanced approach allowed for deep learning and comprehension of compiler construction while leveraging AI for troubleshooting.

This project serves as an educational tool for those interested in compiler construction and the intricacies of programming language implementation.

0 comments

No comments yet.

Sign in to be the first to comment.