Skip to content

parser: allow Map (and comma-bearing generics) as class state fields - #14

Merged
code-by-sia merged 1 commit into
mainfrom
map-in-state
Aug 2, 2026
Merged

parser: allow Map (and comma-bearing generics) as class state fields#14
code-by-sia merged 1 commit into
mainfrom
map-in-state

Conversation

@code-by-sia

Copy link
Copy Markdown
Owner

The state { } init-token collector tracked (), [], and {} depth but not <>, so the comma inside a generic default such as = empty Map<String, Integer> read as depth-zero and ended the field early. The result was a garbled state block; the alias workaround (type IntMap = Map<...>) then hit a second issue where empty <alias> emits a null {0} struct that crashes at first use.

Fix

Track </> (token kinds 114/115) in the collector, so a Map (or any comma-bearing generic) can be a class state field directly. Construction goes through the existing, correct empty Map<...> codegen path, so no {0} and no alias needed:

class Counter {
    state { counts: Map<String, Integer> = empty Map<String, Integer> }
    consumer add(k: String) { this.counts.put(k, this.counts.getOr(k, 0) + 1) }
}

Follow-through

The metrics Meter (std/monitoring/instruments.xi, added with the tracing suite) used a scanned List<compound> to work around this. It now uses Maps directly with O(1) lookups, dropping ~40 lines.

Verification

  • New regression test examples/language/map_state_test.xi.
  • Self-hosting fixpoint holds (gen2 == gen3); all 45 existing test files pass.
  • Still out of scope (separate gap): Map<String, SomeCompound> (compound values) is not monomorphized; use List<compound> there.

The state-block init-token collector tracked (), [], and {} depth but not <>, so
the comma inside a generic default such as `= empty Map<String, Integer>` read
as depth-zero and ended the field early. That left a garbled state block, and
the alias workaround (`type IntMap = Map<...>`) hit a second issue where
`empty <alias>` emits a null {0} struct, crashing at first use. Track <> in the
collector so a Map (or any comma-bearing generic) can be a class state field
directly, constructed properly by the existing empty Map<...> codegen.

The metrics Meter (std/monitoring/instruments.xi) now uses Maps directly with
O(1) lookups instead of a scanned list. Regression test in
examples/language/map_state_test.xi; the self-host fixpoint holds and all
existing tests pass.
@code-by-sia
code-by-sia merged commit 2271166 into main Aug 2, 2026
2 checks 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.

1 participant