Framework
What you write.
Decorators turn ordinary Python classes into POUs (program organization units). @fb, @program, @function, @method. Descriptors (input_var, output_var, static_var, inout_var, temp_var) declare interfaces. Type constructors (BOOL, INT, REAL, ARRAY, STRING) build typed references.
src/plx/framework/
Universal IR
What the compiler produces.
A vendor-agnostic Pydantic model. Every IF, FOR, FB invocation, tag reference compiles to a typed IR node. The simulator walks it. AI agents read and write it. Static analyzers query it.
src/plx/model/
Vendor IRs
Where round-trip happens.
Per-vendor Pydantic models that mirror native vendor schemas (L5X, SimaticML, TcPOU). Lossless parsing into and emission from the vendor IR. The Universal IR is a view onto the vendor IR, not a re-encoding.
src/plx/{ab,siemens,beckhoff}/
Simulator
Deterministic scan-cycle execution.
A tree-walking interpreter that executes the IR cycle by cycle. Same inputs produce same outputs. pytest, coverage, and CI work because the source is Python.
src/plx/simulate/