Implement the following plan:
Fix #85: Support receive into indexed target variables
Context
Channel receive (ch ? var) only accepts a simple identifier as the target. Indexed targets like flags[0] or state.of.neighbour[d] cause parse failures because the parser uses expectPeek(IDENT) and leaves the [...] unprocessed. The same limitation affects ALT case parsing. This blocks historical-examples/life.occ (issue #72).
The fix adds VariableIndices []Expression to Receive and AltCase, mirroring the existing ChannelIndices and Assignment.Indices patterns.
Changes
1. AST — ast/ast.go
Add VariableIndices []Expression field to both structs:
Receive (line 378): Add after Variable string
AltCase (line 402): Add after Variable string
2. Parser — parser/parser.go
After each expectPeek(IDENT) + Variable = curToken.Literal site, add index collection loop:
for p.peekTokenIs(lexer.LBRACKET) {
p.nextToken() // move to [
p.nextToken() // move past [
<target>.VariableIndices = append(<target>.VariableIndices, p.parseExpression(LOWEST))
if !p.expectPeek(lexer.RBRACKET) {
return nil
}
}
5 locations:
1. parseReceive() (~line 1294) — stmt.VariableIndices
2. parseIndexedOperation() receive branch (~line 792) — stmt.VariableIndices
3. parseAltCase() simple channel (~line 1765) — altCase.VariableIndices
4. parseAltCase() indexed channel (~line 1785) — altCase.VariableIndices
5. parseAltCase() guarded channel (~line 1825) — altCase.VariableIndices
3. Codegen — codegen/codegen.go
Build variable reference with indices using existing generateIndicesStr():
6 locations:
1. generateReceive() simple path (~line 1362): Append indices to varRef
2. generateReceive() sequential path (~line 1349): Append indices to primary varRef
3. generateAltBlock() guarded case (line 1906): Build varRef with indices
4. generateAltBlock() indexed channel case (line 1908): Build varRef with indices
5. generateAltBlock() simple channel case (line 1912): Build varRef with indices
6. generateReplicatedAlt() (line 2043): Build varRef with indices
Pattern at each site:
varRef := goIdent(name)
if len(indices) > 0 {
varRef += g.generateIndicesStr(indices)
}
4. Tests
Parser tests (parser/parser_test.go):
- TestReceiveIndexedVariable: ch ? flags[0] — verify VariableIndices has 1 entry
- TestReceiveMultiIndexedVariable: ch ? grid[i][j] — verify 2 indices
- TestIndexedChannelReceiveIndexedVariable: cs[0] ? flags[1] — both channel and variable indexed
E2E tests (codegen/e2e_concurrency_test.go):
- TestE2E_ReceiveIntoIndexedVariable: Simple channel receive into array element
- TestE2E_IndexedChannelReceiveIntoIndexedVariable: cs[i] ? arr[j] pattern
Verification
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/cccd5ad5-122e-445d-bd16-94c2d59c7a1a.jsonl