The first program I ever wrote was in a school notebook. A guessing game, in plain steps: pick a number, ask the player, if too low say "too low." I couldn't run it, obviously. Notebooks don't have compilers.
That annoyed me more than it should have. Every beginner can write an algorithm in plain language — the syntax is the gatekeeper, not the logic. So a year ago, at 13, I started building the unreasonable version of the fix: a programming language where the pseudocode is the code.
This week it hit v0.4.1 — a native VM written from scratch in C++17, zero dependencies, and an AOT backend that compiles your program to machine code. It's called X++ (more on the name later, unfortunately).
aagastyaverma6-sys
/
XPP
X++ is a versatile and superfast programming language made by Aagastya Verma i.e. Atom Software. It contains various modes with different speeds and a included a fully semantic, algorithmic mode using OpenRouter API.
X++ (XPlusPlus) v0.4.1
Programming For Everyone
Same pseudocode. Same ease. Now a real native VM.
X++ is an intent-driven language: you write strict pseudocode (or loose English steps for the AI mode), type one command, and it booms. Version 0.4.1 adds a zero-dependency native VM (C++17) so your programs run without Python — the Python stack is still available for the legacy and AI paths.
-
Ease of Python – pseudocode syntax, automatic garbage collection, no pointers, no manual memory management, no build files. Write the code, type
x run app.xp, done. -
Speed of native code – ZITR is a fast stack VM; ZJIT compiles your
.xpstraight to machine code (via portable C++ emitted by the backend, compiled with your system compiler). -
Unmatched compatibility – the VM and the native backend are pure C++17 and build on Windows / Linux / macOS. Same bytecode
.xbc(.bc)…
What it looks like
RNM=ZITR
fn fib(n):
if n <= 1:
return n
end
return fib(n-1) + fib(n-2)
end
loop i from 0 to 10:
out i, fib(i)
end
That's a complete program. x run fib.xp prints the table.
The entire language fits in a tweet's worth of rules: blocks end with end. No types, no brackets, no semicolons. push 4 to nums reads like what it does. Errors say division by zero, not TypeError: unsupported operand type(s) for /: 'int' and 'int'. Errors you can catch, too:
safe:
x = 1 / 0
fail e:
out "caught:", e
end
Lists, dicts, loop x in list, loop i from 1 to 10 step 2, closures, recursion, and/or that short-circuit. That's the whole shape of it.
How it got out of hand
v0.3 was, I'll admit it, a Python transpiler. X++ went in, Python came out, exec happened. It worked! It also felt like cheating. And it meant my "language" died without Python installed and ran at Python speed.
So for v0.4 I wrote a real engine — no dependencies, pure C++17:
-
NaN-boxed values. Int, float, string, list, dict, function, builtin — all in one machine word. Fun consequence I discovered the hard way:
nil + 1returnsnilinstead of erroring, because the nil tag collides with a float path in my arithmetic. I've been calling it "nil propagation" until someone convinces me it's a bug. - Arena garbage collection. No reference counting, no manual freeing. You write pseudocode; the VM cleans up.
- A flat, non-recursive dispatch loop. A function call pushes a frame and the loop re-fetches it — no C++ recursion. My v0.1 interpreter was recursive and crashed around 100 frames deep. Recursion now works past 20,000.
- ZJIT, the fun one: it transpiles your program into a single self-contained C++ file (runtime inlined), compiles it with your system's g++/clang, and caches the binary — rebuilds only when the source changes.
You pick the engine with one header line: RNM=ZITR (VM), RNM=ZCOM (bytecode AOT), RNM=ZJIT (native). Same .xp file, same language, three different machines underneath.
The numbers, asterisks included
| Workload | CPython 3.11 | ZITR (my VM) | ZJIT (native AOT) |
|---|---|---|---|
| sum 1..5,000,000 | 381 ms | 202 ms | 50 ms |
| fib(28), recursive | 55 ms | 91 ms | 10 ms |
Asterisks, because I'd rather say them first:
- One machine, my machine (Linux x86-64, g++ 12.2).
bash bench/test_all.shreproduces everything — run it and post your numbers, good or bad. - ZJIT times exclude the first build (~1s, then cached).
- Yes, you read the table right: my VM loses the recursive fib to CPython. Call overhead is real and it's my next battle — a register JIT with profiling feedback is on the roadmap. I'd rather show the loss than hide it.
I diffed my language against itself
The project's website has a playground that runs X++ entirely in your browser — a full JavaScript port of the VM's semantics. I didn't trust myself to write the same language twice (correctly, it turns out), so I built a test harness that runs 40+ programs on both engines and requires byte-identical stdout, stderr, and exit codes.
It caught real things. My favorite: while porting sum(), I discovered the native version drops the integer total if a float shows up later in the list — a genuine bug in my C++ accumulator. I reproduced it faithfully in the JavaScript port anyway, because right now divergence scares me more than bugs. Both get fixed in 0.4.2. Fidelity first, correctness second, apparently.
Things I got wrong (an incomplete list)
- The name. Microsoft Dynamics has had a language called X++ for decades. I found out after I'd committed. Genuinely collecting suggestions.
- My first interpreter blew the stack at 100 recursion frames and I shipped it anyway.
- The
sum()thing above.
Try it
- Playground (browser, no install): https://xpplang.vercel.app/playground.html
- Code (GPL-3.0): https://github.com/aagastyaverma6-sys/XPP
- Learn X++ in 15 minutes: https://xpplang.vercel.app/docs.html
What's next: modules (use "file.xp"), a register JIT with profiling feedback, and native FFI.
The part of a project you can't see from the inside is the part you got wrong — so benchmark it, break it, open issues, argue with me about end vs indentation. The feedback form on the site goes straight to my inbox and the issue tracker is right there. Sharp feedback is the most useful thing you can hand me.
VERY BIG NOTE
The website html and css was LLM generated, so if you smell AI there then you are right, also same is true for the readme because I don't have the skills to write a proper cool README so sorry for that too.
— Aagastya Verma · Atom Software
Top comments (0)