Skip to content

v0.95.0 — the ui:: namespace + Colossal Cave Adventure fully playable

Choose a tag to compare

@derekbsnider derekbsnider released this 23 Aug 05:59
· 7 commits to master since this release

Downloads: all six platform binaries for the v0.95 line are attached to v0.95.2.

madc v0.95.0

madc plays Colossal Cave Adventure. This release introduces the
ui:: data-hub namespace and proves it with a complete, fully playable
port of the classic game — a pure madc multi-file project whose output
is byte-identical to the original C open-adventure across all 94
reference transcripts — while the compiler itself got dramatically
faster to start and floating-point code got dramatically faster to run.
Everything since v0.92.1 (v0.93.0, v0.94.0, and v0.95.0) ships in the
attached packages for Linux (.deb/.rpm), Windows, and macOS
(Apple Silicon + Intel).

Features

  • The ui:: namespace — worlds, projections, verbs, and prompts
    (documented in docs/language/ns-ui.md). A madc program opens a
    world file, reads and writes entity state through one hub-managed
    write path, renders text projections where projection selection IS
    the access decision, and dispatches verbs:
    long w = ui::world_open("adventure.world");
    ui::act(out, w, player, "take", "lamp");
    Interaction is one verb too: ui::prompt(line, "> ") writes the
    prompt, flushes, and reads — piped transcripts read exactly like
    interactive sessions, which is how the game's logs stay
    byte-identical while a terminal player finally sees the > prompt.
  • Colossal Cave Adventure, in madc, fully playable
    examples/adventure/: 11 translation units built as one project
    (madc advent.cc.json), all state on a single class Game object,
    4447 lines against the reference's 4681 C lines. The 94-transcript
    parity corpus is a permanent test gate, so the game cannot silently
    regress.
  • Write madc with zero ceremony — no #include, no using, no
    std::: bare print/println/format (including
    println(stderr, ...)), madc::getline(line) for input, quoted user
    modules auto-included, and array literals with a chainable push:
    var ds = { a, b, c }; ds.push(d);
  • The compiler starts in the ~150 ms class on a real 11-file
    project
    (was 829 ms packed at the start of the arc; the dev binary
    fell from 1.9 s to ~0.3 s). The levers: auto-include that no longer
    matches std names in impossible positions, lazy first-call codegen,
    one shared compile substrate and shared prelude images across a
    project's translation units, lazy template hydration (a C-shaped
    launch never decodes the 6.4 MB template payload), a de-RTTI'd hot
    front end, and page-arena allocation in c2mir.
  • Floating-point code runs ~2.8× faster — donut.c now beats
    gcc -O0
    (v0.93.0): MIR's scalar SSE converts carried a false
    dependency that serialized call-heavy FP loops; the fix is the same
    pxor dependency-breaking idiom gcc and clang emit.
  • Every polyglot function has a lean primary form — the 57
    PHP/Python/Perl/Ruby/JS/Rust functions that only accepted
    std::string now take value/char* directly with the source
    language's real semantics (perl::chop mutates — that IS Perl;
    PHP string functions return new strings).
  • Sturdier codegen, from the community (v0.94.0): a wrong-code
    -O2/-O3 ssa_combine loop-PHI fold fixed (reported with reducers
    by ThePeiLin, upstream mir#467 — our fix, submitted upstream),
    the register-allocator spill-table bound adopted from
    Bill Hlavacek (upstream PR #468), and the aarch64 displacement
    gate adopted from Richard Davison (upstream PR #466) — the last
    directly speeding madc's Apple Silicon lane.

Fixes and internals (compact)

  • Cross-TU correctness under --project, each with a pinned test:
    every TU's global initializers now run (was: last module won);
    extern var no longer creates a private per-TU copy; file-scope
    member defaults (NSDMI) apply; --no-embedded-headers reaches
    project TUs (a new fulltest gate covers the whole CLI policy-fanout
    family).
  • A call with no viable overload refuses loudly instead of silently
    binding the wrong function; carrier subscripts are true lvalues over
    the element slot (arr[i] = x writes land); frozen-value container
    mutations degrade to a diagnostic instead of aborting.
  • Duplication audit at the merge wave: one MEMBER param-table decoder,
    forest decode accounting restored, the last zero-filling decode
    destinations converted, remaining families recorded with markers.
  • Build-infrastructure hardening: the container build config no longer
    crosses the sync tunnel (two masked staleness traps closed), and
    bin/madc-release — the profiling vehicle — is rebuilt as a standing
    lane of every merge wave.

See CHANGELOG.md for the complete per-release
record (v0.93.0, v0.94.0, v0.95.0).