Skip to content

Repository files navigation

MiniC Compiler – Full Frontend + IR + MIPS Backend

A compiler for a simplified C-like language written in C.

This project implements:

  • Recursive descent parsing
  • Abstract Syntax Tree (AST) construction
  • Scoped symbol tables
  • Semantic validation
  • Three-Address Code (Quad) intermediate representation
  • Short-circuit boolean code generation
  • Stack-frame based MIPS assembly generation

Compiler Architecture:

Source Code
   ↓
Lexer
   ↓
Recursive Descent Parser
   ↓
AST Construction
   ↓
Semantic Analysis (Scoped Symbol Tables)
   ↓
Three-Address Code (Quad IR)
   ↓
MIPS Code Generation

Language Features

Supported:

  • int variables
  • Multiple declarations (int a, b, c;)
  • Functions with parameters
  • Nested scopes
  • if / else
  • while
  • return
  • Arithmetic expressions
  • Boolean expressions (&&, ||, relational ops)
  • Function calls
  • Argument count validation

Operator Precedence

Correctly layered parsing:

OR
  → AND
    → Relational
      → Add/Sub
        → Mul/Div
          → Unary
            → Primary

Abstract Syntax Tree (AST)

Each node stores:

Node type

Child pointers (left, right, next)

Associated symbol (if applicable)

Generated IR code head/tail pointers

The AST drives both semantic validation and code generation.

Scoped Symbol Tables

Features:

  • Global scope
  • Function scope
  • Block-level scoping
  • Duplicate declaration detection
  • Undeclared variable detection
  • Function existence checks
  • Parameter count verification
Scope stack is managed via:
pushScope()
popScope()

Intermediate Representation (IR)

The compiler lowers AST into Three-Address Code (Quad format).

Each instruction contains:

  • Operation
  • src1
  • src2
  • destination
  • optional label

Example IR (conceptual)

For:

x = a + b;

Generated IR:

t1 = a
t2 = b
t3 = t1 + t2
x  = t3

Control Flow Generation

Short-Circuit Boolean Logic

Logical AND and OR use label-based branching:

    AND evaluates right only if left is true

    OR evaluates right only if left is false

Implemented using dynamically generated labels:

__L0
__L1
__L2
While Loop Lowering

Structure:

goto eval
top:
    body
eval:
    if (cond) goto top
after:

Stack Frame Layout

Offsets are computed per function:

  • Parameters: positive offsets
  • Locals: negative offsets
  • Temporaries: inserted dynamically
Example layout:
| param n   |  +offset
| param 1   |
| return addr |
| local 1   |  -offset
| local 2   |
| temp vars |

Offset calculation handled by:

get_offsets()

MIPS Code Generation

The backend:

  • Emits ENTER / LEAVE
  • Generates CALL / RET
  • Manages temporaries
  • Emits branch instructions
  • Generates label-based control flow
  • Produces runnable assembly

Entry stub:

.text
.globl main
main:
    jal _main
    li $v0, 10
    syscall

Example Program

  int main() {
    int x;
    x = 5;

    while (x > 0) {
        println(x);
        x = x - 1;
    }

    return 0;
}

Build

gcc *.c -o minic
./minic input.c > output.asm

Run with:

  • MARS
  • SPIM

Key Technical Highlights

  • Manual AST memory management
  • Linked-list Quad IR
  • Short-circuit boolean lowering
  • Dynamic temporary variable allocation
  • Explicit stack frame construction
  • Label-based branching
  • Modular codegen per AST node type

About

A compiler for a simple "C like" language

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages