ASPL لباتASPL 0.7.0

Search documentation

Search starts with current English documentation · ASPL 0.7.0

Enter a complete name such as read_line, or words about a topic.

    العربية
    Source files

    Open one UTF-8 .aspl or .لبات file, up to 1 MiB, in a new draft. It stays in this browser and does not run automatically.

    C signatures, Buffer and C-string loans

    ASPL 0.7.0 · Current release

    Look up fixed C signatures, adapter profiles, Buffer operations, span checks and native failure outcomes.

    On this page

    Host and declaration contract

    Native only, published ASPL 0.7.0 on x86-64 Linux with glibc and the System V ABI. Install the native toolchain, check system requirements, then follow the C guide and public examples. The browser rejects foreign imports before execution with foreign-imports-not-supported, even when unused.

    A foreign declaration is top-level and binds an ASPL name and signature to a literal shared-library name, literal C symbol name and supported fixed signature or foreign adapter profile. Names must be nonempty and contain no NUL. Duplicate library/symbol pairs are rejected. Mark the declaration and each call unsafe / غير_آمن; there is no unsafe block that removes the per-call requirement. Foreign declarations are private by default and may be exported with share / شارك in native source modules. They cannot become ordinary callable values.

    Illustrative fragment

    unsafe foreign absolute(value: i32) -> i32 = c("libc.so.6", "abs");
    fn start_main() -> i64 {
        if unsafe absolute(i32(-7)) not matches i32(7) { return 1; }
        return 0;
    }

    The author must match the real C prototype and guarantee pointer validity and library behavior. ASPL does not parse C headers, infer a prototype from a symbol, inspect errno, or translate library-specific failures to ASPL results.

    Supported fixed signatures and profiles

    c / سي derives the exact fixed signature from the source types, with 0 through 32 lowered arguments. Descriptor annotations add no C arguments. There are no implicit scalar conversions; use explicit numeric conversions for arguments of different widths.

    ASPL type or descriptor C representation on this target
    bool One-byte C _Bool
    i8, u8 Signed/unsigned 8-bit integer
    i16, u16 Signed/unsigned 16-bit integer
    i32, u32 Signed/unsigned 32-bit integer
    i64, u64 Signed/unsigned 64-bit integer
    f32, f64 float, double
    c_ptr / مؤشر_سي Opaque nullable unowned C pointer
    Result-only unit / وحدة C void
    string with cstring(parameter) Call-scoped const char * loan
    c::Buffer with a span descriptor Pointer to runtime-owned bytes

    C char is signed here; short is 16 bits, int 32 bits, and long, long long, pointers and size_t 64 bits. Use the actual underlying type for typedefs and enums. c_ptr does not expose an address conversion or convert a managed owner's storage to a raw pointer. Null pointer values use null / عدم.

    No variadic signatures, aggregate-by-value parameters or results, long double, complex values, raw function pointers or imported C data globals are supported. Lists, records, results and ordinary callable values cannot cross as generic C values. A string needs a C-string descriptor, a Buffer needs one span descriptor, and neither is a generic foreign return type.

    Foreign adapter profile Exact ASPL signature Exact C type
    c_int__const_char_ptr / سي_صحيح__مؤشر_محرف_ثابت (string) -> i64 int (*)(const char *)
    c_double__double / سي_مزدوج__مزدوج (f64) -> f64 double (*)(double)

    These profiles keep their original conversions. The first copies a C string and converts the C int result by value to i64; negative results stay ordinary data. The second passes binary64 values, canonicalizes returned NaN and restores the floating-point environment. Neither inspects floating-point exception flags or errno. Their conversions do not widen generic c signatures. The puts and double examples exercise both profiles; ordinary exercises fixed signatures.

    C-string loans

    For generic c, annotate a string parameter with cstring(text) / نص_سي(text). ASPL evaluates arguments, rejects embedded NUL before C entry, copies the UTF-8 bytes and appends a NUL terminator. The profile c_int__const_char_ptr performs the same loan without an explicit descriptor. A loan is valid only for that call. C may read it during the call and may neither modify it nor retain the pointer after return. Its byte length is independent of the number of Unicode characters.

    An empty ASPL string becomes one terminator byte. An embedded NUL traps with foreign-string-contains-nul in the original string profile and with invalid-foreign-argument in generic cstring; allocation failure has a host or resource outcome rather than a library return code. The lifetime check cannot prevent C from retaining or misusing the pointer. A foreign crash is outside ASPL's controlled trap guarantees.

    Buffer operations

    Import core::c or أساسي::سي. Only the written prefix is active. The type is Buffer / مخزن and the paired operations are:

    English / Arabic member Signature using English types
    buffer / أنشئ_مخزن (list<u8>) -> result<Buffer>
    zero_buffer / أنشئ_مخزن_صفري (u64) -> result<Buffer>
    capacity / سعة (Buffer) -> result<u64>
    bytes / انسخ_بايتات (Buffer, u64) -> result<list<u8>>
    close / أغلق (Buffer) -> result<unit>

    buffer copies bytes, including NUL and FF; zero_buffer allocates zeroed bytes. bytes copies the requested prefix to a new list. It rejects a count beyond capacity with foreign.invalid_argument. Lists and native storage stay independent. Buffer aliases retain one shared native owner. Closing an alias invalidates all aliases; repeated close succeeds. Access to a closed Buffer returns foreign.closed. Access while native use is active may return foreign.busy.

    Construction can refuse charged capacity beyond the execution memory budget with foreign.resource_limit. Extracted lists must fit their representable length and allocation size. A zero-capacity Buffer still has one charged sentinel byte. These are recoverable refusals; allocation failure or exhaustion while constructing a result can still end execution. Test ok before inspecting either result branch. result<unit> has no readable value.

    Native access retains charged storage until quiescence. Last-reference and execution cleanup release native owners, including unreachable ownership cycles. Assignment shares native storage; it does not clone it. The Buffer example checks copied bytes, shared aliases, oversized extraction and repeated close.

    Foreign byte spans

    Annotate each Buffer parameter once with input(buffer,count) / إدخال, output / إخراج, or inout / إدخال_وإخراج. The count is a nonnegative literal or a parameter of any supported integer type whose value is nonnegative and within capacity. It is already a source argument if the C prototype needs it; the descriptor adds no argument.

    input supplies readable bytes. output zeroes the selected span before C entry. inout preserves the input bytes for read/write use. A negative C return does not roll back writes. Zero-length spans use a valid sentinel. Read-only aliases are permitted, but passing the same Buffer owner to multiple parameters traps if any of those parameters is writable, even for a zero-length span. Negative/excess counts, closed or busy Buffers and writable aliases trap before C entry. C may access the stated span during the call and must not retain its pointer after return. These checks do not prove that C obeys those rules.

    Loading, failures and managed boundaries

    check and build validate without loading shared libraries. run and generated ELF programs prepare every import before the entry function, including unused declarations, ordered by library bytes, symbol bytes and adapter ID. Each literal library opens once with RTLD_NOW | RTLD_LOCAL, then symbols resolve with dlsym and dlerror. Names pass unchanged to the glibc loader. A first failure prevents entry and closes opened handles in reverse order. Built programs still need the named shared libraries, even though they need no compiler or source files.

    Failure Observable outcome
    Unknown adapter, mismatched signature, invalid name, duplicate target, missing unsafe marker Source error, CLI status 1: unknown-foreign-adapter, foreign-signature-mismatch, invalid-foreign-library-name, invalid-foreign-symbol-name, duplicate-foreign-target, unsafe-required-on-foreign-declaration, unsafe-required-on-foreign-call
    Missing library or symbol Load failure, status 4: foreign-library-open-failed, foreign-symbol-lookup-failed
    NUL string, invalid span, closed/busy Buffer, writable alias Trap, status 5: foreign-string-contains-nul, invalid-foreign-argument, closed-foreign-handle, busy-foreign-buffer, aliased-foreign-buffer
    Buffer utility refusal Failed result: foreign.invalid_argument, foreign.closed, foreign.busy, foreign.resource_limit
    Allocation or execution budget failure Host/resource outcome, not automatic conversion of a C return to a failed result

    Ordinary unsafe calls are synchronous, may block, and cannot acquire managed suspension, cancellation or callback privileges. HTTP handlers and managed callbacks exclude them transitively. Only toolchain-supplied reviewed bindings participate in managed rules; the current public libraries include HTTP and Raylib. User declarations cannot register managed operations, and there is no public independently installed managed-binding ABI. Contributor-only managed-callback fixtures are not public runnable examples. See the HTTP and Raylib collections for their own contracts.

    Historical normative scope

    • Historical specification, English source

      Historical MVP adapter background only; fixed signatures, Buffer and managed boundaries are later extensions audited against the published native 0.7.0 implementation

    Browse pages