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
- literais têm tipo emprestado estático
str; - propriedade
stringtoma emprestado automaticamente comostrquando esperado; lenretornausizepara texto, buffers, fatias e matrizes;string.view()retornastr;bytes.view()eshared_bytes.view()retornam[]u8;bytes.mutable_view()retorna ummut []u8exclusivo com o total comprimento alocado;bytes.zeroed(length)aloca de forma falívellengthbytes inicializados com zero e seumutable_view()cobre a alocação completa;byte_buffer.mutable_view()retorna apenas o prefixo inicializado (comprimento 0 para um buffer novo), não a capacidade — usebytes.zeroedquando um destino de gravação mutável completo for necessário;bytes.zeroed(length)requeri64e aloca falivelmentelengthbytes inicializados com zero;- matrizes fixas derivam visualizações compartilhadas compatíveis e matrizes mutáveis derivam visualizações exclusivas;
str.slice(start, count)é verificado e tem cópia zero;- fatias de texto também verificam UTF-8 limites de pontos de código;
str.equal(other)estr.find_ascii(delimiter, start)verificado são livre de alocação;compiler/llvm/libs/textcria um cursor de divisão seguro para origem e origem a partir de intervalos de bytes retornados;[]u8.slice(start, count)é uma subvisão de cópia zero verificada e[]u8.equal(other)compara comprimento e conteúdo sem alocação;str.to_string()/string.from(str)retornarResult<string, alloc_error>;str.to_bytes()/bytes.from(str)retornarResult<bytes, alloc_error>;bytes.to_shared()/shared_bytes.from(bytes)consomem os bytes do proprietário e retorneResult<shared_bytes, alloc_error>.bytes.into_prefix(length)consome o proprietário, verificalengthem relação ao comprimento inicializado e retorna a mesma alocação com um comprimento lógico menor. Não aloca nem copia; o proprietário original é movido.[N]T.mutable_view() -> mut []Tderiva uma visualização mutável exclusiva quando o o proprietário do array é mutável.
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
- escalares e cópia de agregados somente cópia;
- os recursos se movem e tornam o local de origem indisponível;
.clone()é explícito e capability/effect verificado;- visualizações emprestadas carregam origem sem sintaxe vitalícia;
- a limpeza estruturada é executada exatamente uma vez em saídas estruturadas normais;
- panic/trap/abort não desenrola nem executa destruidores;
linear Tdeve ser consumido exatamente uma vez;- a propriedade parcial é rastreada por meio de campos, campos aninhados, matriz conhecida
índices, cargas úteis ADT, uniões, genéricos, canais, valores de função e
.sdi; as movimentações de recursos de índice dinâmico permanecem rejeitadas.
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:
- multiplicativo (
*,/,%) - aditivo (
+,-) - turnos (
<<,>>) - comparações (
<,<=,>,>=) - igualdade (
==,!=) - E bit a bit (
&), XOR (^), OU (|) - E lógico (
&&) - 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.