A toy, self-hosted (subset of) C Compiler for Linux on x86_64.
charint- Array
- Pointer (including function pointer)
- Struct
- Enum
- Typedef
- Global function
staticattributeexternattribute- Function call with over 6 arguments
- Variadic argument
va_startandva_endis available. (va_argis not supported yet.)
Note that passing/returning struct itself is not supported.
- Global variable
- Local variable
staticattributeexternattribute- Variable initializer (primitive types, structs, arrays)
- Type checking (incomplete)
- So sometimes
mimiccaccepts incorrect C program and rejects correct C program.
- So sometimes
- Decimal, hexadecimal, octal number
- Characters
- String literals
- Escape sequence
\',\",\\,\?,\a,\b,\f,\n,\r,\t,\v, and\0
if,else ifandelsefor(with variable declaration at initializer statement support:for (int i = 0; ...))whileswitch,caseanddefaultbreakcontinuereturn
- Compound literal for struct (it for array is not yet)
- Type cast
- One-line comment (
// ...) - Multi-line comment (
/* ... */)
==,!=,<,>,<=,>=,&&, and||+=,*=,/=,%=,&=,|=,^=,<<=, and>>=++and--of both prefix and postfix+,*,/, and%&,|,^,<<, and>>(Bit operation)!("not" operator)- Addressing
& - Dereferencing
* - Unary
+and-(e.g.+3and-5) sizeof.and->()(function call)[](array accessing)- Ternary operator (
condition ? expr-true : expr-false) ,(expr, expr, expr, ...)
#include <header>and#include "header"#if,#elif,#end, and#ifdef- Nesting them is also OK.
- Macros
- Object-like macro (e.g.
#define BUFSIZE (64)) - Function-like macro (e.g.
#define SIZEOF(ar) (sizeof(ar) / sizeof(ar[0]))) #undef- Note that
mimiccdoesn't have infinite macro expansion guard, somimiccwon't return with recursive macro like this:
- Object-like macro (e.g.
#define REC REC
#define MUTUAL_REC1(arg) MUTUAL_REC2(arg)
#define MUTUAL_REC2(arg) MUTUAL_REC1(arg)
# Build mimicc compiler with gcc. The binary will available at ./mimicc.
$ make
# Build 2nd gen mimicc compiler. The binary will available at ./test/self/mimicc.
$ make self
# Build 3rd gen mimicc compiler. The binary will available at ./test/selfself/mimicc.
$ make selfself
# Run tests for 1st gen mimicc compiler.
$ make test
# Run tests for 2nd gen mimicc compiler.
$ make test_self or $ make self_test
# Run tests for 3rd gen mimicc compiler. Also check there's no differencies
# between assembly of 2nd gen mimicc and of 3rd gen mimicc.
$ make test_selfself or $ make selfself_test
# Run all tests at once
$ make test_all
$ cd path/to/this/repo
$ ./mimicc -o <out-asm-path> <in-c-program-path>
$ gcc -o <out-binary-path> <out-asm-path>
This project is heavily, heavily inspired by this web book. Great thanks:
- 「低レイヤを知りたい人のためのCコンパイラ作成入門」(https://www.sigbus.info/compilerbook)