The loop that fixes the language is written in the language
Since the last devlog the work split in two: a development loop that RaidenScript now drives itself, and a repository that finally stopped mixing the language with a game server.
selfdev - the decision logic is a .rai file
tools/selfdev.rai holds the loop’s rules: pick an area nobody touched last round, run the build, read the log, call the pass green or red, append its own entry to a round journal. Under it sits tools/rsdev.cpp, a sys.* host built on the same C API the browser game and the Minecraft plugin already use. The language had three hosts. The fourth one is its own toolchain.
Pass 2 taught it what not to trust. tools/selfdev-build.cmd reported EXIT=0 for a run that failed to link. The cause is not in the language at all: exit /b inside a ( … ) » log 2>&1 block does not end a .cmd script, so control falls through to the final exit /b 0. A loop whose whole contract is “exit 0 means green” can commit on red - and it did once, on stale .o files. The rule now is read the log, not the exit code, and it is written in capitals at the top of SELFDEV-NOTES.md because I expect to forget it.
What the passes actually fixed
- String building was quadratic. At 60,000 pieces: s += x took 1879 ms, s = s + x took 2382 ms, against a list.push + join baseline of 54 ms - 35x and 44x. Strings stay immutable (SPEC section 2), the fix is ownership: when the slot is the only owner, append in place. Both forms now run in about 25 ms. The indexed form d[k] += x was a separate code path and stayed quadratic after the first fix, so it took a second pass to catch.
- The measurement size was part of the test. At 24,000 pieces the s = s + x check passed green: 288 KB fits in L2 and quadratic copying looks cheap in cache. At 60,000 (720 KB) both went red.
- f-strings could not hold a quoted string inside an interpolation, although SPEC 9/3 said they could. f”{sys.read(“a.txt”)}” was a syntax error. The spec was right and the parser was wrong.
- A blank line in a CRLF file closed a block early. The lone \r counted as content - the kind of bug that only shows up on someone else’s machine.
- Two C API bugs: rs_call could return an empty error message, and a nested rs_call corrupted the string channel of the outer primitive.
- The JVM bridge silently collapsed an int-returning host primitive to 0. Silent zeros are the worst class: the plugin keeps running and the numbers are simply wrong.
68 C API checks green, zero compiler warnings, sanitizer run clean. 29 keywords, still capped at 30. No C API signature changed.
The branch split
227 commits had piled up unpushed and 216 of them were the Minecraft plugin demo. I reset main to origin, cherry-picked only the 13 language and tooling commits, and left the rest on its own branch. main is the language. Nothing else goes there.
Most of the time logged on this project since the last devlog went into that plugin demo - the JVM binding exercised against a real server - and that branch is not on GitHub yet. The language fixes above came out of the unattended loop.I read every pass and hand-picked what entered main. The design, the spec and the original src/ are mine. Logged hours are my editor time only.
Comments 0
No comments yet. Be the first!
Sign in to join the conversation.