UniSet 2.45.1
Класс st2js.codegen.CodeGenerator

Открытые члены

 __init__ (self, IRProgram program, SensorMapping mapping, bool debug=False)
str generate (self)

Открытые атрибуты

 program = program
 mapping = mapping

Защищенные члены

list[str] _emit_sensor_arrays (self)
list[SensorEntry_collect_input_entries (self)
list[SensorEntry_collect_output_entries (self)
list[str] _emit_global_vars (self)
list[str] _emit_local_vars (self)
None _prescan_stub_types (self)
list[str] _emit_auto_stubs (self)
list[str] _emit_fb_instances (self)
list[str] _emit_program_function (self, IRProgram prog)
list[str] _emit_function_block_class (self, IRFunctionBlock fb)
str _format_initial_value (self, IRVariable var)
str _format_struct_literal (self, list[IRStructField] fields)
str _format_array_init (self, IRVariable var)
str _format_python_value (self, Any value, IECType iec_type)
list[str] _emit_statement (self, IRStatement stmt, int indent, IRFunctionBlock|None fb_context=None)
list[str] _emit_fb_call (self, IRFBCall call, int indent, IRFunctionBlock|None fb_context=None)
str _get_fb_type (self, str instance_name)
list[str] _emit_if_else (self, IRIfElse stmt, int indent, IRFunctionBlock|None fb_context=None)
list[str] _emit_case (self, IRCase stmt, int indent)
list[str] _emit_for_loop (self, IRForLoop stmt, int indent)
list[str] _emit_while_loop (self, IRWhileLoop stmt, int indent)
list[str] _emit_repeat_loop (self, IRRepeatLoop stmt, int indent)
str _emit_expression (self, IRExpression expr, IRFunctionBlock|None fb_context=None)
str _emit_function_call_expr (self, IRFunctionCall expr, IRFunctionBlock|None fb_context=None)
str _emit_array_access (self, IRArrayAccess expr, IRFunctionBlock|None fb_context=None)
IRVariable|None _find_variable (self, str name)
str _emit_literal (self, IRLiteral lit)
str _emit_var_ref (self, IRVarRef ref, IRFunctionBlock|None fb_context=None)
str _prefixed_sensor (self, str sensor_name)
str _prefixed_func (self, str func_name)
list[str] _emit_debug_stubs (self)
dict[str, tuple[list[str], list[str]]] _collect_fb_type_ports (self)
list[str] _emit_program_meta (self)
list[dict] _extract_connections (self, list stmts, list operator_nodes=None)
dict|None _classify_connection (self, str instance, str param, expr, list operator_nodes=None, list connections=None)
str|None _build_operator_subgraph (self, expr, list operator_nodes, list connections)
str _emit_type_coercion (self, IRTypeCoercion coercion)

Защищенные статические члены

str _format_array_literal (int size, str default_str)
str _format_scale (float scale)

Защищенные данные

 _debug = debug
 _has_mapping = bool(mapping.inputs or mapping.outputs)
set[str] _unsupported_fbs = set()
set[str] _stub_fb_types = set()
dict _user_fb_types = {fb.name for fb in program.function_blocks}
 _var_prefix = mapping.options.var_prefix
 _func_prefix = mapping.options.func_prefix
dict _input_map
dict _output_map
dict _input_names = {v.name for v in program.inputs}
dict _output_names = {v.name for v in program.outputs}
dict _global_names = {v.name for v in program.globals}
dict _scaled_inputs
dict _scaled_outputs
 _struct_flatten = mapping.options.struct_flatten
dict _flat_input_structs = {}
dict _flat_output_structs = {}
int _op_counter = 0
 _extracted_operator_nodes = operator_nodes

Статические защищенные данные

dict _FLOAT_TYPES = {IECType.REAL, IECType.LREAL}
dict _ALL_INTEGER_TYPES

Подробное описание

Walks IR and emits JavaScript source code.

Builds lookup tables for input/output variable-to-sensor mapping,
then emits the JS file sections in order.

Методы

◆ _build_operator_subgraph()

str | None st2js.codegen.CodeGenerator._build_operator_subgraph ( self,
expr,
list operator_nodes,
list connections )
protected
Recursively build operator nodes for a complex expression.

Returns the output node ID of the subgraph, or None for literals.

◆ _classify_connection()

dict | None st2js.codegen.CodeGenerator._classify_connection ( self,
str instance,
str param,
expr,
list operator_nodes = None,
list connections = None )
protected
Classify an FB call argument as a connection.

For complex expressions, creates operator nodes with inner connections.
Returns the final connection linking to the target FB.param.

◆ _collect_fb_type_ports()

dict[str, tuple[list[str], list[str]]] st2js.codegen.CodeGenerator._collect_fb_type_ports ( self)
protected
Build fb_type -> (input_names, output_names) lookup.

Covers user-defined FBs from the ST source (IRFunctionBlock),
including nested FBs declared inside other FBs, and standard/library
FBs from the fb_registry (IEC 61131-3 primitives + YAML lib types).

◆ _collect_input_entries()

list[SensorEntry] st2js.codegen.CodeGenerator._collect_input_entries ( self)
protected
Collect sensor entries for all input variables.

When struct_flatten is enabled, struct variables expand into their
individual field entries (from dotted mapping names).

◆ _collect_output_entries()

list[SensorEntry] st2js.codegen.CodeGenerator._collect_output_entries ( self)
protected
Collect sensor entries for all output variables.

When struct_flatten is enabled, struct variables expand into their
individual field entries (from dotted mapping names).

◆ _emit_array_access()

str st2js.codegen.CodeGenerator._emit_array_access ( self,
IRArrayAccess expr,
IRFunctionBlock | None fb_context = None )
protected
Emit an array access with 1-based to 0-based index conversion.

Looks up the array variable to determine the lower bound,
then emits arr[index - lower_bound].

◆ _emit_auto_stubs()

list[str] st2js.codegen.CodeGenerator._emit_auto_stubs ( self)
protected
Emit auto-generated stub classes for unknown external FB types.

◆ _emit_case()

list[str] st2js.codegen.CodeGenerator._emit_case ( self,
IRCase stmt,
int indent )
protected
Emit a switch/case statement.

◆ _emit_debug_stubs()

list[str] st2js.codegen.CodeGenerator._emit_debug_stubs ( self)
protected
Emit debug initialization: load uniset2-debug.js and start debug server.

◆ _emit_expression()

str st2js.codegen.CodeGenerator._emit_expression ( self,
IRExpression expr,
IRFunctionBlock | None fb_context = None )
protected
Emit an expression as a JavaScript string.

Args:
    expr: The IR expression to emit.
    fb_context: If set, variable references within a FUNCTION_BLOCK
        body should use this.name prefix for the FB's own variables.

◆ _emit_fb_call()

list[str] st2js.codegen.CodeGenerator._emit_fb_call ( self,
IRFBCall call,
int indent,
IRFunctionBlock | None fb_context = None )
protected
Emit an FB call as instance.update(arg1, arg2, ...).

Arguments are ordered according to the fb_registry update_params order.
When inside a FUNCTION_BLOCK body (fb_context), uses this. prefix.

◆ _emit_fb_instances()

list[str] st2js.codegen.CodeGenerator._emit_fb_instances ( self)
protected
Emit function block instance declarations as const statements.

Timers (TON/TOF/TP): constructor takes PT value -> new TON(ptValue)
Counters (CTU/CTD/CTUD): constructor takes PV value -> new CTU(pvValue)
Bistable/Edge (RS/SR/R_TRIG/F_TRIG): no constructor args -> new RS()

◆ _emit_for_loop()

list[str] st2js.codegen.CodeGenerator._emit_for_loop ( self,
IRForLoop stmt,
int indent )
protected
Emit a for loop statement.

◆ _emit_function_block_class()

list[str] st2js.codegen.CodeGenerator._emit_function_block_class ( self,
IRFunctionBlock fb )
protected
Emit a FUNCTION_BLOCK as a JavaScript class with constructor and execute().

◆ _emit_function_call_expr()

str st2js.codegen.CodeGenerator._emit_function_call_expr ( self,
IRFunctionCall expr,
IRFunctionBlock | None fb_context = None )
protected
Emit a FUNCTION call expression as ``funcName(arg1, arg2, ...)``.

◆ _emit_global_vars()

list[str] st2js.codegen.CodeGenerator._emit_global_vars ( self)
protected
Emit global variable declarations (from VAR_GLOBAL) as let statements.

Skips globals that are shadowed by local/input/output variables.

◆ _emit_if_else()

list[str] st2js.codegen.CodeGenerator._emit_if_else ( self,
IRIfElse stmt,
int indent,
IRFunctionBlock | None fb_context = None )
protected
Emit an if/else if/else statement.

◆ _emit_literal()

str st2js.codegen.CodeGenerator._emit_literal ( self,
IRLiteral lit )
protected
Emit a literal value.

◆ _emit_local_vars()

list[str] st2js.codegen.CodeGenerator._emit_local_vars ( self)
protected
Emit local variable declarations as let statements.

Deduplicates by name (actions copy parent locals, causing repeats).

◆ _emit_program_function()

list[str] st2js.codegen.CodeGenerator._emit_program_function ( self,
IRProgram prog )
protected
Emit a secondary PROGRAM as a JS class with execute() method.

Same pattern as FUNCTION_BLOCK: local variables and FB instances
stored as properties (this.xxx), body in execute(). This ensures
state persists between calls.

Called from main: `ProgramName.execute();`

◆ _emit_program_meta()

list[str] st2js.codegen.CodeGenerator._emit_program_meta ( self)
protected
Emit globalThis._program_meta with program structure info.

◆ _emit_repeat_loop()

list[str] st2js.codegen.CodeGenerator._emit_repeat_loop ( self,
IRRepeatLoop stmt,
int indent )
protected
Emit a do..while loop statement (REPEAT..UNTIL).

◆ _emit_sensor_arrays()

list[str] st2js.codegen.CodeGenerator._emit_sensor_arrays ( self)
protected
Emit uniset_inputs and uniset_outputs array declarations.

◆ _emit_statement()

list[str] st2js.codegen.CodeGenerator._emit_statement ( self,
IRStatement stmt,
int indent,
IRFunctionBlock | None fb_context = None )
protected
Emit a single statement as a list of indented lines.

Args:
    stmt: The IR statement to emit.
    indent: Current indentation level.
    fb_context: If set, we are inside a FUNCTION_BLOCK body and
        variable references should use this.name prefix.

◆ _emit_type_coercion()

str st2js.codegen.CodeGenerator._emit_type_coercion ( self,
IRTypeCoercion coercion )
protected
Emit a type coercion expression.

◆ _emit_var_ref()

str st2js.codegen.CodeGenerator._emit_var_ref ( self,
IRVarRef ref,
IRFunctionBlock | None fb_context = None )
protected
Emit a variable reference with input/output prefix substitution.

When fb_context is set, variables belonging to the FUNCTION_BLOCK
are prefixed with 'this.' instead of using sensor mapping.

◆ _emit_while_loop()

list[str] st2js.codegen.CodeGenerator._emit_while_loop ( self,
IRWhileLoop stmt,
int indent )
protected
Emit a while loop statement.

◆ _extract_connections()

list[dict] st2js.codegen.CodeGenerator._extract_connections ( self,
list stmts,
list operator_nodes = None )
protected
Extract FB connections from IR statements for the schema graph.

Extracts:
1. FB call inputs: fb(PARAM := source) → {from: source, to: fb, toParam: PARAM}
2. Output assignments: var := fb.field → {from: fb, fromField: field, to: var, toParam: "="}
3. Operator nodes: complex expressions (A AND B, NOT C) → virtual nodes with connections

Args:
    stmts: IR statement list
    operator_nodes: accumulator for generated operator nodes

◆ _find_variable()

IRVariable | None st2js.codegen.CodeGenerator._find_variable ( self,
str name )
protected
Find a variable by name across all program variable sections.

◆ _format_array_init()

str st2js.codegen.CodeGenerator._format_array_init ( self,
IRVariable var )
protected
Format an ARRAY as a JS array literal.

◆ _format_array_literal()

str st2js.codegen.CodeGenerator._format_array_literal ( int size,
str default_str )
staticprotected
Format an array as a JS literal [val, val, ...] for QuickJS compatibility.

◆ _format_initial_value()

str st2js.codegen.CodeGenerator._format_initial_value ( self,
IRVariable var )
protected
Format the initial value for a local variable declaration.

◆ _format_python_value()

str st2js.codegen.CodeGenerator._format_python_value ( self,
Any value,
IECType iec_type )
protected
Format a Python value as a JS literal string.

◆ _format_scale()

str st2js.codegen.CodeGenerator._format_scale ( float scale)
staticprotected
Format a scale factor value, omitting .0 for integer values.

◆ _format_struct_literal()

str st2js.codegen.CodeGenerator._format_struct_literal ( self,
list[IRStructField] fields )
protected
Format a STRUCT as a JS object literal with default values per field.

◆ _get_fb_type()

str st2js.codegen.CodeGenerator._get_fb_type ( self,
str instance_name )
protected
Look up the FB type for an instance name from all programs and FBs.

◆ _prefixed_func()

str st2js.codegen.CodeGenerator._prefixed_func ( self,
str func_name )
protected
Apply func_prefix to a function/program/FB name.

◆ _prefixed_sensor()

str st2js.codegen.CodeGenerator._prefixed_sensor ( self,
str sensor_name )
protected
Apply var_prefix to a sensor name.

◆ _prescan_stub_types()

None st2js.codegen.CodeGenerator._prescan_stub_types ( self)
protected
Pre-scan all FB instances and GVL struct fields to find types needing auto-stubs.

◆ generate()

str st2js.codegen.CodeGenerator.generate ( self)
Generate the complete JavaScript source string.

Данные класса

◆ _ALL_INTEGER_TYPES

st2js.codegen.CodeGenerator._ALL_INTEGER_TYPES
staticprotected
Инициализатор
= {
IECType.SINT, IECType.INT, IECType.DINT, IECType.LINT,
IECType.USINT, IECType.UINT, IECType.UDINT, IECType.ULINT,
IECType.BYTE, IECType.WORD, IECType.DWORD, IECType.LWORD,
}

◆ _input_map

dict st2js.codegen.CodeGenerator._input_map
protected
Инициализатор
= {
entry.st_name: entry for entry in mapping.inputs
}

◆ _output_map

dict st2js.codegen.CodeGenerator._output_map
protected
Инициализатор
= {
entry.st_name: entry for entry in mapping.outputs
}

◆ _scaled_inputs

dict st2js.codegen.CodeGenerator._scaled_inputs
protected
Инициализатор
= {
entry.st_name: entry
for entry in mapping.inputs
if entry.scale is not None
}

◆ _scaled_outputs

dict st2js.codegen.CodeGenerator._scaled_outputs
protected
Инициализатор
= {
entry.st_name: entry
for entry in mapping.outputs
if entry.scale is not None
}