Skip to content
Derek Snider edited this page Jul 24, 2026 · 32 revisions

madc

(My Advanced Dialect of C)

C, unbound. A little mad. Just enough to be useful.

madc is a compact native programming platform: its own C/C++-based language, an embeddable compiler and JIT, and a reusable C/C++ toolkit through libmadc.

Write native code with the immediacy of a scripting language. Run it directly, build an executable, embed the compiler in another application, or bring madc's features into an ordinary C/C++ program.

All of that — substantial C and C++ support, a native JIT, embedded headers, executable generation, scripting, eval(), and a reusable runtime — fits into a self-contained binary of about 11 MB.

Validated on x86-64 Linux today. macOS and Apple Silicon support is in active development. The MIR backend also targets aarch64, ppc64le, s390x, and riscv64, making additional architectures ports rather than backend rewrites.


Native programming without the ceremony

C and C++ are powerful, but using them often requires a surprising amount of clerical knowledge before the interesting work can begin:

  • Which header declares this function?
  • Which namespace contains this type?
  • Which library must be linked?
  • How should the build system be configured?
  • Which third-party package provides an operation that is built into higher-level languages?

madc removes much of that friction without replacing native code with a VM or scripting runtime.

Common headers are embedded and can be included automatically. Familiar C++ symbols can be resolved without requiring the programmer to memorize every namespace. Modern language features and practical helpers are available when they make the code clearer.

You can still use explicit headers, namespaces, pointers, structs, classes, templates, native libraries, and ordinary C/C++ conventions whenever you want them.

Start simple. Go as deep as the experiment requires.

Why madc? →


Four ways to use madc

Use madc to... Command / API What happens
Run it madc program.mad JIT-compiles directly to native machine code and runs immediately.
Build it madc -o program program.mad Produces a standalone native Linux executable.
Embed it libmadc Hosts the madc compiler, JIT, scripting runtime, and eval() inside another C/C++ application.
Reuse it madc headers and libmadc Brings madc containers, namespaces, runtime helpers, and other features into conventional C/C++ programs.

Compiled objects are cached, so repeat runs can skip unnecessary recompilation.

Getting Started →
Native Executables →
Embedding Guide →


A language, a compiler, and a library

The madc language

madc is its own evolving dialect of C and C++.

At its foundation are real native types, pointers, structs, functions, headers, preprocessing, linking, classes, templates, exceptions, and direct libc/libstdc++ interoperability.

On top of that foundation, madc adds features intended to make native programming more immediate and expressive:

  • script mode and top-level statements
  • automatic header inclusion
  • automatic namespace resolution
  • defer
  • := type inference
  • multiple return values
  • range-based for
  • lambdas and function pointers
  • embedded standard and POSIX headers
  • familiar containers and stream types
  • helpers inspired by PHP, Perl, Python, Ruby, JavaScript, and Rust

Use ordinary C or C++ when that is the clearest solution. Use madc's extensions when they remove noise or express the idea better.

The compiler and JIT

madc compiles C-family source directly to native machine code through MIR.

It can:

  • execute source immediately through the JIT
  • generate standalone native executables
  • run files as scripts, including shebang-based scripts
  • evaluate expressions dynamically
  • load native shared libraries with #load
  • cache compiled objects
  • emit standard C source for conventional C toolchains
  • build multi-file projects from compile_commands.json

There is no bytecode VM and no separate scripting runtime between the program and the machine.

The libmadc toolkit

libmadc works in both directions.

You can embed madc inside another application:

#include <libmadc/api.h>

madc::program pgm;
pgm.exec_file("script.mad");

int64_t result;
pgm.eval("2 + 2", result);

Or you can use madc's features from an otherwise conventional C++ program:

#include <libmadc/namespaces.h>

std::string csv = "alice,bob,charlie";
madc::array names;

php::explode(names, ",", csv);
php::sort(names);

This makes madc more than a command-line compiler: it is also an embeddable native-code engine and a reusable C/C++ library.


A surprising amount of C++ in about 11 MB

There are many C compilers, but relatively few independent C++ compilers and very few C++-capable JIT environments.

madc packages substantial C and C++ support into a compact, self-contained tool:

  • classes and methods
  • multiple and virtual inheritance
  • virtual functions
  • Itanium ABI support
  • RTTI and dynamic_cast
  • operator overloading, including <=>
  • templates with real instantiation
  • exceptions
  • references and RAII
  • lambdas
  • direct libstdc++ interoperability
  • cout, cin, cerr
  • string, stringstream
  • vector<T>, map<K,V>, set<T>

It also embeds compressed C and C++ headers, its compiler frontend, native-code generation, runtime support, executable generation, and the libmadc API.

The result is intended to be small enough to keep nearby, capable enough to be interesting, and open enough to become part of another program.

C++ Support →


Familiar conveniences, compiled natively

Moving from PHP, Perl, Python, Ruby, or JavaScript to C++ often means giving up concise, familiar operations and searching for replacement libraries.

madc brings many of those useful idioms into native C/C++ through optional language-inspired namespaces:

  • php::explode(), php::implode(), php::sort()
  • perl::grep(), perl::chomp(), perl::split()
  • python::title(), python::ljust(), python::format()
  • ruby::squeeze(), ruby::tr(), ruby::chars()
  • js::btoa(), js::encodeURIComponent()
  • rust::trim(), rust::contains(), rust::split()

These are native functions, not calls into PHP, Python, Ruby, JavaScript, or another language runtime.

They are available inside madc programs and through libmadc in conventional C++ applications.

#include <iostream>

int main()
{
    std::string csv = "alice,bob,charlie";
    std::string delim = ",";

    madc::array names;

    php::explode(names, delim, csv);
    php::sort(names);

    std::string sorted;
    php::implode(sorted, delim, names);

    std::cout << sorted << std::endl;

    std::string title = "hello world";
    python::title(title);
    std::cout << title << std::endl;

    return 0;
}

No additional language runtime is required. No package needs to be installed for these built-in helpers.

Language Namespaces →
Namespace Reference →


Native code as a place to experiment

madc is built for programmers who like to tinker:

  • write a small native utility without creating a project
  • explore C or C++ without beginning with build-system configuration
  • prototype systems code quickly
  • call libc, libstdc++, POSIX APIs, or native shared libraries directly
  • add scripting or runtime compilation to an existing application
  • experiment with language design and modern C extensions
  • begin with a short script and grow it into a native executable
  • use a compact compiler as part of another tool

madc does not hide the machine. It makes the path to it shorter.


C and C++ compatibility

madc is a real native compiler, not a C-shaped interpreter.

It supports ordinary C programs end-to-end, including pointers, arrays, structs, functions, headers, preprocessing, native linking, and direct libc use.

C compatibility is tracked against the GCC torture suite. The current result is 1614/1685, with zero remaining standard-C failures; the remaining failures are GNU extensions on the roadmap.

C23 coverage is expanding alongside continued C++ development.

GCC Compatibility →
C23 Features →


Feature overview

  • Native JIT compilation through MIR
  • Standalone Linux ELF executable generation
  • DWARF debugging information with -g
  • Standard C source output with --emit=c11
  • Script mode, including top-level statements and shebang support
  • Compiled-object caching
  • Direct libc and libstdc++ interoperability
  • More than 40 embedded standard and POSIX headers
  • Automatic header inclusion
  • Automatic namespace resolution
  • Substantial C++ support
  • Modern madc language extensions
  • Expanding C23 support
  • Preprocessor support, including #load "libfoo.so"
  • More than 100 language-inspired helper functions
  • Embeddable libmadc API with C++ support and C shims
  • Reusable native runtime and helper library
  • Multi-file project support
  • No runtime dependency beyond libc for the core compiler

Current platform status

madc is under active development.

Today, the MIR version is validated on x86-64 Linux. Native Linux ELF generation is available now.

macOS and Apple Silicon support are in active development.

The MIR backend also supports:

  • aarch64
  • ppc64le
  • s390x
  • riscv64

Those backend targets do not make every platform immediately supported, but they allow new MadC platforms to be implemented as ports rather than complete code-generation rewrites.

Windows is not currently supported.

See the Changelog for current release information.


What madc is not

madc is not trying to replace GCC or Clang for every production build.

Use a mature conventional toolchain when you need maximum standards coverage, established diagnostics, broad platform support, and decades of production hardening.

Use madc when you want native C/C++ to be immediate, embeddable, exploratory, and unusually compact:

madc program.mad

madc also does not run PHP, Python, Perl, Ruby, JavaScript, or Rust code. It borrows useful vocabulary and ideas from those languages while compiling through its own native C-family toolchain.


Explore the wiki

Getting Started

Language Guide

  • Data Types — integers, floats, strings, arrays, and containers
  • Control Flowif, for, while, switch, and rust::match
  • Functions — declarations, multiple returns, function pointers, and lambdas
  • Structs & Classes — user-defined types, methods, and member access
  • C++ Support — inheritance, templates, exceptions, operators, and libstdc++ interop
  • Strings & I/O — strings, streams, and file I/O
  • Pointers & Arrays — pointers, fixed arrays, and subscripts
  • Modern Featuresdefer, range-for, :=, auto, and more

Language Namespaces

Namespace Focus
php:: String manipulation and array operations
perl:: Chop/chomp, regex grep, split, and join
python:: Title case, alignment, and formatting
ruby:: Squeeze, transliteration, chars, and rotation
js:: Base64, URL encoding, and JSON
rust:: Trim, contains, replace, split, and join

Advanced Topics

Reference


Acknowledgments

madc's code generation is built on MIR by Vladimir Makarov, a lightweight JIT compiler infrastructure whose c2mir C frontend madc's IR feeds directly. madc uses its own MIR fork, released in lockstep with madc; see the repository's MIR_VERSION.

madc's original backend was built on asmjit by Petr Kobalicek, which powered the project through its first year.

madc's unit tests use doctest by Viktor Kirilov, a fast single-header C++ testing framework shipped in-tree.


A C/C++ language, a native compiler and JIT, and a reusable toolkit — compact enough to carry anywhere and open enough to make your own.

C, unbound.

GitHub Repository · Report an Issue · License: MPL 2.0

Clone this wiki locally