Source file is Justine Tunney's published BLC virtual machine:
https://justine.lol/lambda/lambda.c. In the redbean #topics/lambda
thread on 2026-04-19 she described it as
mostly works however I think it has a subtle bug I never got around to fixing.
This directory contains the upstream source plus the fix.
Abs() calls Bye() whenever it encounters an ABS instruction with
an empty continuation stack (!contp). Bye() reads mem[ip+2] as an
exit code:
void Bye(void) {
int rc = mem[ip + 2]; // (λ 0) [exitcode]
if (rc) Error(rc, "CONTINUATIONS EXHAUSTED");
if (postdump && !rc) Dump(0, end, stderr);
exit(0);
}That comment is the assumption: ip is the exit ABS at ROM position
24, where mem[26]=0, so rc=0 and we exit cleanly.
In practice a well-formed program can run out of continuations at other
ABS positions. The clearest case in bit mode: after the lazy input list
bottoms out via NIL and the wrapper's bit-emission chain is exhausted,
control returns to position 14 (the λ.0 wr0 wr1 ABS). At that point
mem[14+2] = mem[16] is the span operand of the APP at ROM position
15, which is 4. rc = 4, not zero, so lambda.c reports
CONTINUATIONS EXHAUSTED and exits with status 4. Tromp's uni and
the AIT reference implementation both exit cleanly on the same input
with the same output bytes.
Concatenate take1k.blc (an ASCII-bit BLC program from Tromp's AIT
distribution) with a short input:
( cat /tmp/AIT/bin/take1k.blc; printf 'hello world!' ) | ./lambdaBefore the fix:
010010110001
ERROR: CONTINUATIONS EXHAUSTED
ip: 14
end: 211
term: put
[exit 4]
After the fix:
010010110001
[exit 0]
uni -b produces the same 12 output bytes and exits 0.
Drop the spurious exit-code reading. Treat empty-contp at any ABS
as graceful program completion. This matches the behavior of Tromp's
uni and the IOCCC reference. The exit-code mechanism only worked
when the program reached one specific ROM position; in normal
execution the wrapper never routes there, so removing it changes
nothing for well-formed programs and removes the spurious error for
programs that terminate elsewhere.
void Bye(void) {
if (postdump) Dump(0, end, stderr);
exit(0);
}The full diff is in this directory; see lambda.c lines 168-185.
make # builds ./lambda
make test # 4 regression tests including byte-for-byte parity vs uniThe fourth test requires /tmp/AIT/uni and /tmp/AIT/bin/take1k.blc
from https://github.com/tromp/AIT; otherwise it is skipped.
The C sources lambda.c, blc.h, vars.c, parse.c, getbit.c,
needbit.c, error.c, print.c, debug.c, dump.c, fgetwc.c,
fputwc.c, tromp.c, lam2bin.c, Blc.S are all from
https://justine.lol/lambda/. Only lambda.c is modified. The change
is the rewrite of Bye(). Everything else is verbatim.
reverse.Blc is from the same source, used in the test suite.