plcopen/structures.py
changeset 125 394d9f168258
parent 109 734e02ab4018
child 151 aaa80b48bead
--- a/plcopen/structures.py	Tue Nov 27 12:58:34 2007 +0100
+++ b/plcopen/structures.py	Thu Dec 06 18:05:29 2007 +0100
@@ -33,38 +33,48 @@
                      "D" : ["DINT", "UDINT", "REAL", "DWORD"],
                      "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} 
 
-def generate_block(generator, block, body, link):
+def generate_block(generator, block, body, link, order=False):
     body_type = body.getContent()["name"]
     name = block.getInstanceName()
     type = block.getTypeName()
+    executionOrderId = block.getExecutionOrderId()
     block_infos = GetBlockType(type)
-    if block_infos["type"] == "function" and link:
-        generator.GeneratePouProgram(type)
-        vars = []
-        for variable in block.inputVariables.getVariable():
-            connections = variable.connectionPointIn.getConnections()
-            if connections and len(connections) == 1:
-                if body_type == "FBD" or body_type == "SFC":
-                    value = generator.ComputeFBDExpression(body, connections[0])
-                elif body_type == "LD":
-                    paths = generator.GenerateLDPaths(variable.connectionPointIn.getConnections(), body)
-                    if len(paths) > 0:
-                        paths = tuple(paths)
-                    else:
-                        paths = paths[0] 
-                    value = generator.ComputeLDExpression(paths, True)
-                vars.append(generator.ExtractModifier(variable, value))
-        variable = block.outputVariables.getVariable()[0]
-        return generator.ExtractModifier(variable, "%s(%s)"%(type, ", ".join(vars)))
+    if block_infos["type"] == "function":
+        output_variable = block.outputVariables.getVariable()[0]
+        output_name = "%s%d_OUT"%(type, block.getLocalId())
+        if not generator.ComputedBlocks.get(block, False) and not order:
+            if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] or generator.Interface[-1][2] or generator.Interface[-1][3]:
+                generator.Interface.append(("VAR", False, False, False, []))
+            if output_variable.connectionPointOut in generator.ConnectionTypes:
+                generator.Interface[-1][4].append((generator.ConnectionTypes[output_variable.connectionPointOut], output_name, None, None))
+            else:
+                generator.Interface[-1][4].append(("ANY", output_name, None, None))
+            vars = []
+            for variable in block.inputVariables.getVariable():
+                connections = variable.connectionPointIn.getConnections()
+                if connections and len(connections) == 1:
+                    if body_type == "FBD" or body_type == "SFC":
+                        value = generator.ComputeFBDExpression(body, connections[0], executionOrderId > 0)
+                    elif body_type == "LD":
+                        paths = generator.GenerateLDPaths(variable.connectionPointIn.getConnections(), body)
+                        if len(paths) > 0:
+                            paths = tuple(paths)
+                        else:
+                            paths = paths[0] 
+                        value = generator.ComputeLDExpression(paths, True)
+                    vars.append(generator.ExtractModifier(variable, value))
+            generator.Program += "  %s := %s(%s);\n"%(output_name, type, ", ".join(vars))
+            generator.ComputedBlocks[block] = True
+        return generator.ExtractModifier(output_variable, output_name)
     elif block_infos["type"] == "functionBlock":
-        if not generator.ComputedBlocks.get(name, False):
+        if not generator.ComputedBlocks.get(block, False) and not order:
             vars = []
             for variable in block.inputVariables.getVariable():
                 connections = variable.connectionPointIn.getConnections()
                 if connections and len(connections) == 1:
                     parameter = variable.getFormalParameter()
                     if body_type == "FBD" or body_type == "SFC":
-                        value = generator.ComputeFBDExpression(body, connections[0])
+                        value = generator.ComputeFBDExpression(body, connections[0], executionOrderId > 0)
                         vars.append("%s := %s"%(parameter, generator.ExtractModifier(variable, value)))
                     elif body_type == "LD":
                         paths = generator.GenerateLDPaths(variable.connectionPointIn.getConnections(), body)
@@ -75,7 +85,7 @@
                         value = generator.ComputeLDExpression(paths, True)
                     vars.append("%s := %s"%(parameter, generator.ExtractModifier(variable, value)))
             generator.Program += "  %s(%s);\n"%(name, ", ".join(vars))
-            generator.ComputedBlocks[name] = True
+            generator.ComputedBlocks[block] = True
         if link:
             connectionPoint = link.getPosition()[-1]
         else:
@@ -281,6 +291,31 @@
 
 TypeHierarchy = dict(TypeHierarchy_list)
 
+def ResetTypeHierarchy():
+    TypeHierarchy = dict(TypeHierarchy_list)
+    
+def AddDataTypeHierarchy(name, reference):
+    TypeHierarchy[name] = reference
+
+DataTypeRange_list = [
+    ("SINT", (-2**7, 2**7 - 1)),
+    ("INT", (-2**15, 2**15 - 1)),
+    ("DINT", (-2**31, 2**31 - 1)),
+    ("LINT", (-2**31, 2**31 - 1)),
+    ("USINT", (0, 2**8 - 1)),
+    ("UINT", (0, 2**16 - 1)),
+    ("UDINT", (0, 2**31 - 1)),
+    ("ULINT", (0, 2**31 - 1))
+]
+
+DataTypeRange = dict(DataTypeRange_list)
+
+def ResetDataTypeRange():
+    DataTypeRange = dict(DataTypeRange_list)
+    
+def AddDataTypeRange(name, range):
+    DataTypeRange[name] = range
+
 """
 returns true if the given data type is the same that "reference" meta-type or one of its types.
 """
@@ -296,16 +331,32 @@
 
 def IsEndType(reference):
     if reference is not None:
-        return len([typename for typename, parenttype in TypeHierarchy_list if parenttype == reference]) == 0
+        return not reference.startswith("ANY")
     else:
         return True
 
+def GetDataTypeRange(reference):
+    while reference is not None:
+        if reference in DataTypeRange:
+            return DataTypeRange[reference]
+        else:
+            reference = TypeHierarchy[reference]
+    return None
+
 """
 returns list of all types that correspont to the ANY* meta type
 """
 def GetSubTypes(reference):
-    return [typename for typename, parenttype in TypeHierarchy_list if typename[:3] != "ANY" and IsOfType(typename, reference)]
-
+    return [typename for typename, parenttype in TypeHierarchy.items() if not typename.startswith("ANY") and IsOfType(typename, reference)]
+
+
+EnumeratedDataValues = []
+
+def ResetEnumeratedDataValues():
+    EnumeratedDataValues = []
+    
+def AddEnumeratedDataValues(values):
+    EnumeratedDataValues.extend(values)
 
 #-------------------------------------------------------------------------------
 #                             Test identifier
@@ -489,7 +540,7 @@
                 else:
                     input_ovrloading_types = [None]
                     output_types = [None]
-                    
+                
                 funcdeclname_orig = Function_decl["name"]
                 funcdeclname = Function_decl["name"].strip('*_')
                 fdc = Function_decl["inputs"][:]