Visão Geral do Artcode
Artcode é uma linguagem de programação experimental construída em Rust com foco em
Complexidade Progressiva: iniciantes têm uma sintaxe simples; especialistas
ganham controle total de memória e concorrência.
Objetivos
- Base modular (lexer, parser, core AST, interpreter, CLI) para evoluir em direção a JIT/AOT
- Result e enums para modelagem de erros sem exceções implícitas
- f-strings poderosas sem sacrificar legibilidade
- Execução determinística e transparente
Fluxo de Execução
- Ler fonte (arquivo ou REPL)
- Lexer gera tokens — inclui
InterpolatedString para f-strings
- Parser converte tokens em AST (
Program = Vec<Stmt>)
- Interpreter percorre statements, avaliando expressões, gerindo ambientes aninhados
- Funções criam closures capturando ambiente pai via weak refs (evita ciclos)
- Pattern matching resolve variantes de enum e injeta bindings no escopo do case
Arquitetura em Camadas
cli --> parser -----> core (AST + tokens + env)
\ ^ ^
\ | |
\--> lexer ---------/
|
+---> interpreter (usa AST + registry de tipos)
Crates do Workspace
- core — AST, valores, tokens, ambiente léxico, padrões de match
- lexer — Tokenizador com suporte a números, strings e f-strings
- parser — Parser recursivo descendente que constrói a AST
- interpreter — Runtime: execução, escopos, pattern matching, métodos,
métricas
- diagnostics — Sistema centralizado de erros com spans e sugestões
- cli — Interface de linha de comando (run, fmt, lint, lsp)
- ir — Intermediate Representation para futuro JIT/AOT
- jit — Scaffold experimental de compilação LLVM
Decisões de Design
| Tema |
Decisão |
Racional |
| Memória |
ARC + weak/unowned |
Determinismo sem GC; controle progressivo |
| Erros |
Diagnostics + Result |
Sem panics; amigável para IDE/LSP |
| f-strings |
Parser recursivo + specs |
Poder expressivo com reutilização do pipeline |
| Pattern Match |
Exaustivo com guards |
Segurança: sem cases esquecidos |
| Métodos |
TypeRegistry + auto-binding |
Clareza sem blocos impl complexos |
| Métricas |
handled_errors, crash_free%,
executed_statements
|
Observabilidade builtin desde o dia 1 |
| Enum shorthand |
Inferência única por variante (.Ok, .Err) |
Ergonomia mantendo determinismo; erro em ambiguidade |
| Qualidade |
CI (fmt, clippy -D warnings, testes, coverage badge) |
Reforça saúde do projeto; scan automático de panics/unwraps |
Estado Atual & Limitações
- Parser e lexer não panicam em entradas malformadas — erros viram diagnostics acumulados
- Métodos existem mas ainda não há bloco
impl agrupador; use
func Tipo.metodo(self) {}
- Sistema de tipos básico: sem generics, sem checagem de campo em parse-time para struct init
- Execução ainda interpretada (sem JIT/AOT) — plano: compilador "Jano" no roadmap v0.2+
- REPL básico: sem histórico e sem exibição automática do último valor
Scripts de Qualidade
cargo xtask ci # fmt + clippy + testes + scan de panics + cobertura
bash scripts/devcheck.sh # atalho rápido de verificação
bash scripts/gen_coverage_badge.sh # gera badge SVG de cobertura atualizado
bash scripts/check_ast_docs.sh # garante sync de docs quando AST mudar
Instalação
A forma mais rápida de instalar o Artcode é com o script de instalação oficial, que baixa o binário
pré-compilado direto da última release e instala em /usr/local/bin.
Instalação rápida (Linux / macOS)
curl -fsSL https://raw.githubusercontent.com/kitsuneislife/artcode/main/install.sh | bash
O script detecta automaticamente seu sistema operacional e arquitetura e baixa o binário correto.
| Plataforma | Binário |
| Linux x86_64 | art-linux-x86_64 |
| macOS Intel | art-macos-x86_64 |
| macOS Apple Silicon | art-macos-arm64 |
| Windows | Baixe o .exe na página de releases |
Verificar instalação
art run examples/00_hello.art
# Olá, Artcode! 🚀
Compilar a partir do fonte
Se preferir compilar você mesmo (ou contribuir com o projeto), siga os passos abaixo.
Requisitos
- Rust stable toolchain via rustup
- Componentes recomendados:
rustfmt, clippy
- Sistema:
build-essential, pkg-config, git
Ubuntu / Debian
sudo apt update
sudo apt install -y build-essential pkg-config curl git
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source $HOME/.cargo/env
rustup component add rustfmt clippy
Arch Linux
sudo pacman -Syu --noconfirm base-devel pkgconf curl git python
sudo pacman -S --noconfirm rustup
rustup default stable
rustup component add rustfmt clippy
Windows
Recomendamos usar WSL2 (Ubuntu) e seguir os passos de Ubuntu. Para instalação
nativa, use rustup e instale o Build Tools for
Visual Studio.
Build & Testes
git clone https://github.com/kitsuneislife/artcode
cd artcode
cargo build -p cli --release
sudo cp target/release/art /usr/local/bin/
cargo test --all # rodar todos os testes
Prelude & Standard Library
O Artcode carrega automaticamente um prelude com funções e tipos essenciais disponíveis em todo
programa, sem necessidade de imports.
Funções Builtin
| Função |
Assinatura |
Comportamento |
println |
println(value: Any) -> None |
Imprime com newline via Display. Retorna None. Sem panic.
|
print |
print(value: Any) -> None |
Imprime sem newline. |
len |
len(Array|String) -> Int |
Diagnostic len: unsupported type se tipo inválido. |
type_of |
type_of(Any) -> String |
Nome do tipo dinâmico. Útil para debug e REPL. |
input |
input(prompt: String) -> String |
Lê linha do stdin após exibir prompt. |
Enum Result (prelude automático)
Registrado via Interpreter::with_prelude(). Inferência shorthand:
.Ok(v)
busca o enum único contendo Ok. Emite diagnostic se 0 ou >1 enum têm essa
variante.
func dividir(a: Int, b: Int) -> Result {
if b == 0 { return .Err("zero") }
return .Ok(a / b)
}
let r = dividir(10, 2);
match r {
case .Ok(v): println(f"valor={v}")
case .Err(e): println(f"erro={e}")
}
Standard Library
| Módulo |
Builtins principais |
Notas |
| Collections |
map_new, map_set, map_get,
set_new, set_add
|
len(m) funciona em Map e Set |
| Math |
math_abs, math_pow, math_clamp,
math_sqrt
|
Funções numéricas sem panic |
| Time |
time_now() -> Int (ms) |
Timestamp em ms para benchmarks embutidos |
| Rand |
rand_next(max: Int) -> Int |
Número inteiro pseudo-aleatório |
| File IO |
io_write_text(path, data), io_read_text(path) |
Sandboxed; apenas caminhos relativos |
Boas Práticas
- Prefira pattern matching em vez de "desembrulhar" diretamente
- Evite variantes polimórficas excessivas; mantenha semântica clara
- Use
type_of() no REPL para inspecionar valores inesperados
Enums & Pattern Matching
Enums em Artcode suportam variantes com payloads e são o mecanismo central de modelagem de dados
junto com o pattern matching exaustivo.
enum Shape {
Circle(Float),
Rect(Float, Float),
Point
}
func area(s: Shape) -> Float {
match s {
case .Circle(let r): 3.14 * r * r
case .Rect(let w, let h): w * h
case .Point: 0.0
}
}
Guards
Cases podem ter condições adicionais com if:
match valor {
case .Ok(let v) if v > 100: println("Grande!")
case .Ok(let v): println(f"Normal: {v}")
case .Err(let e): println(f"Erro: {e}")
}
Shorthand Inference
Quando o tipo esperado é inequívoco, use .Variant sem prefixar o nome do enum. O
compilador detecta ambiguidades automaticamente (.Ok vs Result.Ok).
Erro de ambiguidade se mais de um enum registrado tiver a mesma variante.
Implementação Interna
Enums são representados como ArtValue::EnumInstance { enum_name, variant, values }.
Dentro de métodos de enum, os identificadores variant (String) e
values (Array dos payloads) são injetados automaticamente para introspecção.
Erros Comuns
| Cenário |
Diagnóstico |
| Variante inválida |
Variante não existe no enum registrado |
| Aridade incorreta |
Chamando variante com número errado de argumentos |
| Ambiguidade shorthand |
Mais de um enum contém a variante — use forma qualificada |
Roadmap
- Variantes nomeadas com campos —
Resultado.Sucesso{ valor: 10 }
- Guard clauses em padrões —
case .Ok(v) if v > 0: (implementado)
- Derivações automáticas (Display, Debug) via macro futura
Funções & Closures
Funções são cidadãs de primeira classe em Artcode. Closures capturam o ambiente léxico
automaticamente.
func make_counter() {
var count = 0
return fn() {
count = count + 1
return count
}
}
let next = make_counter()
println(next()) // 1
println(next()) // 2
Métodos
Métodos são definidos em structs e enums com auto-binding de self:
struct Vec2 { x: Float, y: Float }
func Vec2.length(self) -> Float {
return (self.x * self.x + self.y * self.y)
}
Regras de Métodos
- Primeiro parâmetro exatamente
self é removido da lista pública
e ligado implicitamente
- Métodos são registrados por tipo em
TypeRegistry no momento da definição
- Chamada:
inst.metodo(args) → FieldAccess produz BoundFunction com
self predefinido
- Introspecção em enums:
variant (String) e values (Array) são
injetados no corpo
Limitações Atuais
- Sem bloco
impl {} agrupador (planejado)
- Sem sobrecarga: resolução por nome simples
- Checagens de campo de struct acontecem em runtime
Roadmap
| Item |
Status |
Auto-binding self |
✅ Implementado |
Bloco impl Tipo { } |
📅 Planejado |
| Inline caching de chamadas quentes |
📅 Planejado |
| Tail-call optimization (modo AOT) |
📅 Futuro |
f-Strings & Format Specs
Artcode suporta interpolação de strings com expressões arbitrárias e format specs integrados.
let nome = "artcode"
let ver = 0.1
println(f"{nome:upper} v{ver}") // "ARTCODE v0.1"
println(f"{255:hex}") // "ff"
println(f"{"hi":pad10}") // "hi "
Specs Disponíveis
| Spec |
Efeito |
Exemplo |
upper |
Converte para maiúsculas |
{s:upper} |
lower |
Converte para minúsculas |
{s:lower} |
trim |
Remove espaços em volta |
{s:trim} |
hex |
Inteiro em hexadecimal |
{255:hex} → ff |
padN |
Padding à direita até N chars |
{s:pad10} |
debug |
Representação de debug |
{val:debug} |
Escapes
| Sequência |
Resultado |
{{ |
{ literal |
}} |
} literal |
Pipeline de Implementação
- Lexer emite
InterpolatedString com conteúdo bruto sem aspas
- Parser divide em partes (
Literal, Expr, Expr+Spec)
via scanner manual de profundidade de {}
- Cada sub-expressão é re-lexada e re-parseada reutilizando o pipeline completo
- Interpreter avalia cada sub-expressão, converte via
Display e aplica spec
Limitações Atuais
- Erros dentro de sub-expressões ainda não produzem spans precisos
- Specs desconhecidas são ignoradas silenciosamente
- Specs avançadas (alinhamento, precisão numérica) não suportadas ainda
Sistema de Módulos
Artcode suporta módulos e packages para organizar código em projetos maiores.
Packages são definidos com um Art.toml na raiz do diretório, com
main.art como ponto de entrada e lib.art opcional.
Estrutura de um Pacote
meu_projeto/
├── Art.toml
├── main.art
└── lib.art
Manifesto Art.toml
name = "my-lib"
version = "0.1.0"
dependencies = { other = { path = "../other" } }
Resolução de Imports
A ordem de resolução do MVP é:
- Imports relativos —
import ./util ou
import utils.foo resolve para utils/foo.art ou
utils/foo/mod.art
- Cache global — imports não-relativos buscam em
~/.artcode/cache/
- Tentativas de arquivo — tenta
X, X.art,
X/mod.art nessa ordem
CLI art add
art add ./minha-lib # copia direto se tem Art.toml
art add github.com/user/repo # futura resolução via rede
O art add <path-or-git> copia o diretório para
~/.artcode/cache/<name>-<version>
se o Art.toml existir. Caso contrário usa o nome do diretório.
Segurança & Limitações (MVP)
- MVP resolve apenas arquivos locais — resolução de rede/git é opcional futura
- Sem versioning semântico ainda; a versão do
Art.toml é informativa
- Sem namespace isolation entre módulos (planejado com blocos
impl futuros)
Modelo de Memória
Artcode não usa Garbage Collector. A memória é gerenciada através de uma escada de 3
degraus:
Degrau 1: ARC (padrão)
Contagem automática de referências. Objetos são liberados deterministicamente quando a última
referência some. Zero pausas, zero surpresas.
Degrau 2: weak / unowned
Para quebrar ciclos de referência em grafos complexos (delegações, estruturas pai-filho):
let weakRef = weak alvo // Não mantém vivo
let val = weakRef? // Upgrade: Some ou None
let fastRef = unowned alvo // Assume sempre válido
let val = fastRef! // Acesso direto (mais rápido)
Detector de ciclos: art test --detect-cycles identifica vazamentos sem impactar
produção.
Degrau 3: Arenas (performant)
Dentro de blocos performant {}, alocações de curta duração são liberadas
atomicamente:
performant {
arena (1 * 1024 * 1024) as frame {
var p = frame.alloc(Entity { id: 1 })
// Processamento intensivo...
} // Tudo liberado de uma vez
}
Métricas de Runtime
O runtime expõe contadores via art metrics --json:
| Métrica |
Descrição |
weak_created / weak_dangling |
Weak refs criadas e que perderam o dono |
unowned_created / unowned_dangling |
Unowned refs e dangling detectadas |
objects_finalized |
Objetos que tiveram finalizers executados |
arena_alloc_count |
Alocações por arena (chave: arena_id) |
finalizer_promotions_per_arena |
Finalizers que promoveram handles ao heap global |
cycle_reports_run |
Execuções do detector de ciclos em modo debug |
crash_free% |
Proporção de statements sem crash |
Política de Finalização
- Execução dos finalizers: quando
strong chega a 0, o objeto é
marcado alive=false e os finalizers são executados em frame filho temporário
- Sweep: após os finalizers, o runtime remove objetos
alive==false && weak==0. Objetos com weak>0 permanecem
até as weak refs serem liberadas
Detecte ciclos em modo debug: art test --detect-cycles usa o algoritmo Tarjan SCC
sobre o grafo de objetos vivos e classifica candidatos a leak.
Boas Práticas
- Use
weak para referências pai→filho em estruturas de delegação
- Monitore
finalizer_promotions_per_arena — valores altos indicam que temporários
estão escapando para o heap global
- Prefira
unowned somente quando tiver certeza que o dono sobreviverá ao uso
Concorrência & Atores
Artcode usa um modelo híbrido de concorrência: Atores para segurança por
construção, e primitivas de baixo nível quando precisar.
Alto Nível: Modelo de Atores
Cada ator encapsula seu estado e se comunica por mensagens assíncronas — eliminando data races
por design.
let worker = spawn(process_fn)
actor_send(worker, make_envelope("task", data))
// Estado isolado. Sem mutexes. Sem data races.
Baixo Nível: Atomic & Mutex
Protótipo de primitivas de baixo nível disponíveis globalmente. A semântica multithreaded formal
ainda está sendo definida — atualmente são single-threaded com semântica cooperativa.
let a = atomic_new(0);
let old = atomic_add(a, 1);
println(atomic_load(a)); // 1
let m = mutex_new([1, 2, 3]);
mutex_lock(m);
// acesso seguro enquanto "possuímos" o lock
mutex_unlock(m);
Backpressure em Mailboxes
let a = spawn actor { /* ... */ };
actor_set_mailbox_limit(a, 1);
let ok1 = actor_send(a, 1); // true
let ok2 = actor_send(a, 2); // false — mailbox cheia, diagnostic emitido
Análise de Send-Safety
Em chamadas actor_send, make_envelope e spawn actor {},
o compilador faz uma análise conservadora: expressões simples (números, strings, variáveis
primitivas locais, handles Atomic/Mutex) são seguras.
Arrays/structs com handles heap ou closures geram diagnostic informativo.
Blocos Performant
Blocos performant {} são zonas de código onde você opta explicitamente por controle
manual de memória e concorrência de baixo nível em troca de performance máxima.
O que muda dentro de performant
- Acesso a Arenas de memória para alocações de curta duração
- Primitivas de concorrência de baixo nível (
Atomic, Mutex)
- Análise estática mais rigorosa (escape analysis, lifetime checks)
- Tipagem explícita obrigatória (modo strict implícito)
Fora de blocos performant, o código permanece seguro por construção usando ARC e Atores.
Diagnósticos Comuns
| Mensagem |
Causa |
Correção |
Variable initialized with composite value inside performant |
Inicializador cria array/struct/call — objetos compostos não podem escapar |
Mova a construção para fora do bloco, ou prefixe o binding com _ |
return not allowed inside performant |
Retorno exporia referência de arena para o escopo externo |
Reestruture para retornar antes do performant |
Assignment to outer-scope variable inside performant |
Atribuição a variável do escopo externo pode promover objeto de arena |
Use binding local (_tmp) e realize a atribuição fora do bloco |
Exemplo Válido
performant {
let _tmp = 42; // primitivo: ok
let _arr = [1, 2]; // composto mas prefixado com _ e não escapa
on_finalize(_arr, fn_cleanup);
} // arena é finalizada aqui atomicamente
Lexer & Parser
O pipeline de parsing do Artcode é projetado para nunca panicar em entradas
malformadas. Erros são acumulados como diagnostics estruturados com spans precisos.
Pipeline
- Lexer — Tokeniza o source code; inclui
InterpolatedString para
f-strings
- Parser — Recursivo descendente, constrói a AST via
parse_precedence. F-strings delegam sub-expressões a um novo pipeline
lexer/parser interno
- Diagnostics — Erros de qualquer fase centralizados com spans; nenhum panic
chega ao usuário
Tokens Principais
| Família |
Exemplos |
Observação |
| Identificadores / Keywords |
let, func, match |
Mapa de keywords decide entre keyword e Identifier |
| Literais numéricos |
42, 3.14 |
Ponto decimal distingue Int de Float |
| Strings |
"texto" |
Escapes padrão |
| f-strings |
f"olá {nome:upper}" |
Prefixo f → token InterpolatedString bruto para re-parse
|
| Operadores |
+ - * / == != <= >= |
Precedência gerida pelo enum Precedence |
f-strings: Pipeline Interno
- Lexer detecta prefixo
f" → emite InterpolatedString com conteúdo
bruto
- Parser chama
parse_interpolated_string: percorre chars com contador de
profundidade de {}
- Cada segmento
{ expr:spec } é re-lexado e re-parseado como expressão Artcode
completa
Pattern Matching no Parser
Statements Match { expr, cases } armazenam pares (MatchPattern, Stmt).
Padrões suportados: Literal, Wildcard _, Binding let v,
EnumVariant com parâmetros recursivos, e Guards if expr.
Limitações Atuais
- Recuperação de erro básica — sem sincronização avançada após erro
- Sem suporte a comentários de bloco (
/* */)
- Tipos nas anotações são strings sem verificação semântica em parse-time
Roadmap
| Item |
Prioridade |
| Erros com localização precisa (spans em f-strings) |
Alta |
| Árvore de tipos dedicada no parser |
Média |
| Suporte a macros |
Baixa (v0.3+) |
Interpreter (Runtime)
O interpreter percorre a AST e executa o programa, gerindo escopos aninhados, closures com
captura léxica, pattern matching e métodos bound.
Características
- Execução determinística de statements
- Closures com captura de ambiente via weak refs (evita ciclos
Env→Fn→Env)
- Pattern matching com destructuring e guards
- Registry de tipos para métodos em structs e enums (auto-binding de
self)
- Métricas de runtime:
executed_statements, handled_errors,
crash_free%
Tipos de Valor (ArtValue)
| Tipo |
Descrição |
Int, Float, Bool, String |
Primitivos |
Optional(None | Some) |
Valor opcional do prelude |
Array |
Array dinâmico heterogêneo |
StructInstance |
Instância de struct com campos nomeados |
EnumInstance |
Variante de enum com payloads |
Function |
Closure com captura lexical |
BoundFunction |
Função já ligada a self (métodos) |
Erros de Execução
| Tipo |
Condição |
UndefinedVariable |
Nome não encontrado no chain de ambientes |
TypeMismatch |
Operação inválida para os tipos |
DivisionByZero |
Divisão por zero |
WrongNumberOfArguments |
Aridade incorreta em chamada |
InvalidEnumVariant |
Variante não existe no enum |
MissingField |
Campo ausente na inicialização de struct |
Todos os erros convertem-se em Diagnostic — o interpreter não panica em entradas
malformadas (meta: crash-free 99%+).
Otimizações Futuras
- Caching de lookup de variáveis
- Representação interna especializada para arrays numéricos
- JIT tiered: baseline + otimizado com PGO
- Inline caching para chamadas de método frequentes
IR & JIT/AOT
A Intermediate Representation (IR) do Artcode é o passo intermediário entre a AST e o código
de máquina. A IR textual serve para golden tests e inspeção humana.
Estado Atual dos Crates
- crates/ir — Emissão de IR textual estável para golden files e inspeção
- crates/jit — Scaffold experimental com
inkwell (bindings LLVM)
e geração de código básica
Formato da IR Textual
func @add(i64 %a, i64 %b) -> i64 {
entry:
%0 = add i64 %a %b
ret %0
}
func @fact(i64 %n) -> i64 {
entry:
br_cond %n, then, else_
then:
%1 = sub i64 %n 1
%2 = call @fact %1
%3 = mul i64 %n %2
ret %3
else_:
ret 1
}
Instruções Suportadas
| Instrução |
Semântica |
const <type> <val> |
Materializa constante |
add/sub/mul/div i64 %a %b |
Aritmética inteira |
fadd/fsub/fmul/fdiv f64 %a %b |
Aritmética float |
load/store <type> %ptr |
Acesso à memória |
call @fn %arg1 %arg2 |
Chamada de função |
br <label> |
Branch incondicional |
br_cond %pred <true> <false> |
Branch condicional (truthy i64) |
phi <type> [%v1, bb1], [%v2, bb2] |
Seleção SSA em merge |
arena_alloc <id> <bytes> |
Alocação em arena (intrinsic) |
Usando --emit-ir
art run --emit-ir - # imprime IR em stdout
art run --emit-ir out.ir # escreve IR em arquivo
Golden Files
cargo run -p xtask -- irgen --write # atualiza goldens em crates/ir/golden/
cargo run -p xtask -- irgen --check # CI: falha se houver diffs
Compilador "Jano" (Roadmap v0.2+)
Duas faces: JIT para desenvolvimento (compilação instantânea) e
AOT para produção com Profile-Guided Optimization (PGO):
art run --gen-profile prog.art # coleta perfil de execução
art build --release --use-profile # gera binário PGO-otimizado
FFI (Interoperabilidade)
Artcode foi projetada para interoperar com C, Rust e WebAssembly.
FFI com C
Interface direta com marcação explícita de transferência de ownership para dados gerenciados por
ARC.
FFI com Rust (Zero-Cost)
Ambas usam LLVM como backend e compartilham filosofias de segurança. Tipos podem ser
compartilhados sem serialização na fronteira.
WebAssembly
Compilação direta para WASM com controle granular sobre o tamanho do binário (planejado para
v0.2+).
Princípios
- Zero abstrações mágicas — toda fronteira deve declarar conversões explicitamente
- Ownership explícito: quem aloca, quem libera, se a posse é transferida
- Erros retornados via enum
Result ou códigos explícitos — sem unwind/panic
cruzando fronteiras
Tipos Suportados (Roadmap)
| Categoria |
Estado |
Representação |
| Int / Float |
Inicial |
i64 / f64 |
| Bool |
Inicial |
u8 / bool |
| String |
Planejado |
Fat pointer (ptr, len) |
| Array |
Planejado |
Header com len + ptr |
| Struct Plain |
Planejado |
Layout repr(C) restrito |
| Enum (tagged) |
Planejado |
Tag + union simplificado |
Padrões de Ownership na Fronteira
| Padrão |
Descrição |
| Borrow |
Chamador mantém posse; callee não retém (ex: len sobre slice) |
| Transfer |
Callee assume e chamador não usa mais (ex: criação de array) |
| Clone RC |
Incrementa contador para uso compartilhado (ex: cache de string) |
Contribuindo
- Leia
docs/ e as RFCs em docs/rfcs/ antes de mudanças maiores
- Use o checklist em
.kit/checklist.md para priorizar trabalho
- Abra RFCs para mudanças de design; referencie nas PRs
- Panics e
unwrap() são proibidos — use o sistema de Diagnostics
Scripts de Dev
cargo xtask ci — Pipeline local (fmt, clippy, testes, scan de panics)
scripts/devcheck.sh — Atalho rápido de verificação
scripts/gen_coverage_badge.sh — Gera badge SVG de cobertura
Roadmap
As metas de longo prazo estão documentadas no checklist oficial (.kit/checklist.md).
v0.1.0 (atual)
- ✅ Lexer, Parser, Interpreter e Type Checker completos
- ✅ Enums, Pattern Matching, Closures, f-Strings, Result
- ✅ ARC, weak/unowned, Arenas, Finalizers
- ✅ Modelo de Atores, CLI unificada, LSP básico
v0.2+ (planejado)
- JIT/AOT com PGO via LLVM (compilador "Jano")
- LSP avançado (autocompletar, refactoring)
- WASM target
- Generics completos (monomorfização inicial)
- Traits e blocos
impl
- Time-Travel Debugging (record/replay)
- FFI Rust/C/WASM com fronteiras de ownership explícitas
- IR SSA + otimizações intermediárias
Métricas de Sucesso
| Métrica |
Alvo |
| Tempo de bootstrap |
< 50ms (interpretador simples) |
| Cobertura de testes |
> 70% do núcleo (interpreter + parser) |
| Sessões crash-free |
99% (eliminar panics não tratados) |
Riscos & Mitigações
| Risco |
Mitigação |
| Complexidade de generics |
Implementar versão mínima iterativa; RFC antes de merge |
| Crescimento de código sem docs |
Enforcer CI para docs em PRs principais |
| Performance degradada |
Benchmarks semanais básicos — microkernel como canário |
Coverage & Métricas
O projeto usa cargo-llvm-cov para métricas de cobertura de linha e branch,
com alvo de >70% no núcleo (interpreter + parser).
Instalação
cargo install cargo-llvm-cov # requer LLVM toolchain
Comandos Principais
cargo llvm-cov --workspace --html --open # relatório HTML interativo
cargo llvm-cov --workspace # resumo no terminal
cargo llvm-cov clean # limpa dados de instrumentação
bash scripts/gen_coverage_badge.sh # gera badge SVG atualizado
Pipeline de CI Automático (cargo xtask ci)
cargo fmt --check — formatação
cargo clippy -D warnings — lints sem tolerar warnings
cargo test --all — todos os testes
- Scan de
panic! / unwrap() fora de testes
- Cobertura com
cargo-llvm-cov + geração do badge SVG
Métricas de Qualidade
| Métrica |
Fonte |
Alvo |
| Cobertura de linha |
cargo-llvm-cov |
> 70% núcleo |
| Sessões crash-free |
Runtime crash_free% |
99% |
| Panics em produção |
Scan CI |
0 fora de testes |
| Tempo de bootstrap |
Benchmarks canários |
< 50ms |
Próximos Passos
- Threshold mínimo de cobertura em CI — falha o build se cair abaixo de 70%
- Integrar relatório HTML como artefato do CI (GitHub Actions upload)
- Benchmarks canários semanais via
21_microkernel.art