An AOT compiler for COOL (Classroom Object Oriented Language), targeting the MIPS 32-bit Architecture and written entirely in Python 3.
COOL is a small statically-typed object-oriented language that is type-safe and garbage collected. It has mainly 3 primitive data types: Integers, Strings and Booleans (true, false). It supports conditional and iterative control flow in addition to pattern matching. Everything in COOL is an expression! Many example COOL programs can be found under the /examples directory.
A BNF-based specification of COOL's Context-Free Grammar can be found at /docs/Grammar.md.
- Language Features
- Project overview
- Development status
- How to install
- How to use
- How to test
- References
- License
- Primitive Data Types:
- Integers
- Strings
- Booleans (
true,false)
- Object Oriented:
- Class Declaration
- Object Instantiation
- Inheritance
- Class Attributes
- Class Methods
- Strong Static Typing
- Pattern Matching
- Control Flow:
- Switch Case
- If/Then/Else
- While Loops
- Automatic Memory Management:
- Garbage Collection (planned)
PyCOOLC follows classical compiler architecture with Frontend and Backend components:
flowchart LR
subgraph Frontend
A[Source .cl] --> B[Lexer]
B --> |tokens| C[Parser]
C --> |AST| D[Semantic Analysis]
end
subgraph Backend
D --> |typed AST| E[IR Builder]
E --> |TAC| F[Optimizer]
F --> |optimized TAC| G[Code Generator]
end
G --> H[MIPS .s]
| Stage | Module | Description |
|---|---|---|
| Lexer | lexer.py |
Regex-based tokenizer |
| Parser | parser.py |
LALR(1) parser, builds AST |
| Semantic Analysis | semanalyser.py |
Type checking, scope analysis, inheritance |
| IR Builder | ir/ |
Three-Address Code, Control Flow Graph, SSA |
| Optimizer | optimization/ |
Constant propagation, liveness, dead code elimination |
| Code Generator | codegen.py |
MIPS 32-bit with dispatch tables and runtime |
COOL Program:
class Main inherits IO {
main(): Object { out_string("Hello!\n") };
};- Lexer →
CLASS,TYPE(Main),INHERITS,TYPE(IO),{, ... - Parser → AST with
Program → Class → ClassMethod - Semantic Analysis → Type-checks
out_stringcall, resolvesIOinheritance - Code Generation → MIPS assembly with dispatch to
IO.out_string
Each Compiler stage and Runtime feature is designed as a separate component that can be used standalone or as a Python module, the following is the development status of each one:
| Compiler Stage | Python Module | Status |
|---|---|---|
| Lexical Analysis | lexer.py |
✅ done |
| Parsing | parser.py |
✅ done |
| Semantic Analysis | semanalyser.py |
✅ done |
| Optimization | optimization/ |
✅ done |
| Code Generation | codegen.py |
✅ done |
| Garbage Collection | - | 🚧 planned |
- Python >= 3.12
- SPIM - MIPS 32-bit Assembly Simulator (see: Installing SPIM).
- All Python packages listed in:
requirements.txt.
SPIM is a self-contained simulator that runs MIPS32 programs. You'll need it to execute the compiled assembly output.
Download: Get the latest version from SourceForge.
macOS:
# Download and install QtSpim
curl -LO https://sourceforge.net/projects/spimsimulator/files/QtSpim_9.1.24_mac.mpkg.zip
unzip QtSpim_9.1.24_mac.mpkg.zip
open QtSpim_9.1.24_mac.mpkg
# Or use the command-line spim (if installed via homebrew or from source)
brew install spim # if availableLinux (Debian/Ubuntu):
# Download the .deb package
wget https://sourceforge.net/projects/spimsimulator/files/qtspim_9.1.24_linux64.deb
sudo dpkg -i qtspim_9.1.24_linux64.debWindows:
Download QtSpim_9.1.24_Windows.msi from SourceForge and run the installer.
# Clone the repository
git clone https://github.com/aalhour/pycoolc.git
cd pycoolc
# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies and the package
pip install -e .Or use the Makefile:
make venv
source .venv/bin/activateHelp and usage information:
pycoolc --helpCompile a COOL program:
pycoolc hello_world.clCompile multiple files together (classes can reference each other):
pycoolc atoi.cl atoi_test.cl -o atoi_test.sSpecify a custom name for the compiled output program:
pycoolc hello_world.cl --outfile helloWorldAsm.sRun the compiled program (MIPS machine code) with the SPIM simulator:
spim -file helloWorldAsm.sOr with QtSpim (GUI):
qtspim helloWorldAsm.sSkip code generation (type-check only):
pycoolc hello_world.cl --no-codegenView intermediate representations:
pycoolc hello_world.cl --tokens # Show lexer output
pycoolc hello_world.cl --ast # Show parsed AST
pycoolc hello_world.cl --semantics # Show typed ASTfrom pycoolc.lexer import make_lexer
from pycoolc.parser import make_parser
from pycoolc.semanalyser import make_semantic_analyser
from pycoolc.codegen import make_code_generator
# Lexical analysis
lexer = make_lexer()
lexer.input(a_cool_program_source_code_str)
for token in lexer:
print(token)
# Parsing
parser = make_parser()
ast = parser.parse(a_cool_program_source_code_str)
print(ast)
# Semantic analysis
analyzer = make_semantic_analyser()
typed_ast = analyzer.transform(ast)
# Code generation
codegen = make_code_generator(analyzer)
mips_code = codegen.generate(typed_ast)
print(mips_code)make help # Show all available targets
make venv # Create virtual environment
make install # Install package in development mode
make unit-tests # Run unit tests
make integration-test # Run integration tests with SPIM
make test # Run all tests
make clean # Clean build artifactsPyCOOLC has comprehensive test coverage across all compiler phases:
# Run all unit tests
make unit-tests
# Run integration tests (requires SPIM)
make integration-test
# Run everything
make test- Engineering a Compiler, Cooper and Torczon - Amazon
- Modern Compiler Implementation in ML, Appel - www, Amazon
- Stanford's Compiler Theory Course - www12, www16, YouTube
This project is licensed under the MIT License.
All copyrights of the files and documents under the /docs directory belong to their original owners.
