Skip to content
Derek Snider edited this page May 19, 2026 · 32 revisions

C, unbound.

madc is real C with the workflow of a scripting language.

Write C. Run it like a script. Ship it as a native Linux ELF executable. Embed it as a runtime. Or bring madc's built-in features directly into your own C/C++ programs.

No Makefile. No toolchain ceremony. No VM. No bytecode. No fake runtime.

madc compiles C-family source directly to native x86-64 machine code, uses libc directly, caches compiled objects, and can produce real Linux binaries.


How you use it

Use madc to... Command / API What happens
Run it madc program.mad JIT-compiles directly to x86-64 machine code and runs immediately. No bytecode, no interpreter.
Ship it madc -o program program.mad Generates a native Linux ELF executable. Real binaries, real performance.
Embed it libmadc Host madc as a compiler, JIT, and runtime inside your own C/C++ application.
Reuse it madc headers, namespaces, and runtime helpers Bring madc features directly into your own native C/C++ programs.

Compiled objects are cached, so the first run is fast and repeat runs can skip unnecessary recompilation.

Getting Started →
Native Executables →
Embedding Guide →


Real C, not fake C

madc is not a C-flavoured scripting language, bytecode VM, or toy interpreter.

It compiles to real native x86-64 machine code. It uses libc directly. It supports ordinary C-style programs, pointers, structs, functions, headers, preprocessor directives, and native linking.

madc is still growing toward fuller modern C compatibility, including broader C23 coverage, but standards completeness is not what makes something "real C."

K&R C was real C. ANSI C was real C. Embedded C compilers are real C. TinyCC is real C.

madc belongs on that spectrum:

real C at the core, extended where useful, and improving rapidly.


Why madc?

Zero ceremony

No Makefile. No include paths to configure. No separate compile step.

madc file.mad

One file. One command. Native execution.

Real C, plus more

madc starts with familiar C syntax and real native code generation, then adds practical conveniences where they help:

  • cout, cin, cerr
  • string, stringstream
  • vector<T>, map<K,V>, set<T>
  • classes with methods
  • lambdas
  • defer
  • multiple return values
  • := type inference
  • range-based for
  • function pointers
  • embedded standard headers

Use ordinary C when you want it. Reach for modern conveniences when they make the program clearer.

Multi-language namespaces

madc includes useful functions inspired by PHP, Perl, Python, Ruby, JavaScript, and Rust.

Examples:

  • php::explode()
  • perl::grep()
  • python::title()
  • ruby::squeeze()
  • js::btoa()
  • rust::trim()

C gives you control. Scripting languages give you convenience.

madc is designed to give you both.

Embed it

madc is not only a command-line compiler. You can embed libmadc inside your own C/C++ applications — host a full C-family compiler, JIT, and runtime, or evaluate expressions on the fly:

#include <libmadc/api.h>

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

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

Reuse it

Use madc's 100+ namespace functions directly in your own C/C++ code — php::explode(), perl::grep(), python::title(), and more, without going through a scripting layer:

#include <libmadc/namespaces.h>

std::string csv = "alice,bob,charlie";
madc::array names;
php::explode(names, ",", csv);
php::sort(names);

That makes madc both a compiler and a native C/C++ toolkit.

Not a toy

madc is aimed at real C compatibility, native execution, and practical systems-level use.

It is not pretending to be C. It is a real compiler that emits native machine code, uses libc directly, and can compile real C codebases end-to-end.

madc was created by a programmer with 40+ years of experience in C, C++, assembly, and systems development. Read the backstory →


See it in action

Your C code just works:

#include <stdio.h>

int main() {
    printf("hello, world\n");
    return 0;
}

Run it directly:

$ madc hello.mad
hello, world

Or build a native executable:

$ madc -o hello hello.mad
$ ./hello
hello, world

Now mix in the best of other languages:

#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;

    madc::array matches;
    std::string pat = "^a";
    perl::grep(matches, pat, names);

    std::string s = "aabbccdd";
    ruby::squeeze(s);
    std::cout << s << std::endl;

    std::string encoded;
    js::btoa(encoded, s);
    std::cout << encoded << std::endl;

    return 0;
}

No imports to install. No package manager. It is all built in.


Features

  • JIT compilation to x86-64 via asmjit — runs at native speed
  • Native executable generation — produce standalone Linux ELF binaries
  • OBJ caching — compiled objects are cached; repeat runs skip recompilation
  • Direct libc usage
  • 40+ embedded headers — <stdio.h>, <stdlib.h>, <math.h>, <string.h>, <unistd.h>, and more
  • C++ support — cout/cin/cerr, string, stringstream, vector<T>, map<K,V>, set<T>, classes with methods
  • Modern features — lambdas, defer, multiple return values, := inference, range-based for, function pointers
  • 100+ namespace functions across 6 language namespaces
  • C23 early coverage — _Bool, 0b binary literals, static_assert, typeof, nullptr, digit separators
  • Preprocessor — #define, #ifdef, #include, #pragma, plus #load "libfoo.so" for dynamic libraries
  • Embeddable libmadc API with C++ support and C shims
  • Reusable runtime helpers for native C/C++ programs
  • Self-contained — no external dependencies at runtime beyond libc

Who is madc for?

madc is for developers who like C, but want a faster workflow.

Use it when you want to:

  • write small native utilities without setting up a project
  • prototype systems code quickly
  • build C programs that run with script-like immediacy
  • ship a native Linux executable
  • embed a C-family compiler, JIT, and runtime inside a C/C++ application
  • reuse madc's helper namespaces and runtime features directly in native C/C++ programs
  • use familiar helpers from PHP, Python, Perl, Ruby, JavaScript, and Rust
  • experiment with modern C extensions without leaving native code behind

What madc is not

madc is not trying to replace GCC, Clang, or every production C toolchain.

Use GCC or Clang when you need mature, battle-tested, fully standards-focused compilation across large production codebases and many platforms.

Use madc when you want C with immediacy:

madc program.mad

madc is also not Python, Lua, JavaScript, or a scripting VM.

It borrows the convenience of scripting workflows, but the result is native code.


Explore the wiki

Getting Started

Language Guide

Namespaces

  • Namespaces — how multi-language namespaces work
Namespace Focus
php:: String manipulation, array operations
perl:: chop/chomp, regex grep, split/join
python:: Title case, alignment, format
ruby:: squeeze, tr, chars, rotate
js:: Base64, URL encoding, JSON
rust:: trim, contains, replace, split/join

Advanced Topics

Reference


Current status

Current release: v0.17.0

madc is under active development.

The goal is simple:

real C, native code, script-like workflow, modern convenience.

C, unbound.


GitHub Repository · Report an Issue · License: MPL 2.0

Clone this wiki locally