iter 24.1: bool_to_str + str_clone runtime + codegen wiring
First iter of milestone 24 (Show + print rewire). Wires two new heap-Str-producing primitives parallel to hs.4's int_to_str / float_to_str: - runtime/str.c gains ailang_bool_to_str(bool) → heap-Str "true" / "false" and ailang_str_clone(const char *) → memcpy'd heap-Str copy. Both use the existing str_alloc slab helper. - builtins.rs + synth.rs install the two signatures lockstep with ret_mode: Own; str_clone carries param_modes: [Borrow]. - IR-header preamble gains two unconditional `declare ptr @...` lines; Emitter::lower_app gets two new arms; is_static_callee whitelist extends with the two names. - Five IR snapshots regenerate for the two new declares. - Pre-existing-drift fix: int_to_str row added to builtins.rs::list() (hs.4 installed env.globals entry but missed the list() row). Substantive deviation flagged by orchestrator (DONE_WITH_CONCERNS): builtin signatures registered in uniqueness.rs::infer_module and linearity.rs::check_module_with_visible (8 LOC × 2 files), symmetric to iter 23.4-prep's class-method registration in the same globals maps. Without this fix str_clone's param_modes: [Borrow] is invisible to the App-arg walker, src_heap walks as Position::Consume, the scope-close ailang_rc_dec is gated off, and the str_clone_cross_realisation_uniform_abi test's plan-literal `frees == 3` assertion does not hold. The fix is the substantively correct repair, not a design departure. 9 new tests: 2 builtins-install unit, 2 IR-shape unit pins, 5 E2E (2 RC-stats, 2 stdout-smoke for both Bool branches, 1 cross- realisation). 4 new .ail.json fixtures. Full cargo test --workspace: 513 passed, 0 failed. bench/compile_check.py: 24/24 stable. bench/cross_lang.py: 25/25 stable.
This commit is contained in:
@@ -141,3 +141,46 @@ char *ailang_float_to_str(double x) {
|
||||
payload[8 + len] = '\0';
|
||||
return payload;
|
||||
}
|
||||
|
||||
/* Convert a bool into a heap-allocated Str — "true" (4 bytes) or
|
||||
* "false" (5 bytes). Heap-allocates every call; the static-Str
|
||||
* literal alternative (used by a hypothetical `\x -> if x then "true"
|
||||
* else "false"` schema body) would require phi-of-static-Str
|
||||
* through the drop-elision pipeline which is not load-bearing-
|
||||
* ratified today (see parent spec §"Out of scope" / `bool_to_str` as
|
||||
* schema-if).
|
||||
*
|
||||
* Returns the payload pointer of a fresh heap-Str slab.
|
||||
*/
|
||||
char *ailang_bool_to_str(bool b) {
|
||||
const char *lit = b ? "true" : "false";
|
||||
uint64_t len = b ? 4 : 5;
|
||||
char *payload = str_alloc(len);
|
||||
memcpy(payload + 8, lit, len);
|
||||
payload[8 + len] = '\0';
|
||||
return payload;
|
||||
}
|
||||
|
||||
/* Clone a Str into a fresh heap-Str slab. Reads `len` from the
|
||||
* first 8 bytes of the source payload, allocates a new slab of the
|
||||
* same length via `str_alloc`, and memcpy's the payload bytes plus
|
||||
* the trailing NUL. Works uniformly on static-Str and heap-Str
|
||||
* inputs because the consumer ABI (i64 len at offset 0, bytes
|
||||
* starting at offset 8, NUL at offset 8 + len) is identical
|
||||
* between realisations (see DESIGN.md §"Str ABI"); the rc_header at
|
||||
* offset -8 — present only on heap-Str — is never consulted.
|
||||
*
|
||||
* Used by `show__Str` (parent spec milestone 24): converts a
|
||||
* borrowed Str input into an Owned heap-Str output, preserving
|
||||
* the uniform `show : forall a. Show a => (a borrow) -> Str Own`
|
||||
* signature.
|
||||
*
|
||||
* Returns the payload pointer of a fresh heap-Str slab.
|
||||
*/
|
||||
char *ailang_str_clone(const char *src) {
|
||||
uint64_t len = *(const uint64_t *)src;
|
||||
char *payload = str_alloc(len);
|
||||
memcpy(payload + 8, src + 8, len);
|
||||
payload[8 + len] = '\0';
|
||||
return payload;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user