DEV Community

CrabPascal
CrabPascal

Posted on

OOP in CrabPascal: Classes and Streams (v2.11.0) | OOP no CrabPascal: classes e streams (v2.11.0)

Bilingual post · Post bilíngue

Jump to: English · Português


English {#english}

OOP in CrabPascal: Classes and Streams (v2.11.0)

Object Pascal without classes is just structured programming with extra steps. Sprint 3 (v2.11.0) brought System.Classes into the runtime with working TMemoryStream and TStringList — enough OOP to buffer data, build text lists, and prepare for HTTP handlers.

A minimal stream example

program StreamDemo;
uses
  System.Classes, System.SysUtils;

var
  M: TMemoryStream;
  Buf: AnsiString;
begin
  M := TMemoryStream.Create;
  try
    Buf := 'CrabPascal';
    M.Write(PAnsiChar(Buf)^, Length(Buf));
    WriteLn('Size = ', M.Size);
  finally
    M.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

Run with crab-pascal run StreamDemo.dpr. You should see the byte count reflect what was written.

TStringList for config and logs

var
  Lines: TStringList;
begin
  Lines := TStringList.Create;
  try
    Lines.Add('first');
    Lines.Add('second');
    WriteLn('Count = ', Lines.Count);
    WriteLn(Lines.Text);
  finally
    Lines.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

Text returns a single string with platform line breaks — handy before JSON parsers arrive in later sprints.

How the runtime implements this

CrabPascal uses a hybrid model:

  • VMT dispatch for methods declared on classes.
  • Intrinsics in simulate_function_execution for methods without Pascal bodies in the RTL shim.
  • Property access via RecordAccess on ObjectInstance for Count, Size, and Text.

You do not need to implement TMemoryStream.Write yourself; the runtime provides it when you uses System.Classes.

Semantic loading

When the compiler loads System.Classes, symbols for TObject, TStream, TMemoryStream, and TStringList enter the semantic table. That means typos like TMemryStream fail at check time instead of at runtime.

Known limits in v2.11.0

Indexed access like Lines.Strings[i] still hit parser gaps in early sprints — use .Text or .Add until property/indexer work matured in Sprint 6. Inheritance beyond basic TObject chains was expanded later; v2.11.0 focused on concrete utility classes developers use every day.

Validate in the repo

cargo test --test classes_streams
crab-pascal run tests/fixtures/memory_stream_test.pas
Enter fullscreen mode Exit fullscreen mode

Why streams before full inheritance

Real Delphi projects use streams constantly — HTTP bodies, file uploads, in-memory JSON serialization. Shipping TMemoryStream early proves the object model works under the Horse examples and CRUD demos in the repository.

Sprint 4 adds exceptions so your try/finally blocks above actually protect resources when something throws. For now, v2.11.0 is the sprint where CrabPascal stops being "Pascal with records" and starts feeling like Delphi OOP.


Português {#portugus}

OOP no CrabPascal: classes e streams (v2.11.0)

Object Pascal sem classes é programação estruturada com passos extras. A Sprint 3 (v2.11.0) trouxe System.Classes ao runtime com TMemoryStream e TStringList funcionais — OOP suficiente para bufferizar dados, montar listas de texto e preparar handlers HTTP.

Exemplo mínimo com stream

program StreamDemo;
uses
  System.Classes, System.SysUtils;

var
  M: TMemoryStream;
  Buf: AnsiString;
begin
  M := TMemoryStream.Create;
  try
    Buf := 'CrabPascal';
    M.Write(PAnsiChar(Buf)^, Length(Buf));
    WriteLn('Size = ', M.Size);
  finally
    M.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

Execute com crab-pascal run StreamDemo.dpr. A contagem de bytes deve refletir o que foi escrito.

TStringList para config e logs

var
  Lines: TStringList;
begin
  Lines := TStringList.Create;
  try
    Lines.Add('first');
    Lines.Add('second');
    WriteLn('Count = ', Lines.Count);
    WriteLn(Lines.Text);
  finally
    Lines.Free;
  end;
end.
Enter fullscreen mode Exit fullscreen mode

Text retorna uma string única com quebras de linha da plataforma — útil antes de parsers JSON em sprints posteriores.

Como o runtime implementa

O CrabPascal usa um modelo híbrido:

  • Dispatch VMT para métodos declarados em classes.
  • Intrinsics em simulate_function_execution para métodos sem corpo Pascal no shim RTL.
  • Acesso a properties via RecordAccess em ObjectInstance para Count, Size e Text.

Você não precisa implementar TMemoryStream.Write; o runtime fornece ao fazer uses System.Classes.

Carregamento semântico

Quando o compilador carrega System.Classes, símbolos de TObject, TStream, TMemoryStream e TStringList entram na tabela semântica. Typos como TMemryStream falham no check, não só em runtime.

Limites conhecidos na v2.11.0

Acesso indexado como Lines.Strings[i] ainda encontrava gaps de parser nas sprints iniciais — use .Text ou .Add até o trabalho de properties/indexadores amadurecer na Sprint 6. Herança além de cadeias básicas de TObject foi expandida depois; a v2.11.0 focou em classes utilitárias concretas que desenvolvedores usam todo dia.

Validar no repositório

cargo test --test classes_streams
crab-pascal run tests/fixtures/memory_stream_test.pas
Enter fullscreen mode Exit fullscreen mode

Por que streams antes de herança completa

Projetos Delphi reais usam streams constantemente — corpos HTTP, uploads, serialização JSON em memória. Entregar TMemoryStream cedo prova que o modelo de objetos funciona nos exemplos Horse e demos CRUD do repositório.

A Sprint 4 adiciona exceções para seus blocos try/finally protegerem recursos quando algo lança. Por ora, a v2.11.0 é a sprint em que o CrabPascal deixa de ser "Pascal com records" e começa a parecer OOP Delphi.


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

Top comments (0)