tool/lambda: fix Bye() exit-code interpretation at non-exit ABS#1497
Open
calvinbeighle wants to merge 1 commit into
Open
tool/lambda: fix Bye() exit-code interpretation at non-exit ABS#1497calvinbeighle wants to merge 1 commit into
calvinbeighle wants to merge 1 commit into
Conversation
Bye() unconditionally treated mem[ip+2] as an exit code, assuming ip was at a lambda whose body is VAR N. In practice the wrapper allows termination at other ABS positions where mem[ip+2] is a span operand. Reproducer: ( cat tromp_AIT/take1k.blc; printf 'hello world!' ) | ./lambda old: CONTINUATIONS EXHAUSTED, exit 4 new: exit 0, output byte-for-byte matches Tromp's uni Fix only interprets mem[ip+2] when the body actually starts with VAR.
jart
requested changes
Apr 30, 2026
| } | ||
|
|
||
| /* | ||
| * Called from Abs() when a lambda is reached with no continuation. The |
Owner
There was a problem hiding this comment.
Thanks for finding the bug. There's no point in explaining a bug fix in the source code for all history. It's more appropriate to put that in the commit message. So long as the commit message follows the 72 column justification like other messages. Only LLMs I've seen write comments this way.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bye()intool/lambda/lambda.creadsmem[ip+2]as an exit code:That assumes
ipis at aλ.NABS whose body is exactlyVAR N, which holds at the exit ABS at ROM position 24 (mem[24]=ABS,mem[25]=VAR,mem[26]=0) and gives a cleanexit(0).But
Abs()callsBye()for any ABS with emptycontp, and the wrapper allows execution to terminate at other ABS positions whose bodies are notVAR N. The clearest case in bit mode: when the lazy input list bottoms out viaNIL, control returns toip=14(the innerλ. 0 wr0 wr1). Theremem[15]=APPandmem[16]=4(a span operand), so the old code reportsCONTINUATIONS EXHAUSTEDand exits 4.Reproducer
take1k.blcis from https://github.com/tromp/AIT.Before:
After:
Tromp's
uni -bfrom AIT produces the same 12 output bytes and exits 0 on the same input.Fix
Only interpret
mem[ip+2]as an exit code when the body actually looks likeVAR N(i.e.mem[ip+1] == VAR). This preserves the original intent — clean exit through the exit ABS at ROM position 24 is unchanged — and removes the spurious error in cases where the program terminates at a non-exit ABS.This is the bug Justine mentioned in the redbean
#topics/lambdachannel on 2026-04-19 ("mostly works however I think it has a subtle bug I never got around to fixing"). I haven't audited for other bugs.Verification
Standalone build + 4 regression tests at https://github.com/calvinbeighle/lambda-c-fix, including byte-for-byte parity vs Tromp's
uniontake1k.blc + 'hello world!'.