Skip to content

v0.98.0 — the macOS full-suite release

Choose a tag to compare

@github-actions github-actions released this 06 Sep 00:29
· 796 commits to master since this release

madc v0.98.0

madc now builds, tests and ships itself on macOS — and it has an IDE.
Since v0.95.2 the compiler grew a JOE-flavoured terminal IDE that IS the
running compiler, cooperative multitasking in the dialect (go,
channels, scope, await), a complete literal story for the var
carrier, a C++ front-end conformance wave driven by running the whole
suite on Apple Silicon and Intel Macs, an aarch64 backend at parity with
x86-64 (SIMD included), and a packaged install shape whose six release
assets are all built by CI. Everything since v0.95.2 (v0.96.0, v0.97.0
and v0.98.0 — 601 commits, 181 new integration tests, the Linux suite
1134 → 1308) ships in the attached packages for Linux (.deb / .rpm /
relocatable tarball), Windows x86-64 (zip), and macOS (Apple Silicon +
Intel tarballs).

Features

  • madcide — the madc IDE, shipped in the packages. A terminal editor
    with JOE's WordStar chords by default (^K O split, ^K E open,
    ^K B/K/C/M/Y blocks, ^K H help projected from the loaded profile)
    and a full vi modal personality (profiles/neovim.keys: @normal /
    @insert tables, counts, 2dd, :w :q :e) — every key binding is
    profile DATA through one parser, switched live from the ^N modes
    palette. ^P project palette (quick-open rides its filter), ^F
    find, ^B build palette, ^T
    options (tab width, colour scheme, keymap), ^K A cycles read-only
    views of the buffer as original → MC11 → C11 → C++. Syntax colour
    lands on the
    first paint from the lexer alone; the parse runs as a go task so
    typing stays live while a C++ TU compiles; the diagnostics and outline
    panes are projections of compiler data. The running madc IS the
    compiler
    : Build compiles the SCREEN (unsaved edits included) through
    the buffer's live parse handle, Run forks that parse — nothing ever
    shells out to a madc on PATH. The packages install madcide (Linux
    /usr/bin/madcide, the Windows zip's madcide.exe), compiled by the
    just-built release compiler; the mac tarball follows once the darwin
    runtime dylib exists.
  • Cooperative multitasking in the dialect (docs/language/tasks.md):
    go f(args); spawns a task, yield() reschedules, main's return
    joins every live task; value channels with Go's contract
    (madc::chan_make(cap) / chan_send / chan_recv / chan_close),
    deterministic fan-in (madc::chan_select), madc::sleep_ms on a
    pluggable time source (virtual under MADC_TASK_VTIME=1), byte
    endpoints waitable beside channels (madc::chan_readable), and
    Kotlin-shaped structure: scope { go a(); go b(); } joins its members
    and rethrows the first error, scope_cancel lands cooperatively at
    the blocking verbs, and await ch is Go's <-ch as a keyword:
    long ch = madc::chan_make(1); go produce(ch); v = await ch;
    Scheduling is strict FIFO on one OS thread — deterministic by
    construction, and the stated thread-safety contract. Exception state
    is per task; parking the last runnable flow aborts with a message
    instead of hanging.
  • The var carrier's literal story is complete. Keyed literals,
    PHP's empty-[] append, brace literals as expressions, and subscripts
    that dispatch on a var index's LIVE kind — all through the same
    registered operator= rows, so the spellings cannot drift:
    var m = { "a": 1, "b": "two" };
    rows[] = { "act": "colon" }; rows.push({ "k": v });
    m[kn] keys when kn holds a string, indexes when it holds a number.
    Carrier readers are const, the kind predicates are complete
    (is_booleanis_instance, data()), and cout << value works
    whatever stdlib flavor the script compiles against.
  • Compiler data as data — the IDE gateway API. Persistent parse
    handles (madc::parse_open / parse_refresh / parse_check /
    parse_outline / parse_enclosing / parse_spans / parse_close),
    madc::lex_spans for millisecond colouring, madc::diagnostics and
    madc::outline as structured rows, madc::parse_build /
    parse_run for the live-parse build and run, madc::emit(out, src, file, "c++") — and the parser is now error-tolerant: every top-level
    error is reported (gcc's shape), and the tree, outline and spans stay
    alive around a broken region. madc --emit=c++ reverse-renders a TU
    from its retained tokens; the render recompiles byte-identically under
    g++ and clang++.
  • C++ conformance — the wave the Mac runners drove. Running the full
    suite on GitHub's arm64 and Intel mac runners (202 arm64 failures on
    the first run; 1293/0/0TO/24skip / 1294/0/0TO/23skip at this release)
    exposed what libc++'s spelling
    of the standard library asks of a front end; each fix is named by its
    clause and holds on every platform:
    namespace fs = std::filesystem; ([namespace.alias]) and fs::path
    after using namespace lib; ([namespace.udir]/2); nested classes
    declared, then defined out of line — struct path::_Cmpt : path {};,
    P::I &P::I::next() {}, sizeof(O::N); B::x inside a method is the
    member of *this; a < opens a template-argument-list by NAME LOOKUP
    ([temp.names]/3); deduction from two arguments must agree; a
    SFINAE-constrained constructor is a candidate only when its constraint
    holds (std::string s(20, 'x')); dependent non-type defaults fold so
    the right partial specialization is chosen; a template-id named as a
    template ARGUMENT instantiates after the enclosing class completes
    ([temp.inst]/1 — std::list under libc++, and a dependent member
    template-id is one placeholder per argument list, the frozen-pack half of the
    same fix); B d(std::move(a)) picks
    the move constructor and return local; moves ([class.copy.elision]);
    hidden-friend operator templates (cout << setw(5) on libc++); a
    member template hides a same-named global; access control judged by
    the member a lambda is written in; wchar_t / char16_t / char32_t
    distinct types, long double and __int128 their own identities,
    std::cout << char_array and std::wcout << L"x" print text.
  • The Itanium class-call ABI. A class "non-trivial for the purposes
    of calls" is passed by INVISIBLE REFERENCE — the caller constructs the
    parameter object and destroys it — and returned through the hidden
    result pointer; a trivially copyable class travels as a plain struct
    both ways. void f(D d) had received a bitwise image (f 1 where g++
    prints f 101 then ~101), s += s on a by-value std::string freed
    the caller's buffer, and a class with user copy/move constructors
    returned its bytes. A by-value class now crosses to and from
    g++/clang-compiled code correctly in both directions.
  • madc compiles and runs its own C++ embedding example
    bin/madc examples/embed_hello.cpp at g++ parity (variadic class
    templates with mixed fixed+pack heads, class-pack sizeof...,
    explicit constructors modeled, member templates deduced from
    function pointers), and the libmadc host surface is hardened:
    constructing a madc::engine no longer hijacks the host's iostreams,
    host callbacks reach eval_expression, install-libmadc ships every
    header the API includes.
  • C, complete and honest. c-testsuite 220/220 in --std=gnu11
    (C11 _Generic, #line, ## placemarkers, block-scope struct tag
    shadowing, the full C declarator family, the enum TAG namespace,
    flexible-array initialization, pointee-const identity); the real
    SMAUG 1.8 (51 TUs via compile_commands.json) boots again — a
    SIGSEGV that shipped in every release since v0.69.0, now gated in
    fulltest; an undeclared variadic libc call in a zero-include script
    adopts the library's REAL prototype (K&R printf() printed addresses
    on Apple arm64); C23 _FloatN literal suffixes; the GNU vector
    extension as gcc has it ((a + b)[2], opaque signed-lane
    comparisons, v8hu << n); static functions get C internal linkage;
    madc -w inhibits warnings.
  • Platforms. madc builds natively on a Mac (DARWIN_HOST posture:
    brew llvm@18, Apple ld64, xcrun SDK), freezes its own darwin groves,
    and runs the full suite there — .darwin_skip / .darwin-<arch>_expect
    fixtures state the few legitimate differences (long double is
    double on Apple arm64; va_list is a char *; int64_t is long long) — the target's facts come from the compiler that builds madc
    for it, never a baked constant. The MIR aarch64 backend reaches x86-64
    parity: __int128 in x0:x1, _Complex as an HFA, 128-bit vectors
    as Q registers with NEON arithmetic, compares and shifts; the vector
    and stack-argument calling conventions are byte-identical to gcc,
    Apple clang and mingw-gcc on x86-64, aarch64-linux and Apple
    (vector_abi_gate.sh, one side compiled by the platform compiler;
    Apple's sub-8-byte stack packing; win64's by-reference vectors; plain
    char unsigned on aarch64-linux). win64 rides MIR's lazy first-call
    codegen again (two stock-upstream wrapper defects fixed).
  • The packaged install shape. Plain ./configure builds a thin
    madc CLI over libmadc.so.0, which carries the frozen standard-
    library forest (measured: +0.4 ms cold start for a 150 KB CLI); the
    monolithic binary stays an option (--disable-shared). The C ABI is
    classified and gated — C ABI stable, C++ version-locked (ADR
    0003); Linux gains a relocatable tarball; the Windows engine is
    libmadc-0.dll; install-then-run gates execute the SHIPPED bytes of
    every artifact; release.yml builds and attaches all six assets on a
    master tag, the two macOS tarballs natively on GitHub's mac runners.
  • From the community. Two c2mir defects reported with reducers by
    aardappel (upstream vnmakarov/mir#472 — a file-scope extern
    with an initializer is a definition; mir#473 — members of an
    anonymous union carry the union's alias class, the Lobster Value
    type) are fixed in madc's in-tree MIR; the upstream PRs follow this
    master release.

Platform lanes at this release

Lane Result
Linux JIT / EXE / OBJ (fulltest, every gate) 1308/0/9skip · 1249/0 · 1249/0
Linux packed (bin/madc-release) / headerless 1308/0/9skip · 1274/0/43skip
Linux -stdlib=libc++ flavor JIT / EXE / OBJ 1303/0/14skip · 1244/0 · 1244/0
wine64 packed suite (hosted PE) 1251/0/0TO/66skip
c-testsuite (--std=gnu11) 220/220, baseline empty
darwin full suite — arm64 / Intel mac runners 1293/0/0TO/24skip · 1294/0/0TO/23skip
Owner M-series Mac 1293/0/0TO/24skip
Genuine Windows 1253/0/0TO/64skip

Every lane above is a RELEASE-tier gate now (owner law 2026-09-04:
lane_ledger.sh check --release blocks a master push until each has
run green on the promoted content).

Fixes and internals (compact)

  • Silent wrong answers closed, each with an oracle reducer: char[] at
    the format boundary printed a garbage byte; &x over a reference
    typed one pointer level too deep; a constructor initializer storing a
    derived pointer into a base member skipped the upcast; template<> struct N<int*> was invisible; B::x read as 0; a T&& constructor
    lost to the copy; (ua == ub)[0] widened to 4294967295; K<long double> shared K<double>'s instantiation; perl::substr past the
    end aborted the process where Perl yields undef; carrier text returned
    from a function read freed memory.
  • Forest (the frozen standard-library store): a rebound ranked
    constructor stamps its __oN symbol (a by-value return of a struct
    with a std::vector member had failed under every packed binary since
    at least v0.95.2); a missing-content husk re-includes by canonical
    path; an incomplete husk completes on demand; a restored polymorphic
    class refills its secondary vptr owners and vtable slots; friendship
    grants freeze; the embedded stddef.h defines NULL unconditionally;
    a GNU asm label is the forest's link symbol (Apple's stat$INODE64).
  • MIR / c2mir: the win64 lazy-wrapper immediate offsets (the v0.95.1
    crash) and its stack alignment; a NULL context barrier is not an
    owning declaration (nested compound literals); default-level warnings
    match gcc's; MIR_val_t stride in the ff_call shims; the Apple
    interp shim's stack FP offset encoding; 16-byte-aligned stack slots on
    x86-64; the aarch64 fixes above. Upstream-PR candidates are held for
    owner review after this release.
  • Process and gates: platform lanes run BEFORE the tag (v0.95.2) and
    every lane's full suite gates master (v0.98.0); MADC_FAIL_DETAIL puts
    the diagnosis in the runner log; fixture domains (.darwin_skip,
    .<domain>_expect) instead of per-test branches; one-owner gates
    added at every merge wave's duplication audit (clone_origin, the
    delimiter tracker with the Program handle, scalar deduction, C-ABI
    surface, select_fire, push_buffer_row, the subject-document rule)
    — each with a negative control.
  • Documentation: docs/language/tasks.md, docs/adr/0003-c-abi-stance.md,
    docs/man/madcide.1 + docs/examples/madc.ini, and the plan records
    for the darwin-host port, the aarch64 SIMD arc, Apple stack-argument
    packing, the packaging arc, and the planned g++-testsuite conformance
    lane (a roadmap metric, never a release gate).

See CHANGELOG.md for the complete per-release
record (v0.96.0, v0.97.0, v0.98.0) and docs/release-notes/ for the
per-release stories.