Files
sx/current/CHECKPOINT-EXTERN-EXPORT.md
agra bf6ef8370f feat(ffi-linkage): add kw_extern/kw_export tokens (Phase 0.0)
Lex 'extern' and 'export' as keywords beside 'callconv': new token.Tag
variants + keywords StaticStringMap entries + LSP semantic-token keyword
classification. Adds a 'lex linkage keywords' unit test.

Tokens only — parser/AST plumbing and lowering land in later phases.
Corpus sweep confirmed no .sx identifier collides with the new reserved
words. lock commit per the cadence rule.
2026-06-14 12:40:35 +03:00

2.5 KiB

sx extern/export + #foreign retirement — Checkpoint (FFI-linkage stream)

Companion to current/PLAN-EXTERN-EXPORT.md — one merged plan: Part A adds extern/export, Part B migrates #foreign and purges foreign. Update after every commit, one step at a time per the cadence rule.

Last completed step

Phase 0.0 (lock) — added kw_extern/kw_export to token.Tag + the keywords StaticStringMap (beside kw_callconv, token.zig:45,282); classified both as ST.keyword in the LSP classifyToken exhaustive switch (lsp/server.zig); added test "lex linkage keywords" in lexer.zig. Suite green (441 unit / 633 corpus, 0 fail). extern/export are now reserved words; corpus sweep confirmed no .sx identifier used either (only comments + the unpinned issues/0030-* repro, which doesn't run in the suite).

Current state

Syntax decided + ratified: bare extern/export, postfix in the callconv(.c) slot, extern ⇒ callconv(.c), library separate. Touch-points mapped — token token.zig:45,282; parser 1950,3669,316,425,1305; lowering decl.zig:1123,387,2110,2382,2514; IR/emit already capable (no codegen change). Export gap = 4 lowering conditions. Part B foreign footprint to purge: 643 lines / ~57 identifiers in src/ + 28 doc lines. End-state invariant: zero foreign in the live tree (Phase 9.4 gate). Tokens exist (0.0); parser/AST not yet plumbed.

Next step

Phase 0.1 (lock) — parseOptionalExternExport() (mirror parseOptionalCallConv, parser.zig:3669) + ast.ExternExportModifier enum + FnDecl.extern_export + VarDecl.is_extern/extern_name fields; parsed but not yet consumed; unit AST test. Then Phase 1 (extern working: 1.0 xfail accept postfix, 1.1 green lower via declareExtern, 1.2 green rename + extern-global). See the plan's "Kickoff prompt". Stop at end of Phase 1.

Open decisions

Part A ratified (bare / postfix / ⇒ callconv(.c) / lib-separate). Part B (confirm before Phase 9): runtime-class rename target — Runtime*Class* (recommended); historical carve-out — keep issues/*.md provenance, gate the live tree only.

Log

  • (init) Plan written; FFI-linkage stream opened.
  • (merge) Folded FOREIGN-MIGRATION in as Part B; deleted the split plan + checkpoint.
  • (0.0) Added kw_extern/kw_export tokens + keyword-map entries + LSP keyword classification + lex linkage keywords test. Suite green; no identifier collisions in the corpus. lock commit.

Known issues

None yet.