31 "B" : ["SINT", "USINT", "BYTE", "STRING"], |
31 "B" : ["SINT", "USINT", "BYTE", "STRING"], |
32 "W" : ["INT", "UINT", "WORD", "WSTRING"], |
32 "W" : ["INT", "UINT", "WORD", "WSTRING"], |
33 "D" : ["DINT", "UDINT", "REAL", "DWORD"], |
33 "D" : ["DINT", "UDINT", "REAL", "DWORD"], |
34 "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} |
34 "L" : ["LINT", "ULINT", "LREAL", "LWORD"]} |
35 |
35 |
36 def generate_block(generator, block, body, link): |
36 def generate_block(generator, block, body, link, order=False): |
37 body_type = body.getContent()["name"] |
37 body_type = body.getContent()["name"] |
38 name = block.getInstanceName() |
38 name = block.getInstanceName() |
39 type = block.getTypeName() |
39 type = block.getTypeName() |
|
40 executionOrderId = block.getExecutionOrderId() |
40 block_infos = GetBlockType(type) |
41 block_infos = GetBlockType(type) |
41 if block_infos["type"] == "function" and link: |
42 if block_infos["type"] == "function": |
42 generator.GeneratePouProgram(type) |
43 output_variable = block.outputVariables.getVariable()[0] |
43 vars = [] |
44 output_name = "%s%d_OUT"%(type, block.getLocalId()) |
44 for variable in block.inputVariables.getVariable(): |
45 if not generator.ComputedBlocks.get(block, False) and not order: |
45 connections = variable.connectionPointIn.getConnections() |
46 if generator.Interface[-1][0] != "VAR" or generator.Interface[-1][1] or generator.Interface[-1][2] or generator.Interface[-1][3]: |
46 if connections and len(connections) == 1: |
47 generator.Interface.append(("VAR", False, False, False, [])) |
47 if body_type == "FBD" or body_type == "SFC": |
48 if output_variable.connectionPointOut in generator.ConnectionTypes: |
48 value = generator.ComputeFBDExpression(body, connections[0]) |
49 generator.Interface[-1][4].append((generator.ConnectionTypes[output_variable.connectionPointOut], output_name, None, None)) |
49 elif body_type == "LD": |
50 else: |
50 paths = generator.GenerateLDPaths(variable.connectionPointIn.getConnections(), body) |
51 generator.Interface[-1][4].append(("ANY", output_name, None, None)) |
51 if len(paths) > 0: |
52 vars = [] |
52 paths = tuple(paths) |
53 for variable in block.inputVariables.getVariable(): |
53 else: |
54 connections = variable.connectionPointIn.getConnections() |
54 paths = paths[0] |
55 if connections and len(connections) == 1: |
55 value = generator.ComputeLDExpression(paths, True) |
56 if body_type == "FBD" or body_type == "SFC": |
56 vars.append(generator.ExtractModifier(variable, value)) |
57 value = generator.ComputeFBDExpression(body, connections[0], executionOrderId > 0) |
57 variable = block.outputVariables.getVariable()[0] |
58 elif body_type == "LD": |
58 return generator.ExtractModifier(variable, "%s(%s)"%(type, ", ".join(vars))) |
59 paths = generator.GenerateLDPaths(variable.connectionPointIn.getConnections(), body) |
|
60 if len(paths) > 0: |
|
61 paths = tuple(paths) |
|
62 else: |
|
63 paths = paths[0] |
|
64 value = generator.ComputeLDExpression(paths, True) |
|
65 vars.append(generator.ExtractModifier(variable, value)) |
|
66 generator.Program += " %s := %s(%s);\n"%(output_name, type, ", ".join(vars)) |
|
67 generator.ComputedBlocks[block] = True |
|
68 return generator.ExtractModifier(output_variable, output_name) |
59 elif block_infos["type"] == "functionBlock": |
69 elif block_infos["type"] == "functionBlock": |
60 if not generator.ComputedBlocks.get(name, False): |
70 if not generator.ComputedBlocks.get(block, False) and not order: |
61 vars = [] |
71 vars = [] |
62 for variable in block.inputVariables.getVariable(): |
72 for variable in block.inputVariables.getVariable(): |
63 connections = variable.connectionPointIn.getConnections() |
73 connections = variable.connectionPointIn.getConnections() |
64 if connections and len(connections) == 1: |
74 if connections and len(connections) == 1: |
65 parameter = variable.getFormalParameter() |
75 parameter = variable.getFormalParameter() |
66 if body_type == "FBD" or body_type == "SFC": |
76 if body_type == "FBD" or body_type == "SFC": |
67 value = generator.ComputeFBDExpression(body, connections[0]) |
77 value = generator.ComputeFBDExpression(body, connections[0], executionOrderId > 0) |
68 vars.append("%s := %s"%(parameter, generator.ExtractModifier(variable, value))) |
78 vars.append("%s := %s"%(parameter, generator.ExtractModifier(variable, value))) |
69 elif body_type == "LD": |
79 elif body_type == "LD": |
70 paths = generator.GenerateLDPaths(variable.connectionPointIn.getConnections(), body) |
80 paths = generator.GenerateLDPaths(variable.connectionPointIn.getConnections(), body) |
71 if len(paths) > 0: |
81 if len(paths) > 0: |
72 paths = tuple(paths) |
82 paths = tuple(paths) |
73 else: |
83 else: |
74 paths = paths[0] |
84 paths = paths[0] |
75 value = generator.ComputeLDExpression(paths, True) |
85 value = generator.ComputeLDExpression(paths, True) |
76 vars.append("%s := %s"%(parameter, generator.ExtractModifier(variable, value))) |
86 vars.append("%s := %s"%(parameter, generator.ExtractModifier(variable, value))) |
77 generator.Program += " %s(%s);\n"%(name, ", ".join(vars)) |
87 generator.Program += " %s(%s);\n"%(name, ", ".join(vars)) |
78 generator.ComputedBlocks[name] = True |
88 generator.ComputedBlocks[block] = True |
79 if link: |
89 if link: |
80 connectionPoint = link.getPosition()[-1] |
90 connectionPoint = link.getPosition()[-1] |
81 else: |
91 else: |
82 connectionPoint = None |
92 connectionPoint = None |
83 for variable in block.outputVariables.getVariable(): |
93 for variable in block.outputVariables.getVariable(): |
279 #("WSTRING", "ANY_STRING") # TODO |
289 #("WSTRING", "ANY_STRING") # TODO |
280 ] |
290 ] |
281 |
291 |
282 TypeHierarchy = dict(TypeHierarchy_list) |
292 TypeHierarchy = dict(TypeHierarchy_list) |
283 |
293 |
|
294 def ResetTypeHierarchy(): |
|
295 TypeHierarchy = dict(TypeHierarchy_list) |
|
296 |
|
297 def AddDataTypeHierarchy(name, reference): |
|
298 TypeHierarchy[name] = reference |
|
299 |
|
300 DataTypeRange_list = [ |
|
301 ("SINT", (-2**7, 2**7 - 1)), |
|
302 ("INT", (-2**15, 2**15 - 1)), |
|
303 ("DINT", (-2**31, 2**31 - 1)), |
|
304 ("LINT", (-2**31, 2**31 - 1)), |
|
305 ("USINT", (0, 2**8 - 1)), |
|
306 ("UINT", (0, 2**16 - 1)), |
|
307 ("UDINT", (0, 2**31 - 1)), |
|
308 ("ULINT", (0, 2**31 - 1)) |
|
309 ] |
|
310 |
|
311 DataTypeRange = dict(DataTypeRange_list) |
|
312 |
|
313 def ResetDataTypeRange(): |
|
314 DataTypeRange = dict(DataTypeRange_list) |
|
315 |
|
316 def AddDataTypeRange(name, range): |
|
317 DataTypeRange[name] = range |
|
318 |
284 """ |
319 """ |
285 returns true if the given data type is the same that "reference" meta-type or one of its types. |
320 returns true if the given data type is the same that "reference" meta-type or one of its types. |
286 """ |
321 """ |
287 |
322 |
288 def IsOfType(test, reference): |
323 def IsOfType(test, reference): |
294 test = TypeHierarchy[test] |
329 test = TypeHierarchy[test] |
295 return False |
330 return False |
296 |
331 |
297 def IsEndType(reference): |
332 def IsEndType(reference): |
298 if reference is not None: |
333 if reference is not None: |
299 return len([typename for typename, parenttype in TypeHierarchy_list if parenttype == reference]) == 0 |
334 return not reference.startswith("ANY") |
300 else: |
335 else: |
301 return True |
336 return True |
302 |
337 |
|
338 def GetDataTypeRange(reference): |
|
339 while reference is not None: |
|
340 if reference in DataTypeRange: |
|
341 return DataTypeRange[reference] |
|
342 else: |
|
343 reference = TypeHierarchy[reference] |
|
344 return None |
|
345 |
303 """ |
346 """ |
304 returns list of all types that correspont to the ANY* meta type |
347 returns list of all types that correspont to the ANY* meta type |
305 """ |
348 """ |
306 def GetSubTypes(reference): |
349 def GetSubTypes(reference): |
307 return [typename for typename, parenttype in TypeHierarchy_list if typename[:3] != "ANY" and IsOfType(typename, reference)] |
350 return [typename for typename, parenttype in TypeHierarchy.items() if not typename.startswith("ANY") and IsOfType(typename, reference)] |
308 |
351 |
|
352 |
|
353 EnumeratedDataValues = [] |
|
354 |
|
355 def ResetEnumeratedDataValues(): |
|
356 EnumeratedDataValues = [] |
|
357 |
|
358 def AddEnumeratedDataValues(values): |
|
359 EnumeratedDataValues.extend(values) |
309 |
360 |
310 #------------------------------------------------------------------------------- |
361 #------------------------------------------------------------------------------- |
311 # Test identifier |
362 # Test identifier |
312 #------------------------------------------------------------------------------- |
363 #------------------------------------------------------------------------------- |
313 |
364 |