58 lines
2.3 KiB
Python
58 lines
2.3 KiB
Python
# processors/symbol_manager.py
|
|
import sympy
|
|
import re
|
|
|
|
class SymbolManager:
|
|
def __init__(self):
|
|
# plc_name -> py_id (e.g., '"DB".Var' -> 'v0_')
|
|
self.plc_to_py_id = {}
|
|
# py_id -> Symbol object (e.g., 'v0_' -> sympy.Symbol('v0_'))
|
|
self.py_id_to_symbol = {}
|
|
# py_id -> plc_name (e.g., 'v0_' -> '"DB".Var') - Inverse mapping
|
|
self.py_id_to_plc = {}
|
|
self.counter = 0
|
|
# Pre-define common keywords/constants to avoid mapping them
|
|
self.reserved_names = {"TRUE", "FALSE"} # Add others if needed
|
|
|
|
def _generate_py_id(self):
|
|
py_id = f"v{self.counter}_"
|
|
self.counter += 1
|
|
# Extremely unlikely collision, but check anyway
|
|
while py_id in self.py_id_to_symbol:
|
|
py_id = f"v{self.counter}_"
|
|
self.counter += 1
|
|
return py_id
|
|
|
|
def get_symbol(self, plc_var_name):
|
|
"""Gets/Creates a SymPy Symbol for a PLC variable name."""
|
|
if plc_var_name is None:
|
|
print("Warning: Attempted to get symbol for None PLC name.")
|
|
return None # Or handle error appropriately
|
|
if plc_var_name.upper() in self.reserved_names:
|
|
print(f"Warning: Attempted to create symbol for reserved name: {plc_var_name}")
|
|
return None # Or handle differently (e.g., return sympy.true/false?)
|
|
|
|
if plc_var_name not in self.plc_to_py_id:
|
|
py_id = self._generate_py_id()
|
|
self.plc_to_py_id[plc_var_name] = py_id
|
|
self.py_id_to_plc[py_id] = plc_var_name
|
|
self.py_id_to_symbol[py_id] = sympy.symbols(py_id)
|
|
# print(f"DEBUG SymbolManager: Created {py_id} -> {plc_var_name}") # Debug
|
|
else:
|
|
py_id = self.plc_to_py_id[plc_var_name]
|
|
|
|
return self.py_id_to_symbol.get(py_id)
|
|
|
|
def get_plc_name(self, py_id):
|
|
"""Gets the original PLC name from a py_id."""
|
|
return self.py_id_to_plc.get(py_id)
|
|
|
|
def get_inverse_map(self):
|
|
"""Returns the map needed for postprocessing (py_id -> plc_name)."""
|
|
return self.py_id_to_plc.copy()
|
|
|
|
# Helper function to extract PLC variable name from JSON operand info
|
|
def extract_plc_variable_name(operand_info):
|
|
if operand_info and operand_info.get("type") == "variable":
|
|
return operand_info.get("name")
|
|
return None # Not a variable or info missing |