kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 50f2be4ee7f358e1fa5abd6b3808d6a4c4742cd6
parent c09a8d50742caad102d77ca255eb63ae2b68a6ce
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Mon,  1 Jun 2026 12:25:18 -0700

include: make frontend.h the single frontend front door

frontend.h already aspired to be the "one-stop include for source
language implementations" but was missing compile.h (the
CfreeFrontendVTable registration contract), so frontends still pulled
cg.h/compile.h/core.h/object.h directly alongside it.

Add compile.h to frontend.h so <cfree/frontend.h> alone is sufficient to
write and register a frontend, then migrate lang/ to the front door:
drop the now-redundant granular includes from frontend TUs and reduce
the c/toy/wasm public headers to just frontend.h. Internal headers that
genuinely need only the CG surface (decl.h/type.h/cg_public_compat.h)
and the preprocessor (must not pull in cg.h) keep their narrow includes.

Reconcile INTERFACES.md: the "no umbrella header" invariant now
distinguishes a forbidden whole-library cfree.h from the sanctioned
tier-scoped frontend.h facade.

make lib green under -Werror; test-toy (1338/0/24) and test-parse
(3784/0/0 + parse-err 123/123) pass.

Diffstat:
Mdoc/INTERFACES.md | 28++++++++++++++++++++++------
Minclude/cfree/frontend.h | 17++++++++++++-----
Mlang/c/c.c | 2--
Mlang/c/c.h | 3---
Mlang/toy/expr.c | 1-
Mlang/toy/internal.h | 2--
Mlang/toy/parser.c | 1-
Mlang/toy/parser_core.c | 1-
Mlang/toy/toy.h | 1-
Mlang/wasm/wasm.h | 2--
10 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/doc/INTERFACES.md b/doc/INTERFACES.md @@ -48,8 +48,13 @@ entirely do; the deliberate exceptions are the C frontend reaching to `include/cfree/`, don't widen the exception list. **Invariants (keep them true):** -- There is **no** umbrella `include/cfree.h`. Consumers include the specific - headers they use: `include/cfree/*.h` and `include/cfree/support/*.h`. +- There is **no** whole-library umbrella `include/cfree.h`. Consumers include + the specific headers they use: `include/cfree/*.h` and + `include/cfree/support/*.h`. The one sanctioned exception is a *tier-scoped* + facade: `frontend.h` is the deliberate single front door for the frontend + tier and re-exports `cg.h`, `compile.h`, `source.h`, and `support/arena.h`. + Scoping a facade to one tier is fine; a grab-bag spanning the whole library + is not. - The driver includes only `<cfree/...>` (the `-Ilang` exception is a single frontend public header), never `src/`. - `*_internal.h` headers are private to one subsystem and must not be included @@ -72,7 +77,7 @@ it uses. | `config.h` | Build-time component enable flags (arch / obj-format / language / subsystem / tool). Preprocessor-only. | — | build | | `compile.h` | High-level source->object compilation; frontend registration vtable; dep iteration. | `CfreeCompileSession`, `CfreeDepIter` | driver, frontends | | `cg.h` | Code-generation API (the largest contract): a stack-machine typed IR over `CfreeCg`. Types/ABI, functions, control flow, memory, arithmetic, calls, intrinsics, inline+file asm, static data. | `CfreeCg` | frontends | -| `frontend.h` | Frontend convenience bridge: panic boundary (`cfree_frontend_run`), metrics scopes, fatal helpers. | — | frontends | +| `frontend.h` | Frontend **front door**: re-exports `cg.h` / `compile.h` / `source.h` / `support/arena.h`, plus the panic boundary (`cfree_frontend_run`), metrics scopes, and fatal helpers. Including this alone is enough to write and register a frontend. | — | frontends | | `source.h` | Source registry: stable file IDs + include-edge recording. | — | frontends | | `preprocess.h` | Standalone C preprocessor entry. | — | driver | | `object.h` | Format-neutral object model: builder + read-only inspection; section/symbol/reloc enums. | `CfreeObjBuilder`, `CfreeObjFile` | cg, link, jit, disasm, dwarf | @@ -94,6 +99,13 @@ it uses. - `cg.h` is by far the largest contract and the one frontends couple to hardest. Changes here ripple to every frontend — treat it as the highest-risk public interface. +- `frontend.h` is the only sanctioned aggregator header — a *front door* scoped + to the frontend tier. It re-exports the codegen / registration / source / + arena surface so a frontend TU includes just `<cfree/frontend.h>`. This is the + deliberate exception to the "no umbrella header" invariant: the scope is one + tier, not the whole library. A TU still reaches for a single narrow header + directly when that is all it needs — e.g. a lexer wanting only `core.h`, or + the preprocessor, which must not pull in `cg.h`. - `core.h` defines the host vtables (`CfreeHeap`, `CfreeWriter`, `CfreeDiagSink`, `CfreeContext`). These are the project's "no global state" enforcement point; every subsystem threads context through them rather than reaching for a static. @@ -269,9 +281,13 @@ with `cfree_register_frontend(compiler, language, vtable)`; `src/api/lang_registry.h::lang_registry_init` auto-wires the enabled `CFREE_LANG_*` frontends at compiler construction. -**What frontends consume** is overwhelmingly the public API — `cg.h`, -`frontend.h`, `source.h`, `object.h`, `support/arena.h`, `support/hashmap.h`, -`core.h` — with the two documented internal exceptions noted in the boundary map. +**What frontends consume** is overwhelmingly the public API, reached through a +single front door: `<cfree/frontend.h>` re-exports `cg.h`, `compile.h`, +`source.h`, and `support/arena.h` (and transitively `core.h` + `object.h`), so a +frontend TU includes just that one header. The remaining direct public includes +are the ones *outside* the facade — `support/hashmap.h` for hashed tables, and +`preprocess.h` / `jit.h` / `wasm.h` where a specific frontend or runner needs +them — plus the two documented internal exceptions noted in the boundary map. | Frontend | Public entry | Notable internal headers | |----------|--------------|--------------------------| diff --git a/include/cfree/frontend.h b/include/cfree/frontend.h @@ -2,6 +2,7 @@ #define CFREE_FRONTEND_H #include <cfree/cg.h> +#include <cfree/compile.h> #include <cfree/source.h> #include <cfree/support/arena.h> #include <stdarg.h> @@ -10,11 +11,17 @@ /* * Language frontend convenience API. * - * This header is the intended one-stop include for source language - * implementations. It includes: - * - cfree/cg.h for code emission - * - cfree/source.h for source file ids and include-edge recording - * - cfree/support/arena.h for short-lived frontend allocation + * This header is the intended one-stop front door for source language + * implementations. It aggregates the public surface a frontend needs: + * - cfree/cg.h code emission (transitively pulls core.h + object.h) + * - cfree/compile.h the CfreeFrontendVTable registration contract + * - cfree/source.h source file ids and include-edge recording + * - cfree/support/arena.h short-lived frontend allocation + * + * Including <cfree/frontend.h> alone is therefore sufficient to write and + * register a frontend. Reach for a single narrow public header directly only + * when a translation unit genuinely needs just that one — e.g. a lexer that + * wants only core.h, or the preprocessor, which must not pull in cg.h. * * The declarations below are the frontend execution boundary and host-service * shims that do not belong to codegen, source registry, or allocation. diff --git a/lang/c/c.c b/lang/c/c.c @@ -1,7 +1,5 @@ #include "c.h" -#include <cfree/cg.h> - #include "decl/decl.h" #include "lex/lex.h" #include "parse/parse.h" diff --git a/lang/c/c.h b/lang/c/c.h @@ -16,10 +16,7 @@ * Standalone preprocessing has moved to <cfree/preprocess.h>'s * cfree_cpp_preprocess(). */ -#include <cfree/compile.h> -#include <cfree/core.h> #include <cfree/frontend.h> -#include <cfree/object.h> extern const CfreeFrontendVTable cfree_c_frontend_vtable; diff --git a/lang/toy/expr.c b/lang/toy/expr.c @@ -1,4 +1,3 @@ -#include <cfree/cg.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> diff --git a/lang/toy/internal.h b/lang/toy/internal.h @@ -1,8 +1,6 @@ #ifndef CFREE_TOY_INTERNAL_H #define CFREE_TOY_INTERNAL_H -#include <cfree/cg.h> -#include <cfree/compile.h> #include <cfree/frontend.h> #include <stddef.h> #include <stdint.h> diff --git a/lang/toy/parser.c b/lang/toy/parser.c @@ -1,4 +1,3 @@ -#include <cfree/cg.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> diff --git a/lang/toy/parser_core.c b/lang/toy/parser_core.c @@ -1,4 +1,3 @@ -#include <cfree/source.h> #include <stdarg.h> #include <stdio.h> #include <string.h> diff --git a/lang/toy/toy.h b/lang/toy/toy.h @@ -1,7 +1,6 @@ #ifndef CFREE_TOY_H #define CFREE_TOY_H -#include <cfree/compile.h> #include <cfree/frontend.h> extern const CfreeFrontendVTable cfree_toy_frontend_vtable; diff --git a/lang/wasm/wasm.h b/lang/wasm/wasm.h @@ -1,8 +1,6 @@ #ifndef CFREE_LANG_WASM_H #define CFREE_LANG_WASM_H -#include <cfree/compile.h> -#include <cfree/core.h> #include <cfree/frontend.h> #include "runtime_abi.h"