Fix bug in ST code generated for in-out variables in Function and FunctionBlock interface
authorLaurent Bessard
Sun, 02 Sep 2012 01:18:50 +0200
changeset 754 48966b6ceedc
parent 753 8a70e85f7e12
child 755 1d77d700761f
Fix bug in ST code generated for in-out variables in Function and FunctionBlock interface
PLCGenerator.py
plcopen/structures.py
--- a/PLCGenerator.py	Wed Aug 29 23:02:04 2012 +0200
+++ b/PLCGenerator.py	Sun Sep 02 01:18:50 2012 +0200
@@ -905,7 +905,7 @@
         factorized_paths.sort()
         return factorized_paths
 
-    def GeneratePaths(self, connections, body, order = False):
+    def GeneratePaths(self, connections, body, order = False, to_inout = False):
         paths = []
         for connection in connections:
             localId = connection.getrefLocalId()
@@ -922,7 +922,7 @@
                     block_infos = self.GetBlockType(block_type)
                 if block_infos is None:
                     raise PLCGenException, _("Undefined block type \"%s\" in \"%s\" POU")%(block_type, self.Name)
-                paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order)))
+                paths.append(str(block_infos["generate"](self, next, block_infos, body, connection, order, to_inout)))
             elif isinstance(next, plcopen.commonObjects_continuation):
                 name = next.getname()
                 computed_value = self.ComputedConnectors.get(name, None)
@@ -981,8 +981,8 @@
         else:
             return eval(paths)
 
-    def ComputeExpression(self, body, connections, order = False):
-        paths = self.GeneratePaths(connections, body, order)
+    def ComputeExpression(self, body, connections, order = False, to_inout = False):
+        paths = self.GeneratePaths(connections, body, order, to_inout)
         if len(paths) > 1:
             factorized_paths = self.FactorizePaths(paths)
             if len(factorized_paths) > 1:
--- a/plcopen/structures.py	Wed Aug 29 23:02:04 2012 +0200
+++ b/plcopen/structures.py	Sun Sep 02 01:18:50 2012 +0200
@@ -42,11 +42,16 @@
     else :
         return mylist
 
-def generate_block(generator, block, block_infos, body, link, order=False):
+def generate_block(generator, block, block_infos, body, link, order=False, to_inout=False):
     body_type = body.getcontent()["name"]
     name = block.getinstanceName()
     type = block.gettypeName()
     executionOrderId = block.getexecutionOrderId()
+    inout_variables = {}
+    for input_variable in block.inputVariables.getvariable():
+        for output_variable in block.outputVariables.getvariable():
+            if input_variable.getformalParameter() == output_variable.getformalParameter():
+                inout_variables[input_variable.getformalParameter()] = ""
     if block_infos["type"] == "function":
         output_variables = block.outputVariables.getvariable()
         if not generator.ComputedBlocks.get(block, False) and not order:
@@ -60,7 +65,11 @@
                     parameter = variable.getformalParameter()
                     if parameter != "EN":
                         one_input_connected = True
-                    value = generator.ComputeExpression(body, connections, executionOrderId > 0)
+                    if inout_variables.has_key(parameter):
+                        value = generator.ComputeExpression(body, connections, executionOrderId > 0, True)
+                        inout_variables[parameter] = value
+                    else:
+                        value = generator.ComputeExpression(body, connections, executionOrderId > 0)
                     if len(output_variables) > 1:
                         vars.append([(parameter, input_info),
                                      (" := ", ())] + generator.ExtractModifier(variable, value, input_info))
@@ -69,22 +78,23 @@
             if one_input_connected:
                 for i, variable in enumerate(output_variables):
                     parameter = variable.getformalParameter()
-                    if variable.getformalParameter() == "":
-                        variable_name = "%s%d"%(type, block.getlocalId())
-                    else:
-                        variable_name = "%s%d_%s"%(type, block.getlocalId(), parameter)
-                    if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] is not None or generator.Interface[-1][2]:
-                        generator.Interface.append(("VAR", None, False, []))
-                    if variable.connectionPointOut in generator.ConnectionTypes:
-                        generator.Interface[-1][3].append((generator.ConnectionTypes[variable.connectionPointOut], variable_name, None, None))
-                    else:
-                        generator.Interface[-1][3].append(("ANY", variable_name, None, None))
-                    if len(output_variables) > 1 and parameter not in ["", "OUT"]:
-                        vars.append([(parameter, (generator.TagName, "block", block.getlocalId(), "output", i)), 
-                                     (" => %s"%variable_name, ())])
-                    else:
-                        output_info = (generator.TagName, "block", block.getlocalId(), "output", i)
-                        output_name = variable_name
+                    if not inout_variables.has_key(parameter):
+                        if variable.getformalParameter() == "":
+                            variable_name = "%s%d"%(type, block.getlocalId())
+                        else:
+                            variable_name = "%s%d_%s"%(type, block.getlocalId(), parameter)
+                        if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] is not None or generator.Interface[-1][2]:
+                            generator.Interface.append(("VAR", None, False, []))
+                        if variable.connectionPointOut in generator.ConnectionTypes:
+                            generator.Interface[-1][3].append((generator.ConnectionTypes[variable.connectionPointOut], variable_name, None, None))
+                        else:
+                            generator.Interface[-1][3].append(("ANY", variable_name, None, None))
+                        if len(output_variables) > 1 and parameter not in ["", "OUT"]:
+                            vars.append([(parameter, (generator.TagName, "block", block.getlocalId(), "output", i)), 
+                                         (" => %s"%variable_name, ())])
+                        else:
+                            output_info = (generator.TagName, "block", block.getlocalId(), "output", i)
+                            output_name = variable_name
                 generator.Program += [(generator.CurrentIndent, ()),
                                       (output_name, output_info),
                                       (" := ", ()),
@@ -102,12 +112,16 @@
             blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
             if not connectionPoint or block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety():
                 output_info = (generator.TagName, "block", block.getlocalId(), "output", i)
-                output_name = variable.getformalParameter()
-                if variable.getformalParameter() == "":
-                    output_name = "%s%d"%(type, block.getlocalId())
+                parameter = variable.getformalParameter()
+                if inout_variables.has_key(parameter):
+                    output_value = inout_variables[parameter]
                 else:
-                    output_name = "%s%d_%s"%(type, block.getlocalId(), variable.getformalParameter())
-                return generator.ExtractModifier(variable, [(output_name, output_info)], output_info)
+                    if parameter == "":
+                        output_name = "%s%d"%(type, block.getlocalId())
+                    else:
+                        output_name = "%s%d_%s"%(type, block.getlocalId(), parameter)
+                    output_value = [(output_name, output_info)]
+                return generator.ExtractModifier(variable, output_value, output_info)
     elif block_infos["type"] == "functionBlock":
         if not generator.ComputedBlocks.get(block, False) and not order:
             generator.ComputedBlocks[block] = True
@@ -117,7 +131,7 @@
                 connections = variable.connectionPointIn.getconnections()
                 if connections is not None:
                     parameter = variable.getformalParameter()
-                    value = generator.ComputeExpression(body, connections, executionOrderId > 0)
+                    value = generator.ComputeExpression(body, connections, executionOrderId > 0, inout_variables.has_key(parameter))
                     vars.append([(parameter, input_info),
                                  (" := ", ())] + generator.ExtractModifier(variable, value, input_info))
             generator.Program += [(generator.CurrentIndent, ()), 
@@ -133,7 +147,22 @@
             blockPointx, blockPointy = variable.connectionPointOut.getrelPositionXY()
             if not connectionPoint or block.getx() + blockPointx == connectionPoint.getx() and block.gety() + blockPointy == connectionPoint.gety():
                 output_info = (generator.TagName, "block", block.getlocalId(), "output", i)
-                return generator.ExtractModifier(variable, [("%s.%s"%(name, variable.getformalParameter()), output_info)], output_info)
+                output_name = generator.ExtractModifier(variable, [("%s.%s"%(name, variable.getformalParameter()), output_info)], output_info)
+                if to_inout:
+                    variable_name = "%s_%s"%(name, variable.getformalParameter())
+                    if not generator.IsAlreadyDefined(variable_name):
+                        if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] is not None or generator.Interface[-1][2]:
+                            generator.Interface.append(("VAR", None, False, []))
+                        if variable.connectionPointOut in generator.ConnectionTypes:
+                            generator.Interface[-1][3].append((generator.ConnectionTypes[variable.connectionPointOut], variable_name, None, None))
+                        else:
+                            generator.Interface[-1][3].append(("ANY", variable_name, None, None))
+                        generator.Program += [(generator.CurrentIndent, ()),
+                                              ("%s := "%variable_name, ())]
+                        generator.Program += output_name
+                        generator.Program += [(";\n", ())]
+                    return [(variable_name, ())]
+                return output_name 
     if link is not None:
         raise ValueError, _("No output variable found")