DEV Community

CrabPascal
CrabPascal

Posted on

System.* Namespaces and the CrabPascal RTL | Namespaces System.* e a RTL do CrabPascal

Bilingual post · Post bilíngue

Jump to: English · Português


English {#english}

System.* Namespaces and the CrabPascal RTL

Modern Delphi code rarely says uses SysUtils. It says uses System.SysUtils. CrabPascal Sprint 2 (v2.10.0) added first-class support for that dotted unit naming and the rtl/sys/ layout that mirrors Embarcadero's RTL structure.

This is not cosmetic. Unit resolution order, search paths, and filename conventions all affect whether a real-world project compiles unchanged.

How resolution works

When your program contains:

program Demo;
uses
  System.SysUtils;

begin
  WriteLn(UpperCase('crabpascal'));
end.
Enter fullscreen mode Exit fullscreen mode

CrabPascal's UnitResolver looks for System.SysUtils.pas under rtl/sys/ before falling back to legacy rtl/SysUtils.pas. The ProjectConfig puts rtl/sys ahead of rtl/ in search paths so namespaced shims win.

The shim file re-exports familiar routines:

unit System.SysUtils;
interface
uses SysUtils;
implementation
end.
Enter fullscreen mode Exit fullscreen mode

You get Delphi-style uses without duplicating the entire SysUtils implementation.

Why namespaces matter for compatibility

Porting Delphi snippets often fails on the first line — not because WriteLn is missing, but because the unit name does not match. Supporting System.* removes a whole class of friction when pasting Stack Overflow answers or internal company units into CrabPascal examples.

Sprint 2 deliberately scoped layout + resolution, not a rewrite of every RTL function. Most behavior still delegates to existing units; the win is discoverability and path correctness.

Testing your setup

cargo test unit_resolver::test_resolve_system_sysutils_rtl_sys
crab-pascal run tests/fixtures/system_sysutils_ok.pas
Enter fullscreen mode Exit fullscreen mode

If resolution fails, check that your project's search paths include the CrabPascal rtl/sys directory. The resolver also uses CARGO_MANIFEST_DIR in tests so CI does not depend on your current working directory.

Practical tip: mixing styles

During migration you might see both:

uses
  SysUtils,           // legacy path: rtl/SysUtils.pas
  System.Classes;     // namespaced: rtl/sys/System.Classes.pas
Enter fullscreen mode Exit fullscreen mode

Prefer the System.* form for new code. Legacy paths remain for older examples in the repo.

What's next

Sprint 3 adds System.Classes with TMemoryStream and TStringList — the building blocks for streams, configs, and HTTP body buffers in Horse examples.

CrabPascal's RTL strategy is incremental: namespace fidelity first, then fill in runtime behavior sprint by sprint. v2.10.0 is the foundation layer that makes everything else feel like Delphi instead of a Pascal dialect with different file names.


Português {#portugus}

Namespaces System.* e a RTL do CrabPascal

Código Delphi moderno raramente diz uses SysUtils. Diz uses System.SysUtils. A Sprint 2 do CrabPascal (v2.10.0) adicionou suporte de primeira classe a esse nome de unit pontuado e ao layout rtl/sys/ que espelha a estrutura RTL da Embarcadero.

Não é cosmético. Ordem de resolução de units, search paths e convenções de nome de arquivo afetam se um projeto real compila sem alteração.

Como funciona a resolução

Quando seu programa contém:

program Demo;
uses
  System.SysUtils;

begin
  WriteLn(UpperCase('crabpascal'));
end.
Enter fullscreen mode Exit fullscreen mode

O UnitResolver do CrabPascal procura System.SysUtils.pas em rtl/sys/ antes de cair no legado rtl/SysUtils.pas. O ProjectConfig coloca rtl/sys à frente de rtl/ nos search paths para os shims namespaced vencerem.

O arquivo shim reexporta rotinas familiares:

unit System.SysUtils;
interface
uses SysUtils;
implementation
end.
Enter fullscreen mode Exit fullscreen mode

Você obtém uses estilo Delphi sem duplicar toda a implementação de SysUtils.

Por que namespaces importam para compatibilidade

Portar trechos Delphi frequentemente falha na primeira linha — não porque WriteLn falta, mas porque o nome da unit não bate. Suportar System.* remove uma classe inteira de atrito ao colar respostas do Stack Overflow ou units internas em exemplos CrabPascal.

A Sprint 2 escopou de propósito layout + resolução, não reescrita de toda função RTL. A maior parte do comportamento ainda delega para units existentes; o ganho é descobribilidade e correção de paths.

Testando sua configuração

cargo test unit_resolver::test_resolve_system_sysutils_rtl_sys
crab-pascal run tests/fixtures/system_sysutils_ok.pas
Enter fullscreen mode Exit fullscreen mode

Se a resolução falhar, verifique se os search paths do projeto incluem rtl/sys do CrabPascal. O resolver também usa CARGO_MANIFEST_DIR nos testes para o CI não depender do diretório atual.

Dica prática: misturar estilos

Durante migração você pode ver ambos:

uses
  SysUtils,           // path legado: rtl/SysUtils.pas
  System.Classes;     // namespaced: rtl/sys/System.Classes.pas
Enter fullscreen mode Exit fullscreen mode

Prefira a forma System.* em código novo. Paths legados permanecem para exemplos antigos no repositório.

Próximos passos

A Sprint 3 adiciona System.Classes com TMemoryStream e TStringList — blocos de construção para streams, configs e buffers HTTP em exemplos Horse.

A estratégia RTL do CrabPascal é incremental: fidelidade de namespace primeiro, depois preencher comportamento de runtime sprint a sprint. A v2.10.0 é a camada de fundação que faz tudo parecer Delphi em vez de um dialeto Pascal com nomes de arquivo diferentes.


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

Top comments (0)