The user is asking what happened - I was in the middle of exploring the codebase in plan mode and then stopped responding. Let me continue with the plan. I need to write the plan file and call ExitPlanMode.
Let me write the plan file now based on all the research I've done.
Sorry about that — I got interrupted mid-flow. I have all the information I need from the exploration. Let me write the plan file now and present it for your approval.
# Fix Parser Infinite Loop & Support Course Library Transpilation ## Context When transpiling programs that `#INCLUDE "course.module"`, the parser enters an infinite loop causing OOM. The root cause is that occam allows multiple declarations (specifications) scoped before a process in IF/CASE/ALT/WHILE branch bodies, but the parser only calls `parseStatement()` once per body. After parsing the first declaration, it tries to interpret subsequent declarations as new branch conditions, looping forever. A secondary issue is that channel direction annotations at call sites (`out!`, `in?`) aren't handled in expression parsing, causing the first parse error at line 188 of the preprocessed output. ## Changes ### 1. AST: Change `Body` from `Statement` to `[]Statement` (ast/ast.go) Change in four structs: - `IfChoice.Body` (line ~207) - `CaseChoice.Body` (line ~223) - `AltCase.Body` (line ~397) - `WhileLoop.Body` (line ~192) ### 2. Parser: Add `parseBodyStatements()` helper (parser/parser.go) Add a new function modeled on `parseBlockStatements()` (line 1649) that: - Is called after the caller has consumed the INDENT token - Loops parsing statements at the current indent level until DEDENT - Includes a "no progress" safety guard to prevent infinite loops - Returns `[]ast.Statement` Update four call sites to use it: - `parseIfStatement()` (line ~2225): replace `parseStatement()` with `parseBodyStatements()` - `parseCaseStatement()` (line ~2305): same - `parseWhileLoop()` (line ~2148): same - `parseAltCase()` (line ~1635): same ### 3. Parser: Handle channel direction at call sites (parser/parser.go) In `parseProcCall()` (line 1893): after each `parseExpression(LOWEST)` for an argument, check if `peekToken` is `SEND` (`!`) or `RECEIVE` (`?`) and consume it. The direction annotation is informational — in Go codegen we just pass the channel. ### 4. Codegen: Update to iterate over body slices (codegen/codegen.go) **Generators** — change `g.generateStatement(x.Body)` to loop: - `generateWhileLoop()` (line 1503) - `generateIfStatement()` (lines 1551, 1574) - `generateCaseStatement()` (line 1605) - `generateAltBlock()` (line 1252) **Scanner functions** — change `containsX(x.Body)` to loop over slice: - `containsPar()` — AltCase (198), WhileLoop (215), IfChoice (220), CaseChoice (226) - `containsPrint()` — same pattern at ~258, 275, 280, 286 - `containsTimer()` — same pattern at ~309, 338, 343, 349 - `containsStop()` — same pattern at ~381, 398, 403, 409 - `containsMostExpr()` — same pattern at ~468, 476, 490, 511 - `collectChanProtocols()` — same pattern at ~901, 906, 912, 918 - `collectRecordVars()` — same pattern at ~957, 962, 968, 974 Note: `VariantCase.Body` has the same single-statement pattern but is left for a follow-up. ### 5. Tests - Update existing parser tests that access `.Body` (change `nil` checks to `len()` checks, access `Body[0]` instead of `Body`) - Add parser test for multi-statement IF body - Add parser test for channel direction at call site - Add e2e tests for both features ### 6. Documentation Update TODO.md to note these features are supported. ## Implementation Order 1. AST changes (will cause compile errors) 2. Parser changes (fixes parser compile errors) 3. Codegen changes (fixes codegen compile errors) 4. Test updates + new tests 5. `go test ./...` to verify 6. Try transpiling course library demo ## Verification ```bash go test ./... # all existing tests pass go build -o occam2go . ./occam2go gen-module -o kroc/modules/course/libsrc/course.module kroc/modules/course/libsrc/SConscript ./occam2go -I kroc/modules/course/libsrc kroc/demos/complexity/concurrent_hello_1.occ ``` Note: The full course library transpilation may surface additional unsupported constructs (e.g., `RETYPES` in float_io.occ). Those would be addressed as follow-up work. The immediate goal is fixing the infinite loop and the two feature gaps that block parsing.
{
"plan": "# Fix Parser Infinite Loop & Support Course Library Transpilation\n\n## Context\n\nWhen transpiling programs that `#INCLUDE \"course.module\"`, the parser enters an infinite loop causing OOM. The root cause is that occam allows multiple declarations (specifications) scoped before a process in IF/CASE/ALT/WHILE branch bodies, but the parser only calls `parseStatement()` once per body. After parsing the first declaration, it tries to interpret subsequent declarations as new branch conditions, looping forever.\n\nA secondary issue is that channel direction annotations at call sites (`out!`, `in?`) aren't handled in expression parsing, causing the first parse error at line 188 of the preprocessed output.\n\n## Changes\n\n### 1. AST: Change `Body` from `Statement` to `[]Statement` (ast/ast.go)\n\nChange in four structs:\n- `IfChoice.Body` (line ~207)\n- `CaseChoice.Body` (line ~223)\n- `AltCase.Body` (line ~397)\n- `WhileLoop.Body` (line ~192)\n\n### 2. Parser: Add `parseBodyStatements()` helper (parser/parser.go)\n\nAdd a new function modeled on `parseBlockStatements()` (line 1649) that:\n- Is called after the caller has consumed the INDENT token\n- Loops parsing statements at the current indent level until DEDENT\n- Includes a \"no progress\" safety guard to prevent infinite loops\n- Returns `[]ast.Statement`\n\nUpdate four call sites to use it:\n- `parseIfStatement()` (line ~2225): replace `parseStatement()` with `parseBodyStatements()`\n- `parseCaseStatement()` (line ~2305): same\n- `parseWhileLoop()` (line ~2148): same\n- `parseAltCase()` (line ~1635): same\n\n### 3. Parser: Handle channel direction at call sites (parser/parser.go)\n\nIn `parseProcCall()` (line 1893): after each `parseExpression(LOWEST)` for an argument, check if `peekToken` is `SEND` (`!`) or `RECEIVE` (`?`) and consume it. The direction annotation is informational — in Go codegen we just pass the channel.\n\n### 4. Codegen: Update to iterate over body slices (codegen/codegen.go)\n\n**Generators** — change `g.generateStatement(x.Body)` to loop:\n- `generateWhileLoop()` (line 1503)\n- `generateIfStatement()` (lines 1551, 1574)\n- `generateCaseStatement()` (line 1605)\n- `generateAltBlock()` (line 1252)\n\n**Scanner functions** — change `containsX(x.Body)` to loop over slice:\n- `containsPar()` — AltCase (198), WhileLoop (215), IfChoice (220), CaseChoice (226)\n- `containsPrint()` — same pattern at ~258, 275, 280, 286\n- `containsTimer()` — same pattern at ~309, 338, 343, 349\n- `containsStop()` — same pattern at ~381, 398, 403, 409\n- `containsMostExpr()` — same pattern at ~468, 476, 490, 511\n- `collectChanProtocols()` — same pattern at ~901, 906, 912, 918\n- `collectRecordVars()` — same pattern at ~957, 962, 968, 974\n\nNote: `VariantCase.Body` has the same single-statement pattern but is left for a follow-up.\n\n### 5. Tests\n\n- Update existing parser tests that access `.Body` (change `nil` checks to `len()` checks, access `Body[0]` instead of `Body`)\n- Add parser test for multi-statement IF body\n- Add parser test for channel direction at call site\n- Add e2e tests for both features\n\n### 6. Documentation\n\nUpdate TODO.md to note these features are supported.\n\n## Implementation Order\n\n1. AST changes (will cause compile errors)\n2. Parser changes (fixes parser compile errors)\n3. Codegen changes (fixes codegen compile errors)\n4. Test updates + new tests\n5. `go test ./...` to verify\n6. Try transpiling course library demo\n\n## Verification\n\n```bash\ngo test ./... # all existing tests pass\ngo build -o occam2go .\n./occam2go gen-module -o kroc/modules/course/libsrc/course.module kroc/modules/course/libsrc/SConscript\n./occam2go -I kroc/modules/course/libsrc kroc/demos/complexity/concurrent_hello_1.occ\n```\n\nNote: The full course library transpilation may surface additional unsupported constructs (e.g., `RETYPES` in float_io.occ). Those would be addressed as follow-up work. The immediate goal is fixing the infinite loop and the two feature gaps that block parsing.\n"
}The user doesn't want to proceed with this tool use. The tool use was rejected (eg. if it was a file edit, the new_string was NOT written to the file). STOP what you are doing and wait for the user to tell you how to proceed.