Core built-in e librerie standard

<!-- verified-against: seed-llvm; examples: docs-examples-test -->

seed mantiene piccolo il nucleo del linguaggio. File, rete, processi, formattazione, raccolte e sincronizzazione sono normali librerie compilate separatamente, non integrate universali. La superficie integrata del compilatore pulito è sotto; il catalogo dei pacchetti operativi gestiti dal compilatore è documentato in Riferimento libreria, mentre l'albero Grove di generazione mista è classificato separatamente in Grove Compatibility Tree.

Tipi di nucleo

Il compilatore definisce void, never, bool, numeri interi a larghezza fissa, isize, usize, f32, f64, str, string, bytes, shared_bytes, alloc_errore quello nascosto region_handle. byte è accettato come u8. AllocResult<T> è la scorciatoia canonica per Result<T, alloc_error>. Ospitato main() -> Result<i64, E> associa il successo allo stato del processo. alloc_error ha la diagnostica fissa; un altro E deve essere Copia, non avere distruttore e implementare preso in prestito display() -> str. Il fallimento viene stampato una volta prima dello stato 1, dopo la pulizia e senza svolgimento.

Operazioni sicure note al compilatore

Operazione Contratto
len(value) usize byte/element lunghezza per str, string, bytes, shared_bytes, slice e array
size_of(type) / align_of(type) query di layout in fase di compilazione rispetto alla destinazione attiva; valido negli inizializzatori const e nelle lunghezze dell'array ([size_of(i64)]u8), rifiutato altrove
str.bytes() vista []u8 di sola lettura senza allocazione con la provenienza dell'origine
slice.slice(start, count) controllata la visualizzazione secondaria priva di allocazione che preserva il tipo di elemento e la mutabilità
mut_slice.split_at_mut(index) controllato una coppia priva di allocazione di visualizzazioni lessicali esclusive e non sovrapposte
mut_slice.fill(value) riempie una sezione di elementi di copia senza allocazione
mut_slice.copy_from(source) Trasferimento di elementi di copia di uguale lunghezza, sicuro da sovrapposizione, senza assegnazione
bytes.into_prefix(length) consumando il troncamento logico controllato che riutilizza l'allocazione e la capacità
Some(value) / None costruzione di opzioni canoniche; None necessita del previsto ?T
Ok(value) / Err(problem) costruzione del risultato canonico con previsto Result<T, E>
option.is_some() / option.is_none() ispezione presa in prestito senza assegnazione
result.is_ok() / result.is_error() ispezione presa in prestito senza assegnazione
option_or_result.unwrap_or(value) consumo di default con esatta pulizia del valore posseduto non selezionato
or_abort() / expect(message) confine fatale esplicito e irremovibile
or_exit(status) confine solo principale i64 option/result utilizzando il ritorno ordinario ripulito
value.clone() clone strutturale esplicito quando esiste la capacità; viene monitorato l’effetto dell’allocazione
string.view() presi in prestito senza allocazione str
bytes.view() di sola lettura senza allocazione []u8
bytes.mutable_view() lessicale esclusivo mut []u8 che copre l'intera lunghezza allocata
bytes.zeroed(length) fallibile inizializzato a zero Result<bytes, alloc_error>; length deve essere i64
unsafe { bytes.uninitialized(length) } allocazione fallibile della capacità interna; i chiamanti devono inizializzare ogni byte prima di esporre un prefisso
shared_bytes.view() di sola lettura senza allocazione []u8
array.view() / array.mutable_view() porzione compatibile esplicita priva di allocazione; la vista mutabile richiede un proprietario mutabile
str.equal(other) confronto di byte UTF-8 senza allocazione
str.find_ascii(delimiter, start) ricerca delimitatrice controllata senza allocazione; delimitatori non ASCII rifiutati
intrinsic_sqrt_f32/f64(value) / intrinsic_abs_f32/f64(value) / intrinsic_min_f32/f64(a, b) / intrinsic_max_f32/f64(a, b) intrinseci matematici f32/f64 noti al compilatore; la libreria math fornisce i wrapper portatili
str.slice(start, count) controllato la visualizzazione secondaria a copia zero preservando la provenienza
slice.slice(start, count) sottovista generica controllata a copia zero []t che preserva la provenienza
byte_view.equal(other) senza assegnazione []u8 uguaglianza di lunghezza e contenuto
str.to_string() / string.from(view) Result<string, alloc_error>; allocazione esplicita
str.to_bytes() / bytes.from(view) Result<bytes, alloc_error>; esplicito copy/allocation
bytes.to_shared() / shared_bytes.from(data) consumare byte posseduti; Result<shared_bytes, alloc_error>
region(capacity) { body } ambito di allocazione bump controllato lessicale
InputStream.read(mut buffer) (aperto con io.input_stream_new(descriptor)) lettura parziale fallibile limitata; i chiamanti possono elaborare EOF/data in modo incrementale senza conservare tutto l'input

L'indicizzazione sicura di arrays/slices accetta ogni larghezza intera incorporata e controlla l'indice matematico prima della formazione del puntatore. Le API di testo espongono byte; L'elaborazione Unicode scalar/grapheme appartiene alle librerie. Le letture e le scritture degli indici variabili funzionano su mut []u8 e sulle sottosezioni derivate tramite .slice(), con gli stessi limiti controllati di ogni altra forma di sezione (verificata da tests/gate18/mut_slice_dynamic_index_consumer.sd).

byte_buffer nota: byte_buffer.mutable_view() restituisce una vista del prefisso inizializzato, che è di lunghezza 0 per un buffer appena creato. La scrittura oltre la lunghezza restituita provoca un trap fuori limite. Per preparare una destinazione di scrittura di n byte, utilizzare byte_buffer.resize_zeroed(n) (incrementare o ridurre il prefisso inizializzato; i nuovi byte sono zero) o byte_buffer.push_zeroed(n) (aggiungere n byte inizializzati con zero); entrambi sono fallibili con alloc_error in termini di crescita e preservano l'invariante del prefisso impegnato su ogni percorso, incluso il fallimento dell'allocazione. Per scrivere in un buffer non elaborato, utilizzare bytes.zeroed(n) il cui mutable_view() copre l'intera allocazione oppure utilizzare i metodi byte_buffer push/extend/reserve/resize.

Costruzione di stringhe canoniche: si accumula con push/push_str/extend, quindi si materializza una volta con text.utf8_string_from_bytes(buffer.view()), che convalida UTF-8 e segnala Utf8Error invece di trapping. La validazione risiede apposta nella libreria text controllata: gli stati intermedi del buffer possono contenere sequenze parziali, quindi solo il passaggio finale controlla:

use "byte_buffer"
use "text"

fn main() -> AllocResult<i64> {
    let mut builder = byte_buffer_new(8 as usize)?
    builder.push_str("hello ")?
    builder.push_str("world")?
    let built = match text.utf8_string_from_bytes(builder.view()) {
        Ok(value) => value,
        Err(_) => {
            return Ok(1)
        }
    }
    if built.view().equal("hello world") { Ok(0) } else { Ok(2) }
}

Substrato del compilatore non sicuro

Le seguenti operazioni richiedono un blocco unsafe o unsafe fn:

Famiglia Operazioni
memoria grezza digitata raw_try_alloc<t>, raw_null<t>, raw_is_null<t>, raw_read<t>, raw_write<t>, raw_free<t>, raw_slice<t>
atomi acquire/release aiutanti più ordinato load/store/fetch-add/exchange/compare-exchange
ordinare compilatore e recinzioni atomiche con ordini di memoria convalidati
dispositivi digitato volatile read/write e cast dello spazio degli indirizzi
architettura intrinseche dell'assemblaggio grezzo tipizzato
interoperabilità puntatori grezzi, FFI, chiamate di sistema e unioni grezze

raw_try_alloc<t> segnala il conteggio negativo, l'overflow delle dimensioni o l'errore dell'allocatore come alloc_error. read/write/free non elaborato si affida al chiamante non sicuro controllato per limiti, inizializzazione, provenienza, sincronizzazione e rilascio esatto una volta.

Pacchetti bibliotecari ordinari

Il compilatore pulito mette in scena i pacchetti rappresentativi in compiler/llvm/libs:

Pacchetto Ruolo
box indiretto di proprietà fallibile e sicuro per valori ricorsivi e di grandi dimensioni
byte_buffer costruzione fallibile di byte crescenti, mutazione, visualizzazioni e consumo bytes conversione
file wrapper output/file ospitato sul runtime ABI
fibonacci iterativo senza allocazione O(n) i64 Fibonacci con esplicito negative/overflow None
net wrapper di rete ospitato
io input partial/read-all ospitato digitato, output text/bytes/format write-all, buffering limitato e print/println per output rapido
math portatile f32/f64 radice quadrata, valore assoluto, minimo e massimo
parse controllato l'analisi dei numeri interi signed/unsigned e gli helper predefiniti espliciti
process argomenti di processo senza allocazione, visualizzazioni dell'ambiente e identità del processo
serialize pacchetto di serializzazione sicuro rappresentativo
sort ordinamento scalare a sezioni modificabili e ordinamento statico order_key per valori di solo spostamento
slice helper generici per inversione, rotazione e finestra a larghezza fissa senza allocazione; le fette centrali forniscono fill/copy_from
text UTF-8 validazione, controllo Unicode-scalare senza allocazione iteration/counting, conversione della stringa di proprietà e cursori token delimitati da ASCII i cui SplitToken.slice(source) restituisce la visualizzazione a copia zero del token
time millisecondi ospitati monotonici più orologio da parete Unix seconds/milliseconds
vec vettore generico fallibile con costruttori capacity/filled e @mut reserve/push/update/pop, più set<k> (insert/contains), map<k,v> (insert/contains/take su CollectionKey) e queue<t>
task canali con divisione della proprietà, digitati one-shot e Result<T, E> join, eventi, cancellazioni, gruppi di attesa, semafori, barriere e blocchi
system wrapper di sistemi sicuri su spazi di indirizzi, MMIO, atomici, pagine, DMA, init-once e meccanismi locali della CPU

Il launcher è incrementale build/run path mette automaticamente in scena questi pacchetti principali del repository quando un pacchetto ordinario utilizza un'importazione semplice come use "vec" o use "fibonacci"; non è richiesta l'installazione manuale dell'interfaccia o un'FFI visibile dall'applicazione. Il più stretto check il sottocomando non mette prima in scena un pacchetto nudo mancante. Gli utenti del compilatore diretto possono utilizzare una fonte esplicita o .sdi pacchetto. Questi non sono nomi di lingue magiche.

Formattazione e output

Il linguaggio implementa typed phase-1/2 f"..." interpolazione. Una stringa f produce effimero format_args senza allocazione heap. compiler/llvm/libs/io è la superficie tipizzata canonica per testo, porzione di byte e output in formato. Per risultati rapidi, print(text) scrive su stdout e println(text) scrive con una nuova riga finale. print prende str, quindi print(f"...") non controlla il tipo: le stringhe f producono effimeri format_args. Utilizzare print_format / println_format (stesso single/two-write disciplina come print/println) per l'uscita interpolata:

use "io"

fn main() -> Result<i64, IoError> {
    let count = 42
    print_format(f"events={count}\n")?
    println_format(f"done")?
    Ok(0)
}

.to_string()? esegue una materializzazione fallibile esplicita. Sono implementati Width/fill/alignment, specificatori di base interi e la formattazione dei tratti display presa in prestito senza allocazione. La fase 2 aggiunge la formattazione fissa, scientifica e generale f32/f64 priva di libc oltre ai tratti display/debug presi in prestito.

Avviso di compatibilità

lvm-v1 e storico Grove/runtime le tabelle espongono molti nomi come str_cat, read_file, net_connect, vec_new, e sd_*. La loro esistenza in un compilatore archiviato non li rende integrati puliti del compilatore. Quando esegui il porting del codice legacy, importa o implementa un wrapper sicuro corrente e lascialo .sdi contratto definisce proprietà, effetti, ABI e disponibilità.