PLCGenerator.py
branch1.1 Korean release
changeset 1280 72a826dfcfbb
parent 1239 d1f6ea56555d
child 1297 cd639725fba5
equal deleted inserted replaced
977:c8e008b8cefe 1280:72a826dfcfbb
   104         self.Warnings = warnings
   104         self.Warnings = warnings
   105 
   105 
   106     # Compute value according to type given
   106     # Compute value according to type given
   107     def ComputeValue(self, value, var_type):
   107     def ComputeValue(self, value, var_type):
   108         base_type = self.Controler.GetBaseType(var_type)
   108         base_type = self.Controler.GetBaseType(var_type)
   109         if base_type == "STRING":
   109         if base_type == "STRING" and not value.startswith("'") and not value.endswith("'"):
   110             return "'%s'"%value
   110             return "'%s'"%value
   111         elif base_type == "WSTRING":
   111         elif base_type == "WSTRING" and not value.startswith('"') and not value.endswith('"'):
   112             return "\"%s\""%value
   112             return "\"%s\""%value
   113         return value
   113         return value
   114 
   114 
   115     # Generate a data type from its name
   115     # Generate a data type from its name
   116     def GenerateDataType(self, datatype_name):
   116     def GenerateDataType(self, datatype_name):
   652                     option = None
   652                     option = None
   653                 if len(variables) > 0:
   653                 if len(variables) > 0:
   654                     self.Interface.append((varTypeNames[varlist["name"]], option, False, variables))
   654                     self.Interface.append((varTypeNames[varlist["name"]], option, False, variables))
   655                 if len(located) > 0:
   655                 if len(located) > 0:
   656                     self.Interface.append((varTypeNames[varlist["name"]], option, True, located))
   656                     self.Interface.append((varTypeNames[varlist["name"]], option, True, located))
   657         
   657     
       
   658     LITERAL_TYPES = {
       
   659         "T": "TIME",
       
   660         "D": "DATE",
       
   661         "TOD": "TIME_OF_DAY",
       
   662         "DT": "DATE_AND_TIME",
       
   663         "2": None,
       
   664         "8": None,
       
   665         "16": None,
       
   666     }
   658     def ComputeConnectionTypes(self, pou):
   667     def ComputeConnectionTypes(self, pou):
   659         body = pou.getbody()
   668         body = pou.getbody()
   660         if isinstance(body, ListType):
   669         if isinstance(body, ListType):
   661             body = body[0]
   670             body = body[0]
   662         body_content = body.getcontent()
   671         body_content = body.getcontent()
   679                         else:
   688                         else:
   680                             var_type = returntype_content["name"]
   689                             var_type = returntype_content["name"]
   681                     elif var_type is None:
   690                     elif var_type is None:
   682                         parts = expression.split("#")
   691                         parts = expression.split("#")
   683                         if len(parts) > 1:
   692                         if len(parts) > 1:
   684                             var_type = parts[0]
   693                             literal_prefix = parts[0].upper()
       
   694                             var_type = self.LITERAL_TYPES.get(literal_prefix, 
       
   695                                                               literal_prefix)
   685                         elif expression.startswith("'"):
   696                         elif expression.startswith("'"):
   686                             var_type = "STRING"
   697                             var_type = "STRING"
   687                         elif expression.startswith('"'):
   698                         elif expression.startswith('"'):
   688                             var_type = "WSTRING"
   699                             var_type = "WSTRING"
   689                     if var_type is not None:
   700                     if var_type is not None:
   881                     otherInstances["outVariables&coils"].append(instance)
   892                     otherInstances["outVariables&coils"].append(instance)
   882             orderedInstances.sort()
   893             orderedInstances.sort()
   883             otherInstances["outVariables&coils"].sort(SortInstances)
   894             otherInstances["outVariables&coils"].sort(SortInstances)
   884             otherInstances["blocks"].sort(SortInstances)
   895             otherInstances["blocks"].sort(SortInstances)
   885             instances = [instance for (executionOrderId, instance) in orderedInstances]
   896             instances = [instance for (executionOrderId, instance) in orderedInstances]
   886             instances.extend(otherInstances["connectors"] + otherInstances["outVariables&coils"] + otherInstances["blocks"])
   897             instances.extend(otherInstances["outVariables&coils"] + otherInstances["blocks"] + otherInstances["connectors"])
   887             for instance in instances:
   898             for instance in instances:
   888                 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   899                 if isinstance(instance, (plcopen.fbdObjects_outVariable, plcopen.fbdObjects_inOutVariable)):
   889                     connections = instance.connectionPointIn.getconnections()
   900                     connections = instance.connectionPointIn.getconnections()
   890                     if connections is not None:
   901                     if connections is not None:
   891                         expression = self.ComputeExpression(body, connections)
   902                         expression = self.ComputeExpression(body, connections)
   892                         self.Program += [(self.CurrentIndent, ()),
   903                         if expression is not None:
   893                                          (instance.getexpression(), (self.TagName, "io_variable", instance.getlocalId(), "expression")),
   904                             self.Program += [(self.CurrentIndent, ()),
   894                                          (" := ", ())]
   905                                              (instance.getexpression(), (self.TagName, "io_variable", instance.getlocalId(), "expression")),
   895                         self.Program += expression
   906                                              (" := ", ())]
   896                         self.Program += [(";\n", ())]
   907                             self.Program += expression
       
   908                             self.Program += [(";\n", ())]
   897                 elif isinstance(instance, plcopen.fbdObjects_block):
   909                 elif isinstance(instance, plcopen.fbdObjects_block):
   898                     block_type = instance.gettypeName()
   910                     block_type = instance.gettypeName()
   899                     self.ParentGenerator.GeneratePouProgram(block_type)
   911                     self.ParentGenerator.GeneratePouProgram(block_type)
   900                     block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in instance.inputVariables.getvariable() if variable.getformalParameter() != "EN"]))
   912                     block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in instance.inputVariables.getvariable() if variable.getformalParameter() != "EN"]))
   901                     if block_infos is None:
   913                     if block_infos is None:
   902                         block_infos = self.GetBlockType(block_type)
   914                         block_infos = self.GetBlockType(block_type)
   903                     if block_infos is None:
   915                     if block_infos is None:
   904                         raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name)
   916                         raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name)
   905                     block_infos["generate"](self, instance, block_infos, body, None)
   917                     try:
       
   918                         block_infos["generate"](self, instance, block_infos, body, None)
       
   919                     except ValueError, e:
       
   920                         raise PLCGenException, e.message
   906                 elif isinstance(instance, plcopen.commonObjects_connector):
   921                 elif isinstance(instance, plcopen.commonObjects_connector):
   907                     connector = instance.getname()
   922                     connector = instance.getname()
   908                     if self.ComputedConnectors.get(connector, None):
   923                     if self.ComputedConnectors.get(connector, None):
   909                         continue 
   924                         continue
   910                     self.ComputedConnectors[connector] = self.ComputeExpression(body, instance.connectionPointIn.getconnections())
   925                     expression = self.ComputeExpression(body, instance.connectionPointIn.getconnections())
       
   926                     if expression is not None:
       
   927                         self.ComputedConnectors[connector] = expression
   911                 elif isinstance(instance, plcopen.ldObjects_coil):
   928                 elif isinstance(instance, plcopen.ldObjects_coil):
   912                     connections = instance.connectionPointIn.getconnections()
   929                     connections = instance.connectionPointIn.getconnections()
   913                     if connections is not None:
   930                     if connections is not None:
   914                         coil_info = (self.TagName, "coil", instance.getlocalId())
   931                         coil_info = (self.TagName, "coil", instance.getlocalId())
   915                         expression = self.ExtractModifier(instance, self.ComputeExpression(body, connections), coil_info)
   932                         expression = self.ComputeExpression(body, connections)
   916                         self.Program += [(self.CurrentIndent, ())]
   933                         if expression is not None:
   917                         self.Program += [(instance.getvariable(), coil_info + ("reference",))]
   934                             expression = self.ExtractModifier(instance, expression, coil_info)
   918                         self.Program += [(" := ", ())] + expression + [(";\n", ())]
   935                             self.Program += [(self.CurrentIndent, ())]
       
   936                             self.Program += [(instance.getvariable(), coil_info + ("reference",))]
       
   937                             self.Program += [(" := ", ())] + expression + [(";\n", ())]
   919                         
   938                         
   920     def FactorizePaths(self, paths):
   939     def FactorizePaths(self, paths):
   921         same_paths = {}
   940         same_paths = {}
   922         uncomputed_index = range(len(paths))
   941         uncomputed_index = range(len(paths))
   923         factorized_paths = []
   942         factorized_paths = []
   959                 block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in next.inputVariables.getvariable() if variable.getformalParameter() != "EN"]))
   978                 block_infos = self.GetBlockType(block_type, tuple([self.ConnectionTypes.get(variable.connectionPointIn, "ANY") for variable in next.inputVariables.getvariable() if variable.getformalParameter() != "EN"]))
   960                 if block_infos is None:
   979                 if block_infos is None:
   961                     block_infos = self.GetBlockType(block_type)
   980                     block_infos = self.GetBlockType(block_type)
   962                 if block_infos is None:
   981                 if block_infos is None:
   963                     raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name)
   982                     raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name)
   964                 paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order, to_inout)))
   983                 try:
       
   984                     paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order, to_inout)))
       
   985                 except ValueError, e:
       
   986                     raise PLCGenException, e.message
   965             elif isinstance(next, plcopen.commonObjects_continuation):
   987             elif isinstance(next, plcopen.commonObjects_continuation):
   966                 name = next.getname()
   988                 name = next.getname()
   967                 computed_value = self.ComputedConnectors.get(name, None)
   989                 computed_value = self.ComputedConnectors.get(name, None)
   968                 if computed_value != None:
   990                 if computed_value != None:
   969                     paths.append(str(computed_value))
   991                     paths.append(str(computed_value))
   976                             connector = instance
   998                             connector = instance
   977                     if connector is not None:
   999                     if connector is not None:
   978                         connections = connector.connectionPointIn.getconnections()
  1000                         connections = connector.connectionPointIn.getconnections()
   979                         if connections is not None:
  1001                         if connections is not None:
   980                             expression = self.ComputeExpression(body, connections, order)
  1002                             expression = self.ComputeExpression(body, connections, order)
   981                             self.ComputedConnectors[name] = expression
  1003                             if expression is not None:
   982                             paths.append(str(expression))
  1004                                 self.ComputedConnectors[name] = expression
       
  1005                                 paths.append(str(expression))
   983                     else:
  1006                     else:
   984                         raise PLCGenException, _("No connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name)
  1007                         raise PLCGenException, _("No connector found corresponding to \"%s\" continuation in \"%s\" POU")%(name, self.Name)
   985             elif isinstance(next, plcopen.ldObjects_contact):
  1008             elif isinstance(next, plcopen.ldObjects_contact):
   986                 contact_info = (self.TagName, "contact", next.getlocalId())
  1009                 contact_info = (self.TagName, "contact", next.getlocalId())
   987                 variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info))
  1010                 variable = str(self.ExtractModifier(next, [(next.getvariable(), contact_info + ("reference",))], contact_info))
  1020         else:
  1043         else:
  1021             return eval(paths)
  1044             return eval(paths)
  1022 
  1045 
  1023     def ComputeExpression(self, body, connections, order = False, to_inout = False):
  1046     def ComputeExpression(self, body, connections, order = False, to_inout = False):
  1024         paths = self.GeneratePaths(connections, body, order, to_inout)
  1047         paths = self.GeneratePaths(connections, body, order, to_inout)
       
  1048         if len(paths) == 0:
       
  1049             return None
  1025         if len(paths) > 1:
  1050         if len(paths) > 1:
  1026             factorized_paths = self.FactorizePaths(paths)
  1051             factorized_paths = self.FactorizePaths(paths)
  1027             if len(factorized_paths) > 1:
  1052             if len(factorized_paths) > 1:
  1028                 paths = tuple(factorized_paths)
  1053                 paths = tuple(factorized_paths)
  1029             else:
  1054             else:
  1243                         if isinstance(instance, plcopen.fbdObjects_outVariable) and instance.getexpression() == transitionValues["value"]\
  1268                         if isinstance(instance, plcopen.fbdObjects_outVariable) and instance.getexpression() == transitionValues["value"]\
  1244                             or isinstance(instance, plcopen.ldObjects_coil) and instance.getvariable() == transitionValues["value"]:
  1269                             or isinstance(instance, plcopen.ldObjects_coil) and instance.getvariable() == transitionValues["value"]:
  1245                             connections = instance.connectionPointIn.getconnections()
  1270                             connections = instance.connectionPointIn.getconnections()
  1246                             if connections is not None:
  1271                             if connections is not None:
  1247                                 expression = self.ComputeExpression(transitionBody, connections)
  1272                                 expression = self.ComputeExpression(transitionBody, connections)
  1248                                 transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1273                                 if expression is not None:
  1249                                 self.SFCComputedBlocks += self.Program
  1274                                     transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1250                                 self.Program = []
  1275                                     self.SFCComputedBlocks += self.Program
       
  1276                                     self.Program = []
  1251                     if not transition_infos.has_key("content"):
  1277                     if not transition_infos.has_key("content"):
  1252                         raise PLCGenException, _("Transition \"%s\" body must contain an output variable or coil referring to its name") % transitionValues["value"]
  1278                         raise PLCGenException, _("Transition \"%s\" body must contain an output variable or coil referring to its name") % transitionValues["value"]
  1253                 self.TagName = previous_tagname
  1279                 self.TagName = previous_tagname
  1254             elif transitionValues["type"] == "connection":
  1280             elif transitionValues["type"] == "connection":
  1255                 body = pou.getbody()
  1281                 body = pou.getbody()
  1256                 if isinstance(body, ListType):
  1282                 if isinstance(body, ListType):
  1257                     body = body[0]
  1283                     body = body[0]
  1258                 connections = transition.getconnections()
  1284                 connections = transition.getconnections()
  1259                 if connections is not None:
  1285                 if connections is not None:
  1260                     expression = self.ComputeExpression(body, connections)
  1286                     expression = self.ComputeExpression(body, connections)
  1261                     transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1287                     if expression is not None:
  1262                     self.SFCComputedBlocks += self.Program
  1288                         transition_infos["content"] = [("\n%s:= "%self.CurrentIndent, ())] + expression + [(";\n", ())]
  1263                     self.Program = []
  1289                         self.SFCComputedBlocks += self.Program
       
  1290                         self.Program = []
  1264             for step in steps:
  1291             for step in steps:
  1265                 self.GenerateSFCStep(step, pou)
  1292                 self.GenerateSFCStep(step, pou)
  1266                 step_name = step.getname()
  1293                 step_name = step.getname()
  1267                 if step_name in self.SFCNetworks["Steps"].keys():
  1294                 if step_name in self.SFCNetworks["Steps"].keys():
  1268                     transition_infos["from"].append([(step_name, (self.TagName, "transition", transition.getlocalId(), "from", step.getlocalId()))])
  1295                     transition_infos["from"].append([(step_name, (self.TagName, "transition", transition.getlocalId(), "from", step.getlocalId()))])