Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

FCC — Finite Compiler Collection

FCC is a multi-language compiler collection framework written in C# (.NET 8). It packages support for multiple programming languages into a single tool, similar to GCC, Clang, or .NET's Roslyn.

By default FCC does not ship with any frontends or backends. Those are plugged in via ICompilerBackend / ICompilerFrontend interfaces (see Backends & Frontends).


Project structure

FCC/
├── fcc/                         # CLI entry point
│   └── Program.cs               #   fcc <input.cpp> [output.oir]
├── libs/
│   ├── ObjectIR.Core/           #   Core IR library (object-oriented IR)
│   ├── CppToObjectIR/           #   C++ → ObjectIR frontend
│   └── CppToObjectIR.Tests/     #   C++ frontend test suite
├── ObjectIR.Programming/        #   Type-system library (G#/GS project)
├── Docs/                        #   This documentation
├── examples/                    #   Sample C++ programs
├── repro/                       #   Repro cases / regression tests
└── FCC.sln                     #   Visual Studio solution file

Architecture

FCC is organised in layers. Each layer depends only on layers below it.

Source text (.cpp, .cs, …)
        │
        ▼
  Frontend (e.g. CppToObjectIR)
        │  Lex → Parse → CodeGen
        ▼
  ObjectIR.Core.AST
        │
        ├──► ModuleSerializer     → JSON / BSON / text
        ├──► ModuleComposer       → merged Module
        │       └──► DependencyResolver
        └──► FobIrCompiler        → .fob binary (compact binary format)

Components

Component Language Description
fcc (CLI) C# Entry point. Reads input, invokes the frontend, serialises the result.
ObjectIR.Core C# The shared intermediate representation. Types, methods, instructions, serialization, composition, and the fluent builder API. Published as a NuGet package.
CppToObjectIR C# C++ (subset) frontend. Lexer → Parser → IrCodeGenerator → ObjectIR Module.
ObjectIR.Programming G# Type checking and type system library for compiler manufacturers.

Data flow

fcc input.cpp output.oir
  1. Read input.cpp
  2. Resolve #include directives in the same directory
  3. Lex + Parse C++ → AST
  4. Build a member type registry from AST + headers
  5. Compile AST → ObjectIR Module
  6. Serialise Module → .oir (FOB binary) file

Getting started

Prerequisites

Build

git clone https://git.finite.ovh/FCC
cd FCC
dotnet build FCC.slnx

Run

dotnet run --project fcc -- examples/test.cpp output.oir

This compiles a C++ file into a .oir (FOB binary) file. You can also pipe the output through any registered backend for code generation.


CLI usage

Single-file mode

fcc <input> [output] [-o <output>] [--target fob|bir|textir|json] [-I <path>] [-D <define>]
Flag Default Description
input Source file to compile
output <input>.oir Output file path (positional or -o)
-t / --target / --emit fob Output format
-I Add include search path for header resolution
-D Add preprocessor define

Output targets:

Target Extension Description
fob .fobir FOB/IR binary format (compact, default)
bir .bir BSON IR format
textir .oir Human-readable IR code text
json .json Structured JSON format

Project mode

fcc build [<project.fccproj>] [args...]
fcc <project.fccproj>

When fcc build is run without a project path, FCC scans the current directory for a single .fccproj file. If exactly one is found, it is used automatically.

Project files use an XML format modelled after .csproj:

<Project Sdk="FCC">
  <PropertyGroup>
    <OutputName>MyApp</OutputName>
    <OutputPath>bin</OutputPath>
    <TargetFormat>fob</TargetFormat>
  </PropertyGroup>

  <ItemGroup>
    <Compile Include="src/**/*.cpp" />
    <Compile Include="src/**/*.h" />
    <IncludePath Include="include" />
    <Define Include="DEBUG" />
  </ItemGroup>
</Project>

PropertyGroup settings:

Element Default Description
OutputName output Base name of the compiled output
OutputPath bin Directory for the compiled output
TargetFormat fob Output format (fob, bir, textir, json)
RootNamespace (reserved)

ItemGroup elements:

Element Attribute Description
Compile Include Source file or glob pattern (e.g. src/**/*.cpp)
IncludePath Include Directory to search for #include headers
Define Include Preprocessor define

Paths in project files are resolved relative to the project directory. Glob patterns (*, ?) are supported in Compile Include attributes.

Exit codes:

Code Meaning
0 Success
1 Input/project error
2 Compilation error

Examples

# Compile a C++ file to FOB binary
fcc examples/test.cpp

# Compile to human-readable IR text
fcc examples/test.cpp --target textir -o output.ir.txt

# Compile with include paths
fcc examples/test.cpp -I examples/include

# Build a project
fcc build examples/sample.fccproj

# Auto-discover project in current directory
cd examples && fcc build

# Override target format for a project build
fcc build sample.fccproj --target json

C++ frontend (CppToObjectIR)

The C++ frontend compiles a subset of C++ into ObjectIR. It lives in libs/CppToObjectIR/ and is structured as a classic three-phase compiler:

Source text
    │
    ▼
  Lexer (libs/CppToObjectIR/Lexing/)
    │  Tokenizes: keywords, identifiers, operators, literals, skips # directives
    │  56 token kinds covering C++ type keywords, control flow, OOP, and operators
    ▼
  Parser (libs/CppToObjectIR/Parsing/)
    │  Produces a C++ AST (libs/CppToObjectIR/Ast/)
    │  30+ AST node types: classes, structs, enums, namespaces, methods,
    │  fields, statements (if/while/for/do-while/try-catch/throw),
    │  expressions (binary, unary, call, member access, new, cast, ternary)
    ▼
  IrCodeGenerator (libs/CppToObjectIR/CodeGen/)
    │  Walks the AST and emits ObjectIR instructions
    │  Handles: type mapping (C++ → IR), std::cout chains, type inference
    ▼
  ObjectIR.Core.Module

Supported C++ features

Feature Status
Namespaces Yes (emitted as static classes with free functions)
Classes (fields, methods, constructors) Yes
Structs Yes
Enums (with underlying type) Yes
Inheritance Yes (base class + interfaces)
Virtual / override / pure virtual Yes
Access specifiers (public/private/protected) Yes
Static members Yes
if / else Yes
while, for, do-while Yes
break / continue Yes
try / catch / throw Yes
new / delete Yes (new)
std::cout << ... chaining Yes (maps to System.Console.Write/WriteLine)
Type inference for member access Yes (via member type registry)
Conversion methods (ToString, ToInt, etc.) Yes (maps to System.Convert)
Ternary operator Yes
Arrays (new int[n]) Yes
Templates Basic (template args are mapped)
Preprocessor Minimal (skips #include, #define, #ifdef, etc.)
Pointers / references Parsed, treated as the base type in IR

The IR system (ObjectIR.Core)

ObjectIR.Core is the heart of FCC — an object-oriented intermediate representation designed from the ground up for OO languages. Think LLVM IR, but for classes, interfaces, generics, and virtual dispatch.

Full documentation lives in libs/ObjectIR.Core/docs/:

Page Description
Architecture Namespace layout, layer diagram, design decisions
Getting Started Install, first module, what to read next
IR Model Module, TypeDefinition, MethodDefinition, Instructions
Builder API Fluent IRBuilder with annotated examples
Serialization Text format, JSON/BSON, ModuleLoader
Composition Merging modules, dependency resolution
FOB Format Compact binary .fob format spec

IR at a glance

Module "TodoApp" version 1.0.0

interface IItem {
    method GetId() -> int32
    method GetDescription() -> string
}

class TodoItem : IItem {
    private field id: int32
    private field description: string

    constructor(id: int32, description: string) {
        ldarg this
        ldarg id
        stfld TodoItem.id
        ret
    }

    method GetId() -> int32 implements IItem.GetId {
        ldarg this
        ldfld TodoItem.id
        ret
    }
}

Key properties:

  • Stack-based IL (like CIL/bytecode)
  • First-class structured control flowIfInstruction, WhileInstruction, ForEachInstruction, TryInstruction as IR nodes, not raw branch targets
  • Visitor pattern for instruction passes — implement IInstructionVisitor
  • Fluent builderIRBuilder for constructing modules in C# code
  • Cross-module compositionModuleComposer merges modules, resolves dependency order, detects cycles
  • Multiple serialisation formats — human-readable text, JSON/BSON for interop, compact FOB binary for distribution

Backends & Frontends

FCC is designed as a compiler collection — one tool that can handle many languages. Support for new languages is added through two interfaces (defined in the ObjectIR.Programming library):

interface ICompilerBackend {
    void Compile(string path);               // compile one module
    void CompileAll(string path, List<string> files);  // batch compile
}

interface ICompilerFrontend {
    // (defined in ObjectIR.Programming)
}
Interface Purpose
ICompilerBackend Takes an ObjectIR module and produces target code (machine code, C#, IL, JS, etc.)
ICompilerFrontend Takes source code and produces an ObjectIR module

Because FCC has no built-in understanding of ObjectIR types, the standard library, or language-specific semantics, compiler manufacturers should use the ObjectIR.Programming library for type checking.

Note: ObjectIR.Programming is a separate repository. The type checker and type system are being developed there.

Creating a backend

  1. Implement ICompilerBackend
  2. Register it with the FCC runtime
  3. The fcc CLI will use it when generating final output

Creating a frontend

  1. Implement ICompilerFrontend
  2. Your frontend receives source text and returns an ObjectIR Module
  3. The fcc CLI dispatches to the right frontend based on file extension

Examples

The examples/ directory contains sample C++ programs:

File Description
test.cpp Hello World, get_value() call
classes.cpp Class with fields, methods, constructors
playercontroller.cpp Unity-style player controller
crystal.cpp Crystal language test
UnityEngine.h Unity engine header stub
IRRuntime.h IR runtime header stub

The repro/ directory contains regression test cases:

File Description
main.cpp Program calling get_value() from a C-linkage header
repro.h C-linkage function declaration
impl.c Implementation of get_value()
main.oir Compiled output (FOB binary)

Complete IR example

See Docs/COMPLETE_EXAMPLE.md for a full todo-list application written in ObjectIR text format, demonstrating:

  • Class hierarchies and interface implementation
  • Generic collections (List<T>)
  • Constructors with parameters
  • Conditional logic and loops
  • String operations
  • The C# Builder API equivalent
  • Backend considerations (C#, JS, C++, Java)

Building the solution

# Restore and build everything
dotnet restore FCC.sln
dotnet build FCC.sln

# Run the C++ frontend tests
dotnet test libs/CppToObjectIR.Tests

# Compile a test file
dotnet run --project fcc -- examples/test.cpp

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages