:title C++ Preprocessor :sig UCE source preprocessing :see load unit_render unit_call 0_Request 1_COMPONENT :content UCE runs a small custom source-to-source preprocessor before Clang sees a `.uce` or `.ws.uce` file. The template rewriting implementation lives in `src/lib/compiler-parser.cpp`, with orchestration in `src/lib/compiler.cpp`. It does not try to parse all of C++. Instead, it performs a narrow character-wise rewrite that understands literal output, inline code islands, `#load`, and `EXPORT` harvesting, then writes a generated `.cpp` file and compiles that file into a shared object. ## Syntax - `<> ... >` enters literal-output mode. - `?> ... ` also enters literal-output mode. - The open and close pairs are interchangeable, so `<> ... `, `?> ... >`, and the traditional matched forms all work. - Inside literal output, ` ... ?>` emits raw C++. - Inside a literal block, `= expression ?>` emits `print(html_escape(expression));`. - Inside a literal block, `` emits `print(expression);` without HTML escaping. - `#load "other.uce"` injects another UCE unit at compile time. - `RENDER(Request& context)`, `COMPONENT(Request& context)`, `ONCE(Request& context)`, `INIT(Request& context)`, and `WS(Request& context)` are normal C++ macros from `src/lib/compiler.h`. - `COMPONENT:NAME(Request& context)` is rewritten by the custom pass into an exported named component handler. - `EXPORT` is also a normal C++ macro, but the custom pass additionally records exported declarations for metadata. ## Pipeline - The generated file starts by including `COMPILER_SYS_PATH/src/lib/uce_lib.h`. - It then inlines the configured setup template from `SETUP_TEMPLATE` (by default `scripts/setup.h.template`), which defines the internal hook `__uce_set_current_request(Request*)`. - It inserts `#line 1` before page code so compiler diagnostics point back to the original `.uce` file. - Each literal region is rewritten into one or more `print(R"...( ... )...");` calls using a safe raw-string delimiter selected for that literal content. - `<>` and `?>` both switch from code mode into literal output. - `>` and `` both switch from literal output back into code mode. - ` ... ?>` temporarily breaks out of literal printing, emits the enclosed C++ unchanged, then resumes literal output. - `= ... ?>` becomes `print(html_escape(...));`. - `` becomes `print(...);` and is intended for trusted markup or already-escaped content. - `#load "file.uce"` is replaced with a generated C++ `#include` that points at the loaded unit's preprocessed `.cpp` file under `BIN_DIRECTORY`. - Lines beginning with `EXPORT` are scanned so their declarations can be written to a sibling `.exports.txt` file. - Lines beginning with `RENDER:NAME(...)` are rewritten into exported `__uce_render_NAME(...)` functions. - Lines beginning with `COMPONENT:NAME(...)` are rewritten into exported `__uce_component_NAME(...)` functions for the component helpers. - The final generated source is written to `BIN_DIRECTORY + src_path + "/" + source_file + ".cpp"`. - `scripts/compile` then compiles that generated `.cpp` into `source_file + ".so"` with `clang++ -shared -std=c++20 ...`. - When a worker loads the compiled unit into memory, the runtime checks for `INIT(Request& context)` and calls it once for that worker-side load. - On each request, the first time a given unit is entered through `RENDER()` or any `COMPONENT...` handler, the runtime checks for `ONCE(Request& context)` and calls it before the render/component handler. ## Generated Files For a source file like `/some/path/page.uce`, the preprocessor produces: - generated C++: `BIN_DIRECTORY/some/path/page.uce.cpp` - shared object: `BIN_DIRECTORY/some/path/page.uce.so` - export list: `BIN_DIRECTORY/some/path/page.uce.exports.txt` ## Examples Literal output with escaped data: ```cpp RENDER(Request& context) { <>