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.
53 lines
3.0 KiB
Markdown
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.
|