34 Commits

Author SHA1 Message Date
agra
f3c9747f5a chore(ffi-linkage): post-stream polish — vscode keywords + vestigial param + extension metadata
Two post-stream follow-ups flagged in CHECKPOINT-EXTERN-EXPORT.md, plus a
reproducible vscode-extension packaging setup:

- parser: drop the vestigial `RuntimeClassPrefix.is_extern` field and
  `parseRuntimeClassDecl`'s `is_extern` param. Always false since the
  `#foreign` token was deleted; the postfix `extern`/`export` keyword is the
  sole reference-vs-define decider. No behavior change (644 corpus / 442 unit).
- vscode grammar: highlight `extern`/`export` as `storage.modifier.sx`.
- vscode packaging: declare `@vscode/vsce` as a devDep + add `package` /
  `vscode:prepublish` scripts so the vsix rebuilds reproducibly (was an
  ambient tool). Add repository/homepage/bugs (Gitea), icon (swipelab logo,
  256x256), galleryBanner, README with cover banner. Rebuilt the vsix.
2026-06-15 12:57:07 +03:00
agra
c1ab2cbfc0 docs(ffi-linkage): checkpoint — PHASE 9 COMPLETE, FFI-linkage stream DONE (9.4 gate passes) 2026-06-15 11:19:26 +03:00
agra
811a280517 refactor(ffi-linkage): Phase 9.3 — purge 'foreign' from comments (src caps + examples + docs)
src/: ~21 capital-Foreign comments the case-sensitive verify grep missed
(Foreign-class→Runtime-class, Foreign path→Runtime path, Foreign decls→Extern decls,
FOREIGN function→extern function) across calls/inst/ffi_objc/jni_descriptor/emit_llvm/
c_import/lower.*/ops. src 'foreign' now = ONLY the hash_foreign token + 4 rejection
messages (9.0-delete targets). examples/*.sx comments → extern/runtime-class (1219
stdout regen; KEPT 1176). docs/inline-asm-design + debugger purged. Comments only —
no build impact. 9.0 ratified: DELETE hash_foreign token next.
2026-06-15 10:52:56 +03:00
agra
145b6d8eff docs(ffi-linkage): checkpoint — Phase 9.1+9.2 IDENTIFIER purge COMPLETE; comment/doc/issues text purge remains 2026-06-15 09:21:55 +03:00
agra
98264b8640 docs(ffi-linkage): checkpoint — Phase 9.1a/b/c done (linkage purge started); collision analysis + scoped gate + ordered remaining plan 2026-06-15 08:48:33 +03:00
agra
7ca074e1b0 docs(ffi-linkage): checkpoint — PHASE 8 COMPLETE (cutover); Decision 6 ratified (purge everything); Phase 9 next 2026-06-15 08:08:33 +03:00
agra
8b91677a1b docs(ffi-linkage): checkpoint — Phase 7 migratable work COMPLETE (7.1-7.4); next Phase 8 cutover 2026-06-15 07:05:11 +03:00
agra
496390e442 docs(ffi-linkage): checkpoint — Phase 7.1 done + keep-list policy; next Phase 7.2 (13xx objc) 2026-06-15 06:50:26 +03:00
agra
d3425fa287 docs(ffi-linkage): checkpoint — Phase 6.4+6.5 done; PHASE 6 COMPLETE (library/ #foreign-free); next Phase 7 2026-06-15 06:25:16 +03:00
agra
48a8769d19 docs(ffi-linkage): checkpoint — Phase 6.3 (std) done; next Phase 6.4 (ffi) 2026-06-15 04:36:28 +03:00
agra
0fbcee7e36 docs(ffi-linkage): checkpoint — Phase 6.2 (platform) done; next Phase 6.3 (std) 2026-06-15 04:33:06 +03:00
agra
32e83c90cc docs(ffi-linkage): checkpoint — Phase 6.1 (sqlite) done; next Phase 6.2 (platform) 2026-06-15 04:26:12 +03:00
agra
346d4a81c3 docs(ffi-linkage): checkpoint — Phase 5.1 done; PHASE 5 COMPLETE, next Phase 6 2026-06-15 04:22:24 +03:00
agra
bde284ee21 docs(ffi-linkage): checkpoint — Phase 5.0 parser routing COMPLETE (fn-body flip landed)
fn-decl #foreign body marker now builds the unified extern AST. All four
#foreign parser paths resolved (global + fn-body flipped; const-with-type
dead; runtime-class already coalesced). Decision 7 ratified (accept churn).
Next: Phase 5.1 (confirm A->B gate covers post-flip) then Phases 6-7
(source #foreign->extern rename in stdlib + examples).
2026-06-15 04:05:04 +03:00
agra
4dca38881e docs(ffi-linkage): checkpoint — prereqs 3 & 4 done (4/4); fn-body flip de-risked, Decision 7 open
Plain-free classification + extern lib-ref validation closed (the 3rd and
4th extern/#foreign divergences). All four fn-path prereqs now done. The
fn-decl #foreign->extern flip is scoped: IR zero-churn, only example 1620's
lib-ref wording churns. Records Decision 7 (interim diagnostic wording) as
the one gate before executing the flip.
2026-06-15 03:55:09 +03:00
agra
b5411efeb8 docs(ffi-linkage): checkpoint — extern C-variadic prereq DONE; both fn-path prereqs cleared
Next step is the fn-decl #foreign body-marker migration onto extern
(behavior-preserving single refactor commit; lowering + both prereq
gates already coalesce is_foreign with extern_export).
2026-06-14 21:06:35 +03:00
agra
28d38f2f2f docs(ffi-linkage): checkpoint — Phase 5.0 visibility-gate prereq DONE; const-with-type/runtime-class findings
- Mark deferred prereq (b) visibility-gate equivalence CLOSED (1228).
- Record const-with-type as a dead path (deferred per user) and the
  runtime-class prefix as already-coalesced (no Phase 5.0 change).
- Next step is the fn-path variadic prerequisite.
2026-06-14 20:58:31 +03:00
agra
47aaf3662a docs(ffi-linkage): checkpoint — Phase 5.0 global path routed (Part B started) 2026-06-14 20:32:48 +03:00
agra
9ad04e2dda docs(ffi-linkage): note -Dupdate-goldens churn resolved (1-byte conform) 2026-06-14 16:17:26 +03:00
agra
fde767913b docs(ffi-linkage): ratify decision 5 (Runtime*Class*); decision 6 stays open 2026-06-14 16:10:01 +03:00
agra
aafcbf6d78 docs(ffi-linkage): checkpoint — Phase 4 complete, Part A done, A→B gate locked 2026-06-14 16:08:01 +03:00
agra
d4f683f525 docs(ffi-linkage): checkpoint — Phase 3 complete (aggregate extern/export) 2026-06-14 15:14:09 +03:00
agra
9f1d7be105 docs(ffi-linkage): checkpoint — Phase 3.0 xfail logged 2026-06-14 15:01:19 +03:00
agra
5ba8d302c2 docs(ffi-linkage): checkpoint — Phase 2 (export) complete + JIT spike findings 2026-06-14 14:55:15 +03:00
agra
6932426c41 feat(ffi-linkage): lower extern data globals (Phase 1.2d) — Phase 1 complete
Parser: a 'kw_extern' branch in the var-decl-with-type-annotation path
(beside #foreign) parses 'name : type extern [LIB] ["csym"];' into
VarDecl.is_extern/extern_lib/extern_name; the trailing diagnostic now
lists 'extern'. Lowering: registerTopLevelGlobal uses
extern_name orelse foreign_name orelse name for the C symbol and sets
is_extern = is_foreign or is_extern; globalInitValue returns null (no
initializer) for extern globals too.

examples/1225 green: '__stdinp : *void extern;' lowers to
'@__stdinp = external global ptr'; @__stdinp reads non-null. Suite
green (636 corpus / 443 unit).

Phase 1 done: extern functions (bare + rename) and data globals (bare +
rename) all work, behavior-equivalent to the matching #foreign form.
export (Phase 2), aggregates (Phase 3), docs + A->B gate (Phase 4)
remain. green commit.
2026-06-14 13:39:05 +03:00
agra
235f74a8c9 test(ffi-linkage): xfail example for extern data global (Phase 1.2c)
Add examples/1225-ffi-extern-global.sx — '__stdinp : *void extern;'
references libSystem's stdin pointer via the bare 'extern' modifier on
a typed var decl (the extern-named counterpart of the #foreign global
in examples/1205). Hand-authored snapshot expects the success output.

RED: 1225 is the sole corpus failure (636 ran, 1 failed) — parse error,
'extern' after a type annotation is not yet accepted in the var-decl
path. Phase 1.2d parses it and lowers the extern global.

xfail commit per the cadence rule.
2026-06-14 13:33:50 +03:00
agra
5777ff62ad feat(ffi-linkage): consume extern LIB "csym" rename for fns (Phase 1.2b)
parseFnDecl parses the optional [LIB] ["csym"] tail after the
extern/export keyword into FnDecl.extern_lib/extern_name (mirrors
'#foreign LIB "csym"'). declareFunction unifies the symbol-name
override: rename_c_name = foreign_expr.c_name (for #foreign) OR
fd.extern_name (for extern) -> declare under the C name and map sx->C
in foreign_name_map; the dedupe guard now covers extern too.

examples/1224 green: 'c_abs :: (n) -> i32 extern "abs";' resolves
c_abs to libc abs -> c_abs(-42) = 42. 1223 (bare extern) unregressed.
Suite green (635 corpus / 443 unit).

extern_lib is parsed + stored but not a linking driver — like
'#foreign libc', it references a lib; the #library decl + build flags
remain the separate linking axis (decision 4). green commit.
2026-06-14 13:30:59 +03:00
agra
5f946a3d44 test(ffi-linkage): xfail example for extern fn rename (Phase 1.2a)
Add examples/1224-ffi-extern-fn-rename.sx — 'c_abs :: (n) -> i32
extern "abs";' binds C's abs via the optional symbol-name override.
Hand-authored expected captures the success output (c_abs(-42) = 42).

RED: 1224 is the sole corpus failure (635 ran, 1 failed) — parse error,
the '"abs"' string after 'extern' is not yet accepted. Phase 1.2b
parses the optional [LIB] ["csym"] tail and consumes the rename.

xfail commit per the cadence rule.
2026-06-14 13:26:57 +03:00
agra
18c43984e1 feat(ffi-linkage): lower extern fns as C imports (Phase 1.1)
Route a bare 'extern' fn declare-only, exactly like a lib-less #foreign
import. Six edits in decl.zig, each mirroring an existing foreign_expr
guard so the empty-block placeholder body is never lowered:

  1. funcWantsImplicitCtx: suppress the implicit __sx_ctx for .extern_
  2. declareFunction: add is_extern_decl
  3. ...and include it in the C-ABI calling-convention promotion
  4. lazyLowerFunction: .extern_ -> declareFunction (declare-only)
  5. lowerFunction: .extern_ in the declare-only guard
  6. lowerFunctionBodyInto: never promote/lower an extern stub

examples/1223 now green: 'extern' abs lowers to 'declare i32 @abs(i32)'
(external linkage, C ABI, no ctx param) and the call resolves against
the default-linked libc -> abs(-7)=7, abs(42)=42. The 1.0b hand-authored
snapshot matched byte-exact (no regen). Suite green (634 corpus / 443
unit). green commit (makes the 1.0b xfail pass; adds no new test).
2026-06-14 13:17:00 +03:00
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
agra
df6b675e67 feat(ffi-linkage): fn-path accepts postfix extern/export + lib/name fields (Phase 1.0a)
parseFnDecl now calls parseOptionalExternExport() after the callconv
slot and stores the modifier on FnDecl.extern_export. For 'extern' the
body is ';' (an empty-block placeholder — the modifier carries the
linkage, no *_expr node, per the naming constraint). Both fn-decl
lookahead predicates (isFunctionDef, hasFnBodyAfterArrow) now treat
kw_extern/kw_export as fn-body markers beside kw_callconv, so
'(...) -> R extern;' is recognized as a fn def rather than a fn-type
const.

Per user feedback, decision 4 ("library separate") is REVISED: extern
carries an optional LIB + "csym" axis mirroring '#foreign LIB "csym"',
so it is a true #foreign superset (Gate A->B requirement — the Part B
migration of 466 #foreign uses across 6 libs must preserve each
symbol's library). Added FnDecl.extern_lib/extern_name and
VarDecl.extern_lib (beside is_extern/extern_name).

All unconsumed by lowering: extern parses, but a fn still errors at
sema (body produces no value). Suite green (443 unit / 633 corpus).
lock commit.
2026-06-14 13:02:42 +03:00
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
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
agra
c562fe236d docs(plans): inline-asm design + ASM and FFI-linkage plans/checkpoints
Two new workstreams:
- ASM: inline assembly — asm { "tmpl", "=r" -> T, "r" = expr, clobbers(.…) },
  multi-return tuples; lowers via the existing llvm_api.c (no shim).
- FFI-linkage: add extern/export postfix keywords, migrate every #foreign onto
  them, then purge 'foreign' from the tree (end-state invariant).

Drop current/ from .gitignore so plans + checkpoints are tracked normally
(the dir was ignored; only checkpoints had been force-added). Includes
docs/inline-asm-design.md. specs.md change left uncommitted.
2026-06-14 12:16:10 +03:00