Quick and dirty "C" to MIPS compiler - written in a day (and night) at Jugendforum Informatik 2020
- C# 97.4%
- Assembly 2.6%
| examples | ||
| mips-samples | ||
| .gitattributes | ||
| .gitignore | ||
| Generator.cs | ||
| JFICompiler.csproj | ||
| Parser.cs | ||
| Program.cs | ||
| README.md | ||
| Tokenizer.cs | ||
JFI-Compiler
A tiny C-like to MIPS compiler written in one night at Jugenforum Informatik, a 4-day coding camp on Burg Liebenzell for participants of the German federal computer science competition (BWInf).
Four C# files, ~1000 lines, zero dependencies.
Note: 2026: This is project has since been modernized with .NET 10 best practices (no functionality or scope was changed).
Language
It's basically C, but with only int and these quirks:
print(x)-- prints an integer (no format strings)read-- reads an integer from stdin (used as an rvalue:x = read)return;-- statement-level (no value)x += 1/x -= 1-- compound assignment at statement level only- No functions (single implicit main block)
- No
else - No nested expressions in conditions (must be
a op b) - Only
==,!=,<,>,<=,>=,+,-,*,/,^,&&,||
Example
int number = read;
int factor = read;
int result = 0;
int i = 0;
while (i < factor)
{
result += number;
i += 1;
}
print(result);
ADDI $sp, $sp, 0
LI $v0, 5
SYSCALL
MOVE $t0, $v0
SW $t0, 0($sp)
LI $v0, 5
SYSCALL
MOVE $t0, $v0
SW $t0, -4($sp)
LI $t0, 0
SW $t0, -8($sp)
LI $t0, 0
SW $t0, -12($sp)
WHILE0:
LW $t1, -12($sp)
LW $t2, -4($sp)
BLT $t1, $t2, WHILE1
J WHILE2
WHILE1:
ADDI $sp, $sp, -16
LW $t0, 8($sp)
LW $t1, 16($sp)
ADD $t0, $t0, $t1
SW $t0, 8($sp)
LW $t0, 4($sp)
LI $t1, 1
ADD $t0, $t0, $t1
SW $t0, 4($sp)
BLOCK1:
ADDI $sp, $sp, 16
J WHILE0
WHILE2:
LW $a0, -8($sp)
LI $v0, 1
SYSCALL
BLOCK0:
ADDI $sp, $sp, 0
Usage
JFICompiler.exe <input.c> <output.asm>
Sample Outputs
print(16)
print(16);
li $a0, 16
li $v0, 1
syscall
Reading and writing variables (stack)
int x = 16;
print(x);
li $t1, 16
sw $t1, 4($sp)
lw $a0, 4($sp)
li $v0, 1
syscall
If statement
if (1 == 2)
{
// true branch
}
LI $t1, 1
LI $t2, 2
BEQ $t1, $t2, IF1
J IF2
IF1:
; true branch
IF2:
; continue
While loop
while (i < j)
{
// loop body
}
WHILE0:
BEQ $t1, $t2, WHILE1
J WHILE2
WHILE1:
; loop body
J WHILE0
WHILE2:
; continue