Referência de idioma

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

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, enum, união, característica, parâmetro genérico [A-Z][a-zA-Z0-9]* Document, T
variante enum [A-Z][a-zA-Z0-9]* Some, Ok, Red
constante [A-Z][A-Z0-9_]* MAX_DOCUMENT_SIZE

O nome formal do idioma é seed, sempre em letras minúsculas. Os nomes dos valores usam letras minúsculas; tipos nominais e variantes enum usam UpperCamelCase e correspondem a [A-Z][a-zA-Z0-9]*. Constantes usam caixa de cobra superior. _ é a ligação de descarte; 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

const MAX_COUNT: usize = 100

fn release(ticket: i64) {}

fn main() -> i64 {
    let answer = 42
    let mut count: usize = 0
    count += 1
    let linear ticket = 7
    release(ticket)
    if count < MAX_COUNT { answer } else { 0 }
}

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.

A anotação de tipo constante é opcional, correspondendo a const_decl = "const", constant_ident, [ ":", type ], "=", expression: uma constante não anotada infere seu tipo de seu inicializador (const MAX_ITEMS = 64 é i64, const OFFSETS = [1, 4, 9] é [3]i64), incluindo texto estático, tuplas, estruturas e constantes nomeadas. Um inicializador cujo tipo não pode ser inferido precisa de uma anotação explícita e é rejeitado com R037 na declaração.

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.

let também aceita padrões irrefutáveis: desestruturação de tupla (let (a, b) = pair), desestruturação de estrutura (let Point { x, y } = origin), curingas (_) e aninhamento. Cada folha nomeada torna-se uma ligação comum movida para fora do componente do inicializador, portanto, propriedade, linearidade e limpeza rastreiam os componentes de forma independente. Padrões refutáveis ​​(variantes, literais) são rejeitados (error[B043]); use match para eles.

Uma anotação let aceita qualquer tipo válido em uma posição de parâmetro (matrizes, fatias, tuplas, ponteiros, tipos de função, genéricos, nomes qualificados) e é verificada em relação ao tipo de inicializador inferido (error[H059] em caso de incompatibilidade). As consultas de layout em tempo de compilação size_of(type) e align_of(type) são avaliadas em relação ao destino ativo e são válidas em contextos constantes — inicializadores const e comprimentos de matriz, como [size_of(i64)]u8; em outros lugares eles são rejeitados com error[H129].

Para descartar um valor de retorno, use let _ = expression que avalia e limpa o valor sem criar uma ligação; _ repetido em um escopo é legal e _ nunca é acessível. let _unused = expression com um sublinhado à esquerda também marca uma ligação intencionalmente não utilizada, mas cria uma ligação nomeada.

Funções, métodos e retornos

struct Document {
    title: string
}

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. return expression retorna mais cedo; o compilador limpo não usa ret. 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 TypeName.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.

str os retornos são baseados na proveniência, não restritos a métodos: uma função livre pode retornar uma visão estática ou derivada de entrada. Uma visão derivada de uma propriedade local string/bytes o valor não pode escapar (V001); devolver o proprietário quando a propriedade tiver que deixar a função. Não há sintaxe vitalícia.

As declarações públicas usam pub. As 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/enums/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

AllocResult<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 tipo literal de caractere dependente de localidade.

Literais inteiros são decimais, 0x hexadecimal ou 0b binário, com _ como um separador de dígitos opcional (20_000_000, 0xFF, 0b1010). Cada forma aceita chega ao codegen em todos os lugares onde um literal é permitido, incluindo literais de array e literais repetidos.

Um literal de matriz repetida preenche uma matriz fixa a partir de um literal: let slots: [4]usize = [0; 4], [255; 3], [[0; 2]; 3]. O tipo de elemento vem da anotação ou do tipo esperado do array, portanto, nenhuma conversão é necessária. O valor deve ser um literal (ou uma conversão de um, ou uma matriz deles) - um valor de local ou chamada é rejeitado como B048 em vez de avaliado silenciosamente uma vez por elemento - e a contagem deve ser um literal inteiro positivo (B049) de no máximo 65536 (B050), porque os elementos são materializados individualmente; preenchimentos maiores pertencem a um buffer de heap ou a um loop explícito.

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 é Document { title: owned_title }. Um construtor ADT é qualificado, por exemplo LookupResult.Found(value), e sua carga útil é inspecionada por meio de exaustivos match. Uma enumeração sem carga útil:

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

Some(value) e None do tipo esperado constroem uma opção. Ok(value) e Err(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.

? pode cruzar um limite spawn quando o corpo é falível: spawn { fallible_work()? } armazena Result<T, E> em uma célula de junção e a expressão spawn produz um identificador task_join cujo wait() retorna Result<T, E>; payload e error devem ser tipos de cópia sem destruidores. Um ? 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 if/else if/else, while, loop, for, exaustivo match, blocos, break, continuee return. else if é a grafia necessária; elif não é aceito. Os braços de fósforo não precisam de vírgulas, a menos que o limite seja ambíguo: um braço cujo corpo termina numa expressão seguida por um (/[ padrão requer a vírgula (B044). 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. _ é uma verdadeira ligação de descarte: let _ = expr avalia e limpa sem vincular, repetido _ em um escopo é legal, e _ nunca está acessível. ref é 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 (Some(ref info) em um @borrow self campo); ligações ref não podem ser movidas ou mutadas, ref _ 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 match fallible() { Ok(v) => ... } compila sem let x = expr invólucro.

if let e while let são os formulários concisos sobre match: if let Some(x) = found { ... } else { ... } e while let Some(x) = next { ... }. Tanto desugar para uma partida de dois braços, então vinculação, comportamento move/borrow e limpeza são exatamente as regras de partida. if let Some(...) nomeia seu complemento como None; qualquer outro padrão variante mantém um braço curinga, e H032 rejeita isso quando o examinado carrega uma carga útil somente de movimento - escreva os braços match explícitos lá. Um padrão irrefutável (while let name = value) é rejeitado como H029.

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:

use "file"

fn main() -> Result<i64, alloc_error> {
    let name = "widget"
    let count = 3
    write_stdout_format(f"name={name} count={count} braces={{ok}}\n")
    let message = f"count={count}".to_string()?
    Ok(len(message) as i64)
}

As expressões são avaliadas uma vez da esquerda para a direita. Os valores suportados são str, emprestado string, boole inteiros integrados - como expressões arbitrárias, não apenas nomes: chamadas, operadores e aninhamento, todos funcionam (f"{a + b}", f"{p.distance()}"). 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 UpperCamelCase. As definições são verificadas em relação aos seus limites e, em seguida, as instâncias concretas alcançáveis ​​são monomorfizadas. Um parâmetro pode declarar vários limites de características com + (fn f<T: Metric + Named>(x: T)); cada limite deve nomear uma característica declarada, o argumento deve implementar todas elas (error[H072] por limite ausente) e os métodos de característica são resolvidos através de qualquer limite. Os blocos Impl podem ser genéricos: impl<T: Show> Show for Pair<T> implementa a característica para cada instância cujos argumentos satisfazem os limites do impl; os argumentos de destino devem ser exatamente os parâmetros do impl em ordem (error[P042]), e um impl genérico sobreposto a outro impl da mesma característica para o mesmo tipo é rejeitado (error[R019]). 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 format_args 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 17 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
}

fn main() -> i64 {
    let base = 40
    let total = apply([1, 2, 3], |value: i64| base + value)
    let retained = (box |value: i64| base + value).or_abort()
    total + retained(1)
}

|...| 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. Um corpo falível (? dentro, ou uma cauda do tipo Result<T, E>) produz uma junção digitada: o contorno armazena o resultado em uma célula de junção e handle.wait() retorna Result<T, E>; task_result_* permanece para junções manuais. 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.

use "name" importa um módulo de origem ou uma interface .sdi com origem excluída. Funções públicas importadas podem ser chamadas com ou sem seu qualificador de módulo: use "process" torna environment("HOME") e process.environment("HOME") válidos. Um símbolo qualificado desconhecido relata error[H002]: unknown symbol in module.

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 requerem unsafe. Os aplicativos normais devem consumir wrappers seguros das bibliotecas.

Iniciador de repositório

./seed/seed check [--lib] [path|file.sd]
./seed/seed check [--json|--deep] [--report report.json] [--max-ms n] [--max-rss-kib n] [--max-files n] [--max-loc n] [--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 fmt [--check] [file.sd]  # short alias
./seed/seed fmt --write directory/
./seed/seed fmt --check --json [--output file] [file.sd|directory]

With `--check`, a directory recursively checks its `.sd` files; `.git`,
`target`, and `.seed` directories are ignored.
With `--json`, the formatter emits `seed.format.v1` with per-file status and
stable checked/needs-format/error counts; a non-zero status still includes the
complete JSON result.
./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] [--json] [--check-links] [--output file]
./seed/seed lint [--json] [--deny-warnings] [--cache dir] [--no-cache] [--fix] [--output file] [path]
./seed/seed explain [--json] CODE
./seed/seed explain [--json] --list
./seed/seed lsp
./seed/seed repl [--json]
./seed/seed publish --check [--json] [path]
./seed/seed publish --check [path]
./seed/seed mobile android <setup|sign|build|stage|check|package|run|doctor>

check é uma verificação estreita e direta da fonte que executa todo o pipeline semântico, incluindo todas as provas de segurança obrigatórias (propriedade, proveniência, efeitos, limpeza, empréstimos, simultaneidade); reutilizar um HIR armazenado em cache não ignora nenhum deles. check --deep adiciona apenas a passagem didática do lint após a verificação semântica passar; nunca substitui uma prova. 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.

check --report report.json escreve um determinístico seed.check-report.v1 resumo com a fonte, file/LOC contagens, sinalizador de modo profundo, resultado, tempo total decorrido e fases separadas de resolução de origem, verificação semântica e (quando solicitado) deep-lint. Em hosts POSIX também registra peak_child_rss_kib para o compiler/lint subprocessos. Se o deep lint falhar, o relatório marcará a fase do deep-lint e o resultado geral como fail e inclui seu error/warning conta. O relatório também inclui tempos de fase do compilador interno e pico de RSS quando o LLVM o criador de perfil está disponível. --max-ms e --max-rss-kib adicionar orçamentos de CI explícitos; elas são verificações pós-execução: o subprocesso do compilador é executado até a conclusão e, em seguida, as ferramentas avaliam o tempo de parede (desde o início da ferramenta) e o pico filho de RSS em relação aos limites máximos. Os orçamentos excedidos são registrados no relatório e falham no comando após a emissão da saída estruturada (budgets.violations mais o distinto check budget exceeded erro). --max-files e --max-loc aplique a mesma política ao tamanho da fonte alcançável.

As falhas do compilador vêm em duas classes. Uma falha semântica é uma violação do programa relatada como diagnósticos específicos (códigos como S001, H022) com vãos, notas e ajuda. Uma falha de infraestrutura — falta de memória do compilador ou uma violação do contrato do conjunto de ferramentas — é relatada como error[I-code]: detail (I900 fallback) ou a mensagem genérica "compilador ficou sem memória ou violou um contrato de infraestrutura", sem nenhum artefato de saída publicado. Nem o lado do programa alloc_error, que é um tipo de resultado de tempo de execução recuperável dentro dos programas gerados (consulte o capítulo sobre propriedade).

check --json emite o diagnóstico legível por máquina do compilador mais o verificado source e um estábulo summary com error/warning conta. Pode ser combinado com --deep para incluir o seed.lint.v1 carga útil de lint profundo; adicionar --deny-warnings para fazer com que os avisos do compilador e do deep-lint falhem na verificação enquanto ainda emitem o completo JSON envelope. --output file escreve isso JSON atomicamente e mantém o stdout limpo, inclusive quando a verificação falha.

doc --json emite um seed.doc.v1 índice de documentação contendo declarações públicas, Markdown renderizado, dependências somente de interface e diagnóstico de links estruturados. doc --check-links transforma links não resolvidos em um status de falha. lint --deny-warnings da mesma forma, transforma os avisos de lint em um status de falha sem alterar o comportamento de aviso padrão; lint --output file escreve o JSON ou resultado de texto atomicamente, inclusive em uma execução de lint com falha. Os resultados do Lint são reutilizados a partir de um cache por origem endereçado ao conteúdo em .seed/cache/lint por padrão; --cache dir ou SEED_LINT_CACHE substitui-lo, e --no-cache força uma corrida a frio. --prune-days N remove entradas antigas do cache e relata a contagem. SEED_BUILD_JOBS controla verificações de fontes paralelas limitadas enquanto preserva a ordem de diagnóstico. As entradas de cache usam o seed.lint-cache.v1 envelope; entradas malformadas ou mais antigas são reconstruídas e relatadas como cache.invalidated. Apenas documentação L001 os diagnósticos são armazenados em cache de forma independente por declaração pública, para que edições não relacionadas possam reutilizá-los; a verificação semântica permanece na fonte inteira. --fix aplica apenas correções seguras de comentários de documentação e desativa a reutilização de cache para essa execução.

O cache HIR verificado do compilador pode ser mantido explicitamente com --cache-prune-days N junto com --cache-dir dir. Ele remove apenas arquivos de identidade .hci regulares antigos desse diretório; arquivos não relacionados, links simbólicos, publicações temporárias e entradas recentes são preservados. A poda é consultiva e nunca ignora a compilação ou verificação de segurança.

explain --json CODE emite um registro seed.explain.v1 contendo o título, significado, exemplo inválido e orientação de reparo para um código de diagnóstico. Sem --json, ele mantém a explicação longa orientada para o ser humano. explain --list enumera o catálogo disponível; O modo JSON emite seed.explain-catalog.v1 com os registros estruturados completos.

repl é uma sessão orientada apenas para verificação. Cada linha inserida é validada como parte do atual fn main região antes de ser aceito. Uso de regiões multilinha :begin e :end transacionalmente; :check, :show, :reset, :undo, :helpe :quit gerenciar a sessão. :show imprime apenas a região aceita, excluindo qualquer transação aberta. Ele não executa código nem enfraquece as regras de propriedade. A conclusão do LSP segue a gramática atual, incluindo return, loop, breake continue; grafias herdadas removidas não são sugeridas. repl --json emite um seed.repl-event.v1 JSON objeto por evento para editores e consumidores de automação, incluindo linhas de transação pendentes e saída de sessão. check --max-files N e check --max-loc N rejeitar projetos que excedam orçamentos explícitos em escala de fontes acessíveis e registrem violações no relatório de verificação e JSON envelope de diagnóstico. O JSON envelope também expõe observado metrics para arquivos acessíveis, LOC, milissegundos decorridos e pico de RSS filho. O result campo é explicitamente pass ou fail, incluindo falhas orçamentárias. Com --report, JSON O modo também incorpora o relatório de fase completo enquanto grava o arquivo de relatório solicitado atomicamente.

publish --check --json emite seed.publish-check.v1 com o pacote, versão e pass/fail resultado para integrações de CI; --output file escreve atomicamente. As falhas de validação ainda retornam um status diferente de zero após a emissão do resultado estruturado. Envelopes de falha incluem estável error_code e o resolvido project, para que os consumidores não precisem analisar o texto de erro humano. As classes conhecidas incluem PUBLISH_MANIFEST, PUBLISH_LICENSE, PUBLISH_DEPENDENCY, PUBLISH_PLATFORMe PUBLISH_FFI_INSTALL.

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 do pacote instalado transacional 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. Declaração de pacotes extern fn também deve fornecer INSTALL.md descrevendo a configuração nativa necessária para as plataformas declaradas; o arquivo deve ser legível UTF-8 e não vazio. 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á operação --unchecked ou --fast-unsafe perfil.

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.