Implement the following plan:
Fix: Scope boolVars per proc/function body (Issue #56)
Context
The boolVars map in codegen.go is flat and global. A pre-pass (collectBoolVars) adds ALL BOOL-typed variables from the entire program (including #INCLUDEd modules) into a single map. When generating a type conversion like INT16 b where b is a BYTE, the codegen checks g.boolVars["b"] and incorrectly finds true because a different proc in an included file declared BOOL b:. This produces invalid Go: int16(_boolToInt(b)) instead of int16(b).
Approach
Follow the existing refParams scoping pattern (save/restore in generateProcDecl):
Changes in codegen/codegen.go
1. Scope boolVars in generateProcDecl (~line 1927)
After the existing oldRefParams save (line 1929), add save/restore for boolVars:
- Save:
oldBoolVars := g.boolVars
- Create new map: fresh for top-level procs (
nestingLevel == 0), inherited copy for nested procs (closures can reference parent BOOL vars)
- Register BOOL-typed params from
proc.Params (where p.Type == "BOOL" and not a chan/chanArray)
- Also delete non-BOOL params that shadow inherited names
- After body generation, restore:
g.boolVars = oldBoolVars (next to existing g.refParams = oldRefParams at line 2016)
generateVarDecl (line 1084-1088) already adds BOOL vars dynamically during body generation, so local BOOL declarations will correctly populate the scoped map.
2. Scope boolVars in generateFuncDecl (~line 2103)
Same pattern: save before body generation, create scoped map (inheriting if nested), register BOOL params, restore after body.
Files to modify
codegen/codegen.go — generateProcDecl, generateFuncDecl
What stays unchanged
- The pre-pass
collectBoolVars (lines 114-117) — still needed for containsBoolConversion to decide whether to emit the _boolToInt helper function
generateVarDecl BOOL tracking (lines 1084-1088) — already correct, adds to whatever the current scoped map is
isBoolExpression (line 2675) — no changes needed, it already checks g.boolVars
Verification
# Reproduce the bug (should fail with go vet error before fix)
./occam2go -I kroc/modules/course/libsrc -D TARGET.BITS.PER.WORD=32 -o /tmp/cast.go kroc/modules/course/examples/cast.occ
go vet /tmp/cast.go
# Full course module still compiles
./occam2go -I kroc/modules/course/libsrc -D TARGET.BITS.PER.WORD=32 -o /tmp/course_out.go kroc/modules/course/libsrc/course.module
go vet /tmp/course_out.go
# All existing tests pass
go test ./...
If you need specific details from before exiting plan mode (like exact code snippets, error messages, or content you generated), read the full transcript at: /home/david/.claude/projects/-home-david-projects-code-associates-occam2go/f025241a-2f05-4a0f-bd8b-62efa9622376.jsonl