English {#english}
Codegen to C: Native Binaries from Pascal (v2.18.0)
Sprint 10 (v2.18.0) closes the loop on CrabPascal's most ambitious feature: turning Pascal source into real native executables via C codegen — with string builtins that actually match the interpreter.
The pipeline
Pascal (.dpr/.pas) → AST → C source + stubs.c → gcc/clang → native binary
run skips the last steps and executes in Rust. build-exe is for when you want an .exe or ELF on disk without carrying the CrabPascal runtime as a dependency.
End-to-end example
program NativeHello;
uses
System.SysUtils;
begin
WriteLn(Trim(' Hello, native world! '));
end.
crab-pascal build-exe NativeHello.dpr
./NativeHello # or NativeHello.exe on Windows
Expected output: Hello, native world! — no leading or trailing spaces.
What Sprint 10 fixed
Parser: Trim, Copy, Length, and friends are recognized as SysUtils builtins, not mistaken for type names starting with T. A denylist prevents hard-casts that produced invalid C.
Codegen:
- Forward declarations for
pascal_*helpers in generated C. -
WriteLnemits correct%sformats for string expressions. -
mainreturns0like a well-behaved C program.
Tests: build_string_conformance_stdout_matches_run_when_toolchain_present runs only when gcc/clang is available — skipping cleanly in CI sandboxes without a compiler, failing loudly when a compiler is present but output diverges.
cargo test --test run_build_parity
stubs.c: shared runtime surface
String functions implemented once in Rust for run mirror into stubs.c for native builds:
// conceptual — see repo for full signatures
int pascal_Length(const char* s);
char* pascal_Trim(const char* s);
Generated Pascal calls route through these instead of ad-hoc inline logic, keeping Sprint 5–8 string semantics intact in binaries.
When build-exe is not enough yet
Sprint 10 explicitly did not ship full OO, exception, or generics codegen parity — those appear in later sprints (v2.19+). Reach for build-exe when your program uses:
-
WriteLnand SysUtils strings - Straight-line control flow
- Procedures/functions without complex object graphs
For Horse HTTP servers and heavy OOP, run remained the supported path at v2.18.0.
VS Code extension note
Marketplace extension version stayed at v2.17.0 until CI validated native parity with gcc — documented as TD-MARKETPLACE-001. The compiler tag v2.18.0 still advanced; tooling caught up in the next release.
Developer workflow tip
Keep a tight loop:
-
crab-pascal check— fast semantic feedback -
crab-pascal run— behavior validation -
crab-pascal build-exe— ship candidate
If step 3 differs from step 2, file a parity bug — that is exactly what Sprint 9–10 infrastructure was built to catch.
Summary
Codegen is not magic; it is disciplined translation with tests that refuse to lie. v2.18.0 is the sprint where CrabPascal's C output became trustworthy for string-heavy CLI tools — the first taste of Pascal-in, binary-out without Delphi or FPC installed.
Português {#portugus}
Codegen para C: binários nativos a partir de Pascal (v2.18.0)
A Sprint 10 (v2.18.0) fecha o ciclo na feature mais ambiciosa do CrabPascal: transformar código Pascal em executáveis nativos reais via codegen C — com builtins de string que de fato batem com o interpretador.
O pipeline
Pascal (.dpr/.pas) → AST → fonte C + stubs.c → gcc/clang → binário nativo
O run pula os últimos passos e executa em Rust. O build-exe é para quando você quer .exe ou ELF em disco sem carregar o runtime CrabPascal como dependência.
Exemplo ponta a ponta
program NativeHello;
uses
System.SysUtils;
begin
WriteLn(Trim(' Hello, native world! '));
end.
crab-pascal build-exe NativeHello.dpr
./NativeHello # ou NativeHello.exe no Windows
Saída esperada: Hello, native world! — sem espaços no início ou fim.
O que a Sprint 10 corrigiu
Parser: Trim, Copy, Length e similares são reconhecidos como builtins SysUtils, não confundidos com nomes de tipo começando em T. Denylist evita hard-casts que geravam C inválido.
Codegen:
- Declarações forward de helpers
pascal_*no C gerado. -
WriteLnemite formatos%scorretos para expressões string. -
mainretorna0como programa C bem comportado.
Testes: build_string_conformance_stdout_matches_run_when_toolchain_present roda só com gcc/clang disponível — skip limpo em CI sem compilador, falha alta quando há compilador mas a saída diverge.
cargo test --test run_build_parity
stubs.c: superfície de runtime compartilhada
Funções de string implementadas uma vez em Rust para run espelham em stubs.c para builds nativos:
// conceitual — veja o repo para assinaturas completas
int pascal_Length(const char* s);
char* pascal_Trim(const char* s);
Chamadas Pascal geradas roteiam por aqui em vez de lógica inline ad hoc, mantendo semântica de strings das Sprints 5–8 intacta em binários.
Quando build-exe ainda não basta
A Sprint 10 não entregou paridade completa de codegen OO, exceções ou generics — isso aparece em sprints posteriores (v2.19+). Use build-exe quando seu programa usa:
-
WriteLne strings SysUtils - Fluxo de controle linear
- Procedures/functions sem grafos de objetos complexos
Para servidores HTTP Horse e OOP pesado, run permaneceu o caminho suportado na v2.18.0.
Nota sobre extensão VS Code
Versão da extensão marketplace ficou em v2.17.0 até CI validar paridade nativa com gcc — documentado como TD-MARKETPLACE-001. A tag do compilador v2.18.0 avançou mesmo assim; tooling alcançou na release seguinte.
Dica de workflow
Mantenha loop curto:
-
crab-pascal check— feedback semântico rápido -
crab-pascal run— validação de comportamento -
crab-pascal build-exe— candidato a entrega
Se o passo 3 difere do 2, abra bug de paridade — é exatamente para isso que a infra das Sprints 9–10 foi construída.
Resumo
Codegen não é magia; é tradução disciplinada com testes que recusam mentir. A v2.18.0 é a sprint em que a saída C do CrabPascal ficou confiável para CLIs ricos em strings — primeiro gosto de Pascal-in, binary-out sem Delphi ou FPC instalados.
Published on dev.to/@crabpascal · Código em CrabPascal
Top comments (0)