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.
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'));
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
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;
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
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.
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'));
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
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;
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
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)