Implement the following plan:
Plan: Get Course Module to Compile
Context
The occam2go transpiler has all the individual language features needed for the course module, but when transpiling the actual course.module file (which #INCLUDEs 8 source files), the parser hits several unsupported syntactic patterns that are pervasive in real-world occam code. Previous sessions fixed parser infinite loops; this session gets the module actually compiling.
Error Categories (from attempting ./occam2go -I kroc/modules/course/libsrc -o course_out.go kroc/modules/course/libsrc/course.module)
Phase 1: Parser fixes for core files (utils.occ, string.occ, demo_cycles.occ, demo_nets.occ, file_in.occ, random.occ)
Fix 1: Shared-type parameters (~50+ errors, affects every file)
- Occam allows CHAN INT in?, out! (two params sharing CHAN INT type), VAL INT a, b, c (three params sharing VAL INT), etc.
- Parser currently expects a full type declaration for each parameter after a comma
- File: parser/parser.go — parseProcParams() (~line 1864)
- Fix: After consuming a comma, peek at the next token. If it's an IDENT (not a type keyword/CHAN/VAL/[), re-use the previous param's type/flags and just parse name + optional direction
- Examples: PROC plus (CHAN INT in.1?, in.2?, out!), PROC cursor.x.y (VAL BYTE x, y, CHAN BYTE out!)
Fix 2: VAL []TYPE abbreviations (~5 errors)
- VAL []BYTE cmap IS "0123456789ABCDEF": — array abbreviation
- parseAbbreviation() (line 317) only handles scalar types after VAL
- File: parser/parser.go — parseAbbreviation()
- File: ast/ast.go — Abbreviation struct needs IsOpenArray bool
- File: codegen/codegen.go — generateAbbreviation() needs to handle array type
- Fix: Check for [ after VAL; if []TYPE, set IsOpenArray = true and parse the element type
Fix 3: [arr FOR n] shorthand slices (~8 errors)
- Occam shorthand for [arr FROM 0 FOR n]
- Parser requires FROM keyword but source uses FOR directly
- File: parser/parser.go — slice expression parsing (~line 2495) and parseSliceAssignment() (~line 564)
- Fix: After parsing array expr, if next token is FOR (not FROM), use integer literal 0 as start
Fix 4: Multi-line parameter lists (~4 errors)
- PROC ask.string (VAL []BYTE prompt, []BYTE s, INT length,\n VAL INT max, CHAN BYTE in?, out!)
- The lexer emits NEWLINE tokens inside (...) which breaks param parsing
- File: parser/parser.go — parseProcParams()
- Fix: Skip NEWLINE tokens at the start of each param iteration and after consuming commas
Fix 5: RESULT parameter qualifier (~4 errors, float_io.occ)
- PROC foo (RESULT INT len, RESULT []BYTE string, VAL REAL32 X, ...)
- RESULT in parameter position means output-only (write, don't read). Semantically same as non-VAL (pointer) in Go.
- File: parser/parser.go — parseProcParams()
- Fix: Add lexer.RESULT check similar to VAL check; just skip the keyword (it maps to pointer params like non-VAL)
Phase 2: float_io.occ specific fixes
Fix 6: Fixed-size array parameters [n]TYPE
- VAL [2]INT X — fixed-size array parameter
- File: parser/parser.go — parseProcParams()
- File: ast/ast.go — ProcParam needs ArraySize field
- File: codegen/codegen.go — param type generation
- Fix: When [ is followed by an integer (not ]), parse as [n]TYPE
Fix 7: RETYPES
- VAL INT X RETYPES X : — reinterpret REAL32 bits as INT
- VAL [2]INT X RETYPES X : — reinterpret REAL64 as two INTs
- File: parser/parser.go, ast/ast.go, codegen/codegen.go
- Fix: Parse as a new RetypesDecl statement. Codegen uses math.Float32frombits/Float64bits or unsafe pointer casts
Fix 8: Transputer intrinsics (LONGPROD, LONGDIV, LONGSUM, LONGDIFF, NORMALISE, SHIFTRIGHT, SHIFTLEFT)
- Extended-precision arithmetic for float-to-string conversion
- ~50+ occurrences in float_io.occ
- Fix: Parse as function calls (they already look like a, b := LONGPROD(x, y, z)). Implement as Go helper functions using math/bits or uint64 arithmetic
Fix 9: CAUSEERROR()
- Error-raising primitive
- Fix: Parse as procedure call, generate panic("CAUSEERROR")
Implementation Order (Phase 1 only — float_io.occ deferred)
- Fix 1 (shared-type params) — unlocks most PROCs
- Fix 4 (multi-line params) — needed for a few PROCs
- Fix 2 (VAL []TYPE abbreviations)
- Fix 3 ([arr FOR n] slices)
- Fix 5 (RESULT qualifier) — only needed for float_io.occ, include for completeness
- Create a reduced
course_nofloat.module excluding float_io.occ for testing
- Fix any remaining codegen issues that emerge when Go-compiling the output
Phase 2 (float_io.occ) deferred to a future session.
Files to Modify
parser/parser.go — Fixes 1-6
ast/ast.go — Fixes 2, 6 (add IsOpenArray to Abbreviation, ArraySize to ProcParam)
codegen/codegen.go — Fixes 2, 6 (abbreviation and param generation)
lexer/token.go — May need RESULT as a recognized keyword (check if already present)
Verification
After each fix:
go test ./... # ensure existing tests still pass
After all Phase 1 fixes:
# Transpile course module excluding float_io.occ (create a reduced module file)
# Or transpile the full module with -D TARGET.BITS.PER.WORD=32 and check which errors remain
./occam2go -I kroc/modules/course/libsrc -D TARGET.BITS.PER.WORD=32 -o course_out.go kroc/modules/course/libsrc/course.module 2>&1
# If float_io.occ is too complex, create a course_nofloat.module that excludes it
# and verify the rest compiles:
# go build course_out.go
After all Phase 1 fixes:
# Create a course_nofloat.module that excludes float_io.occ
# Transpile it:
./occam2go -I kroc/modules/course/libsrc -D TARGET.BITS.PER.WORD=32 -o course_out.go course_nofloat.module
# Verify Go compilation:
go build course_out.go
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/165f2ab5-3d3c-45b5-b8be-71d8e1cc5d3e.jsonl