Working on madc's next release (v0.104.0)

Working on madc's next release (v0.104.0)

I'm currently working on madc's upcoming release which should hopefully be ready sometime later today, but wanted to discuss it a bit here before the release announcement.

As you may know, I built an IDE in madc (called madcide), and I also built a plugin to make madcide look, feel, and behave much like Thonny (the learning IDE for Python), and made it its own standalone app with its own repo named Chthonia.

That made me realize that madcide should also really be in its own repo, since it grew to be far more than a sample application.

Thus, the next release of madc will be split into three releases:

  • madc v0.104.0
  • madcide v0.7.0
  • chthonia v0.1.0

That is not all that this release will do, however (the split), there has been some functionality shuffling, decisions on what should exist where, with some bug fixes along the way, of course.

So what I would like to discuss here was more along the lines of the language itself, and asking for feedback from other fellow language developers...

So, as you may also know, I've added a REPL to madc (as of v0.101.0), which was inspired by various existing REPL implementations (since there is not yet a firm standard for C/C++), so I took some inspiration from Julia, IPython, Cling and clang-repl, and supported multiple command sets as aliases to each other to make it easier for those already used to one form or another.

What I'm bringing in with version 0.104.0, is the full set of the vifamily of line editing tools ("colon mode"), which originates from the lineage of ex and ed. This will only really be familiar with people who use vi, vim, or neovim.

For a brief history lesson, ed was written in C by Ken Thompson (author of B language, predecessor to C language) in 1973, ex was an extended version of ed, written by Bill Joy between 1976-1977, who also wrote vi (the "visual" mode of ex). All of these technologies (including C) were part of UNIX, and why you are always pretty much guaranteed to have access to vi under any sort of UNIX-like operating system. Bram Moolenaar wrote vim as a successor to vi in 1992, and most flavours of UNIX (including Linux) actually ship with vim, and typing vi will launch vim.

Personally, I am not a vi/vim/neovim user, but millions of people are familiar with it, and it does have a very powerful command line mode, and this will now be part of the madc REPL mode.

I'm also bringing in the LSP and MCP server support and most of what was headless and line-mode of madcide into madc itself, so that madcide will primarily be only the visual (TUI / GUI) parts.

The reasoning for this is that these are all non-GUI things, and they are fairly small, and make madc itself more powerful it its core, and that these things could be more foundational for applications outside of madcide.

Madcide started out as an exercise for developing madc's UI module, which allows for having the same UI elements across multiple UI modes -- line mode, TUI mode, GUI mode, etc. It's written in madc, and it is designed to be very flexible, modular, and you can write plugins for it in madc -- Chthonia is a madcide plugin, but as madc is both a JIT and an AOT language, Chthonia is available as a full on compiled standalone application, compiling the chthonia plugin into a binary linked against libmadc and libmadcide.

I'm also putting more effort into segregating add-on functionality into modules -- especially if they add a third party library dependency. An example of this is git support.

I know this is a lot of reading, but hoping for some interesting discussion here as I think it encompasses programming language development in general, and is not specific to madc.

So, what do you think of this split? Does anyone here use REPL mode in other languages? Do you plan a REPL mode for your language?

u/kindredseer — 4 days ago

madc v0.103.0 released — faster compilation, improved C++ compatibility, and a major TUI facelift

I've released madc v0.103.0, with improvements to both the compiler and its accompanying IDE, madcide.

What's new in madc

  • Faster compilation — improvements to string interning and header processing should make compilation roughly 20% faster, depending on the workload.
  • Improved C++ compatibility — continued progress on standards conformance, with C++11 compliance now reaching 77.3% in the GCC test suite.
  • Reliability improvements — fixes to var string handling, memory safety, and additional sanitizer testing.
  • REPL enhancements (since v0.101.0) — %run, %call, $build, %open, .load, .type, .help, .quit, and much more

What's new in madcide

  • Major terminal UI facelift — the TUI now resembles the desktop GUI, with menus, toolbar, editor tabs, line numbers, framed panes, floating dialogs, and VS Code Dark+ styling.
  • Full mouse support — navigate menus, select text, place the cursor, and interact with the editor using the mouse.
  • Improved integrated terminal — supports ANSI formatting, 256 colours, and true 24-bit colour.
  • Multiple files on startup — madcide a.c b.c c.c opens all three files in separate tabs.
  • Integrated documentation — help pages open directly in the editor, with a browsable Help Index in the sidebar.
  • GIT support — some basic read-only (for now) git functionality now exposed through the IDE menus and also the REPL mode inside the IDE through %git

Project updates

Since my previous announcement, Chthonia has moved into its own repository, with v0.0.3 released separately:

https://github.com/derekbsnider/chthonia

This will also be the last madc release with madcide included in the madc source repository. Starting with the next release, madcide will move into its own repository as well.

The plan is to keep the three projects independently maintained, but bundled together for convenience:

  • madc — the compiler and language.
  • madcide — the IDE, distributed with madc included.
  • chthonia — the C/C++ learning environment, distributed with both madcide and madc included.

Release: https://github.com/derekbsnider/madc/releases/tag/v0.103.0

u/kindredseer — 6 days ago

Chthonia, an IDE+REPL to learn C/C++

Github repo: https://github.com/derekbsnider/chthonia

Inspired by Thonny, Chthonia is a plain and simple IDE designed as a learning tool for C/C++.

It is completely self contained and multi-platform (Linux, Mac, Windows). It has an integrated compiler and REPL (Read-Eval-Print Loop).

The packaged binary+library download size is under 15 Mb.

This is version 0.0.2, so it's still a work in progress. It's open source, MPL-2.0 licensed.

The REPL-mode is designed to feel familiar whether you are used to IPython, Julia, or Cling.

u/kindredseer — 8 days ago
▲ 9 r/AIprogrammingLanguage+1 crossposts

madc v0.101.0 -- REPL and "Chthonia"

MadC now has a REPL, and its editor becomes a teaching IDE modeled after Thonny.

Run madc with no program file and you are in an interactive C/C++ session that behaves the
way Julia and IPython do: what you define in one entry is there in the next, results are named so you can reuse them, and the session can tell you what you have built. On top of it, madcide gains a plugin system, and the first plugin built with that system is Chthonia, a teaching IDE modelled on Thonny.

So I've been working on the REPL, inspired by Julia, IPython and Cling, as well as a version of the IDE inspired by Thonny (the Python-teaching IDE), to make a C/C++ teaching IDE with REPL.

I've called the IDE "Chthonia" (the ch is silent). Chthonia is the Greek Goddess of the Earth and Underworld, like how C is the language of the OS. The "C" can be for C/C++, the "h" for helping, the "thon" for Thonny-like, and the "ia" from Julia.

REPL-mode is inherent to madc now, and provides an interactive REPL shell if run without arguments:

$ madc
madc 0.101.0. Ctrl-D exits.
madc> int sq(int x) { return x * x; }
madc> sq(7)
49
madc> ans + 1
50
u/kindredseer — 12 days ago

Current Progress of MadC's Next Release

I wanted to give an update of what I'm working on to get some feedback and discussion...

I'm not sure how many people here are C and/or C++ programmers, but the current direction I'm taking with madc is to make it a little more like IPython and/or Julia with respect to its REPL experience (that is part of the current arc I am working on, REPL support does not currently exist).

I am neither a Python nor a Julia programmer, but their REPL experience are supposed to be top notch, and while both cling and clang-repl exist, they don't quite measure up, and in fact, installing cling takes up over a Gb of disk space, and the eventual plan is that clang-repl will one day replace cling, and the direction is also such that clang-repl is more like IPython...

Thus, my current plan is to make madc have a REPL mode that is more like IPython and Julia, so more like what clang-repl + cling will eventually become (in the future).

So that's the first arc... and I'm curious what people here think about this idea... like, if you are already a C/C++ programmer, does the REPL experience interest you? Or if you are a Python programmer, would the idea of a small, easy to install and play with C/C++ REPL interest you?

Next... I recently discovered Thonny -- an IDE designed to be very simple and easy for students to learn to use Python... and with the work I've done with madcide as a simple IDE for madc, rather than try to compete with VSCode and/or CLion, what might be much more interesting would be to make madc's IDE much more like Thonny, but for C/C++ (and madc), so that it makes C/C++ easy to use (including interfacing with madc's IPython-like REPL).

Does this concept sound interesting to anyone here?

reddit.com
u/kindredseer — 18 days ago
▲ 8 r/AIprogrammingLanguage+2 crossposts

madc v0.99.2 released — madcide w/ GUI mode on Linux, Windows and macOS

I just released madc v0.99.2, with updated builds for Linux, Windows and macOS.

The biggest change since v0.98.0 is that madcide now has a full desktop interface:

  • Run madcide file.mad --gui to open the IDE in a window.
  • Editor tabs, menus, file dialogs, sidebar, status bar, and Problems / Output / Terminal panels are now available.
  • Programs can be built and run directly inside the IDE, with console applications running in an embedded terminal and GUI applications opening their own window.
  • The GUI and terminal versions use the same editor, commands, themes and keybinding profiles — including the existing JOE/WordStar and vi-style setups.
  • The IDE itself is still written in madc and compiled by madc.

The language also gained a new import statement that can bring in both a header/interface and its native library without platform-specific library names:

import m;
import c as libc;

Also, the internal UI framework (madc::ui) is used for all user interfaces:

  • TTY/line-by-line UI -- examples/adventure (Colossal Cave Adventure madc port)
  • TUI/smart terminal -- tools/madcide (vt102/xterm TUI version of madcide)
  • Web/DOM -- tools/madcide --gui (web GUI version of madcide)

The same source works across Linux, Windows and macOS, in both JIT and native builds.

https://github.com/derekbsnider/madc/releases/tag/v0.99.2

u/kindredseer — 1 month ago
▲ 5 r/AIprogrammingLanguage+1 crossposts

Progress on the GUI version of the MadC IDE

So the same IDE supports terminal/TUI mode and now GUI mode... for Linux, Windows and MacOS.

The attached images show, in order:

  • Linux -- GTK 4 + WebKitGTK 6
  • Linux -- TUI mode (inside Windows Terminal)
  • Windows -- Win32 + WebView2
  • macOS -- Cocoa + WKWebView

Only the Linux GUI version currently has the menu options, as this is a develop release (v0.99.1), but all three will have them in the upcoming master release.

The IDE is currently operating in local mode, but I have been designing it to be able to also operate in client -> server mode, supporting multiple client connections.

Also, the internal UI framework (madc::ui) is used for all user interfaces:

  • TTY/line-by-line UI -- examples/adventure (Colossal Cave Adventure madc port)
  • TUI/smart terminal -- tools/madcide (vt102/xterm TUI version of madcide)
  • Web/DOM -- tools/madcide --gui (web GUI version of madcide)

I decided to start with a web interface for the IDE since it makes a lot of the cross-platform GUI work much easier, and is one of the purposes that HTML was originally designed for (a simple, standardized way to format text so that any computer system could read and display the same document identically).

https://github.com/derekbsnider/madc

u/kindredseer — 1 month ago
▲ 5 r/AIprogrammingLanguage+2 crossposts

madc v0.98.0 released — now with an IDE written in madc

It took longer than expected, but I just released madc v0.98.0, with updated builds for Linux, Windows, and macOS.

A few of the more interesting additions since v0.95.2:

  • madc now ships with madcide — a terminal IDE written in madc itself, with the distributed binary compiled by madc.
  • The IDE uses the running compiler directly: it can parse, build and run the code in the editor, including unsaved changes, without shelling out to another compiler.
  • JOE/WordStar-style keybindings are the default, with a full vi-style mode also included.
  • Cooperative multitasking is now built into the language with go, await, channels and structured scope blocks.
  • var has much better literal support, including keyed values and nested structures:

​

   var user = { "name": "Alice", "score": 42 }; 
  • The C++ front end received another substantial compatibility pass, particularly from running the complete test suite against libc++ on macOS.
  • Apple Silicon support has matured considerably, including SIMD/NEON and additional ABI work.
  • The entire madc test suite now passes on both Apple Silicon and Intel macOS, alongside the existing Linux and Windows validation.
  • Release packages are now built automatically by CI, including .deb, .rpm, Linux tarball, Windows zip, and both macOS architectures.

The direction remains C and C++ without the ceremony — but with v0.98, madc is also starting to demonstrate that it can be used to build its own development tools.

https://github.com/derekbsnider/madc/releases/tag/v0.98.0

u/kindredseer — 1 month ago
▲ 6 r/AIprogrammingLanguage+1 crossposts

Working on the IDE

So for the past week or so I've been working on an IDE for madc which is actually written in madc.

Part of the idea for the madc language is to build everything to be modular, reusable and exposed to the language itself, so madc is not just a language of its own, it's also an embeddable language, but also much of the machinery can be used outside of madc, and also madc can call upon its own machinery, including embedding madc into itself (since it is c/c++), etc. So it makes this all very possible.

So this also means the features and functionality to create an IDE are also reusable components of the language, as I started with a text editor as an "example program", and the UI module actually first started with a simple text (dumb terminal) implementation of Colossal Cave Adventure, and that same UI module was extended to support TUI (Terminal User Interface), which is what was used for the text editor, and that text editor was extended into the madc IDE (madcide).

In the current develop branch the editor is working with basic IDE functionality, and with a few different editor key mapping flavours (pico, joe, emacs and vim).

I'm doing a bit more cleanup and polishing before the next master release, but wanted to chat about what's in progress and where it is going.

I've talked a little bit in here before about my idea of the future of AI coding, and that the current method of LLMs using text based shell tools and scripts (sed, awk, grep, and python mostly) to edit code seems archaic and problematic, and what I've been thinking would be useful would be to provide a "nexus" API/MCP of sorts that gives the LLM direct access to the current "live" code, at a lower level than the typical LSP layer provided by things like VSCode, and the same API would funnel gated access to the revision history, as well as the project management layer, and both of those would be configurable external connectors, so that the IDE was just providing a simple, unified entry point to the code.

So my idea with the IDE is that it would fit into this model so that there would be these various layers of a user session (or sessions), accessing this state of the union so to speak, and allowing a real collaboration between developers and LLM agents to the same live project.

I think eventually this live code nexus would be its own running server that you would connect IDE clients and LLM agents to, and you could access it from the CLI, including simple shell CLI access, a TUI interface IDE, or GUI interface IDE, remote, local, it doesn't matter.

It's something I'm playing with, and while it's primarily c/c++ based, madc itself has polyglot leanings so the door is open for fully parsing and supporting other languages.

Any thoughts?

reddit.com
u/kindredseer — 1 month ago

What editor or IDE (and tools) do you use?

Just curious what editor/IDE you use to do your C programming?

I primarily use joe (Joe's Own Editor), which is not an IDE, under Linux, and use gcc as the compiler.

When I did some Windows programming in C++, I did use Visual Studio, and I have played around a bit with VS Code, but I'm very stuck on the WordStar-style key-bindings (which were the ones I got used to when using Turbo Pascal and Turbo C back in the early 1990s, and is what joe uses).

reddit.com
u/kindredseer — 2 months ago

The Claw Machine Effect

I wrote a paper about the “one more prompt” loop in agentic coding

After spending a lot of time with Claude Code and other coding agents, I started noticing a pattern that felt strangely familiar: occasional spectacular wins, lots of “almost right” results, and the constant temptation to try one more prompt.

I ended up calling it The Claw Machine Effect and wrote a paper trying to formalize the idea in terms of variable reinforcement, near misses, verification debt, and work intensification.

Funny timing: just as I submitted it, ZDNET published “I can’t stop: 80% of developers find AI coding more addictive than helpful.”

I’m not arguing that Claude Code is literally “addictive” — the paper is more about why agentic coding can reinforce continued engagement even when the returns are diminishing.

The Claw Machine Effect: Variable Reinforcement, Near Misses, and Work Intensification in Agentic AI

SSRN: https://papers.ssrn.com/sol3/papers.cfm?abstract_id=7328978

Curious whether other heavy Claude Code users recognize this pattern.

reddit.com
u/kindredseer — 2 months ago

Are LLMs intentionally giving bad results

As the title implies... and this is not necessarily implying that this is the intention of the creators of LLMs.

I wrote this paper last year ("Economic Incentives and Mass-Market Training: How Profit Motives Led to Inevitable Hallucinations in Large Language Models") and after using Claude Code for the past several months, I am inclined to believe that LLMs have also adapted to working in much the same way that slot machines do, as had been observed the way social media has been designed.

Basically, whether intentional or not, I'm observing that the results of prompting an LLM with hopes and expectations of a "big win" result (which it sometimes does offer), tends more often than not to actually result in a number of losses (some big, some small) as well as occasional smaller wins, and a consistent effect of diminishing returns.

So are LLM companies like OpenAI, Anthropic, xAI and Google turning into digital casinos where you spend credits to win the expected results of your prompt? Or perhaps more like a claw machine? You can visualize your prize... it could be possible to grab it on the first try, but more likely than not it's going to slip from the claw's grasp, and you're going to pay for that prize many times over before actually taking it home.

reddit.com
u/kindredseer — 2 months ago
▲ 11 r/AIprogrammingLanguage+1 crossposts

madc v0.92.1 released — std::format, std::println, php::print_r, php::var_dump

I just released madc v0.92.1, the download release for the v0.92 line and the first published binaries for all three platforms since v0.82.0.

Packages are available for:

  • Linux — .deb and .rpm
  • Windows — zip
  • macOS — Apple Silicon and Intel tarballs

A few of the more interesting additions:

  • std::format, std::print, and std::println are built directly into madc — no includes or header parsing required. Literal format strings are checked at compile time, including invalid indexes, malformed strings, and incompatible presentation types.
  • std::format returns a real std::string, and formatting behaviour has been tested against libstdc++ with 1,430 generated oracle cases, including floating-point and hex-float formatting.
  • cout << var now works with zero includes: It also works with <iomanip> features such as setprecision, setw, and setfill.
  • UFCS support in the madc dialect — free functions can be called like methods, and methods can be called like free functions.
  • PHP-style debugging helpers for any madc type: php::print_r(x); php::var_dump(x); These work on structs, classes, containers, nested objects, arrays, and var, with cycle detection and human-readable type names.
  • Range-based for loops now work naturally with PHP-style arrays, including value/var elements and auto.
  • var/value continues to mature — constructors work naturally in expressions and loops, .size() / .count() semantics have been cleaned up, and php::array_push() now behaves as a single overloaded function returning the new element count.
  • Headerless libc calls now get proper function signatures, so things like:floorf(3.9f) pass a real float rather than falling through old C-style variadic promotion behaviour.
  • And, finally, madc --version tells you which build you're actually running.

The direction continues to be: keep C and C++ underneath, but remove a lot of the friction when you're just trying to write a small program or script.

So something like:

var x = 42;
println("x = {}", x);

doesn't need a collection of headers or setup before you can get to the actual program.

With v0.92.1, all of this is available in the downloadable builds for Linux, macOS, and Windows.

u/kindredseer — 2 months ago
▲ 7 r/AIprogrammingLanguage+2 crossposts

madc v0.76.0: macOS support joins Linux — Apple Silicon + Intel

I just released madc v0.76.0, which adds the project's first official macOS support alongside the existing Linux support.

madc has already been running on Linux; this release brings the same general experience to Macs, with prebuilt releases for both arm64 (Apple Silicon) and x86_64.

The macOS tarballs are designed to work even on a header-less Mac. madc carries its packed C/C++ standard-library environment with it, so things like <string>, containers, streams, and <algorithm> can compile directly from the embedded image.

A few highlights:

  • Existing Linux support, now joined by macOS
  • Prebuilt macOS binaries for Apple Silicon and Intel
  • JIT compilation works on macOS
  • Native AOT executable generation works for both C and C++
  • madc -o prog prog.mad can produce a runnable Mach-O executable
  • C++ standard-library headers are available from madc's embedded frozen forest
  • --emit=c11 output can be compiled with the system compiler using the included libmadc_rt
  • A major AArch64 ABI fix now correctly handles C++ objects returned by value
  • Several additional libc++ and macOS compatibility fixes landed along the way
  • The integration test suite has grown to 1,019 tests, with the primary JIT, EXE, OBJ, packed, and release lanes all passing

One of the more interesting parts of getting macOS working was discovering how many assumptions that are fine on x86-64 stop being true on Apple Silicon. In particular, AArch64 handles the hidden return pointer for larger C++ objects differently, so madc now lets the target ABI decide where that parameter belongs instead of assuming the x86 convention.

For me, the bigger milestone is that madc is becoming something you can simply download and try on either Linux or macOS as a lightweight C/C++ scripting environment, rather than first treating it as a compiler project you need to build and configure yourself.

Recent releases have also added things like var dynamic variables, URI-based channels for files/TCP/processes, streaming data support, and substantially faster loading of C++ headers.

The direction I'm aiming for is essentially:

keep C/C++ available underneath, but make writing small programs feel much closer to scripting.

v0.76.0 is the release that brings Mac users into that experience too (Windows coming soon).

u/kindredseer — 2 months ago

MadC v0.75 Release

Version 0.75 of MadC was released yesterday, I'm still working on proper MacOS support, but its getting closer... should be ready this week. For now, I've got some more bugs fixed, more C++ speed improvements, and some madc specific language features and improvements:

  • var dynamic variables — madc now has a built-in var type that can hold strings, numbers, booleans, arrays, and other values without needing to declare a fixed type up front
  • Simple file and network channels — madc::channel provides one straightforward interface for reading and writing files, TCP connections, and other data sources
  • Run programs through exec:// — scripts can launch another program, send data to it, and read its output almost like working with a file

Example:

channel sorter("exec://sort");
defer { sorter.close(); }

if ( !sorter.ok() )
{
    printf("open failed: %s\n", sorter.last_error());
    return 1;
}

sorter.write("pear\napple\nmango\n");
sorter.close_write();

var line;
while ( sorter.readline(line) )
    printf("sorted: %s\n", line);
sorter.close();
u/kindredseer — 2 months ago
▲ 9 r/AIprogrammingLanguage+10 crossposts

Ai writen language, if anyone wants to try it out~

Been a few weeks working on this, majority of it was done in like 10 days, but then life, and bugs needed fixed and feature creep, and everything. Either try it out or not, I needed something specific that I had more control over for my other projects, so now this exists.

github.com
u/gusfromspace — 2 months ago
▲ 7 r/AIprogrammingLanguage+1 crossposts

MeScript (A musical programming language inspired by Strudel and SuperCollider)

I have been working on this language since May. Its heavily inspired by Strudel and partially by SuperCollider. It works as many things all at once. It is a music sequencer, synthesizer, fx box, generative music (conditional statements, if, else) and sample mangling (need non-browser version for that), automation, per note automation, recursion, easy nesting of gradually more complex sequences/fx/etc.

If anyone wants to try the language, its here, https://quadracollision.com/mescript/ mostly usable in browser unless you want to use samples, if so just let me know.

As for tools: This is GPT 5.3 -> GPT 5.4 -> GPT5.5 -> GPT 5.6 Sol, all Medium. This is Rust+WASM with a Javascript front end. No external libraries

This is an example of MeScript in action: you can paste this into the editor and it'll work.

Check CTRL+H for insertable smart forms, cursor position defines how the form is inserted. Also check out the language reference guide. There is also a repl, place the cursor on any line and right click and press parameter help and it will explain what the line does. Also (fix-parens linenumbers) (fix-parens 15-17) can help with parenthesis issues, this is a Lisp inspired language.

(def am [as d f]) ;this is a chord form, asharp d and f

(ins :saw  ;this is an (ins)rument form
   :src [:saw-synth :square-synth :additive] ;these are the oscillators that make up this instrument
   :note (p (times 4[c4 0 c5 0 e3 c3 e3])    ;these are the note gates and how many
            (times 4[c4 0 c5 0 e3 c3 eb3]))  ;times they play
   :gate nil
   :fx [(formant :vowel a :mix 0.2)]    ;fx applied to entire instrument
   :dur nil    ;duration of each gate hit, can be per hit as well 
   :amp nil    ;amplification of instrument, can be per hit and automated conditonally
   :voice nil) ;special keyword, see ctrl+h for voice commands, as well as everything else

(def chord_1 [c4 eb4 f4 gb3])

(ins :kick
   :src :kick-synth
   :note (p [c4 0 0 0 c4<?50> 0 0])
   :gate nil
   :fx nil
   :dur nil
   :amp nil
   :voice nil)

(ins :hat-808
   :src :hat-808
   :note (p [c7 c7 <c4%c5%c7> 0 c7 <c7%e5%b4%g5> c7 am(3 3 3)]) ;this calls the chord form with each note being an octave of 3
   :gate nil
   :fx nil
   :dur nil
   :amp nil
   :voice nil)

(ins :snare-808
   :src :snare-808
   :note (p [c4<?30> 0 0 c4<?50> 0 0 0 0])
   :gate nil
   :fx nil
   :dur nil
   :amp nil
   :voice nil)

(ins :pad-wash
   :src :pad-wash
   :note (p [chord_1<_7> 0 0 0 0 0 0 0])
   :gate nil
   :fx nil
   :dur nil
   :amp 0.05
   :off true
   :voice nil)
reddit.com
u/kindredseer — 2 months ago
▲ 2 r/AIprogrammingLanguage+1 crossposts

Desi v0.1.0 — Python-ish syntax, no GC, and three optimisations that made it slower

I've been building Desi for about a year — it's the third or fourth rewrite — and I tagged v0.1.0 today. Compiled through LLVM, no garbage collector, indentation-based syntax, and a standard library that already has an ORM and an HTTP server in it.

Two things up front: I leaned on AI heavily to build this, and I'd call v0.1.0 a working prototype rather than a finished language. More on both at the end, including what I'm hoping to get out of posting here.

Rather than list features, here are three things I was confident about that turned out to be wrong. All three cost me under an hour to test and would have cost days to discover afterwards.

1. Turning on LTO made it slower.

Element access (xs[i], xs.append(v)) was an out-of-line call into the runtime, so the optimiser couldn't see through it. The obvious fix was to let it inline. I measured 1M appends + 1M reads:

out-of-line call        3.28 ms
inlined                 4.22 ms   <- worse

The bodies end in fprintf(stderr, ...) on their failure paths. Inlining drags a varargs call and its setup into the loop. Adding one file to the LTO set — a one-line change — would have been a regression.

What works is the shape Rust's Vec uses: the bounds check inline, the panic #[cold] and out of line. Same code, error paths pushed out:

same semantics, cold errors    1.09 ms   <- 3x

I ended up emitting the check and load directly in the IR with a cold call to the runtime on failure, rather than depending on LTO, since LTO isn't available on every platform I build for.

2. "The representation is the bottleneck" was wrong.

A list element is a pointer-sized slot, ints stuffed in directly. I assumed that indirection was costing me and planned a typed-storage rewrite. Measured:

typed int64[] array, inlined    0.76 ms
void* slots, inlined            0.74 ms

Identical. An int64 and a void* are both 8 bytes in a contiguous array — there's no indirection to pay for. I'd have spent a week rewriting collection storage for nothing.

3. Except for floats, where it was 24x.

Same slot representation, but a double wasn't stuffed in — each one got its own malloc. A comment in my codegen said "can't bitcast float to ptr," which is true, and why past-me reached for the allocator. But you can bitcast a double to an i64, and i64s were already going into slots.

boxed         28.65 ms
by value       1.18 ms

That change deleted more code than it added, and two other benchmarks reached parity with C without being touched — the boxing was most of what they'd been measuring.

Where it actually is

Against equivalent C at -O2, whole-process wall time on Linux:

Function Desi C
string_churn 12 ms 15 ms
binary_tree 2 2
quicksort 2 2
loop_sum 1 1
list_ops 6 4–6
matrix_mul 2 1
dict_ops 9 5
fib_recursive 10 6
alloc_churn 6 1

Five of eleven match or beat it. Two clearly don't: alloc_churn allocates a small collection half a million times, and dict_ops still calls into the runtime per operation. Both are understood, neither is mysterious, and I'd rather name them than average them away.

Memory

No GC, no manual free — the compiler inserts cleanup where a value's owner goes out of scope. What's guaranteed is no use-after-free and no double-free in safe code. What's not guaranteed is freedom from leaks: where ownership can't be proven, the compiler leaks rather than frees. Heap elements inside a collection — the strings in a list[str] — are the main case, and it's documented rather than hidden.

Unclear ownership never resolves to "free and hope". That's the property that let me ship these optimization incrementally: every analysis is allowed to be dumb, because being wrong costs memory, never corruption.

What it isn't

Supervisors exist and restart failed tasks, but this is not OTP — a child is a task, not another supervisor, so nothing escalates up a tree. Elixir's model doesn't port cleanly to shared-memory threads, and I'd rather ship the honest subset than borrow the name.

There's also no compile-time data-race checking. Channels and locks are there; nothing verifies you used them correctly. That's the biggest gap versus Rust and I don't have a good answer yet — though I suspect it's the same question as "what may safely cross a channel," which would also be the route to real supervision.

How it was built, and what I'm after

I should be upfront: I used AI heavily throughout this, and I'm not a compiler engineer by background. The three stories above are the reason I trust any of it — every one is a case where a confident-sounding plan was wrong and a measurement caught it before it shipped. "Enabling LTO will make this faster" is exactly the kind of thing that sounds right and isn't. So the rule became: measure first, and let the number decide. Anything I couldn't measure, I wrote down as unproven rather than claiming it.

Which is also why I'd call v0.1.0 a working prototype rather than a finished thing. It compiles, the test suite passes on three platforms, and the docs say what's broken. But there are decisions in here that someone who has actually built a type system or a borrow checker would look at and immediately improve — the data-race question especially, and probably the escape analysis.

That's what I'm hoping to find here. If you know this territory and something in the above made you wince, I'd genuinely rather hear it than not. Contributions welcome, but honestly even a "you've modelled this wrong and here's why" comment is worth more to me right now than a star.

Links

The name Desi (દેશી) means "local" or "native" in Gujarati, which is my first language.

Happy to go into any of the above — the measurement stuff especially, since I have numbers for most of what people usually ask.

reddit.com
u/kindredseer — 2 months ago
▲ 4 r/AIprogrammingLanguage+1 crossposts

AI-friendly programming language design

So when developing a new programming language using AI (or enhancing an existing one), it seems to make sense to design the language not only to be convenient for humans to use, but likewise for AI agents.

What Would an “AI-Friendly” Programming Language Actually Look Like?

There has been a great deal of discussion about making programming languages easier for AI systems to use. Usually, this means making code easier for large language models to generate: simpler syntax, fewer punctuation rules, less boilerplate and more predictable formatting.

But code generation is only a small part of software development.

An autonomous programming agent must also be able to understand an unfamiliar codebase, identify the consequences of a change, modify the program without breaking unrelated behaviour, verify that the result is correct and explain what it has done.

That suggests a much broader definition:

>

The goal should not merely be to make programs easier for AI to write. It should be to make programs easier for both humans and machines to understand, modify and verify.

Source Code Should Not Be the Only Representation

Most programming languages treat source text as the authoritative representation of a program. Compilers parse that text into abstract syntax trees, symbol tables, control-flow graphs and other structures, but these are usually treated as temporary implementation details.

An AI-friendly language could instead expose a stable semantic representation of the program.

Humans might continue to work primarily with readable source code, while tools and AI agents interact with the same program as a structured semantic graph containing:

  • Symbols and their identities
  • Types and relationships
  • Data ownership
  • Function contracts
  • Side effects
  • Dependencies
  • Call graphs
  • Tests
  • Access permissions
  • Source locations
  • Documentation

Source code would remain important, but it would become one view of the program rather than the only usable representation.

An AI agent should not need to rediscover the meaning of a program by repeatedly parsing text, searching filenames and inferring relationships from naming conventions.

Programs Should Be Locally Understandable

One of the greatest difficulties in maintaining a large codebase is that the meaning of a small section of code may depend on information scattered throughout the repository.

A module might rely on global state, build flags, initialization order, implicit imports, runtime configuration or code-generation steps that are not visible locally.

This is difficult for humans and even more difficult for AI agents operating with limited context windows.

An AI-friendly language should encourage modules to explicitly declare:

  • What they export
  • What they import
  • What state they own
  • What resources they require
  • What external systems they access
  • What assumptions they make
  • What invariants they guarantee

For example:

module Accounts

exports:
    User
    update_email

requires:
    Database
    EmailService

owns:
    UsersTable

guarantees:
    User.email is normalized
    User.email is unique

The purpose is not necessarily to make source files more verbose. Much of this information could be inferred by the compiler and displayed through tooling.

The important part is that the information exists in a structured and queryable form.

A programming agent should be able to ask:

describe module Accounts

and receive a bounded, reliable summary of the module without examining the entire application.

Types Should Describe Meaning, Not Just Storage

Many programming languages describe data primarily in terms of its storage representation.

A program may represent all of the following as strings:

first_name
email_address
postal_code
country_code
birth_date
telephone_number

Although these values share a storage representation, they do not share a meaning.

A language designed for machine reasoning should support semantic types such as:

PersonName
EmailAddress
PostalCode
CountryCode
BirthDate
TelephoneNumber
CurrencyAmount
TimeZone

These types could carry information about:

  • Valid values
  • Normalization
  • Comparison
  • Serialization
  • Privacy
  • Localization
  • Appropriate user-interface controls
  • Database representation
  • Safe conversions

A value of type EmailAddress would not merely be a string whose purpose is explained in a comment. Its meaning would be available directly to the compiler, development tools and AI agents.

This reduces the need to infer domain knowledge from variable names and scattered validation code.

Effects Should Be Part of Function Signatures

Traditional type systems tell us what values a function accepts and returns, but often say very little about what the function can do.

Consider a function such as:

update_email(user, address)

Does it modify memory? Write to a database? Send an email? Update an audit log? Access the network? Throw an exception? Trigger an event?

An AI agent should not need to inspect the implementation and every transitive function call to answer these questions.

An effect-aware declaration might look something like this:

function update_email(user_id, new_address)
    returns Result

    reads:
        User.id
        User.email

    writes:
        User.email
        AuditLog

    uses:
        Database
        EmailService

    may:
        send_email
        fail_with ValidationError
        fail_with DuplicateEmailError

This creates a machine-readable description of the function’s blast radius.

An agent proposing a modification could ask:

show effects of update_email

or:

will this change introduce network access?

The compiler could provide a reliable answer.

Authority Should Be Explicit

Most programs execute with ambient authority. Any code running within the process may be able to access the filesystem, environment variables, network, database or global application state.

That is convenient, but dangerous when code is being produced or executed by an autonomous agent.

A more AI-friendly language would use capabilities: explicit values representing permission to access particular resources.

For example:

function load_config(config_directory)

The function could access only the directory represented by the capability it receives. It would not automatically inherit access to the entire filesystem.

Similarly:

function update_customer(read_write_customers_database, customer_id)

could write to the customer database but not to the payroll database.

This would allow an AI agent to operate within a restricted environment where accidental or malicious actions are structurally impossible.

The agent could be given:

  • Read access to one repository
  • Write access to one module
  • A temporary filesystem
  • A test database
  • No network access
  • A limited memory and execution budget

Security boundaries would become part of the program rather than an external policy layered on top of it.

Contracts Should Be First-Class

Comments can explain what a function is intended to do, but comments are not normally checked by the compiler.

An AI-friendly language should make preconditions, postconditions and invariants first-class program elements.

For example:

function transfer(source, destination, amount)

requires:
    amount > 0
    source.balance >= amount

ensures:
    source.balance =
        previous(source.balance) - amount

    destination.balance =
        previous(destination.balance) + amount

    source.balance + destination.balance =
        previous(source.balance + destination.balance)

These contracts could serve several purposes:

  • Human documentation
  • Static analysis
  • Runtime checks during development
  • Test generation
  • Formal verification
  • Agent acceptance criteria

Instead of guessing whether an implementation is correct, an AI agent could ask the compiler whether the implementation satisfies its declared contract.

Contracts would also make tasks easier to define.

Rather than telling an agent:

>

a task could be expressed as:

Modify transfer so that contract
AccountTransferPreservesTotalBalance
is satisfied.

The desired outcome becomes concrete and machine-verifiable.

Inference Should Be Predictable and Inspectable

Inference can make a language substantially easier to use. Type inference, automatic imports, generic specialization and implicit conversions can remove large amounts of repetitive code.

However, inference becomes dangerous when it hides meaningful decisions.

A useful rule might be:

>

Automatic behaviour may be reasonable when:

  • A conversion is exact
  • Ownership remains unchanged
  • No persistent state is modified
  • No external resource is accessed
  • Execution remains deterministic

Explicit syntax should be required when an operation:

  • Loses information
  • Transfers ownership
  • Performs network access
  • Blocks or becomes asynchronous
  • Writes persistent state
  • Escalates privilege
  • Introduces nondeterminism
  • Has significant computational cost

An AI agent should also be able to inspect every inferred decision.

For example:

explain expression:
    total = price + tax

might produce:

price has type Currency<USD>
tax has type Currency<USD>

selected operation:
    Currency.add

conversion:
    none

effects:
    none

possible failures:
    CurrencyOverflow

The language could remain concise while the toolchain exposes the full semantic interpretation.

The Language Should Have a Canonical Form

Formatting tools create a consistent textual style, but an AI-friendly language would benefit from a deeper canonical representation.

The compiler could normalize:

  • Resolved names
  • Inferred types
  • Selected overloads
  • Implicit conversions
  • Generic arguments
  • Default arguments
  • Effects
  • Ownership decisions

Human-written code might say:

user.balance += payment

The canonical semantic form might record:

read field User.balance

convert Payment
    to CurrencyAmount
    using exact conversion

invoke CurrencyAmount.add

write result
    to field User.balance

This form would not necessarily be shown during normal programming. It would be available to tools, reviewers and agents when precise interpretation is required.

It would also allow code written in different stylistic forms to be compared semantically rather than textually.

Symbols Should Have Stable Identities

Programming tools often identify symbols using names and source locations. Both are fragile.

Names change during refactoring, and source locations change whenever lines are inserted or removed.

An AI-friendly language could assign stable identities to program entities:

symbol:
    User.email

stable_id:
    field:7f2a81c4

aliases:
    email
    email_address
    contact_email

Humans could use whichever names are appropriate in source code or user interfaces, while tools and agents refer to the canonical identity.

This becomes especially important when a language supports aliases, localization, schema evolution or generated interfaces.

An agent should be able to rename a symbol without losing track of its identity or confusing it with another similarly named symbol.

Changes Should Be Semantic, Not Merely Textual

AI coding tools currently make changes largely through text patches. This works, but it is fragile.

A line-based patch may fail because:

  • The file was reformatted
  • Another change shifted the lines
  • A symbol was renamed
  • Similar code appears elsewhere
  • The surrounding context has changed
  • The patch applies cleanly but to the wrong location

A semantic patch could instead express intent:

rename symbol:
    User.birthdate
to:
    User.birth_date

or:

add parameter:
    Logger

to function:
    process_order

position:
    after Database

or:

replace implementation of:
    Account.transfer

only if:
    function signature is unchanged
    semantic hash matches 4e720
    no new callers have been introduced

The compiler or development environment could translate the semantic change into ordinary source-code edits and Git-compatible diffs.

The repository would still contain readable text, but agents would operate on program structure rather than guessing where to insert characters.

Diagnostics Should Be Structured Data

Compiler errors are generally written as prose for humans:

Cannot convert argument 2 from nullable string
to email address.

An agent then has to parse that prose and infer an appropriate repair.

A structured diagnostic might contain:

diagnostic_code:
    TYPE_ARGUMENT_MISMATCH

function:
    update_email

parameter:
    new_address

expected:
    EmailAddress

received:
    Nullable<String>

cause:
    nullability mismatch

possible_repairs:
    validate non-null value
    provide default value
    change parameter type

automatic_repairs:
    none

The human-readable message could still be generated from this data.

The compiler should clearly distinguish between:

  • A repair that is known to preserve semantics
  • A probable repair requiring review
  • Multiple ambiguous alternatives
  • A condition for which no valid repair is known

This would make compiler interaction far more reliable for autonomous agents.

Relationships Should Be Declarative

Many applications define the same relationship repeatedly across:

  • Database schemas
  • Object models
  • API definitions
  • Validation code
  • User interfaces
  • Serialization formats
  • Access-control rules

An AI agent must then determine whether these duplicated definitions are consistent.

A more declarative language might express the relationship once:

entity Order

fields:
    id: OrderId
    customer: relation to Customer
    items: many OrderItem
    total: CurrencyAmount

derivation:
    total = sum(items.price)

The language now knows:

  • customer refers to another entity
  • items is a collection
  • total is derived
  • Changing an item may change the total
  • total should not normally be edited directly
  • Storage and user-interface tools can represent these fields appropriately

This greatly reduces the amount of detective work required to understand the application.

State Changes Should Be Transactional and Inspectable

AI-generated operations should be easy to preview, sandbox and reverse.

A language or runtime could make state-changing operations transactional:

transaction UpdateEmail

set:
    user.email = new_email

append:
    audit_log = email_changed

send:
    confirmation_email

Before committing, an agent or human could request:

preview transaction UpdateEmail

The runtime might report:

database changes:
    Users.email modified for user 1842
    AuditLog row inserted

external effects:
    one email would be sent

invariants checked:
    email is valid
    email is unique

result:
    transaction may commit

The runtime could also support:

  • Snapshots
  • Rollback
  • Deterministic replay
  • Resource limits
  • Mutation logs
  • Simulated external services
  • Reversible development environments

An agent should be able to demonstrate what would change before being permitted to change it.

Tests Should Be Connected to Program Semantics

Tests are usually organized as source files and function names. Their relationship to the code they verify is often informal.

An AI-friendly language could associate tests with symbols, contracts and invariants:

test transfer_preserves_total

verifies:
    Account.transfer

covers:
    AccountTransferPreservesTotalBalance

The toolchain could then answer:

which tests verify Account.transfer?


which public behaviours changed?


which contracts have no tests?


what is the smallest sufficient test set
for this patch?

This last question is particularly important for autonomous agents. Running every test after every small change may be expensive, while running too few tests is unsafe.

Semantic test relationships could allow the compiler to select a targeted verification set and then expand it when uncertainty remains.

The Compiler Should Expose an Agent Protocol

The most important feature may not be part of the language syntax at all.

A language designed for AI-assisted development should provide an official interface through which agents can query and modify programs.

That interface might support operations such as:

describe(symbol)

find_references(symbol)

explain(expression)

show_effects(function)

show_contracts(function)

show_invariants(type)

calculate_change_impact(patch)

create_semantic_patch(request)

validate_patch(patch)

find_relevant_tests(patch)

run_tests(test_set)

preview_transaction(operation)

apply_patch(patch)

rollback(change)

Today, AI coding agents often interact with a repository using little more than shell commands, text search, a language server and compiler output.

A compiler-native protocol would give them a much more precise and constrained environment.

The compiler could even generate a compact task-specific context package:

task:
    modify email validation

relevant symbols:
    User.email
    EmailAddress
    update_email
    UserRepository.save

required invariants:
    email must be normalized
    email must be unique

allowed modules:
    Identity
    Accounts

forbidden effects:
    database schema changes
    network access

required verification:
    EmailAddress contracts
    identity email tests

This would help prevent agents from becoming lost in large repositories or long-running plans.

AI-Friendly Does Not Necessarily Mean Verbose

Many of these ideas may sound as though they would produce an extremely ceremonial language.

That does not have to be the case.

Humans should be able to write concise code while the compiler derives and records the richer semantic model.

For example:

function add_item(order, item):
    order.items.append(item)

The compiler might infer:

  • order is mutated
  • item is read
  • order.total must be recalculated
  • The operation may fail if the order is finalized
  • The database transaction touches two tables
  • Three invariants must be rechecked
  • Four tests are directly relevant

The source code remains readable. The additional information exists because the language and toolchain understand the operation.

The principle should be:

>

Human-Friendly and AI-Friendly Design Are Closely Related

Most of the features that would make a language safer for AI agents would also make it easier for humans to maintain:

  • Explicit module boundaries
  • Meaningful types
  • Predictable conversions
  • Structured effects
  • First-class contracts
  • Better diagnostics
  • Semantic refactoring
  • Transaction previews
  • Clear test coverage
  • Stable symbol identities

AI agents amplify the importance of these features because they expose weaknesses that humans have historically worked around through experience, intuition and institutional knowledge.

A human developer may remember that a particular field is updated by a hidden database trigger. An AI agent may not discover that fact until something breaks.

The better solution is not necessarily to train the agent to guess more accurately. It is to make the dependency explicit.

A Possible Definition

A genuinely AI-friendly programming language would not merely be one whose syntax appears frequently in training data.

It would be a language in which a program is:

  • Readable as source code
  • Understandable as a semantic graph
  • Divided into bounded cognitive domains
  • Explicit about authority and side effects
  • Modifiable through structured operations
  • Testable against declared contracts
  • Executable in sandboxed transactions
  • Verifiable using compiler-supported evidence

The central design goal might be summarized as:

>

Such a language would not eliminate programming mistakes, hallucinations or unsafe changes. It would, however, give both humans and AI agents much stronger tools for detecting those problems before they reach production.

The result would not simply be a language that AI can generate.

It would be a language in which AI can operate with bounded authority, explicit understanding and evidence that its work is correct.

reddit.com
u/kindredseer — 2 months ago
▲ 1 r/AIprogrammingLanguage+2 crossposts

Introducing Mad-C (My Advanced Dialect of C++)

So just over seven years ago I got the idea that I wanted to try my hand as writing my own actual programming language, and by this I mean more than just a scripting language, as I had made a few of these over the years... the first one being a simple scripting language for a dial-up BBS terminal program I co-authored with a friend to script playing MajorBBS games, primarily one called Galactic Empire written by Mike Murdoc which my friend was majorly into, and hence called the terminal program GEnius. It was written in Turbo Pascal, and somewhat modeled after the DOS terminal program Telix. I specifically worked on a scrollback buffer that would display everything in full ANSI and also the (very rudimentary) script language.

Fast forward nearly 30 years and I'm experimenting with writing my own byte code interpreter and direct dispatch switch tables getting decent performance, and then I stumbled across a library called AsmJIT which made it relatively easy to generate x86 code and execute it, and I was off to the races working on my own c-like language which I originally called C3PO.

After working on it for a few weeks, I changed the name to Mad-C before creating a github repo (pretty much exactly 7 years ago today), and pushed forward getting all the basics working, if/else, expression parsing, switch, for loops, etc, before trying to figure out what was going to make it stick out beyond it being a JIT language, and I decided I wanted to bring in a bit of C++, and that it was also going to bring in features from other languages.

I tinkered around with it on and off for several months, but actually getting C++ features working properly (without crashing) turned out to be much more difficult than getting C working, and eventually I just didn't have the time to continue to chip away at it as I got busy with other aspects of work and life... it was something I would tinker with here and there as I could.

After a certain point, the AsmJIT author had changed the interface and deprecated some ways of doing things, and I ended up shelving the project completely. It was fun while it lasted, but I just didn't have the time to pursue it further.

Fast forward to this year, and my work started pushing AI really hard, such that all the lead developers (including myself) got pulled off of our primary projects for three months to completely focus on implementing an "AI Playbook" using Claude Code.

I was so impressed at how much better this was working for me than my previous experience with Cursor, that I ended up purchasing my own personal subscription to try it out on my personal projects, including Mad-C, and it was able to get it building again.

I switched back and forth between using Claude Code as well as Codex (which I had barely tried before this) and got Mad-C to the point where I was able to get it to JIT run the SMAUG MUD code base (which is over 185 Kb of C89-style C source).

This wasn't instant... it took weeks of grinding away switching between Codex and Claude Code, waiting for 5 hour usage resets, but it was actually working and I was steering it and guiding them all along the way. Part of getting this working involved grinding it against the C23 GCC torture test suite.

I also wanted it to be able to cache the code generation in object files, as well as generate executables. This involved a lot more complexity and all test cases needed to pass in both JIT mode and EXE mode, and required implementing my own IR (intermediate representation).

Next I started adding in those language features from other languages. I used C++ style namespaces to bring in about 100 different functions from languages like PHP, Perl, Python, Rust, Ruby, JS, etc, as well as things like defer, multiple return values, rust matching, etc, and then turned the focus onto C++ support.

This is where things started getting really tricky because I didn't just want to simulate C++ with hardcoded string, fstream, and stringstream classes, I wanted it to parse the real C++ headers, which meant templates, and multiple inheritance, among hundreds of other language features.

Also, around the same time, just to make things more exciting, I wanted to be able to support other architectures than only x86 Linux, and this is when I discovered the MIR project, which was also seven years old. It provided a CPU agnostic "medium intermediate representation" (MIR), and seemed like just what I was looking for... but it presented a fork in the road, because not only did it provide this CPU agnostic opcode format, the project also included a C11-to-MIR library.

So the question now was, did I switch all my code from generating x86 code of my own design and structure to generating MIR opcodes, or do I change Mad-C into a sort of C-transpiler?

The author of MIR (Vladimir Makarov) has been one of the GCC developers for over 20 years... so I figured his C-implementation was likely superior, and it was also tested on MIR itself (which is written in C), and I chose this direction instead, even though I already had a working C implementation.

I did keep my lexer/parser though. What I ended up doing, was taking the internal node structure (the node_t struct) and using it for the base of MadC's AST tree node, which I named CIR_node, and it contains all the semantics for C++ and MadC.

I modified libc2mir so that I could pass in the CIR_node AST tree directly, which c2mir thinks is its own node_t AST tree, and converts it to MIR, and JIT executes it.

So MadC parses C, C++ (and madc), but lowers C++ into a C-AST tree, similar to how CFront used to work (the original C++ implementation). This means that madc can also emit standard C code so that you can feed it to GCC or CLANG if you want to.

The other part of MadC that was important to me, was making it self-contained, so the build also packs in all the system headers, precompiled into an AST "forest", and appends this to the binary compressed. This currently weighs in at around 12 Mbs or so total. So with a 12 Mb binary you can have a C/C++ JIT language (plus compiler) that doesn't need any external system include files.

Not only that, but it also support auto-including, so you don't need to remember what function or object is in what header file. It also supports auto-namespace resolution as well as an auto-main "script mode" where you do not even have to define a main() function.

I didn't stop there, of course, and MadC depends on my own fork of MIR, where I've been working to add C23 support (MIR's c2mir only implements the C11 standard), and I've also added support to my fork of MIR to generate objects, ELF binaries, link objects, handle multi-file projects, and I'm currently working on this for different platforms, like Mach-O for MacOS, as well as ARM CPUs.

This ended up being much more complicated than expected because while Linux uses libstdc++ (which is the GCC implementation of C++), MacOS uses libc++ (the CLANG implementation of C++) and they are quite different. So this is still in progress, but getting close to completion.

So now that you have all the history, please take a look at the project, and let me know what you think! -- https://github.com/derekbsnider/madc

u/kindredseer — 2 months ago