Files
sx/current/CHECKPOINT-EXTERN-EXPORT.md
agra 78e304f552 test(ffi-linkage): xfail example for extern fn binding (Phase 1.0b)
Add examples/1223-ffi-extern-fn.sx — binds libc 'abs' via bare 'extern'
(sx name = C symbol, no rename). Hand-authored expected/ captures the
SUCCESS output (abs(-7)=7 / abs(42)=42, exit 0).

RED: 1223 is the sole corpus failure (634 ran, 1 failed) — it parses
then errors at sema ('body produces no value') because lowering does
not yet route extern fns through declareExtern. Phase 1.1 wires the
lowering and turns this green.

xfail commit per the cadence rule (no commit both adds a test and makes
it pass).
2026-06-14 13:06:54 +03:00

3.8 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 1.0b (xfail — example half of 1.0) — added examples/1223-ffi-extern-fn.sx (extern-binds libc abs via bare extern; sx name = C symbol, no rename) + hand-authored expected/ capturing the SUCCESS output (abs(-7) = 7 / abs(42) = 42, exit 0). RED: 1223 is the only corpus failure (634 ran, 1 failed) — it parses then errors at sema (body produces no value) because lowering doesn't route extern yet. Phase 1.1 turns it green. (Prior: 1.0a (lock, green) wired fn-path extern parsing — parseFnDeclparseOptionalExternExport()FnDecl.extern_export, ; body = empty-block placeholder; both lookahead predicates accept kw_extern/kw_export; per user feedback added FnDecl.extern_lib/extern_name + VarDecl.extern_lib, decision 4 REVISED.)

Current state

Syntax: bare extern/export, postfix after callconv(.c), extern ⇒ callconv(.c). Decision 4 revised (user 2026-06-14): extern carries an optional LIB+"csym" axis (extern_lib/extern_name) like #foreign; the #library decl + build-flag linking stays separate. Touch-points: 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). Part B foreign footprint to purge: 643 lines / ~57 identifiers in src/ + 28 doc lines. End-state invariant: zero foreign (Phase 9.4 gate). Done: tokens (0.0) + AST/parser plumbing (0.1) + fn-path extern parsing

  • lib/name fields (1.0a), all unconsumed. Lowering not yet wired.

Next step

Phase 1.1 (green, turns 1223 green) — in decl.zig, when fn_decl.extern_export == .extern_, route the fn through declareExtern (is_extern, .external linkage, callconv(.c), no implicit ctx — anchors decl.zig:1123,387, 2110,2113) instead of lowering the empty-block placeholder body. Treat the bare extern (no extern_lib/extern_name yet) like a lib-less #foreign import — the sx name IS the C symbol, resolves against the default-linked libc. Run, then -Dupdate-goldens to finalize 1223's snapshot byte-exact; review diff. Then 1.2 (green): consume extern LIB "csym" rename (extern_lib/extern_name) + 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.
  • (1.0a) Wired fn-path extern parsing (parseFnDecl + both lookahead predicates) + added FnDecl.extern_lib/extern_name + VarDecl.extern_lib per user feedback (decision 4 revised: extern carries an optional lib axis). Unconsumed by lowering. Suite green (443/633). lock commit.
  • (1.0b) Added examples/1223-ffi-extern-fn.sx + hand-authored success snapshots. RED (634 ran, 1 failed — sema body produces no value). xfail commit; 1.1 greens it.

Known issues

None yet.