DEV Community

CrabPascal
CrabPascal

Posted on

Delphi-Style String Functions in CrabPascal (v2.13.0) | Funções de string estilo Delphi no CrabPascal (v2.13.0)

Bilingual post · Post bilíngue

Jump to: English · Português


English {#english}

Delphi-Style String Functions in CrabPascal (v2.13.0)

Every Delphi developer muscle-memorizes Length, Copy, Pos, and Trim. Sprint 5 (v2.13.0) centralized those builtins in a Rust module — pascal_strings — so the interpreter and future C stubs share one implementation.

One-based indexing (non-negotiable)

Delphi strings are 1-based. CrabPascal matches that:

program StringDemo;
uses
  System.SysUtils;

var
  S: string;
begin
  S := 'CrabPascal';
  WriteLn('Length = ', Length(S));       // 10
  WriteLn('Copy   = ', Copy(S, 1, 4));   // Crab
  WriteLn('Pos    = ', Pos('Pascal', S)); // 5
  WriteLn('Trim   = [', Trim('  hi  '), ']');
end.
Enter fullscreen mode Exit fullscreen mode

If you come from C or Python, remember: Copy(S, 1, n) takes from the first character, not zero.

Case conversion

WriteLn(UpperCase('rust'));
WriteLn(LowerCase('PASCAL'));
Enter fullscreen mode Exit fullscreen mode

These delegate to the same module, keeping behavior consistent between run and generated C (via stubs.c helpers like pascal_Trim and pascal_Length).

Why centralize in Rust?

Before v2.13.0, string helpers risked drift — runtime doing one thing, codegen another. Consolidating in src/pascal_strings.rs means:

  • One test suite (cargo test pascal_strings)
  • One conformance gate (tests/string_conformance.rs)
  • Easier Unicode upgrade in Sprint 8
cargo test --test string_conformance
cargo test pascal_strings
Enter fullscreen mode Exit fullscreen mode

Practical parsing example

Extract a file extension Delphi-style:

function GetExt(const FileName: string): string;
var
  P: Integer;
begin
  P := Pos('.', FileName);
  if P = 0 then
    Exit('');
  Result := Copy(FileName, P + 1, MaxInt);
end;
Enter fullscreen mode Exit fullscreen mode

This pattern appears constantly in CRUD and upload handlers — no regex library required.

UTF-8 vs Unicode note

At v2.13.0, Length counted UTF-8 codepoints pragmatically. Sprint 8 moved semantic length to UTF-16 code units to align with modern UnicodeString. If you target v2.13.0 specifically, document that difference; on current CrabPascal (v2.22.0), Unicode rules apply.

Codegen parity status

Sprint 5 wired stubs in stubs.c but full build-exe parity for every string call landed in Sprints 9–10. For rapid development, use run; for shipping binaries, verify with:

crab-pascal build-exe StringDemo.dpr
./StringDemo
Enter fullscreen mode Exit fullscreen mode

Takeaway

Strings look boring until they diverge silently between modes. v2.13.0 is where CrabPascal committed to one string brain — Delphi API on the surface, Rust implementation underneath, C mirrors for native output.


Português {#portugus}

Funções de string estilo Delphi no CrabPascal (v2.13.0)

Todo desenvolvedor Delphi memoriza Length, Copy, Pos e Trim. A Sprint 5 (v2.13.0) centralizou esses builtins em um módulo Rust — pascal_strings — para interpretador e stubs C futuros compartilharem uma implementação.

Indexação base 1 (innegociável)

Strings Delphi são base 1. O CrabPascal segue isso:

program StringDemo;
uses
  System.SysUtils;

var
  S: string;
begin
  S := 'CrabPascal';
  WriteLn('Length = ', Length(S));       // 10
  WriteLn('Copy   = ', Copy(S, 1, 4));   // Crab
  WriteLn('Pos    = ', Pos('Pascal', S)); // 5
  WriteLn('Trim   = [', Trim('  hi  '), ']');
end.
Enter fullscreen mode Exit fullscreen mode

Se você vem de C ou Python, lembre: Copy(S, 1, n) começa no primeiro caractere, não no zero.

Conversão de case

WriteLn(UpperCase('rust'));
WriteLn(LowerCase('PASCAL'));
Enter fullscreen mode Exit fullscreen mode

Delegam ao mesmo módulo, mantendo comportamento consistente entre run e C gerado (via helpers pascal_Trim e pascal_Length em stubs.c).

Por que centralizar em Rust?

Antes da v2.13.0, helpers de string corriam risco de drift — runtime fazendo uma coisa, codegen outra. Consolidar em src/pascal_strings.rs significa:

  • Uma suite de testes (cargo test pascal_strings)
  • Um gate de conformidade (tests/string_conformance.rs)
  • Upgrade Unicode mais fácil na Sprint 8
cargo test --test string_conformance
cargo test pascal_strings
Enter fullscreen mode Exit fullscreen mode

Exemplo prático de parsing

Extrair extensão de arquivo estilo Delphi:

function GetExt(const FileName: string): string;
var
  P: Integer;
begin
  P := Pos('.', FileName);
  if P = 0 then
    Exit('');
  Result := Copy(FileName, P + 1, MaxInt);
end;
Enter fullscreen mode Exit fullscreen mode

Esse padrão aparece o tempo todo em CRUD e handlers de upload — sem biblioteca regex.

Nota UTF-8 vs Unicode

Na v2.13.0, Length contava codepoints UTF-8 pragmaticamente. A Sprint 8 moveu o comprimento semântico para code units UTF-16, alinhado ao UnicodeString moderno. Se você mira a v2.13.0 especificamente, documente essa diferença; no CrabPascal atual (v2.22.0), valem as regras Unicode.

Status de paridade codegen

A Sprint 5 ligou stubs em stubs.c, mas paridade completa build-exe para cada chamada de string chegou nas Sprints 9–10. Para desenvolvimento rápido, use run; para entregar binários, valide com:

crab-pascal build-exe StringDemo.dpr
./StringDemo
Enter fullscreen mode Exit fullscreen mode

Conclusão

Strings parecem triviais até divergirem silenciosamente entre modos. A v2.13.0 é quando o CrabPascal se comprometeu com um cérebro de strings — API Delphi na superfície, implementação Rust embaixo, espelhos C para saída nativa.


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

Top comments (0)