DEV Community

CrabPascal
CrabPascal

Posted on

Nova Arquitetura v2.0.1: A Turning Point | Nova arquitetura v2.0.1 explicada

Bilingual post · Post bilíngue

Jump to: English · Português


English {#english}

Nova Arquitetura v2.0.1: A Turning Point

Postman tests in post 036 proved Horse APIs run. Under the hood, that only works because v2.0.1 stopped pretending to be a toy interpreter with infinite hardcoded shims. The architectural pivot is documented in nova-arquitetura-v2-0-1 and the broader design rationale in arquitetura-design.

The v2.0.0 problem: simulated everything

Before v2.0.1, complete_runtime.rs contained a growing match function_name table — THorse.Get, IntToStr, TJSONObject.Create, ad infinitum. Every new Delphi unit meant more Rust simulation, not more Pascal.

// Anti-pattern we retired
match function_name {
    "THorse.Get" => { /* hand-waved HTTP */ },
    "IntToStr" => { /* special case */ },
    // ... unbounded growth
}
Enter fullscreen mode Exit fullscreen mode

That scaled poorly and wasn't a real compiler — it was an interpreter wearing Delphi cosplay.

v2.0.1 solution: real units from real projects

The new pipeline reads Delphi project metadata and loads .pas files from configured search paths:

.dpr program
  ↓
.dproj (optional) → DCC_UnitSearchPath
  ↓
ProjectConfig.find_unit_file("Horse")
  ↓
Parse + execute actual Horse.pas sources
Enter fullscreen mode Exit fullscreen mode

ProjectConfig in src/project_config.rs parses .dproj XML:

<DCC_UnitSearchPath>
  examples\crud\modules;
  examples\crud\modules\horse\src;
</DCC_UnitSearchPath>
Enter fullscreen mode Exit fullscreen mode

Paths resolve relative to the project directory, with recursive search when needed.

Runtime integration

CompletePascalRuntime accepts optional config:

pub struct CompletePascalRuntime {
    project_config: Option<ProjectConfig>,
    // ...
}

impl CompletePascalRuntime {
    pub fn with_config(project_config: Option<ProjectConfig>) -> Self { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

Unit loading changed from hardcoded guesses:

// Before: vec!["examples/agenda/Foo.pas", ...]
// After:
if let Some(path) = config.find_unit_file(unit_name) {
    self.parse_and_load_unit(path, unit_name)?;
}
Enter fullscreen mode Exit fullscreen mode

main.rs loads config at startup when a sibling .dproj exists — transparent for crab-pascal run myapp.dpr.

Five-phase compiler context

arquitetura-design places v2.0.1 inside the classic pipeline:

Lexer → Parser → Semantic → Codegen / Runtime
         ↑
    Unit resolver + ProjectConfig feed real symbols here
Enter fullscreen mode Exit fullscreen mode

Frontend analysis stays in Rust. Library behavior increasingly lives in Pascal RTL shims under rtl/sys/ and third-party .pas trees — the same split Delphi uses.

Why this matters for Horse and CRUD

Your Postman session hits routes compiled from real Horse units on the search path, not a 200-line Rust stub. When Horse adds middleware signatures, you update Pascal sources — the compiler loads them on next run.

Recursive unit loading (blog post 026) builds on this foundation: once paths are honest, dependency graphs follow .pas uses clauses naturally.

Trade-offs we accept

  • Requires search paths — missing .dproj falls back to cwd; document paths in examples.
  • Parse cost — first load parses units; cache wins on repeat runs within process.
  • Not full MSBuild — we read paths, not every Delphi conditional; crabpascal.toml fills gaps.

Migration checklist for your project

  1. Add or verify .dproj with DCC_UnitSearchPath
  2. Mirror paths in crabpascal.toml if you skip .dproj
  3. Run crab-pascal check — unresolved unit errors should name the missing path
  4. Compare run vs build-exe parity (post 040)

v2.0.1 was the line between demo and platform. Everything since — sprints, Mintlify architecture section, honest build — assumes real units.

Related modules in the repo

Trace these files while reading nova-arquitetura-v2-0-1:

File Role
src/project_config.rs .dproj XML → search paths
src/unit_resolver.rs Recursive uses graph
src/main.rs Wires config into run / check
mintlify/architecture/carregamento-recursivo-v2-0-1.md Deep dive on recursive loading

When a unit fails to resolve, enable verbose logging and print the candidate paths ProjectConfig tried — most "Horse not found" reports are misconfigured DCC_UnitSearchPath, not missing compiler features.

Next in series

Post 038 — Runtime Internals dives into heap allocation, virtual method tables, and built-in dispatch — the machinery that makes OOP Pascal actually run after units load.


Português {#portugus}

Nova arquitetura v2.0.1: ponto de virada

Testes Postman no post 036 provaram que APIs Horse rodam. Por baixo, isso só funciona porque a v2.0.1 parou de fingir ser interpretador de brinquedo com shims hardcoded infinitos. A virada arquitetural está em nova-arquitetura-v2-0-1 e a rationale ampla em arquitetura-design.

O problema da v2.0.0: simular tudo

Antes da v2.0.1, complete_runtime.rs tinha uma tabela match function_name crescente — THorse.Get, IntToStr, TJSONObject.Create, sem fim. Cada unit Delphi nova significava mais simulação em Rust, não mais Pascal.

// Anti-padrão que aposentamos
match function_name {
    "THorse.Get" => { /* HTTP improvisado */ },
    "IntToStr" => { /* caso especial */ },
    // ... crescimento ilimitado
}
Enter fullscreen mode Exit fullscreen mode

Isso não escalava e não era compilador de verdade — era interpretador de fantasia Delphi.

Solução v2.0.1: units reais de projetos reais

O pipeline novo lê metadados de projeto Delphi e carrega .pas dos search paths configurados:

programa .dpr
  ↓
.dproj (opcional) → DCC_UnitSearchPath
  ↓
ProjectConfig.find_unit_file("Horse")
  ↓
Parse + executa fontes Horse.pas de verdade
Enter fullscreen mode Exit fullscreen mode

ProjectConfig em src/project_config.rs parseia XML do .dproj:

<DCC_UnitSearchPath>
  examples\crud\modules;
  examples\crud\modules\horse\src;
</DCC_UnitSearchPath>
Enter fullscreen mode Exit fullscreen mode

Paths resolvem relativos ao diretório do projeto, com busca recursiva quando necessário.

Integração no runtime

CompletePascalRuntime aceita config opcional:

pub struct CompletePascalRuntime {
    project_config: Option<ProjectConfig>,
    // ...
}

impl CompletePascalRuntime {
    pub fn with_config(project_config: Option<ProjectConfig>) -> Self { /* ... */ }
}
Enter fullscreen mode Exit fullscreen mode

Carregamento de units saiu de chutes hardcoded:

// Antes: vec!["examples/agenda/Foo.pas", ...]
// Depois:
if let Some(path) = config.find_unit_file(unit_name) {
    self.parse_and_load_unit(path, unit_name)?;
}
Enter fullscreen mode Exit fullscreen mode

main.rs carrega config na subida quando existe .dproj irmão — transparente para crab-pascal run myapp.dpr.

Contexto do compilador em cinco fases

arquitetura-design encaixa v2.0.1 no pipeline clássico:

Lexer → Parser → Semântica → Codegen / Runtime
         ↑
    Unit resolver + ProjectConfig alimentam símbolos reais aqui
Enter fullscreen mode Exit fullscreen mode

Análise frontend fica em Rust. Comportamento de biblioteca migra para shims Pascal em rtl/sys/ e árvores .pas de terceiros — o mesmo split do Delphi.

Por que importa para Horse e CRUD

Sua sessão Postman acerta rotas compiladas de units Horse reais no search path, não stub Rust de 200 linhas. Quando Horse ganha assinaturas de middleware, você atualiza Pascal — o compilador recarrega na próxima execução.

Carregamento recursivo de units (post 026) constrói sobre isso: paths honestos, grafo de dependências segue uses naturalmente.

Trade-offs que aceitamos

  • Exige search paths — sem .dproj cai no cwd; documente paths nos exemplos.
  • Custo de parse — primeira carga parseia units; cache ajuda na mesma execução.
  • Não é MSBuild completo — lemos paths, não todo conditional Delphi; crabpascal.toml preenche lacunas.

Checklist de migração do seu projeto

  1. Adicione ou verifique .dproj com DCC_UnitSearchPath
  2. Espelhe paths em crabpascal.toml se pular .dproj
  3. Rode crab-pascal check — erros de unit devem nomear path faltante
  4. Compare paridade run vs build-exe (post 040)

v2.0.1 foi a linha entre demo e plataforma. Tudo desde então — sprints, seção arquitetura Mintlify, build honesto — assume units reais.

Módulos relacionados no repo

Trace estes arquivos lendo nova-arquitetura-v2-0-1:

Arquivo Papel
src/project_config.rs XML .dproj → search paths
src/unit_resolver.rs Grafo recursivo de uses
src/main.rs Liga config em run / check
mintlify/architecture/carregamento-recursivo-v2-0-1.md Deep dive em carga recursiva

Quando unit falha ao resolver, habilite log verbose e imprima paths candidatos — a maioria dos "Horse not found" são DCC_UnitSearchPath mal configurado, não feature faltando no compilador.

Próximo da série

Post 038 — Internals do runtime mergulha em heap, tabelas de métodos virtuais e dispatch de built-ins — a maquinaria que faz OOP Pascal rodar depois que units carregam.


Published on dev.to/@crabpascal · Código em CrabPascal

Top comments (0)