DEV Community

CrabPascal
CrabPascal

Posted on

RTL Shims: System.SysUtils and Classes | RTL: shims System.SysUtils e Classes

Bilingual post · Post bilíngue

Jump to: English · Português


English {#english}

RTL Shims: System.SysUtils and Classes

Delphi code assumes a rich runtime library: System.SysUtils for strings and conversions, System.Classes for streams and string lists. CrabPascal implements most behavior in Rust intrinsics, but Delphi projects still need .pas files to satisfy uses clauses and IDE tooling. Welcome to the shim layer under rtl/sys/.

Two-layer model

  1. Pascal surface — unit files with Delphi-compatible declarations
  2. Rust runtime — actual implementations wired through complete_runtime

The .pas bodies are often stubs; calls dispatch to native code:

unit System.SysUtils;

interface

function IntToStr(Value: Integer): String;
function Trim(const S: String): String;
function StrToIntDef(const S: String; Default: Integer): Integer;

implementation

function IntToStr(Value: Integer): String; begin Result := ''; end;
// Runtime intercepts and executes native IntToStr
Enter fullscreen mode Exit fullscreen mode

This pattern unlocked Sprint 2 acceptance: uses System.SysUtils resolves and runs.

Namespace mapping

The unit resolver maps dotted names to filesystem paths:

System.SysUtils  →  rtl/sys/System.SysUtils.pas
System.Classes   →  rtl/sys/System.Classes.pas
System.JSON      →  rtl/sys/System.JSON.pas
Enter fullscreen mode Exit fullscreen mode

Legacy flat units remain for older examples:

SysUtils  →  rtl/SysUtils.pas
Enter fullscreen mode Exit fullscreen mode
uses
  System.SysUtils,
  System.Classes;

var
  SL: TStringList;
begin
  SL := TStringList.Create;
  SL.Add(Trim('  hello  '));
  WriteLn(SL.Text);
  SL.Free;
end.
Enter fullscreen mode Exit fullscreen mode

System.Classes surface

Sprint 3 expanded shims for OOP-heavy code:

type
  TStream = class(TObject)
    function Size: Int64; virtual;
    procedure Write(const Buffer: String); overload; virtual;
  end;

  TMemoryStream = class(TStream)
    constructor Create;
  end;

  TStringList = class(TStrings)
    procedure Add(const S: String);
    property Text: String;
  end;
Enter fullscreen mode Exit fullscreen mode

TMemoryStream and TStringList have Rust backends — enough for JSON helpers, config files, and Horse middleware.

Generics collections

System.Generics.Collections shims declare TList<T> and TDictionary<K,V> templates. Monomorphization happens in the runtime; the Pascal file exists so generics syntax parses like Delphi:

uses System.Generics.Collections;

var
  Items: TList<string>;
begin
  Items := TList<string>.Create;
  Items.Add('CrabPascal');
end.
Enter fullscreen mode Exit fullscreen mode

What shims are not

They are not a full Delphi RTL drop-in. Missing or partial APIs should fail in check with clear messages, not crash silently. The 360° review tracks gaps: System.IOUtils, exception hierarchies, UTF-16 string semantics.

Contributing RTL coverage

Adding a function:

  1. Declare in the appropriate rtl/sys/*.pas shim
  2. Implement intrinsic in Rust runtime
  3. Add a small .pas test under tests/fixtures/

Keep signatures Delphi-compatible — overload sets matter.

Horse and JSON shims

HTTP examples depend on more than SysUtils. The repo includes:

rtl/Horse.pas              ← HTTP framework surface
rtl/sys/System.JSON.pas    ← TJSONObject, TJSONArray
rtl/sys/System.IOUtils.pas ← path helpers (partial)
Enter fullscreen mode Exit fullscreen mode

Together with ProdutoService in examples/crud/, they prove the shim strategy scales beyond string utilities.

Resolver interaction

When the compiler sees uses System.Generics.Collections, unit_resolver.rs maps the dotted name to a file under rtl/sys/. Search paths from .dproj are tried first; RTL defaults apply when the unit is not in your tree. Legacy code using flat uses SysUtils, Classes still resolves via rtl/SysUtils.pas without breaking older tutorials.

Summary

Shims bridge Delphi expectations and Rust implementation. They let real projects compile with familiar uses lines while the compiler team grows native coverage sprint by sprint. Explore the tree at bitbucket.org/alphatecnologia/crabpascal under rtl/sys/.


Português {#portugus}

RTL: shims System.SysUtils e Classes

Código Delphi assume RTL rica: System.SysUtils para strings e conversões, System.Classes para streams e listas. O CrabPascal implementa a maior parte em intrinsics Rust, mas projetos Delphi ainda precisam de arquivos .pas para satisfazer uses e tooling de IDE. Entram os shims em rtl/sys/.

Modelo de duas camadas

  1. Superfície Pascal — units com declarações compatíveis com Delphi
  2. Runtime Rust — implementações reais ligadas ao complete_runtime

Corpos .pas são often stubs; chamadas dispatcham para código nativo:

unit System.SysUtils;

interface

function IntToStr(Value: Integer): String;
function Trim(const S: String): String;
function StrToIntDef(const S: String; Default: Integer): Integer;

implementation

function IntToStr(Value: Integer): String; begin Result := ''; end;
// Runtime intercepta e executa IntToStr nativo
Enter fullscreen mode Exit fullscreen mode

Esse padrão destravou aceitação do Sprint 2: uses System.SysUtils resolve e roda.

Mapeamento de namespace

O unit resolver mapeia nomes pontuados para paths:

System.SysUtils  →  rtl/sys/System.SysUtils.pas
System.Classes   →  rtl/sys/System.Classes.pas
System.JSON      →  rtl/sys/System.JSON.pas
Enter fullscreen mode Exit fullscreen mode

Units legadas flat permanecem para exemplos antigos:

SysUtils  →  rtl/SysUtils.pas
Enter fullscreen mode Exit fullscreen mode
uses
  System.SysUtils,
  System.Classes;

var
  SL: TStringList;
begin
  SL := TStringList.Create;
  SL.Add(Trim('  hello  '));
  WriteLn(SL.Text);
  SL.Free;
end.
Enter fullscreen mode Exit fullscreen mode

Superfície System.Classes

Sprint 3 expandiu shims para código OOP:

type
  TStream = class(TObject)
    function Size: Int64; virtual;
    procedure Write(const Buffer: String); overload; virtual;
  end;

  TMemoryStream = class(TStream)
    constructor Create;
  end;

  TStringList = class(TStrings)
    procedure Add(const S: String);
    property Text: String;
  end;
Enter fullscreen mode Exit fullscreen mode

TMemoryStream e TStringList têm backends Rust — suficiente para helpers JSON, configs e middleware Horse.

Collections genéricas

Shims System.Generics.Collections declaram templates TList<T> e TDictionary<K,V>. Monomorphização no runtime; arquivo Pascal existe para syntax de generics parsear como Delphi:

uses System.Generics.Collections;

var
  Items: TList<string>;
begin
  Items := TList<string>.Create;
  Items.Add('CrabPascal');
end.
Enter fullscreen mode Exit fullscreen mode

O que shims não são

Não são RTL Delphi completa. APIs faltantes ou parciais devem falhar no check com mensagem clara, não crash silencioso. O review 360° rastreia gaps: System.IOUtils, hierarquia de exceptions, semântica UTF-16.

Contribuindo cobertura RTL

Para adicionar função:

  1. Declarar no shim rtl/sys/*.pas adequado
  2. Implementar intrinsic no runtime Rust
  3. Adicionar teste .pas em tests/fixtures/

Mantenha assinaturas compatíveis com Delphi — overloads importam.

Shims Horse e JSON

Exemplos HTTP dependem de mais que SysUtils. O repositório inclui:

rtl/Horse.pas              ← superfície do framework HTTP
rtl/sys/System.JSON.pas    ← TJSONObject, TJSONArray
rtl/sys/System.IOUtils.pas ← helpers de path (parcial)
Enter fullscreen mode Exit fullscreen mode

Junto com ProdutoService em examples/crud/, provam que a estratégia de shim escala além de utilitários de string.

Interação com o resolver

Quando o compilador vê uses System.Generics.Collections, unit_resolver.rs mapeia o nome pontuado para arquivo em rtl/sys/. Search paths do .dproj vêm primeiro; defaults RTL aplicam quando a unit não está na sua árvore. Código legado com uses SysUtils, Classes flat ainda resolve via rtl/SysUtils.pas sem quebrar tutoriais antigos.

Resumo

Shims ligam expectativa Delphi e implementação Rust. Permitem projetos reais compilarem com uses familiares enquanto o time cresce cobertura nativa sprint a sprint. Explore em bitbucket.org/alphatecnologia/crabpascal em rtl/sys/.


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

Top comments (0)