Files
sx/current/CHECKPOINT-EXTERN-EXPORT.md
agra 62a3b46f6e feat(ffi-linkage): extern/export parser+AST plumbing, unconsumed (Phase 0.1)
Add ast.ExternExportModifier { none, extern_, export_ } beside
CallingConvention; FnDecl.extern_export and VarDecl.is_extern/extern_name
fields (all defaulting to absent); and Parser.parseOptionalExternExport()
mirroring parseOptionalCallConv.

None of this is consumed by a decl path yet — no user-facing behavior
change, corpus diff empty. Two inline parser unit tests pin the helper's
keyword mapping and the field defaults. Phase 1.0 wires the helper into
the fn-decl path. lock commit.
2026-06-14 12:48:56 +03:00

53 lines
3.0 KiB
Markdown

# 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.1** (lock) — added `ast.ExternExportModifier = enum { none, extern_,
export_ }` (beside `CallingConvention`), `FnDecl.extern_export` (default `.none`),
`VarDecl.is_extern`/`extern_name` (defaults absent), and
`parser.parseOptionalExternExport()` (mirrors `parseOptionalCallConv`, just below it
at `parser.zig:~3683`). **Helper + fields defined but NOT consumed by any decl path**
— no user-facing behavior change, corpus diff empty. Two inline parser unit tests
(`parseOptionalExternExport recognizes linkage keywords`, `extern/export AST fields
default to absent`). Suite green (443 unit [+2] / 633 corpus, 0 fail).
## 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). **Phase 0 done**: tokens (0.0) + AST/parser plumbing
(0.1) exist, unconsumed. Phase 1 wires `extern` into the fn/global decl paths.
## Next step
**Phase 1.0** (xfail) — accept postfix `extern` after the callconv slot in the
fn-decl path (`parser.zig:1950`: call `parseOptionalExternExport()`, store on
`FnDecl.extern_export`); add `examples/12xx-ffi-extern-fn.sx` that extern-binds a libc
symbol — **red** (parses, but lowering not wired yet). Then 1.1 green (lower via
`declareExtern`: `is_extern`, `.external`, `callconv(.c)`, no ctx — anchors
`decl.zig:1123,387,2110,2113`), 1.2 green (`extern "csym"` rename + extern-global
`g : T extern;`, `parser.zig:425`). 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.
- (0.1) Added `ast.ExternExportModifier` + `FnDecl.extern_export` +
`VarDecl.is_extern`/`extern_name` + `parseOptionalExternExport()` (unconsumed) + 2
parser unit tests. Suite green (443/633). `lock` commit.
## Known issues
None yet.