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
Source Code
↓
Lexer
↓
Recursive Descent Parser
↓
AST Construction
↓
Semantic Analysis (Scoped Symbol Tables)
↓
Three-Address Code (Quad IR)
↓
MIPS Code Generation
- 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
Correctly layered parsing:
OR
→ AND
→ Relational
→ Add/Sub
→ Mul/Div
→ Unary
→ Primary
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.
Features:
- Global scope
- Function scope
- Block-level scoping
- Duplicate declaration detection
- Undeclared variable detection
- Function existence checks
- Parameter count verification
pushScope()
popScope()
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
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:
Offsets are computed per function:
- Parameters: positive offsets
- Locals: negative offsets
- Temporaries: inserted dynamically
| param n | +offset
| param 1 |
| return addr |
| local 1 | -offset
| local 2 |
| temp vars |
Offset calculation handled by:
get_offsets()
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