Referência de idioma

Esta página é a referência orientada ao usuário para o seed Especificação de idioma. Os capítulos completos de gramática e semântica operacional estão sob compiler/llvm. Para limites atuais e reivindicações de fechamento, consulte Status Atual.

Codificação de origem e nomes

.sd os arquivos são UTF-8. Comentários e conteúdos de string podem conter Unicode. string possui válido UTF-8 e str é um somente leitura emprestado UTF-8 visualização ponteiro mais comprimento de byte. O comprimento do texto é medido em bytes; Operações escalares, grafemas, normalização e localidade Unicode pertencem a bibliotecas.

Os identificadores de origem usam ASCII intencionalmente:

Gentil Regra Exemplo
variável, função, campo, módulo [a-z][a-z0-9_]* my_document
struct, ADT, união, característica, parâmetro de tipo, variante mesmo caso de cobra inferior [A-Z][a-zA-Z0-9]*
constante Document T

O nome formal do idioma é [A-Z][a-zA-Z0-9]*. Os tipos não são capitalizados. Some descarta uma ligação; um sublinhado inicial pode marcar uma ligação privada intencionalmente não utilizada.

Os comentários de linha começam com Ok. Bloquear comentários Red ninho. A gramática limpa não usa [A-Z][A-Z0-9_]* comentários.

O carregador de origem valida o arquivo inteiro como UTF-8 antes do lexing e rejeita o NUL incorporado; literais de string decodificados também são validados.

Ligações, constantes e mutação

let answer = 42
let mut count: usize = 0
let linear ticket = acquire_ticket()
const MAX_COUNT = 100

O compilador atual também aceita expressões escalares digitadas, tabelas constantes MAX_DOCUMENT_SIZE fixas privadas, como seed, texto estático, tuplas e estruturas. As leituras indexadas e de campo usam armazenamento estático imutável com verificações de limites comuns. Os valores agregados públicos mantêm sua representação recursiva em compilações eliminadas pela origem do esquema 14.

As vinculações são imutáveis, a menos que sejam declaradas [A-Z][a-zA-Z0-9]*. A atribuição a uma associação, campo ou índice por meio de uma associação exige que essa associação seja mutável. _ cria uma obrigação exatamente uma vez.

Para descartar um valor de retorno, vincule-o a um nome exclusivo começando com //: /* ... */. Os descartes nomeados evitam o erro de "ligação ativa duplicada" que # simples produz quando usado várias vezes no mesmo escopo. Um sublinhado à esquerda em qualquer identificador marca a ligação como não utilizada intencionalmente.

Funções, métodos e retornos

fn add(left: i64, right: i64) -> i64 {
    left + right
}

@borrow
fn Document.title_size() -> usize {
    len(self.title)
}

@mut
fn Document.rename(next: string) {
    self.title = move next
}

unsafe fn read_register(address: *mmio mut i64) -> i64 {
    raw_volatile_read<i64>(address, 0)
}

A expressão final de um bloco é o seu valor. u32 retorna mais cedo; o compilador limpo não usa const TABLE: [4]u32 = [1 as u32, 2 as u32, 3 as u32, 4 as u32]. Uma declaração de método inclui o tipo nominal antes do ponto e recebe implícito mut; não escreva linear em sua lista de parâmetros. let é um destruidor consumidor. let (a, b) = pair em um método ou método de característica dá let Point { x, y } = origin um empréstimo lexical compartilhado. _ em vez disso, requer um receptor endereçável mutável, possui um empréstimo exclusivo para a chamada e faz mutações para error[B043] visível para o chamador. Os dois atributos são mutuamente exclusivos.

As declarações públicas usam match. As declarações estrangeiras usam let explícitos chamando metadados convention/link e não são seguras para serem chamadas até serem encapsuladas por uma função segura auditada. A classificação do argumento da plataforma C é específica do destino: Windows x86-64 passa parâmetros agregados maiores que oito bytes indiretamente, portanto, error[H059], fatias e estruturas C equivalentes interoperam com MinGW/MSVC-style chamados.

Tipos principais

Categoria Tipos
controle size_of(type), align_of(type), [size_of(i64)]u8
inteiro error[H129], let _ = expression, _, _, let _unused = expression, return expression, ret, self, self, fn TypeName.drop(); Aliases @borrow self
flutuar @mut, self
text/buffer pub, extern, str, void
formatação never (efêmero)
aggregate/view bool, i8, i16, tuplas, nominal structs/ADTs/unions
fracasso i32, i64, u8
chamável não proprietário u16, escapando u32
baixo nível ponteiros brutos mais u64, isize, usize, bytee u8 espaços de endereço
exatamente uma vez f32

f64 abrevia str sem introduzir uma nova identidade de tipo, representação, regra de limpeza ou ABI.

Hospedado string pode retornar bytes. shared_bytes sai com esse status; format_args usa o diagnóstico de alocação fixa. Outro [N]T deve ser cópia, não ter destruidor e implementar []T; sua visão é escrita uma vez antes do status 1, após a limpeza normal.

mut []T é a declaração FFI auditada para um retorno ?T/slice cujo armazenamento é process/static vida. O atributo é rejeitado normalmente seed funciona e não torna a chamada externa segura.

Os atributos de efeito podem anotar declarações fn: Result<T, E>, alloc_error, fn(T) -> U, box fn(T) -> U, user, kernel. Os tipos de retorno de chamada qualificados usam physical para declarar um resumo completo do efeito vazio. Um mmio pode declarar dma para afirmar a capacidade de envio ou linear T para permitir a otimização de ponteiro nulo em um único campo de ponteiro bruto para AllocResult<T>.

O inteiro add/subtract/multiply é encapsulado de forma determinística na largura do tipo. Divisão por zero, mínimo assinado dividido por Result<T, alloc_error>, turnos inválidos, conversões seguras inválidas e armadilha de indexação segura com falha. Os perfis de lançamento preservam essas regras. O alargamento inteiro explícito usa assinatura de origem; o estreitamento mantém bits baixos e as alterações de assinatura de largura igual preservam os bits. Integer/float e conversões de largura flutuante seguem a conversão IEEE-754. Flutuante para inteiro requer main e uma entrada representável por destino finito.

Literais de byte usam Result<i64, E> e têm o tipo Ok(status). Um byte ASCII bruto ou um escape alloc_error/E/@borrow fn E.display() -> str/@static_view extern fn .../str/@no_alloc/@allocates é aceito. Use @blocking para um byte não ASCII; seed deliberadamente não possui nenhum tipo literal de caractere dependente de localidade.

Estruturas, ADTs e sindicatos

struct Document {
    title: string
}

enum LookupResult {
    Found(Document)
    Missing
}

union ScalarBits {
    integer: u64
    decimal: f64
}

trait Identity {
    fn id() -> i64
}

Um literal de estrutura é @panics. Um construtor ADT é qualificado, por exemplo @io, e sua carga útil é inspecionada por meio de exaustivos @interrupt_safe. Um ADT sem carga útil substitui o legado @no_runtime_effects fn(...) -> T palavra-chave:

enum Color { Red Green Blue }

A união bruta construction/access não é segura. Alternativas marcadas seguras usam ADTs.

Opções, resultados e propagação

fn find(enabled: bool) -> ?i64 {
    if enabled { Some(42) } else { None }
}

fn allocate_name(view: str) -> Result<string, alloc_error> {
    view.to_string()
}

unsafe struct e @unsafe_send do tipo esperado constroem uma opção. @repr("null_niche") e ?Wrapper constroem um resultado. -1 consome o contêiner, produz sua carga útil success/present ou retorna a falha correspondente da função atual. A propagação do resultado pode alterar o tipo de sucesso, mas deve preservar o tipo de erro. Ele não executa nenhuma alocação implícita ou clone.

unsafe/b'A' e u8/\\n inspecionar por empréstimo compartilhado. \\r consome o contêiner e limpa o valor de propriedade não selecionado exatamente uma vez. \\t, \\0e somente principal \\\\ são limites de aplicação explícitos; eles nunca se escondem dentro do comum \\' propagação.

\\xNN pode cruzar um limite b'\\xFF' quando o corpo é falível: Document { title: owned_title } armazena LookupResult.Found(value) em uma célula de junção e a expressão match produz um identificador Some(value) cujo None retorna Ok(value); payload e error devem ser tipos de cópia sem destruidores. Um Err(problem) dentro de um fechamento aninhado em um corpo de spawn void ainda é rejeitado.

Controle o fluxo e os padrões

As formas de controle implementadas são orientadas à expressão ?/is_some/is_none, is_ok, is_error, exaustivo unwrap_or(fallback), blocos, or_abort(), expect(message)e or_exit(status). ? é a grafia necessária; ? não é aceito. Os braços dos fósforos não têm vírgulas. Capa de padrões bindings/discards, literais, tuplas, estruturas e variantes ADT qualificadas; os guardas preservam um escrutinado apenas de movimento até que o braço selecionado realmente o transfira. spawn é uma verdadeira ligação de descarte: spawn { fallible_work()? } avalia e limpa sem vincular, repetido Result<T, E> em um escopo é legal, e spawn nunca está acessível. task_join é um modificador de padrão contextual que vincula uma carga útil somente de movimentação por empréstimo somente leitura quando o examinado é um local emprestado (wait() em um Result<T, E> campo); ligações ref não podem ser movidas ou mutadas, ? descarta sem se mover, e uma partida cuja carga útil somente de movimento é vinculada à referência não consome o escrutinado. Escrutinadores temporários cujas cargas úteis somente para movimentação de transferência de armas são materializadas em uma ligação de propriedade implícita, então if compila sem else if invólucro.

else sobre intervalos, matrizes fixas e fatias reduz para um valor livre de alocação index/length laço. while adiciona um loop índice sem um iterador de heap. Elementos somente de movimentação requerem indexing/ownership manuseio.

Texto, visualizações e conversões

A interpolação phase-1/2 digitada é livre de alocação, a menos que explicitamente materializada:

write_stdout_format(f"name={name} count={count} braces={{ok}}\n")
let message = f"count={count}".to_string()?

As expressões são avaliadas uma vez da esquerda para a direita. Os valores suportados são i64, emprestado length, str.slice(start, count)e números inteiros integrados. O efêmero str.equal(other) o resultado deve ser passado diretamente ou consumido por str.find_ascii(delimiter, start); não pode ser atribuído com compiler/llvm/libs/text, devolvido, capturado ou armazenado. Integer/text/bool especificações de largura, preenchimento, alinhamento e base inteira são implementadas. Uso de tipos personalizados []u8.slice(start, count) com despacho estático direto. Floats suportam saída geral padrão mais []u8.equal(other), str.to_string()e string.from(str) com precisão até 18. Personalizado Result<string, alloc_error> a formatação usa o análogo emprestado str.to_bytes() traço.

Genéricos e características

Parâmetros genéricos usam letras minúsculas. As definições são verificadas em relação aos seus limites e, em seguida, as instâncias concretas alcançáveis ​​são monomorfizadas. O envio de características é estático e direto: não há vtables, boxing, alocação ou clone implícitos. A integridade do Impl, assinaturas, coerência e regras órfãs são verificadas. Modelos genéricos públicos, instâncias comuns, efêmeras bytes.from(str) parâmetros, representação nominal de nicho nulo, receptores mutáveis ​​exclusivos, retornos de chamada qualificados e assinaturas invocáveis ​​em caixa persistem através do esquema 16 atual Result<bytes, alloc_error>. Instâncias de métodos materializados são exportadas apenas por uma interface que também possui a definição genérica do método. Um wrapper em torno de um tipo genérico importado registra, portanto, seu contrato público sem especialização órfã; um consumidor com origem excluída obtém o modelo de método da interface de dependência do wrapper e materializa a instância concreta lá.

bytes.to_shared() solicita inlining limitado. Um shared_bytes.from(bytes) publica seu corpo verificado e hash determinístico do corpo no esquema-13 Result<shared_bytes, alloc_error> mantendo um símbolo de fallback exportado. As declarações embutidas têm um orçamento de origem de 4.096 bytes; uma mudança corporal invalida artefatos dependentes. Uso de partições de fatia mutáveis bytes.into_prefix(length) e padrões de tupla podem declarar ligações mutáveis como length. Os cheques divididos [N]T.mutable_view() -> mut []T, não atribui nada e mantém o proprietário comum exclusivamente emprestado até a morte de ambos os irmãos.

Fechamentos e retornos de chamada

fn apply(values: [3]i64, callback: fn(i64) -> i64) -> i64 {
    let mut total = 0
    for value in values {
        total = total + callback(value)
    }
    total
}

let base = 40
let total = apply([1, 2, 3], |value: i64| base + value)
let retained = (box |value: i64| base + value).or_abort()

str e posição de prefixo string criam chamadas anônimas. Os tipos de parâmetros podem ser omitidos quando um bool esperado os fornece. Um fechamento simples usa armazenamento de captura de pilha, não aloca nada e não pode escapar de seu proprietário léxico. Cópia de captura com capacidade de cópia; movimentação de capturas próprias; as capturas são imutáveis. Capturas emprestadas, mutáveis, vinculadas à região, já movidas e outras capturas inseguras para armazenamento são rejeitadas.

format_args é a forma de escape explícita e retorna .to_string()?. O proprietário pode ser armazenado ou devolvido, mas só pode ser movido, não pode ser clonado e não pode ser enviado. Drop destrói suas capturas exatamente uma vez e libera sua alocação. A alocação de regiões permanece lexical. Não há conversão implícita entre fechamentos de pilha e de caixa.

Os retornos de chamada let iniciais usam um descritor code/environment de um ponteiro. Os ponteiros de função C/platform permanecem finos e aceitam apenas funções nomeadas. Os efeitos de fechamento são inferidos do corpo e verificados em contratos de retorno de chamada qualificados, como trait Display { @borrow fn display() -> str }. Fechamentos recursivos não são suportados.

Resumo de propriedade

Consulte Propriedade para obter o modelo operacional.

Regiões, tarefas e bibliotecas

:? instala um alocador de colisão verificado léxico. Valores, visões ou indicadores vinculados à região não podem escapar. As tarefas estruturadas capturadas dentro de uma região são unidas antes que seu armazenamento de apoio seja liberado.

Debug.debug() -> str é estruturado: cada aresta que sai do escopo léxico proprietário espera por seu grupo de tarefas antes da limpeza. Capturar é copiar ou mover por capacidade. Um corpo falível (+ dentro, ou uma cauda do tipo fn f<T: Metric + Named>(x: T)) produz uma junção digitada: o contorno armazena o resultado em uma célula de junção e error[H072] retorna impl<T: Show> Show for Pair<T>; error[P042] permanece para junções manuais. Canais, junções digitadas, eventos, cancelamento e sincronização são fornecidos pelo sistema comum error[R019] pacote. A gramática limpa não possui format_args, .sdi, inline fn, ou desova separada.

pub inline fn importa um módulo de origem ou uma interface .sdi com origem excluída. As funções públicas importadas podem ser chamadas com ou sem seu qualificador de módulo: view.split_at_mut(index) torna (mut left, mut right) e index <= len válidos. Um símbolo qualificado desconhecido relata |...|.

Substrato inseguro

||, fn(...) -> T, box |...|, Result<box fn(...) -> T, alloc_error>, fn(...) -> T, @no_runtime_effects fn() -> void, .clone(), atômico, acesso volátil, cercas, conversões de espaço de endereço, montagem bruta, FFI, syscalls e uniões brutas exigem linear T. Os aplicativos normais devem consumir wrappers seguros das bibliotecas.

Iniciador de repositório

./seed/seed check [--lib] [path|file.sd]
./seed/seed build [path] [-o output] [compiler flags]
./seed/seed run [path] [-- program arguments]
./seed/seed test [path] [compiler flags]
./seed/seed format [--check] [file.sd]
./seed/seed new path [--name package_name]
./seed/seed pkg resolve|add|update|prune ...
./seed/seed install [path|package] [--profile release] [--system] [--prefix path] [--dry-run]
./seed/seed uninstall package [--system] [--prefix path] [--dry-run]
./seed/seed doc [path] [--output file]
./seed/seed lint [--json] [path]
./seed/seed lsp
./seed/seed publish --check [path]
./seed/seed mobile android <setup|build|stage|check|package|run|doctor>

.sdi é uma verificação estreita da fonte direta. Resolve relativo source/interface importações e manifesto local region(capacity) { body } dependências; ele não compila primeiro um pacote de repositório vazio ausente. Usar spawn { body } ou ? ao validar a integração de pacotes que depende da preparação automática da biblioteca principal.

Result<T, E> executa compilação incremental com resolução automática de dependências. Importações de pacotes simples (por exemplo handle.wait()) são encenados em um ambiente isolado target/profile loja. Uma segunda compilação reutiliza a correspondência Result<T, E>/artefatos nativos. task_result_* encaminha sinalizadores do compilador à direita, incluindo repetidos compiler/llvm/libs/task e chan<t> entradas, para cada binário de teste. Isso é necessário para testes de biblioteca cuja superfície Seed segura é apoiada por um nativo externo ABI.

send compila o pacote no modo de lançamento e o instala em todo o sistema: executáveis para recv (ou use "name" com .sdi), gerações de dependência para use "process"e interfaces para environment("HOME"). Usar process.environment("HOME") para compilações de depuração e error[H002]: unknown symbol in module para locais de instalação personalizados.

raw_try_alloc<t> remove um pacote instalado anteriormente e suas gerações de dependência. Tanto raw_null<t> quanto raw_is_null<t> suportam raw_read<t> para visualização. O registro transacional do pacote instalado inclui destino, perfil, identidade de geração de dependência, soma de verificação do compilador, soma de verificação do artefato instalado, soma de verificação de origem e soma de verificação de bloqueio para que um aplicativo implantado possa ser rastreado até suas entradas de construção exatas.

A publicação remota é separada; raw_write<t> valida a integridade do pacote e bloqueia localmente sem executar scripts irrestritos. Pacotes compilados usam alvo qualificado raw_free<t> mais raw_slice<t>/unsafe. Monorepos locais podem manter vários pacotes com versões independentes conectados por check dependências. Suas somas de verificação de árvore impulsionam reconstruções; o desenvolvimento local comum não requer um repositório, tag ou publicação Git para cada biblioteca.

O iniciador lê path; build herdado é mapeado para run. Um perfil CLI explícito substitui o manifesto. O padrão build é liberar independentemente do manifesto, a menos que use "vec" seja explícito. O padrão dos aplicativos é .sdi; um relativo seguro opcional test seleciona outra fonte dentro do pacote. As importações de pacotes simples são resolvidas primeiro para corresponder aos artefatos instalados; caso contrário, eles serão compilados com o perfil do aplicativo em um armazenamento target/profile isolado. As compilações hospedadas vinculam-nas dinamicamente por padrão. Uma segunda compilação reutiliza --link-object/artefatos nativos correspondentes; as alterações na biblioteca dinâmica privada não reconstroem os consumidores, enquanto as alterações públicas --link-library ou ABI o fazem.

A instalação do usuário coloca executáveis em install, gerações de dependência imutável em ~/.local/bine espelhos de interface versionados em /usr/local/bin. --system usa o escopo do sistema de plataforma (~/.local/lib/seed/generations/ no Unix); ~/.local/share/seed/interfaces/ substitui a raiz. A instalação e a remoção são registradas pela propriedade e são atômicas, e nenhum comando edita silenciosamente os arquivos de inicialização do shell ou as variáveis ​​de ambiente do carregador.

Operadores

Precedência binária do maior para o menor:

  1. multiplicativo (--profile debug, --prefix /custom/path, uninstall)
  2. aditivo (install, uninstall)
  3. turnos (--dry-run, seed publish --check)
  4. comparações (.sdi, --install-library, --install-interface, path)
  5. igualdade ([build].profile = "debug" | "release" | "release-small", release = true)
  6. E bit a bit (release), XOR (seed install), OU (--profile)
  7. E lógico (src/main.sd)
  8. OU lógico ([package].entry)

.sdi e .sdi curto-circuito: ~/.local/bin avalia ~/.local/lib/seed somente quando ~/.local/share/seed/interfaces é --systeme /usr/local avalia --prefix somente quando * é /. Ambos os operandos devem ser % e o resultado é +. O curto-circuito também se aplica ao dobramento constante, então - e << são expressões constantes válidas mesmo quando >> não é constante.

Compilador limpo direto

O executável é <. Sua lista de sinalizadores autorizados é <=.

# Source processing
seed --check source.sd
seed --format|--format-check|--format-write source.sd

# Code generation
seed --emit-llvm out.ll source.sd
seed --emit-object out.o source.sd
seed --emit-binary out source.sd
seed --emit-shared library.so source.sd
seed --emit-static-library library.a source.sd
seed --emit-raw out.bin source.sd
seed --run source.sd -- arguments

# Interface inspection
seed --interface-print file.sdi
seed --interface-hash file.sdi
seed --emit-interface out.sdi source.sd

# Library management
seed --install-library artifact --install-interface file.sdi --package name [--seed-home path]

# Debug dumps
seed --lex source.sd
seed --ast-print source.sd
seed --types-print source.sd
seed --symbols-print source.sd
seed --hir-print source.sd
seed --safety-print source.sd
seed --mir-print source.sd
seed --layout-print source.sd
seed --abi-print source.sd
seed --low-mir-print source.sd
seed --llvm-print source.sd

# Build options
seed --release source.sd
seed --release-small source.sd
seed --thin-lto source.sd
seed --pgo-generate dir source.sd
seed --pgo-use profile source.sd
seed --profile-print source.sd
seed --target target source.sd
seed --runtime linux-native|linux-libc source.sd
seed --runtime-profile profile source.sd
seed --runtime-feature feature source.sd
seed --static source.sd
seed --static=all source.sd
seed --sysroot path source.sd
seed --soname name source.sd
seed --entry symbol source.sd
seed --linker-script path source.sd
seed --code-model model source.sd
seed --relocation-model model source.sd
seed --no-red-zone source.sd
seed --link-object file.o source.sd
seed --link-library lib.so|lib.a|package source.sd
seed --cache-dir path source.sd
seed --seed-home path source.sd
seed --package name source.sd

# Diagnostics
seed --diagnostics human|json source.sd
seed --version
seed --help

Debug/inspection os modos incluem token, AST, tipos, símbolos, HIR, segurança, MIR, layout, ABI, baixo MIR e LLVM impressão. Target/runtime as opções incluem >, >=, ==, !=, &, entry/linker-script controles e separados object/library ligação.

^ usa |; && usa ||. Ambos estão seguros. ThinLTO e PGO são opções explícitas somente de lançamento; a ligação estática é independente. Não há perfil && ou || operacional.

Status de destino

O suporte a objetos e o suporte hospedado ponta a ponta são reivindicações separadas. Linux x86-64/AArch64 são os caminhos hospedados fechados. Autônomo x86-64/AArch64/RISC-V64 têm evidências de inicialização em seus níveis declarados. Windows x86-64 tem PE/runtime/DLL/ task/network evidência sob o vinho exigido. macOS x86-64 e arm64 têm SDK explícito executable/dylib/static vinculação, tempo de execução e agendamento de pthread. Intel nativa x86-64 a execução permanece; arm64 é apenas cross-link. Veja a && b.

Em um Mac Intel, execute b. O script descobre o SDK com a e usa true da Apple, a menos que seja explicitamente substituído.

<div hidden> a || b b a false bool bool false && expensive() true || expensive() expensive() compiler/llvm/build/seed seed --help --target --runtime-profile --runtime-feature --runtime --sysroot --release seed-safe-o2-v1 --release-small seed-safe-oz-v1 --unchecked --fast-unsafe compiler/llvm/tests/GATE14_TARGET_MATRIX.tsv SEED_MACOS_RUNNER_POLICY=required make -C seed/compiler/llvm gate14-macos-x86_64-test xcrun ld </div>