madc v0.99.2
madcide is a desktop application — on Linux, Windows and macOS. Since
v0.98.0 the IDE that IS the running compiler gained a window: the same
editor, the same commands and the same key profiles as the terminal, now
inside native application chrome with a menu bar, file dialogs, editor
tabs, a Problems / Output / Terminal panel, dialogs, a status bar, and a
program's output streaming into an embedded terminal as it runs. The
language grew import (C++20's import made whole: the interface AND the
library, no platform spelling), a machine-readable capability manifest,
and the ui:: web target the window is built on. Everything since v0.98.0
(v0.99.0, v0.99.1 and v0.99.2 — 213 madc commits, 44 new integration
tests, the Linux suite 1308 → 1335, a new 17-test GUI stage under Xvfb)
ships in the attached packages for Linux (.deb / .rpm / relocatable
tarball), Windows x86-64 (zip), and macOS (Apple Silicon + Intel tarballs),
each with the platform webview library beside the binaries.
Features
- madcide in a window:
madcide file.mad --gui. A native window on
Windows (WebView2), macOS (WKWebView) and Linux (WebKitGTK 6 / GTK 4)
with the platform's own menu bar and Open / Save As dialogs on all three,
arranged as the workbench an IDE user expects: editor tabs over the
open buffers (*while modified; a click switches), the bottom panel
(View → Toggle Panel) with Problems (the diagnostics; a click goes to
the line), Output (the build stream) and Terminal tabs, a
sidebar, and a status bar rendered as chrome (file name, row and
column, the modified badge, the pending chord, the enclosing function).
The Build, Project, Options, Modes and Help panes are titled dialogs
with the rows as pick targets and buttons named after what the pane's
keys do; the bottom-line prompts (find, go to line, file names) are quick
inputs and the quit question a confirm dialog. The^K Osplit renders
as JOE's window stack, the mouse places the caret and drags a selection,
a click picks the window, and the panel and sidebar resize by
dragging their edge (double-click maximizes the panel). ONE composer and
ONE client loop serve the terminal and the window — the terminal is
byte-identical, and every menu item, tab and button is the same command
a profile key runs. - Build and Run inside the window. Build → Run runs the live parse
forked (nothing execs) with no overlay; a console program runs on a
real pseudo-terminal in the Terminal tab — prompts flush, what you type
reaches it,^]hands the keyboard back — and a gui program opens its
own window while its output streams into Output. Every stream ends with
the program's exit status, and the output appears as it happens, with
no keystroke: the window's wait is the cooperative scheduler's bounded
wait, as the terminal's always was. A failed check or build opens
Problems; the Build menu lists every^Brow (Check, Build, Run, Run
native, Stop, the project's rows and a manifest's own commands). - Projects in the window. File → Open Project… loads a manifest through
the native open dialog; the manifest's"kind": "console" | "gui"(the
^TOptions row toggles and persists it) routes Run and stamps the
Windows executable's subsystem — a gui program starts without a console
window, as-mwindowsdoes for a single file on the CLI. - One colour scheme for both faces. The window renders the terminal's
.themestyles (keyword bold,string cyan) over a sixteen-colour
palette, bold-as-bright; a theme's@guisection sets the palette and
the chrome colours (@gui pal-cyan #56b6c2,@gui accent #7aa2f7).
^K Tswaps the scheme in both. - Menus and commands are data.
profiles/default.menuis the one
command registry and menu map (VS Code's contribution shape on the action
vocabulary the key profiles bind,[when]clauses against the live
context); the engine resolves each command's bound chord and shows it
beside the item. Commands take arguments (a tab postsbufsel <index>;
the palette's Switch to Buffer… prompts for a name). import name [as ns];— C++20'simportmade whole. One line binds
a module's interface AND its library, with no platform spelling in the
source, on the JIT and in native artifacts alike:
import m;tokenizes<math.h>and binds libm;import c as libc;
binds the C runtime under a namespace whose members resolve by name at
first call;import <stdio.h>;/import "h";are the header-unit
spellings. The module map names the real runtime image per target OS
(libc.so.6,libSystem.B.dylib,ucrtbase.dll), and-l<name>
resolves through it too. Alias-form members lower to a runtime-resolved
indirect call in EVERY lane, so a.ofrom a TU with module imports
records its module list andmadc file.oopens them before load
(docs/language/import.md).madc --capabilities=json— the machine-readable capability
manifest (the--std=table, targets, features), gated against the
binary. Reworked from PR #7 with credit to its author.- The
ui::web target.ui::open(ui_web::target())shows the same
value tree the terminal target renders in a window through the platform
webview (import madcwebview, a lazy module row: a machine without the
library refuses at open with the reason), and returns the same semantic
events;ui::register_hostlets a script host its own target. The web
editor is incremental (a keystroke moves work proportional to what
changed — the wire dropped from ~296 KB to ~700 B per keystroke); the ui
event vocabularies (ui::key,ui::event_kind,ui::pointer_phase) are
enums the compiler checks (docs/language/ns-ui.md). - Resource guards default off (owner ruling): madc arms no memory or
CPU guard unlessMADC_MEM_LIMIT/MADC_CPU_LIMITor themadc.ini
keys ask (off|auto|<N>); the test runner asks forauto, and
a program that imports a GUI module lifts the soft memory limit. extern "C"inside a namespace keeps the C name ([dcl.link]/6):
namespace sys { extern "C" int puts(const char *); }+sys::puts(...)
binds libc'sputs, in the JIT and natively.
Packaging
- The platform webview library ships in every package —
bin\madcwebview.dll
besidemadc.exe,lib/libmadcwebview.dylibbesidebin/madc,
lib/libmadcwebview.soin the Linux tarball and the deb/rpm libdir as a
WEAK dependency (Recommendson the WebKitGTK 6.0 / GTK 4 runtimes): madc
never loads it, only a program that imports it does. The webview/webview
MIT notice ships beside it. - All six release assets (Linux deb / rpm / tarball, the Windows zip, the two
macOS tarballs) are built by CI from the tag and gated by the install
smokes; the macOS tarballs are built natively on GitHub's arm64 and Intel
mac runners.
Fixes, internals and process
- Carrier fixes found on the way (each at its layer, each with a
reducer):var &r = o["h"]binds the live slot;6 == v/v == E::z
compare by value (the reversed equality candidate);c ? v : php::trim(p)
is a value prvalue materialized into a temp; avar &in a%sposition
coerces like avar. - Auto-include and resolution fixes: the declaration-head guard no
longer treatsconst/static/externas declaring the next word;
static ns::T xresolves through the declared-type resolver; a
namespace-qualified type is a C-style cast target; a dialect fragment's
ownprintln/stderrmentions pull their providers before tokenizing;
every route to a module-bound namespace member goes through one lookup
owner (a statement-positionlibc::puts("x");used to link only by
accident on the JIT). - The window's wait is the scheduler's wait: a new optional host op,
tick(a one-shot UI-thread timer on GTK, Cocoa and Win32), lets the
engine drive cooperative tasks while the window blocks; a GUI feature
exercised only headlessly had hidden the hole — the GUI test now waits
for the engine's wake with no input. - The page: a keyed element re-used for a different kind of node wipes
the old kind's furniture (a closed dialog no longer lingers in the panel);
GTK's cairo renderer is the default over a remote X display (the GL
renderer painted black over a no-shared-memory TCP connection); the
upstream webview GTK window-sizing error after a successful resize is
fixed. - Engine plumbing the window needed: the process owner's
child_body
(fork through the one spawn owner) andptyoptions; themadcrun://,
madcproj://andpty://channel schemes;ui::term_feed(a bounded
terminal screen) andui::key_bytes(the inverse of the key parser);
Windows runs the pty-requesting schemes on pipes with the pump's line
discipline (ConPTY is a named follow-up). - One-owner gates added to fulltest: one key/focus/input owner shared
by the terminal and web models; one module-member lookup owner; one
library-spelling owner (theMADC_DSO_SUFFIXhost macro is gone — a
-sharedoutput takes the TARGET's suffix); one style vocabulary (the
page carries no syntax palette of its own); the dialect-literals rule
(var x = { "k": v }, never a barevar x;filled field-by-field);
twin-fixture drift (check-expect-twins.shwith.domainsidecars); the
madcide command registry; the generated embedded-header table lives only
inobj/(the committed source is an#errorstub). - Platform lanes: every master promotion runs the release tier — the
libc++ flavor suite, the FULL suite on both mac runner arches, and the
full suite on genuine Windows 11 — recorded in the lane ledger that gates
the master push; one darwin-domain skip was added with its reason (the
hosted umbrella prelude declares the whole libc after any include, so the
M_PI negative import control is out of that domain).
Credits
- The platform webview library embeds webview/webview
(MIT) as a subtree — Serge Zaitsev, Steffen André Langnes and the
webview contributors; their history is part of this repository's log
since v0.99.0. madc --capabilities=jsonreworks PR #7 by its author, uhhidk.
See CHANGELOG.md for full details; the per-release
notes are v0.99.0, v0.99.1 and
v0.99.2.