Experimental C Backend
Relevant source files
The following files were used as context for generating this wiki page:
The Experimental C Backend is an inspectable backend for Pop Lang that transpiles verified Intermediate Representations into deterministic ISO C11 source code. It is designed to exercise canonical MIR without dependencies on LLVM or the native runtime, serving as a portable distribution and audit format.
This backend is explicitly designated as experimental and not a development priority. It supports a narrow, runtime-free subset of Pop Lang features to ensure security by construction and avoid undefined behavior inherent in standard C implementations.
Sources: architecture/decisions/0059-experimental-secure-c-transpilation-backend.md:8-12, AGENTS.md:387-390
Pipeline and Architecture
The C backend is located in crates/compiler/backends/c. It consumes only frozen, verified canonical MIR after portable MIR optimization. This architecture ensures that semantic lowering is not duplicated and that the backend does not diverge from the language's core semantics.
Transpilation Flow
The following diagram illustrates the path from source code to the final C11 artifact:
The driver ensures that each stage completes successfully before proceeding; no partial C is emitted upon failure.
Sources: architecture/decisions/0059-experimental-secure-c-transpilation-backend.md:16-24, architecture/21-cli-tooling-and-code-units.md:301-309
Core Semantic Constraints
To preserve Pop Lang's safety and static guarantees, the C backend enforces strict rules on the generated code:
- Fixed-Width Types: The backend uses exact-width
<stdint.h>types andstdbool.hinstead of platform-dependent C types to ensure cross-platform consistency. - Security by Construction: It preserves Pop Lang's checked integer overflow, division-by-zero, and evaluation-order semantics, avoiding C undefined behaviors such as signed overflow or aliasing violations.
- Identifier Mangling: External and internal C identifiers are derived solely from typed Bubble/item/value IDs. This prevents source-text injection where a programmer could potentially inject C tokens through Pop source spelling.
- Deterministic Output: Generated code contains no embedded timestamps, host paths, or environment values that could compromise reproducibility.
Sources: architecture/decisions/0059-experimental-secure-c-transpilation-backend.md:26-40
Supported Feature Subset
The initial slice of the C backend supports a restricted, runtime-free capability set. If a source program uses an excluded operation, the backend produces a deterministic capability error.
| Feature Category | Supported Capabilities |
|---|---|
| Primitives | Fixed-width integers, Boolean, Float32, Float64 |
| Operations | Scalar constants, basic arithmetic, branches, local SSA values |
| Control Flow | Direct calls, returns, entry wrapper for main |
| Built-ins | print(Int) and print(String) via backend-private adapters |
| Strings | Literal-backed immutable strings (numeric byte-slices) |
Excluded Features: The backend currently does not support managed allocation (strings, arrays, tables), GC operations, records, unions, classes, closures, interface dispatch, coroutines, or FFI.
Sources: architecture/decisions/0059-experimental-secure-c-transpilation-backend.md:42-53
Tooling and CLI Usage
The C backend is invoked via the unified pop command using the transpile subcommand.
pop transpile <source.pop> --to c
Execution Details
- Input Handling: The driver supplies an ephemeral Workspace, Package, and Bubble context for the single-module invocation.
- Entry Point: The program must contain a canonical binary entry (
main) with no arguments and either no result or anIntresult. - Output: The complete C11 translation unit is written to stdout, while diagnostics and errors are written to stderr.
Sources: architecture/decisions/0059-experimental-secure-c-transpilation-backend.md:21-25, architecture/21-cli-tooling-and-code-units.md:301-309
Verification and Conformance
The C backend is subject to strict architecture-regression checks to ensure it does not introduce dynamic typing or backend-specific IR leaks.
Verification requires that generated C executes supported programs with identical results to the MIR interpreter, particularly regarding numeric boundary conditions.
Sources: architecture/decisions/0059-experimental-secure-c-transpilation-backend.md:68-81, architecture/19-architecture-conformance-and-regression-policy.md:214-216
Summary
The Experimental C Backend provides an auditable, portable pathway for Pop Lang programs by lowering optimized MIR to strict C11. By focusing on a secure, runtime-free subset of the language, it avoids the semantic pitfalls of C's undefined behavior while ensuring that Pop Lang's static guarantees remain intact across different execution strategies.