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 parse_result
constante [A-Z][A-Z0-9_]* MAX_DOCUMENT_SIZE

O nome formal do idioma é seed. Os tipos não são capitalizados. _ 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 //. Bloquear comentários /* ... */ ninho. A gramática limpa não usa # 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 u32 fixas privadas, como const TABLE: [4]u32 = [1 as u32, 2 as u32, 3 as u32, 4 as u32], 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 mut. A atribuição a uma associação, campo ou índice por meio de uma associação exige que essa associação seja mutável. linear cria uma obrigação exatamente uma vez.

Para descartar um valor de retorno, vincule-o a um nome exclusivo começando com _: let _unused = expression. Os descartes nomeados evitam o erro de "ligação ativa duplicada" que let _ = expression 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
}

fn document.title_size() -> usize {
    len(self.title)
}

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. ret expression retorna mais cedo; o compilador limpo não usa return. Uma declaração de método inclui o tipo nominal antes do ponto e recebe implícito self; não escreva self em sua lista de parâmetros. fn type_name.drop() é um destruidor consumidor. @borrow em um método ou método de característica dá self um empréstimo lexical compartilhado. @mut em vez disso, requer um receptor endereçável mutável, possui um empréstimo exclusivo para a chamada e faz mutações para self visível para o chamador. Os dois atributos são mutuamente exclusivos.

As declarações públicas usam pub. Declarações estrangeiras usam extern 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, str, fatias e estruturas C equivalentes interoperam com MinGW/MSVC-style chamados.

Tipos principais

Categoria Tipos
controle void, never, bool
inteiro i8, i16, i32, i64, u8, u16, u32, u64, isize, usize; Aliases byte u8
flutuar f32, f64
text/buffer str, string, bytes, shared_bytes
formatação format_args (efêmero)
aggregate/view [n]t, []t, mut []t, tuplas, nominal structs/ADTs/unions
fracasso ?t, result<t,e>, alloc_error
chamável não proprietário fn(t) -> u, escapando box fn(t) -> u
baixo nível ponteiros brutos mais user, kernel, physical, mmioe dma espaços de endereço
exatamente uma vez linear t

alloc_result<t> abrevia result<t, alloc_error> sem introduzir uma nova identidade de tipo, representação, regra de limpeza ou ABI.

Hospedado main pode retornar result<i64, e>. ok(status) sai com esse status; alloc_error usa o diagnóstico de alocação fixa. Outro e deve ser cópia, não ter destruidor e implementar @borrow fn e.display() -> str; sua visão é escrita uma vez antes do status 1, após a limpeza normal.

@static_view extern fn ... é a declaração FFI auditada para um retorno str/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: @no_alloc, @allocates, @blocking, @panics, @io, @interrupt_safe. Os tipos de retorno de chamada qualificados usam @no_runtime_effects fn(...) -> t para declarar um resumo completo do efeito vazio. Um unsafe struct pode declarar @unsafe_send para afirmar a capacidade de envio ou @repr("null_niche") para permitir a otimização de ponteiro nulo em um único campo de ponteiro bruto para ?wrapper.

O inteiro add/subtract/multiply é encapsulado de forma determinística na largura do tipo. Divisão por zero, mínimo assinado dividido por -1, 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 unsafe e uma entrada representável por destino finito.

Literais de byte usam b'A' e têm o tipo u8. Um byte ASCII bruto ou um escape \\n/\\r/\\t/\\0/\\\\/\\'/\\xNN é aceito. Use b'\\xFF' 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
}

type parse_result {
    parsed(document)
    invalid(str)
}

union scalar_bits {
    integer: u64
    decimal: f64
}

Um literal de estrutura é document.{ title: owned_title }. Um construtor ADT é qualificado, por exemplo parse_result.parsed(value), e sua carga útil é inspecionada por meio de exaustivos match. Um ADT sem carga útil substitui o legado enum palavra-chave:

type 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()
}

some(value) e none do tipo esperado constroem uma opção. result.ok(value) e result.error(problem) constroem um resultado. ? 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.

is_some/is_none e is_ok/is_error inspecionar por empréstimo compartilhado. unwrap_or(fallback) consome o contêiner e limpa o valor de propriedade não selecionado exatamente uma vez. or_abort(), expect(message)e somente principal or_exit(status) são limites de aplicação explícitos; eles nunca se escondem dentro do comum ? propagação.

? não pode cruzar um limite spawn enquanto a tarefa descrita ABI retorna void.

Controle o fluxo e os padrões

As formas de controle implementadas são orientadas à expressão if/elif/else, while, for, exaustivo match, blocos, break, continuee ret. elif é a grafia necessária; else if 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.

for sobre intervalos, matrizes fixas e fatias reduz para um valor livre de alocação index/length laço. for index, value in enumerate(items) adiciona um usize í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 str, emprestado string, boole números inteiros integrados. O efêmero format_args o resultado deve ser passado diretamente ou consumido por .to_string()?; não pode ser atribuído com let, devolvido, capturado ou armazenado. Integer/text/bool especificações de largura, preenchimento, alinhamento e base inteira são implementadas. Uso de tipos personalizados trait display { @borrow fn display() -> str } com despacho estático direto. Floats suportam saída geral padrão mais f/F, e/Ee g/G com precisão até 18. Personalizado :? a formatação usa o análogo emprestado debug.debug() -> str 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, parâmetros format_args efêmeros, representação nominal de nicho nulo, receptores mutáveis ​​​​exclusivos, retornos de chamada qualificados e assinaturas que podem ser chamadas em caixa persistem através do esquema 16 atual .sdi. 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á.

inline fn solicita inlining limitado. Um pub inline fn publica seu corpo verificado e hash determinístico do corpo no esquema-13 .sdi 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 view.split_at_mut(index) e padrões de tupla podem declarar ligações mutáveis como (mut left, mut right). Os cheques divididos index <= len, 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()

|...| e posição de prefixo || criam chamadas anônimas. Os tipos de parâmetros podem ser omitidos quando um fn(...) -> t 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; movimento 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.

box |...| é a forma de escape explícita e retorna result<box fn(...) -> t, alloc_error>. 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 fn(...) -> t 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 @no_runtime_effects fn() -> void. Fechamentos recursivos não são suportados.

Resumo de propriedade

Consulte Propriedade para obter o modelo operacional.

Regiões, tarefas e bibliotecas

region(capacity) { body } instala um alocador de colisão verificado lexical. 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.

spawn { body } é 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. Canais, junções digitadas, eventos, cancelamento e sincronização são fornecidos pelo sistema comum compiler/llvm/libs/task pacote. A gramática limpa não possui chan<t>, send, recv, ou desova separada.

Substrato inseguro

raw_try_alloc<t>, raw_null<t>, raw_is_null<t>, raw_read<t>, raw_write<t>, raw_free<t>, raw_slice<t>, atômico, acesso volátil, cercas, conversões de espaço de endereço, montagem bruta, FFI, syscalls e uniões brutas exigem unsafe. 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>

check é uma verificação estreita da fonte direta. Resolve relativo source/interface importações e manifesto local path dependências; ele não compila primeiro um pacote de repositório vazio ausente. Usar build ou run ao validar a integração de pacotes que depende da preparação automática da biblioteca principal.

build executa compilação incremental com resolução automática de dependências. Importações de pacotes simples (por exemplo use "vec") são encenados em um ambiente isolado target/profile loja. Uma segunda compilação reutiliza a correspondência .sdi/artefatos nativos. test encaminha sinalizadores do compilador à direita, incluindo repetidos --link-object e --link-library 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.

install compila o pacote no modo de lançamento e o instala em todo o sistema: executáveis para ~/.local/bin (ou /usr/local/bin com --system), gerações de dependência para ~/.local/lib/seed/generations/e interfaces para ~/.local/share/seed/interfaces/. Usar --profile debug para compilações de depuração e --prefix /custom/path para locais de instalação personalizados.

uninstall remove um pacote instalado anteriormente e suas gerações de dependência. Tanto install quanto uninstall suportam --dry-run 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; seed publish --check valida a integridade do pacote e bloqueia localmente sem executar scripts irrestritos. Pacotes compilados usam alvo qualificado .sdi mais --install-library/--install-interface. Monorepos locais podem manter vários pacotes com versões independentes conectados por path 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ê [build].profile = "debug" | "release" | "release-small"; release = true herdado é mapeado para release. Um perfil CLI explícito substitui o manifesto. O padrão seed install é liberar independentemente do manifesto, a menos que --profile seja explícito. O padrão dos aplicativos é src/main.sd; um relativo seguro opcional [package].entry 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 .sdi/artefatos nativos correspondentes; as alterações na biblioteca dinâmica privada não reconstroem os consumidores, enquanto as alterações públicas .sdi ou ABI o fazem.

A instalação do usuário coloca executáveis em ~/.local/bin, gerações de dependência imutável em ~/.local/lib/seede espelhos de interface versionados em ~/.local/share/seed/interfaces. --system usa o escopo do sistema de plataforma (/usr/local no Unix); --prefix 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 (*, /, %)
  2. aditivo (+, -)
  3. turnos (<<, >>)
  4. comparações (<, <=, >, >=)
  5. igualdade (==, !=)
  6. E bit a bit (&), XOR (^), OU (|)
  7. E lógico (&&)
  8. OU lógico (||)

&& e || curto-circuito: a && b avalia b somente quando a é truee a || b avalia b somente quando a é false. Ambos os operandos devem ser bool e o resultado é bool. O curto-circuito também se aplica ao dobramento constante, então false && expensive() e true || expensive() são expressões constantes válidas mesmo quando expensive() não é constante.

Compilador limpo direto

O executável é compiler/llvm/build/seed. Sua lista de sinalizadores autorizados é seed --help.

# 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 --target, --runtime-profile, --runtime-feature, --runtime, --sysroot, entry/linker-script controles e separados object/library ligação.

--release usa seed-safe-o2-v1; --release-small usa seed-safe-oz-v1. 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 --unchecked ou --fast-unsafe 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 compiler/llvm/tests/GATE14_TARGET_MATRIX.tsv.

Em um Mac Intel, execute SEED_MACOS_RUNNER_POLICY=required make -C seed/compiler/llvm gate14-macos-x86_64-test. O script descobre o SDK com xcrun e usa ld da Apple, a menos que seja explicitamente substituído.