English | 日本語
LaCC is a minimalist C compiler that implements only the core language features you need to get simple C programs running.
- Primitive:
int,char,void,unsigned,long,long long,short,_Bool - Derived: pointer types (
T*), arrays (T[]) - Composite: structures (
struct), unions (union), enumerations (enum)
- Definition: specify parameter and return types
- Declaration & Invocation: define and call functions; use
returnto send back a value
Both global and local (stack) variable declarations are supported.
- Conditional Branching
if (condition) { … }else { … }
- Loops
for (init; condition; step) { … }
You can omit any or all of the three components of a for loop (initialization, condition, and step).while (condition) { … }do { … } while (condition);
- Loop Control
breakexits a loopcontinueskips to the next iteration
- Arithmetic:
+,-,*,/,% - Relational:
==,!=,<,<=,>,>= - Logical:
&&,||,! - Bitwise:
&,|,^,~,<<,>>
-
Include directive LaCC can process
#includestatements with double quotes (e.g.,#include "foo.h") and with angle brackets (e.g.,#include <bar.h>).
Quoted includes first look relative to the including file, while angle brackets search configured include paths.
/usr/includeand/usr/include/x86_64-linux-gnuare added automatically, but many system headers still rely on unsupported language features. -
Preprocessor macros
Object-like and function-like#definedirectives (including#stringizing and##token pasting) are expanded during tokenization.
Diagnostics that originate inside macro expansions point back to the original file/line so complex headers remain debuggable. -
Preprocessor conditionals
Conditional compilation with#if,#ifdef,#ifndef,#elif,#else, and#endifis supported, along with#undeffor removing macro definitions. -
Built-in predefined macros
__LACC__,__x86_64__,__LP64__, , and a handful of compat aliases are defined so typical Unix headers can detect the environment. -
Initializer lists for arrays and structs (with limitations)
- Array initialization with a list of integer constants:
int arr[3] = {3, 6, 2}; - String literal initialization for character arrays:
char str[15] = "Hello, World!\n"; - Designated initializers for structs/unions:
struct AB v = {.a = 1, .b = 2};
Initializer expressions must currently be integer constants (or string literals for
char[]). Nested array initializers beyond a single level are not supported. - Array initialization with a list of integer constants:
-
Extern declarations
LaCC supports external variable declarations with basic types, pointers, and arrays. -
Typedef support
LaCC supports thetypedefkeyword for creating type aliases. -
Type qualifiers & storage-class specifiers:
const,volatile,static, and pointer-only qualifiers seen in system headers (restrict,_Nullable,_Nonnull,__strong, etc.) are parsed and safely ignored. -
gotostatement and labels
LaCC supportsgotostatements and label definitions, allowing for non-linear control flow. -
Struct and Union member access
Both dot notation (.) for direct access and arrow notation (->) for pointer access are supported. -
Struct/union bit-fields
C-style bit-field declarations (with optional zero-width separators and unnamed fields) are parsed and contribute to layout checks. Code-gen still treats them as opaque aggregates. -
Binary and Hexadecimal numbers:
0b001011or0xFF2A -
Inline Assembly passthrough
__asm__, and variants withvolatile/clobber lists are recognized and skipped, allowing headers that embed inline assembly to preprocess successfully (no assembly is emitted by LaCC). -
Comment support
// single-line comment /* multi-line comment */
-
switchstatements andcase/defaultlabels
LaCC supportsswitchstatements withcaselabels for branching based on the value of an expression. -
Explicit type casting
LaCC allows explicit type casting between compatible pointer types. -
Ternary conditional operator LaCC supports the ternary conditional operator (
?:) for inline conditional expressions.
To keep system headers parsable, float and double are recognized only for parsing purposes.
- Arithmetic, comparisons, and code generation for floating-point types are not implemented yet.
sizeof(float)is treated as 4 andsizeof(double)as 8 (LP64).long doubleis also simplified to 8 bytes.- Header typedefs like
typedef float _Float32;andtypedef double _Float64;parse successfully, but do not rely on using these types in expressions for now.
Full floating-point semantics (dedicated TY_FLOAT / TY_DOUBLE, arithmetic, and ABI handling) may be added later. Until then, avoid expressions that require floating-point operations.
LaCC does not support the following:
- Floating-point operations: while
floatanddoubleare recognized for parsing andsizeof, arithmetic and codegen are not implemented - Initializer lists do not yet support deeply nested array initializers
- Inline assembly
- Variadic functions (macros such as
va_list,va_start, andva_argare not supported) - Nested functions (functions defined within other functions)
- Variable Length Arrays (VLAs)
LaCC only handles one .c file at a time — there's no support for separate compilation or linking multiple translation units.
There are no code-generation optimizations beyond what's needed to make it work.
git clone https://github.com/Latte72R/LaCC
cd LaCCAfter that, you have a few make targets to build and test your compiler:
make selfhostHere, a bootstrap compiler bootstrap is used to recompile the compiler source itself,
producing a self-hosted compiler named lacc.
This ensures that your compiler can correctly compile its own code.
make run FILE=./examples/lifegame.c
make run FILE=./examples/rotate.cThis command compiles and runs the specified C file using the self-hosted compiler lacc.
make unittestPassing all tests confirms that your self-hosted compiler behaves as expected.
The unit tests are located in the tests/unittest.c file.
make warntestThis command runs warning tests to ensure that the compiler correctly identifies and reports warnings.
The warning tests are located in the tests/warntest.c file.
make errortestThis command runs error tests to ensure that the compiler correctly identifies and reports errors.
The error tests are located in the tests/errortest.sh file.
make cleanRemoves the generated binaries and assembly files created during the build process.
make helpDisplays a list of available make targets and their descriptions.
LaCC is designed and maintained by student engineer Latte72 !
- Website: https://latte72.net/
- GitHub: @Latte72R
- X a.k.a Twitter: @Latte72R
- Qiita: @Latte72R
