Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions src/backend/shared/transpilers/st-transpiler/emit/pou-graphical.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/**
* IR-native graphical-POU emitter — LD / FBD bodies.
*
Expand Down Expand Up @@ -26,6 +26,38 @@
vars: TranspileVariable[]
}

/**
* Destination types of the IEC 61131-3 polymorphic conversion family
* (`TO_BOOL`, `TO_INT`, `TO_UINT`, …). Hard-coded here rather than
* derived at runtime from the catalog so any future addition is visible
* in code review. Kept in sync with `data/std_block_catalog.json` — any
* `<SRC>_TO_<X>` entry in the catalog implies `TO_<X>` is a valid
* polymorphic conversion target.
*/
const TO_CONVERSION_TARGETS: ReadonlySet<string> = new Set([
'BCD',
'BOOL',
'BYTE',
'DATE',
'DINT',
'DT',
'DWORD',
'INT',
'LINT',
'LREAL',
'LWORD',
'REAL',
'SINT',
'STRING',
'TIME',
'TOD',
'UDINT',
'UINT',
'ULINT',
'USINT',
'WORD',
])

/* ─────────────────────────── public entry ───────────────────────────────── */

/**
Expand Down Expand Up @@ -68,6 +100,15 @@
// …) collapse to `BOOL`, which matches the corpus where these
// operators are always Boolean rung logic. A future
// computeConnectionTypes port will narrow these properly.
// 3. Polymorphic IEC 61131-3 type-conversion functions of the
// form `TO_<TYPE>` (TO_INT, TO_UINT, TO_REAL, …) — the
// catalog enumerates the source-specific variants
// (`BOOL_TO_UINT`, `INT_TO_UINT`, …) but NOT the generic
// `TO_<TYPE>` family, so resolveBlockType returns null for
// them. Without this case the synthetic var stayed at
// `ANY` and strucpp rejected the program with
// "Undefined type 'ANY' in PROGRAM" — fixed here by reading
// the destination type directly from the function name.
const resolvedSyntheticVars = emitted.syntheticVars.map<SyntheticVar>((sv) => {
if (sv.type !== 'ANY' || sv.originBlockTypeName === undefined) return sv
const referenced = project.pous.find((p) => p.name === sv.originBlockTypeName)
Expand All @@ -82,6 +123,10 @@
return { ...sv, type: collapsed }
}
}
const polymorphicMatch = sv.originBlockTypeName.match(/^TO_([A-Z]+)$/)
if (polymorphicMatch && TO_CONVERSION_TARGETS.has(polymorphicMatch[1])) {
return { ...sv, type: polymorphicMatch[1] }
}
return sv
})

Expand Down
Loading