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

  1. Ler fonte (arquivo ou REPL)
  2. Lexer gera tokens — inclui InterpolatedString para f-strings
  3. Parser converte tokens em AST (Program = Vec<Stmt>)
  4. Interpreter percorre statements, avaliando expressões, gerindo ambientes aninhados
  5. Funções criam closures capturando ambiente pai via weak refs (evita ciclos)
  6. Pattern matching resolve variantes de enum e injeta bindings no escopo do case

Arquitetura em Camadas

architecture
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

terminal
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)

terminal
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.

PlataformaBinário
Linux x86_64art-linux-x86_64
macOS Intelart-macos-x86_64
macOS Apple Siliconart-macos-arm64
WindowsBaixe o .exe na página de releases

Verificar instalação

terminal
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

terminal
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

terminal
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

terminal
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.

prelude.art
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.

enums.art
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:

guards.art
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.

closures.art
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:

methods.art
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.

fstrings.art
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

  1. Lexer emite InterpolatedString com conteúdo bruto sem aspas
  2. Parser divide em partes (Literal, Expr, Expr+Spec) via scanner manual de profundidade de {}
  3. Cada sub-expressão é re-lexada e re-parseada reutilizando o pipeline completo
  4. 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

estrutura
meu_projeto/
├── Art.toml
├── main.art
└── lib.art

Manifesto Art.toml

Art.toml
name = "my-lib"
version = "0.1.0"
dependencies = { other = { path = "../other" } }

Resolução de Imports

A ordem de resolução do MVP é:

  1. Imports relativosimport ./util ou import utils.foo resolve para utils/foo.art ou utils/foo/mod.art
  2. Cache global — imports não-relativos buscam em ~/.artcode/cache/
  3. Tentativas de arquivo — tenta X, X.art, X/mod.art nessa ordem

CLI art add

terminal
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):

weak.art
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:

arena.art
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

  1. 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
  2. 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.

actors.art
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.

atomic.art
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

backpressure.art
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_ok.art
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

  1. Lexer — Tokeniza o source code; inclui InterpolatedString para f-strings
  2. Parser — Recursivo descendente, constrói a AST via parse_precedence. F-strings delegam sub-expressões a um novo pipeline lexer/parser interno
  3. 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

  1. Lexer detecta prefixo f" → emite InterpolatedString com conteúdo bruto
  2. Parser chama parse_interpolated_string: percorre chars com contador de profundidade de {}
  3. 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

exemplo.ir
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

terminal
art run --emit-ir -         # imprime IR em stdout
art run --emit-ir out.ir   # escreve IR em arquivo

Golden Files

terminal
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):

terminal
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

terminal
cargo install cargo-llvm-cov   # requer LLVM toolchain

Comandos Principais

terminal
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)

  1. cargo fmt --check — formatação
  2. cargo clippy -D warnings — lints sem tolerar warnings
  3. cargo test --all — todos os testes
  4. Scan de panic! / unwrap() fora de testes
  5. 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