plato-239.md
July 31, 2026 · View on GitHub
Issue
Plato.CppWriter is a TIR-only POC (--cpp / --cuda) moving toward first-class coverage.
M1–M5, residual functors, and M3/M4 (Character/String + Tier-1 fixed arrays) landed.
Dynamic IArray remains out of scope (documented).
Decisions (binding, 2026-07-27)
- Keep identical C++/CUDA bodies for now (
Dialects_Differ_Only_In_The_Preamblestays). - String and array = simple Plato data types, built from first principles; only the most
basic surface as intrinsics — not
std::string/std::vector(M3/M4). - Order: M1+M2 ? M5 (
--inline) ? residual closures as C++ functors ? M3/M4.
Impact
Blocks using Plato-generated geometry as a C++/CUDA library. After M3/M4: demos 147/0;
stdlib with --inline 1638 emitted / 1367 skipped (was 1090 / 1507 post-functor).
Affected code
submodules/Plato/Plato.CppWriter/CppPrelude.cs— fixedStringPOD,HashString,plato::Idsubmodules/Plato/Plato.CppWriter/CppWriter.cs— Character/String/Angle; MapComponents templatessubmodules/Plato/Plato.CppWriter/TirCppBodyWriter.cs— string literals, Angle?float coerce
Priority
p2: multi-target value is real (CUDA especially), but C# remains production.
Dependencies
- Related: plato-078 (TS), plato-024 (Rust), plato-235 (GLSL Angle)
- Follow-on (optional): dynamic IArray without std::vector if a device-friendly design appears
Bedrock
Strengthen the TIR-lowering seam (TirInliner / TirRewrite) so every non-closure backend
consumes the same specialized bodies. Do not bake std::vector/std::string into shared bodies.
Done means
- Docs mention C++/CUDA alongside TS/Rust/GLSL (POC-accurate)
- String + Character as simple Plato data types (not std::string) — M3
- Array story: simple Plato data type (not std::vector); Tier-1 fixed-size via Components + MapComponents — M4 (dynamic IArray deferred/documented)
- Static
_members emitted as free functions (type-tag param kept for overloads) - Straightforward reflection helpers emitted (Equals/NotEquals/GetHashCode; IArrayLike Components)
- Intrinsics over user structs lowered (componentwise / convert-to-floatN)
- Lambda plan executed (M5
--inline);Plato.CppWriter.Testscompile gates green - Residual closures as C++ functors (fixed-size Components / floatN); compile gates green
Simplest next slice
Optional: device-friendly dynamic IArray (still not std::vector) if a design fits identical bodies.
Prevention
- Keep
Dialects_Differ_Only_In_The_Preambleas the tripwire - Prefer sharing TirInliner across writers over per-backend lambda hacks
- nvcc test gate must load vcvars (cl.exe on PATH)
- Functors must stay device-friendly (no std::function / heap)
- String stays fixed-capacity POD; do not silently switch to heap strings