DEV Community

CrabPascal
CrabPascal

Posted on

Codegen to C: Native Binaries from Pascal (v2.18.0) | Codegen para C: binários nativos a partir de Pascal (v2.18.0)

Bilingual post · Post bilíngue

Jump to: English · Português


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
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode
crab-pascal build-exe NativeHello.dpr
./NativeHello    # or NativeHello.exe on Windows
Enter fullscreen mode Exit fullscreen mode

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.
  • WriteLn emits correct %s formats for string expressions.
  • main returns 0 like 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
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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:

  • WriteLn and 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:

  1. crab-pascal check — fast semantic feedback
  2. crab-pascal run — behavior validation
  3. 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
Enter fullscreen mode Exit fullscreen mode

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.
Enter fullscreen mode Exit fullscreen mode
crab-pascal build-exe NativeHello.dpr
./NativeHello    # ou NativeHello.exe no Windows
Enter fullscreen mode Exit fullscreen mode

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.
  • WriteLn emite formatos %s corretos para expressões string.
  • main retorna 0 como 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
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

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:

  • WriteLn e 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:

  1. crab-pascal check — feedback semântico rápido
  2. crab-pascal run — validação de comportamento
  3. 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)