diff --git a/CLAUDE.md b/CLAUDE.md index c69859a..e3f3023 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -553,7 +553,7 @@ The compiler shrinks to: parse → IR → codegen → link → invoke a sx function. Codesigning / Info.plist / AndroidManifest / javac / d8 / aapt2 / zipalign / apksigner / framework embed / entitlements / asset trees all run in the IR interpreter post-link via libc / process.run -foreign calls. +extern calls. | File | Role | |------|------| @@ -563,7 +563,7 @@ foreign calls. | [library/modules/build.sx](library/modules/build.sx) | `BuildOptions` setters + accessors. Adding a new bundling parameter = add a setter here + a hook in compiler_hooks.zig. | | [library/modules/platform/android.sx](library/modules/platform/android.sx) | `AndroidPlatform` (state-on-struct, no module globals). `sx_android_*` helpers take `plat: *AndroidPlatform` as first arg. `logical_w` field drives `dpi_scale = pixel_w / logical_w` so consumer's design-width fits any physical resolution. | | [src/ir/compiler_hooks.zig](src/ir/compiler_hooks.zig) | `BuildConfig` + every `BuildOptions.*` hook. Hook registry is in `Registry.registerDefaults`. | -| [src/ir/host_ffi.zig](src/ir/host_ffi.zig) | `dlsym(RTLD_DEFAULT)` + arity-switched cdecl trampolines. Lets `#foreign("c")` decls resolve at `#run` / post-link time against host libc. | +| [src/ir/host_ffi.zig](src/ir/host_ffi.zig) | `dlsym(RTLD_DEFAULT)` + arity-switched cdecl trampolines. Lets `extern "c"` decls resolve at `#run` / post-link time against host libc. | | [src/main.zig](src/main.zig) | After `target.link()`, threads target_triple + frameworks + jni_main emissions into BuildConfig, then invokes the post-link callback by FuncId (or by `.bundle_main` name). `--bundle` / `--apk` flags feed `bundle_path`; auto-fallback to `post_link_module = "platform.bundle"` when bundle_path is set without a registered callback. | Specifics in [specs.md §10.5](specs.md). The full bundling pipeline diff --git a/readme.md b/readme.md index 4286632..818255b 100644 --- a/readme.md +++ b/readme.md @@ -208,8 +208,8 @@ function is bare-callable (`i2(10)`). A backtick name used as a type resolves to `` `name ``-declared type — including a parameterized template (`` `i2(i64) ``) and under pointer/optional wrappers — else a normal `unknown type` error. -Foreign declarations from `#import c { … }` are exempt automatically: C names that -collide with reserved type names (e.g. `i1`, `i2`) import unedited, and a foreign +Extern declarations from `#import c { … }` are exempt automatically: C names that +collide with reserved type names (e.g. `i1`, `i2`) import unedited, and an extern reserved-name function is bare-callable by its C name. ### Structs diff --git a/specs.md b/specs.md index 63a2a09..11e2804 100644 --- a/specs.md +++ b/specs.md @@ -21,11 +21,11 @@ is reserved. A bare reserved spelling is rejected at **value-binding and declaration-name sites**: a value binding (`:=` / typed local / parameter), a `::` **constant** or **function** declaration, an `impl` method **definition**, and a `::` **type** declaration (`struct` / `enum` / `union` / `error` / type -alias / `protocol` / foreign class / ufcs alias / namespaced import). A +alias / `protocol` / runtime class / ufcs alias / namespaced import). A value-spelled-as-type parses as a *type*, not a value, so its address-of / autoref paths would mis-lower; a type / const / function / method name spelled as a builtin would shadow the builtin. The exemptions are the backtick escape -(below), `#import c` foreign decls, and **member-name positions** (next) — it is +(below), `#import c` extern decls, and **member-name positions** (next) — it is **not** rejected at every place a name appears. **Member-name positions are exempt.** A struct **field** name, a union **tag** @@ -90,7 +90,7 @@ x : i2 = 3; // bare `i2` is still the 2-bit signed int **Declaration position.** A *bare* reserved-name declaration of every kind still errors (a value binding, a `::` constant / function, and a `::` type / alias / -protocol / foreign-class / ufcs / namespaced-import name); the backtick form is +protocol / runtime-class / ufcs / namespaced-import name); the backtick form is exempt. The escape works in **every identifier position** — local, global, parameter, struct field, union tag, function name, type/alias/import name, a later reference, and every control-flow / capture / binding form (destructure name, @@ -125,12 +125,12 @@ to the function when one of that name is in scope; `TypeName(val)` is not a cast A backtick may also escape a keyword spelling (`` `for ``, `` `struct ``), yielding an identifier with that text. -**`#import c` exemption.** Foreign declarations synthesized by an `#import c { … }` +**`#import c` exemption.** Extern declarations synthesized by an `#import c { … }` block are treated as raw automatically: a generated C parameter or function name that collides with a reserved type name (e.g. `i1`, `i2`) imports unedited, with no -backticks and no reserved-name error, and a foreign reserved-name function is -bare-callable by its C name. The exemption is scoped to the foreign decls — it does -not make a foreign `i2` usable as the sx `i2` type, nor relax the rule for +backticks and no reserved-name error, and an extern reserved-name function is +bare-callable by its C name. The exemption is scoped to the extern decls — it does +not make an extern `i2` usable as the sx `i2` type, nor relax the rule for hand-written sx code. ### Literals @@ -1188,7 +1188,7 @@ n := Node.{ value = 10 }; // n.next is null #### Comptime Optionals work in `#run` blocks — `??`, `!`, `if val :=`, null checks all supported. -### Foreign Function Interface (C Interop) +### C Interop C linkage is expressed with the postfix `extern` (import) and `export` (define + expose) keywords. `extern` declares a symbol defined elsewhere — a C function or @@ -2660,7 +2660,7 @@ response :: format("HTTP/1.1 200 OK\r\nContent-Length: {}\r\n\r\n{}", body.len, // response is a static string constant — no runtime allocation ``` -This works for any function, not just `format`. The mechanism is general: the VM compiles the function body (including `#insert` directives, variadic `..args: []Any` args, and calls to other functions) and executes it entirely at compile time. If the VM encounters something it cannot evaluate (e.g., foreign function calls, unsupported operations), it silently falls through to runtime codegen. +This works for any function, not just `format`. The mechanism is general: the VM compiles the function body (including `#insert` directives, variadic `..args: []Any` args, and calls to other functions) and executes it entirely at compile time. If the VM encounters something it cannot evaluate (e.g., extern function calls, unsupported operations), it silently falls through to runtime codegen. ### Build Configuration @@ -3341,7 +3341,7 @@ function, or at top level, is rejected. with the same signature share one inferred-set node; the SCC pass unions every closure flowing into any matching slot. - **FFI boundary.** A failable closure cannot be assigned to a non-failable - function-type slot — foreign code can't observe the error channel. Wrap and + function-type slot — extern (C) code can't observe the error channel. Wrap and absorb the error instead. - **Non-failable → failable widening is allowed** (∅ ⊆ any set). A non-failable closure assigned to a failable slot contributes ∅; a single