A complete, multi-phase compiler for the Quasar programming language, translating a custom C-like high-level language into executable 32-bit x86 assembly code.
The Quasar Compiler is a comprehensive implementation of modern compiler theory, demonstrating the entire compilation pipeline from source code tokenization to machine code generation. This project serves as an educational tool for computer science students, a portfolio piece for aspiring systems programmers, and a reference for language design enthusiasts.
Quasar is a small, statically-typed procedural language with syntax familiar to C, Java, and JavaScript developers. It emphasizes clarity and simplicity while maintaining robust type safety.
| Category | Feature | Syntax & Description |
|---|---|---|
| Variables & Types | Data Types | Int (integers), Dub (floating-point), Bool (true/false) |
| Variable Declaration | let my_var = 10; (mutable) |
|
| Constant Declaration | const PI = 3.14; (immutable) |
|
| String Literals | Supported for output via print |
|
| Operators | Arithmetic | +, -, *, /, % |
| Relational & Equality | ==, !=, <, >, <=, >= |
|
| Logical | && (AND), || (OR), ! (NOT) |
|
| Assignment | =, +=, -=, *=, /=, %= |
|
| Increment/Decrement | ++, -- (prefix and postfix) |
|
| Control Flow | Conditionals | if-else statements with nesting support |
| Loops | for and while loops |
|
| Loop Control | break and continue statements |
|
| Built-in Functions | Output | print "Hello, World!"; |
| Program Exit | return statement with integer exit code |
// File: examples/for_loop_break.lang
print "--- Starting Calculation ---";
const THRESHOLD = 100;
let final_result = 0;
for (let i = 1; i <= 10; i = i + 1) {
final_result = final_result + (i * 5);
if (final_result > THRESHOLD) {
print "Threshold exceeded!";
break;
}
}
print "--- Calculation Complete ---";
return final_result;
// File: examples/nested_if.lang
print "--- Program Start ---";
const score_math: Int = 90;
const score_science: Int = 78;
const passing_grade: Int = 60;
let extra_credit: Int = 5;
let final_status: Int = 0;
if (score_math >= passing_grade) {
print "Math score is passing.";
if ((score_science + extra_credit) > 80 && score_math > 85) {
print "Science score with extra credit is also excellent.";
final_status = (score_math * 2) - (score_science % 10);
} else {
print "Science score is good, but not in the top tier.";
final_status = -1;
}
} else {
print "Math score is failing.";
final_status = -99;
}
print "--- Program End ---";
return final_status;
The Quasar Compiler implements a classic five-phase compilation pipeline:
Source Code → [Lexer] → Tokens → [Parser] → AST → [Semantic Analyzer] →
Annotated AST → [ICG] → TAC → [Code Generator] → Assembly
- Lexical Analysis (Flex): Scans source text and converts it into a token stream
- Syntax Analysis (Bison): Validates tokens against language grammar and builds an Abstract Syntax Tree (AST)
- Semantic Analysis: Performs type checking and scope resolution using a Symbol Table, annotating the AST
- Intermediate Code Generation (ICG): Translates annotated AST into machine-independent Three-Address Code (TAC)
- Final Code Generation: Converts TAC into executable 32-bit x86 assembly code (AT&T syntax)
- 32-bit MinGW environment (MSYS2 recommended for Windows)
- Flex (lexical analyzer generator)
- Bison (parser generator)
- GCC (GNU Compiler Collection)
Execute the following commands in the project's root directory:
bison -dy parser.yflex scanner.l
gcc y.tab.c lex.yy.c symtab.c semantic.c ast_printer.c icg.c codegen.cThis produces a.exe (the Quasar compiler executable).
./a.exeThis reads input.lang and generates output.s (assembly file).
gcc -m32 -o final_program.exe main.c output.s./final_program.exesequenceDiagram
participant S as Source Code
participant L as Lexer (scanner.l)
participant P as Parser (parser.y)
participant ST as Symbol Table (symtab.c)
participant SA as Semantic Analysis (semantic.c)
participant AST as AST (ast_printer.c)
participant ICG as Intermediate Code (icg.c)
participant CG as Code Generator (codegen.c)
participant O as Output Assembly
S->>L: Input Quasar Source
L->>P: Generate Tokens
P->>ST: Build Symbol Table
P->>AST: Construct Abstract Syntax Tree
AST->>SA: Perform Semantic Analysis
SA->>ICG: Generate Intermediate Code
ICG->>CG: Convert to x86 Assembly
CG->>O: Produce .asm File
Contributions are welcome and appreciated! This project follows a standard fork-and-pull-request workflow. If you wish to contribute, please adhere to the following steps to ensure a smooth process.
Click the "Fork" button at the top-right corner of this page to create your own copy of the repository.
Clone your forked repository to your local machine.
git clone https://github.com/YOUR_USERNAME/Compiler.gitBefore making any changes, create a new branch for your feature or bug fix. Do not commit directly to the main branch. This is a critical step.
# For a new feature:
git checkout -b feature/MyNewFeature# For a bug fix:
git checkout -b fix/BugDescriptionImplement your changes, additions, or bug fixes. Ensure that your code builds correctly by following the build steps outlined above.
Commit your work with a clear and descriptive commit message.
git commit -m "Add: Implement a cool new feature"Push your new branch to your forked repository on GitHub.
git push origin feature/MyNewFeatureNavigate to the original repository and click "New Pull Request". Provide a clear description of your changes and submit the pull request for review.
This project is licensed under the MIT License - see below for details.
