test: group examples into per-category folders

Move examples/*.sx and their expected/ snapshots into per-category
subfolders (examples/<category>/...). Folder = leading filename token,
with ffi-objc/ffi-jni kept whole; filenames are unchanged. The corpus
runner and LSP sweep now discover each category's expected/ dir, while
issues/ stays flat. Example 1058's repo-root-relative companion import
is made file-relative. Path strings embedded in 164 snapshots were
regenerated (path-only changes). Test-layout docs in CLAUDE.md updated.
This commit is contained in:
agra
2026-06-21 14:41:34 +03:00
parent 6d1409bc1f
commit 66bdc70bf1
3357 changed files with 456 additions and 363 deletions

View File

@@ -0,0 +1,18 @@
// Pins the NAMED `#import c` block (PLAN-C C0.1): the block's name
// namespaces the decls synthesized from `#include`, and `#define` /
// `#flags` entries reach the unit's clang invocation — the macro decides
// what cdef_value answers.
#import "modules/std.sx";
cu :: #import c {
#include "1618-cimport-named-defines/cdef.h";
#source "1618-cimport-named-defines/cdef.c";
#define "CDEF_BASE=42";
#flags "-O2";
};
main :: () -> i32 {
print("value = {}\n", cu.cdef_value());
print("doubled = {}\n", cu.cdef_doubled(21));
0
}

View File

@@ -0,0 +1,6 @@
#include "cdef.h"
#ifndef CDEF_BASE
#define CDEF_BASE 1
#endif
int cdef_value(void) { return CDEF_BASE; }
int cdef_doubled(int x) { return x * 2; }

View File

@@ -0,0 +1,5 @@
#ifndef CDEF_H
#define CDEF_H
int cdef_value(void);
int cdef_doubled(int x);
#endif

View File

@@ -0,0 +1,17 @@
// Pins the curated-bindings shape (PLAN-C C0.2): a `#source`-only unit
// (no `#include`, so no auto-synthesized decls) paired with a
// hand-written `extern` decl naming the unit. Works in JIT and AOT
// today — but see 1620: the unit ref is not yet validated or scoped,
// so the symbol actually resolves globally, not through the unit.
#import "modules/std.sx";
only :: #import c {
#source "1619-cimport-source-only/only.c";
};
only_answer :: () -> i32 extern only "only_answer";
main :: () -> i32 {
print("answer = {}\n", only_answer() + 1);
0
}

View File

@@ -0,0 +1 @@
int only_answer(void) { return 41; }

View File

@@ -0,0 +1,18 @@
// Unit-first JIT resolution (PLAN-C C2): a `#source` unit defining a
// symbol that ALSO lives in an OS image already loaded into the
// compiler process (libz, via libLLVM) still wins — the unit's dylib
// is a priority symbol-search target ahead of the process-wide
// fallback. The unit's zlibCompileFlags answers 0xDEADBEEF; the OS
// one answers real flag bits, so `true` proves the unit won.
// Regression (PLAN-C C0.3 xfail, flipped by C2.1).
#import "modules/std.sx";
zshadow :: #import c {
#include "1621-cimport-shadow-os-lib/shadow.h";
#source "1621-cimport-shadow-os-lib/shadow.c";
};
main :: () -> i32 {
print("from_unit: {}\n", zshadow.zlibCompileFlags() == 3735928559);
0
}

View File

@@ -0,0 +1 @@
unsigned long zlibCompileFlags(void) { return 3735928559UL; }

View File

@@ -0,0 +1 @@
unsigned long zlibCompileFlags(void);

View File

@@ -0,0 +1,17 @@
// `#define`/`#flags` reach a unit whose ONLY consumer is hand-curated
// `extern` decls (PLAN-C C3.3) — no `#include`, no auto-synthesis:
// the macro decides what the unit-bound decl answers.
#import "modules/std.sx";
unit :: #import c {
#define "UNIT_BASE=33";
#flags "-O2";
#source "1622-cimport-unit-bound-defines/unit.c";
};
unit_answer :: () -> i32 extern unit "unit_answer";
main :: () -> i32 {
print("unit answer = {}\n", unit_answer());
0
}

View File

@@ -0,0 +1,4 @@
#ifndef UNIT_BASE
#define UNIT_BASE 1
#endif
int unit_answer(void) { return UNIT_BASE; }

View File

@@ -0,0 +1,11 @@
// A named `#import c` unit declared INSIDE an aliased module (so the
// unit's namespace nests two deep in the merged tree) still compiles
// and links — collectCImportSources recurses through namespaces, the
// same way #library collection does (issue 0130's pattern).
#import "modules/std.sx";
m :: #import "1623-cimport-unit-in-aliased-module/mod.sx";
main :: () -> i32 {
print("nested unit answer = {}\n", m.answer_via_mod());
0
}

View File

@@ -0,0 +1 @@
int unit_in_mod_answer(void) { return 54; }

View File

@@ -0,0 +1,10 @@
// A module that owns a named C unit + a hand-curated binding.
#import "modules/std.sx";
cunit :: #import c {
#source "inmod.c";
};
unit_in_mod_answer :: () -> i32 extern cunit "unit_in_mod_answer";
answer_via_mod :: () -> i32 { return unit_in_mod_answer(); }

View File

@@ -0,0 +1,20 @@
// Two `#import c` units defining the same exported symbol is a
// compile-time diagnostic naming both sources — previously it died
// inside the JIT dylib link (or the AOT link) with raw linker spew.
// All units share one link namespace; per-unit symbol isolation is
// PLAN-C C3.2 (deferred).
#import "modules/std.sx";
ua :: #import c {
#source "1628-cimport-duplicate-export/a.c";
};
ub :: #import c {
#source "1628-cimport-duplicate-export/b.c";
};
clash :: () -> i32 extern ua "clash";
main :: () -> i32 {
print("{}\n", clash());
0
}

View File

@@ -0,0 +1 @@
int clash(void) { return 1; }

View File

@@ -0,0 +1 @@
int clash(void) { return 2; }

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1,2 @@
value = 42
doubled = 42

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@
answer = 42

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@

View File

@@ -0,0 +1 @@
from_unit: true

View File

@@ -0,0 +1 @@
0

View File

@@ -0,0 +1 @@
unit answer = 33

View File

@@ -0,0 +1 @@
nested unit answer = 54

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1 @@
error: C symbol 'clash' is defined by multiple '#import c' sources: 'examples/cimport/1628-cimport-duplicate-export/a.c' and 'examples/cimport/1628-cimport-duplicate-export/b.c' — all units share one link namespace