Skip to content

HowlFrame #90 Phase 3b: experimental while bytecode - #59

Merged
howlcipher merged 1 commit into
mainfrom
cursor/hfir-while-control-edges-1c56
Sep 30, 2026
Merged

howlcipher merged 1 commit into
mainfrom
cursor/hfir-while-control-edges-1c56

Conversation

@howlcipher

Copy link
Copy Markdown
Owner

Summary

Experimental -compile-hfir-bc now compiles and runs a tiny while. LowerAST records that loop header's control edges as the condition, then the body. LowerToBytecode follows those edges and emits the existing JUMP_IF_FALSE and JUMP opcodes, with the same relative offsets as the AST bytecode compiler. A while whose control edges are missing or swapped fails closed with HFIR_BYTECODE_UNSUPPORTED and no bytecode program.

Production -compile-bc is still runHFIRGate and then bytecode.CompileToBytecode on the AST. sleep still compiles on that flag and is still rejected by -compile-hfir-bc. This is not a CFG or SSA pass: if, for, and every other node still have empty control edges. No new opcode, no new capability, no Wasm, and no module linker. The model-adapter transport still rejects while, so #88 stays closed. write_file and mkdir stay deferred. #90 stays Partial.

Journal: docs/journals/2026-09-30_lowered_hfir_abi_phase3b_while.md.

How to test

gofmt -l .
go vet ./...
go test ./...

The shared fixture is tests/conformance/abi_v1/10_while.howl (while_control in tests/conformance/lowered_hfir_abi_v1.json). A false loop must not print. A counting loop prints 1, 2, and 3 on the experimental bytecode path, production bytecode, the interpreter, Go, and JavaScript:

go test ./tools/difftest/ -run TestLoweredHFIRABIConformance -count=1

go test ./internal/vm/ -run TestHFIRBytecode -count=1 compares the experimental artifact with AST bytecode on a counting loop, a loop that does not enter, a nested loop, a loop inside defun, and a non-bool condition (TYPE_ERROR, empty stdout).

Open in Web Open in Cursor 

-compile-hfir-bc now emits existing JUMP_IF_FALSE and JUMP for while. A while header's control edges are the condition, then the body. Production -compile-bc stays AST bytecode after the gate. #90 stays Partial.

Co-authored-by: William Elias <wylelias.123@gmail.com>

@howlcipher howlcipher left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Phase 3b looks clean on the fence.

-compile-hfir-bc now runs a tiny while off ControlEdges (condition → body) with the existing JUMP_IF_FALSE / JUMP layout. Prod -compile-bc is still AST after the gate — locked by the sleep split. No new opcode, no new cap, no Wasm, no linker, no #88 reopen. write_file / mkdir stay deferred. #90 stays Partial.

Hard nos look clean. CI build is green on d466ff5e. Good to undraft + squash-merge when you’re ready — leave #90 Partial.

@howlcipher
howlcipher marked this pull request as ready for review September 30, 2026 05:15
@howlcipher
howlcipher merged commit 0cf7d23 into main Sep 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants