142 Ordored list of common data types defined in the IEC 61131-3 |
144 Ordored list of common data types defined in the IEC 61131-3 |
143 Each type is associated to his direct parent type. It defines then a hierarchy |
145 Each type is associated to his direct parent type. It defines then a hierarchy |
144 between type that permits to make a comparison of two types |
146 between type that permits to make a comparison of two types |
145 """ |
147 """ |
146 TypeHierarchy_list = [ |
148 TypeHierarchy_list = [ |
147 ("ANY" , None), |
149 ("ANY", None), |
148 ("ANY_DERIVED" , "ANY"), |
150 ("ANY_DERIVED", "ANY"), |
149 ("ANY_ELEMENTARY" , "ANY"), |
151 ("ANY_ELEMENTARY", "ANY"), |
150 ("ANY_MAGNITUDE", "ANY_ELEMENTARY"), |
152 ("ANY_MAGNITUDE", "ANY_ELEMENTARY"), |
151 ("ANY_BIT" , "ANY_ELEMENTARY"), |
153 ("ANY_BIT", "ANY_ELEMENTARY"), |
152 ("ANY_STRING" , "ANY_ELEMENTARY"), |
154 ("ANY_STRING", "ANY_ELEMENTARY"), |
153 ("ANY_DATE" , "ANY_ELEMENTARY"), |
155 ("ANY_DATE", "ANY_ELEMENTARY"), |
154 ("ANY_NUM" , "ANY_MAGNITUDE"), |
156 ("ANY_NUM", "ANY_MAGNITUDE"), |
155 ("ANY_REAL" , "ANY_NUM"), |
157 ("ANY_REAL", "ANY_NUM"), |
156 ("ANY_INT" , "ANY_NUM"), |
158 ("ANY_INT", "ANY_NUM"), |
157 ("REAL" , "ANY_REAL"), |
159 ("REAL", "ANY_REAL"), |
158 ("LREAL" , "ANY_REAL"), |
160 ("LREAL", "ANY_REAL"), |
159 ("SINT" , "ANY_INT"), |
161 ("SINT", "ANY_INT"), |
160 ("INT" , "ANY_INT"), |
162 ("INT", "ANY_INT"), |
161 ("DINT" , "ANY_INT"), |
163 ("DINT", "ANY_INT"), |
162 ("LINT" , "ANY_INT"), |
164 ("LINT", "ANY_INT"), |
163 ("USINT" , "ANY_INT"), |
165 ("USINT", "ANY_INT"), |
164 ("UINT" , "ANY_INT"), |
166 ("UINT", "ANY_INT"), |
165 ("UDINT" , "ANY_INT"), |
167 ("UDINT", "ANY_INT"), |
166 ("ULINT" , "ANY_INT"), |
168 ("ULINT", "ANY_INT"), |
167 ("TIME" , "ANY_MAGNITUDE"), |
169 ("TIME", "ANY_MAGNITUDE"), |
168 ("BOOL" , "ANY_BIT"), |
170 ("BOOL", "ANY_BIT"), |
169 ("BYTE" , "ANY_BIT"), |
171 ("BYTE", "ANY_BIT"), |
170 ("WORD" , "ANY_BIT"), |
172 ("WORD", "ANY_BIT"), |
171 ("DWORD" , "ANY_BIT"), |
173 ("DWORD", "ANY_BIT"), |
172 ("LWORD" , "ANY_BIT"), |
174 ("LWORD", "ANY_BIT"), |
173 ("STRING" , "ANY_STRING"), |
175 ("STRING", "ANY_STRING"), |
174 ("WSTRING" , "ANY_STRING"), |
176 ("WSTRING", "ANY_STRING"), |
175 ("DATE" , "ANY_DATE"), |
177 ("DATE", "ANY_DATE"), |
176 ("TOD" , "ANY_DATE"), |
178 ("TOD", "ANY_DATE"), |
177 ("DT" , "ANY_DATE")] |
179 ("DT", "ANY_DATE")] |
178 |
180 |
179 TypeHierarchy = dict(TypeHierarchy_list) |
181 TypeHierarchy = dict(TypeHierarchy_list) |
180 |
182 |
181 """ |
183 """ |
182 returns true if the given data type is the same that "reference" meta-type or one of its types. |
184 returns true if the given data type is the same that "reference" meta-type or one of its types. |
194 """ |
196 """ |
195 def GetSubTypes(reference): |
197 def GetSubTypes(reference): |
196 return [ typename for typename in TypeHierarchy.iterkeys() if typename[:3] != "ANY" and IsOfType(typename, reference)] |
198 return [ typename for typename in TypeHierarchy.iterkeys() if typename[:3] != "ANY" and IsOfType(typename, reference)] |
197 |
199 |
198 |
200 |
199 def IsATime(iectype): |
201 #------------------------------------------------------------------------------- |
200 return IsOfType(iectype, TIME) or IsOfType(iectype, ANY_DATE) |
202 # Test identifier |
|
203 #------------------------------------------------------------------------------- |
|
204 |
|
205 |
|
206 |
|
207 # Test if identifier is valid |
|
208 def TestIdentifier(identifier): |
|
209 if identifier[0].isdigit(): |
|
210 return False |
|
211 words = identifier.split('_') |
|
212 for i, word in enumerate(words): |
|
213 if len(word) == 0 and i != 0: |
|
214 return False |
|
215 if len(word) != 0 and not word.isalnum(): |
|
216 return False |
|
217 return True |
|
218 |
|
219 |
|
220 #------------------------------------------------------------------------------- |
|
221 # Languages Keywords |
|
222 #------------------------------------------------------------------------------- |
|
223 |
|
224 |
|
225 # Keywords for Pou Declaration |
|
226 POU_KEYWORDS = ["FUNCTION", "END_FUNCTION", "FUNCTION_BLOCK", "END_FUNCTION_BLOCK", |
|
227 "PROGRAM", "END_PROGRAM", "EN", "ENO", "F_EDGE", "R_EDGE"] |
|
228 for category in BlockTypes: |
|
229 for block in category["list"]: |
|
230 if block["name"] not in POU_KEYWORDS: |
|
231 POU_KEYWORDS.append(block["name"]) |
|
232 |
|
233 |
|
234 # Keywords for Type Declaration |
|
235 TYPE_KEYWORDS = ["TYPE", "END_TYPE", "STRUCT", "END_STRUCT", "ARRAY", "OF", "T", |
|
236 "D", "TIME_OF_DAY", "DATE_AND_TIME"] |
|
237 TYPE_KEYWORDS.extend([keyword for keyword in TypeHierarchy.keys() if keyword not in TYPE_KEYWORDS]) |
|
238 |
|
239 |
|
240 # Keywords for Variable Declaration |
|
241 VAR_KEYWORDS = ["VAR", "VAR_INPUT", "VAR_OUTPUT", "VAR_IN_OUT", "VAR_TEMP", |
|
242 "VAR_EXTERNAL", "END_VAR", "AT", "CONSTANT", "RETAIN", "NON_RETAIN"] |
|
243 |
|
244 |
|
245 # Keywords for Configuration Declaration |
|
246 CONFIG_KEYWORDS = ["CONFIGURATION", "END_CONFIGURATION", "RESOURCE", "ON", "END_RESOURCE", |
|
247 "PROGRAM", "WITH", "READ_ONLY", "READ_WRITE", "TASK", "VAR_ACCESS", "VAR_CONFIG", |
|
248 "VAR_GLOBAL", "END_VAR"] |
|
249 |
|
250 |
|
251 # Keywords for Structured Function Chart |
|
252 SFC_KEYWORDS = ["ACTION", "END_ACTION", "INITIAL_STEP", "STEP", "END_STEP", "TRANSITION", |
|
253 "FROM", "TO", "END_TRANSITION"] |
|
254 |
|
255 |
|
256 # Keywords for Instruction List |
|
257 IL_KEYWORDS = ["LD", "LDN", "ST", "STN", "S", "R", "AND", "ANDN", "OR", "ORN", |
|
258 "XOR", "XORN", "NOT", "ADD", "SUB", "MUL", "DIV", "MOD", "GT", "GE", "EQ", "NE", |
|
259 "LE", "LT", "JMP", "JMPC", "JMPNC", "CAL", "CALC", "CALNC", "RET", "RETC", "RETNC"] |
|
260 |
|
261 |
|
262 # Keywords for Instruction List and Structured Text |
|
263 ST_KEYWORDS = ["IF", "THEN", "ELSIF", "ELSE", "END_IF", "CASE", "OF", "END_CASE", |
|
264 "FOR", "TO", "BY", "DO", "END_FOR", "WHILE", "DO", "END_WHILE", "REPEAT", "UNTIL", |
|
265 "END_REPEAT", "EXIT", "RETURN", "NOT", "MOD", "AND", "XOR", "OR"] |
|
266 |
|
267 |
|
268 # All the keywords of IEC |
|
269 IEC_KEYWORDS = ["E", "TRUE", "FALSE"] |
|
270 IEC_KEYWORDS.extend([keyword for keyword in POU_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
271 IEC_KEYWORDS.extend([keyword for keyword in TYPE_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
272 IEC_KEYWORDS.extend([keyword for keyword in VAR_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
273 IEC_KEYWORDS.extend([keyword for keyword in CONFIG_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
274 IEC_KEYWORDS.extend([keyword for keyword in SFC_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
275 IEC_KEYWORDS.extend([keyword for keyword in IL_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
276 IEC_KEYWORDS.extend([keyword for keyword in ST_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
277 |
201 |
278 |
202 |
279 |
203 """ |
280 """ |
204 take a .csv file and translate it it a "csv_table" |
281 take a .csv file and translate it it a "csv_table" |
205 """ |
282 """ |
409 |
486 |
410 Standard_Functions_Decl.append(Current_section) |
487 Standard_Functions_Decl.append(Current_section) |
411 |
488 |
412 return Standard_Functions_Decl |
489 return Standard_Functions_Decl |
413 |
490 |
414 #------------------------------------------------------------------------------- |
|
415 # Test identifier |
|
416 #------------------------------------------------------------------------------- |
|
417 |
|
418 |
|
419 |
|
420 # Test if identifier is valid |
|
421 def TestIdentifier(identifier): |
|
422 if identifier[0].isdigit(): |
|
423 return False |
|
424 words = identifier.split('_') |
|
425 for i, word in enumerate(words): |
|
426 if len(word) == 0 and i != 0: |
|
427 return False |
|
428 if len(word) != 0 and not word.isalnum(): |
|
429 return False |
|
430 return True |
|
431 |
|
432 #------------------------------------------------------------------------------- |
|
433 # Languages Keywords |
|
434 #------------------------------------------------------------------------------- |
|
435 |
|
436 |
|
437 |
|
438 # Keywords for Pou Declaration |
|
439 POU_KEYWORDS = ["FUNCTION", "END_FUNCTION", "FUNCTION_BLOCK", "END_FUNCTION_BLOCK", |
|
440 "PROGRAM", "END_PROGRAM", "EN", "ENO", "F_EDGE", "R_EDGE"] |
|
441 for category in BlockTypes: |
|
442 for block in category["list"]: |
|
443 if block["name"] not in POU_KEYWORDS: |
|
444 POU_KEYWORDS.append(block["name"]) |
|
445 |
|
446 |
|
447 # Keywords for Type Declaration |
|
448 TYPE_KEYWORDS = ["TYPE", "END_TYPE", "STRUCT", "END_STRUCT", "ARRAY", "OF", "T", |
|
449 "D", "TIME_OF_DAY", "DATE_AND_TIME"] |
|
450 TYPE_KEYWORDS.extend([keyword for keyword in TypeHierarchy.keys() if keyword not in TYPE_KEYWORDS]) |
|
451 |
|
452 |
|
453 # Keywords for Variable Declaration |
|
454 VAR_KEYWORDS = ["VAR", "VAR_INPUT", "VAR_OUTPUT", "VAR_IN_OUT", "VAR_TEMP", |
|
455 "VAR_EXTERNAL", "END_VAR", "AT", "CONSTANT", "RETAIN", "NON_RETAIN"] |
|
456 |
|
457 |
|
458 # Keywords for Configuration Declaration |
|
459 CONFIG_KEYWORDS = ["CONFIGURATION", "END_CONFIGURATION", "RESOURCE", "ON", "END_RESOURCE", |
|
460 "PROGRAM", "WITH", "READ_ONLY", "READ_WRITE", "TASK", "VAR_ACCESS", "VAR_CONFIG", |
|
461 "VAR_GLOBAL", "END_VAR"] |
|
462 |
|
463 |
|
464 # Keywords for Structured Function Chart |
|
465 SFC_KEYWORDS = ["ACTION", "END_ACTION", "INITIAL_STEP", "STEP", "END_STEP", "TRANSITION", |
|
466 "FROM", "TO", "END_TRANSITION"] |
|
467 |
|
468 |
|
469 # Keywords for Instruction List |
|
470 IL_KEYWORDS = ["LD", "LDN", "ST", "STN", "S", "R", "AND", "ANDN", "OR", "ORN", |
|
471 "XOR", "XORN", "NOT", "ADD", "SUB", "MUL", "DIV", "MOD", "GT", "GE", "EQ", "NE", |
|
472 "LE", "LT", "JMP", "JMPC", "JMPNC", "CAL", "CALC", "CALNC", "RET", "RETC", "RETNC"] |
|
473 |
|
474 |
|
475 # Keywords for Instruction List and Structured Text |
|
476 ST_KEYWORDS = ["IF", "THEN", "ELSIF", "ELSE", "END_IF", "CASE", "OF", "END_CASE", |
|
477 "FOR", "TO", "BY", "DO", "END_FOR", "WHILE", "DO", "END_WHILE", "REPEAT", "UNTIL", |
|
478 "END_REPEAT", "EXIT", "RETURN", "NOT", "MOD", "AND", "XOR", "OR"] |
|
479 |
|
480 |
|
481 # All the keywords of IEC |
|
482 IEC_KEYWORDS = ["E", "TRUE", "FALSE"] |
|
483 IEC_KEYWORDS.extend([keyword for keyword in POU_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
484 IEC_KEYWORDS.extend([keyword for keyword in TYPE_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
485 IEC_KEYWORDS.extend([keyword for keyword in VAR_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
486 IEC_KEYWORDS.extend([keyword for keyword in CONFIG_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
487 IEC_KEYWORDS.extend([keyword for keyword in SFC_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
488 IEC_KEYWORDS.extend([keyword for keyword in IL_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
489 IEC_KEYWORDS.extend([keyword for keyword in ST_KEYWORDS if keyword not in IEC_KEYWORDS]) |
|
490 |
491 |
491 if __name__ == '__main__': |
492 if __name__ == '__main__': |
492 |
493 |
493 import pprint |
494 import pprint |
494 pp = pprint.PrettyPrinter(indent=4) |
495 pp = pprint.PrettyPrinter(indent=4) |
495 |
496 |
496 def ANY_to_compiler_test_type_GEN(typename, paramname): |
497 def ANY_to_compiler_test_type_GEN(typename, paramname): |
497 return {"ANY" : "", |
498 return {"ANY" : "", |
498 "ANY_BIT" : "if(search_expression_type->is_binary_type(%(paramname)s_param_value))", |
499 "ANY_BIT" : "if(search_expression_type->is_binary_type(%(paramname)s_type_symbol))", |
499 "ANY_NUM" : "if(search_expression_type->is_num_type(%(paramname)s_param_value))", |
500 "ANY_NUM" : "if(search_expression_type->is_num_type(%(paramname)s_type_symbol))", |
500 "ANY_REAL" : "if(search_expression_type->is_real_type(%(paramname)s_param_value))", |
501 "ANY_REAL" : "if(search_expression_type->is_real_type(%(paramname)s_type_symbol))", |
501 "ANY_INT" : "if(search_expression_type->is_integer_type(%(paramname)s_param_value))" |
502 "ANY_INT" : "if(search_expression_type->is_integer_type(%(paramname)s_type_symbol))" |
502 }.get(typename, |
503 }.get(typename, |
503 "if (typeid(*last_type_symbol) == typeid(%(typename)s_type_name_c))")%{ |
504 "if (typeid(*last_type_symbol) == typeid(%(typename)s_type_name_c))")%{ |
504 "paramname" : paramname, "typename": typename.lower()} |
505 "paramname" : paramname, "typename": typename.lower()} |
505 |
506 |
506 def recurse_and_indent(fdecls, indent, do_type_search_only = False): |
507 def recurse_and_indent(fdecls, indent, do_type_search_only = False): |
557 for paramname,paramtype,unused in fdecl["inputs"]: |
558 for paramname,paramtype,unused in fdecl["inputs"]: |
558 code_gen_dic_decl[paramname+"_value"] = '");\n%s_param_value->accept(*this);\ns4o.print("'%(paramname) |
559 code_gen_dic_decl[paramname+"_value"] = '");\n%s_param_value->accept(*this);\ns4o.print("'%(paramname) |
559 code_gen_dic_decl[paramname+"_type"] = '");\n%s_type_symbol->accept(*this);\ns4o.print("'%(paramname) |
560 code_gen_dic_decl[paramname+"_type"] = '");\n%s_type_symbol->accept(*this);\ns4o.print("'%(paramname) |
560 code_gen_dic_decl["return_type"] = '");\nreturn_type_symbol->accept(*this);\ns4o.print("' |
561 code_gen_dic_decl["return_type"] = '");\nreturn_type_symbol->accept(*this);\ns4o.print("' |
561 code_gen_dic_decl["param_count"] = '");\ns4o.print_integer(nb_param);\ns4o.print("' |
562 code_gen_dic_decl["param_count"] = '");\ns4o.print_integer(nb_param);\ns4o.print("' |
562 |
563 code_gen_dic_decl["start_bool_filter"] = '");\nif (search_expression_type->is_bool_type(last_type_symbol))\n s4o.print("(' |
|
564 code_gen_dic_decl["end_bool_filter"] = '");\nif (search_expression_type->is_bool_type(last_type_symbol)) {\n s4o.print("&1");\n s4o.print(")");\n}\ns4o.print("' |
|
565 |
563 if type(code_gen) == type(tuple()): |
566 if type(code_gen) == type(tuple()): |
564 res += 's4o.print("%s");\n'%(code_gen[0]%code_gen_dic_decl) |
567 res += 's4o.print("%s");\n'%(code_gen[0]%code_gen_dic_decl) |
565 static_param_accept_list = [] |
568 static_param_accept_list = [] |
566 for paramname,paramtype,unused in fdecl["inputs"]: |
569 for paramname,paramtype,unused in fdecl["inputs"]: |
567 static_param_accept_list.append("%s_param_value->accept(*this);\n"%(paramname)) |
570 static_param_accept_list.append("%s_param_value->accept(*this);\n"%(paramname)) |
568 res += ('s4o.print("%s");\n'%(code_gen[1])).join(static_param_accept_list) |
571 res += ('s4o.print("%s");\n'%(code_gen[1])).join(static_param_accept_list) |
569 code = 's4o.print("%s");\nparam_value->accept(*this);\n'%(code_gen[1]) |
572 code = 's4o.print("%s");\nparam_value->accept(*this);\n'%(code_gen[1]) |
570 end_code = 's4o.print("%s");\nreturn NULL;\n'%(code_gen[2]) |
573 end_code = 's4o.print("%s");\nreturn NULL;\n'%(code_gen[2]%code_gen_dic_decl) |
571 else: |
574 else: |
572 code = '' |
575 code = '' |
573 end_code = ('s4o.print("' + code_gen%code_gen_dic_decl + '");\nreturn NULL;\n').replace('s4o.print("");\n','') |
576 end_code = ('s4o.print("' + code_gen%code_gen_dic_decl + '");\nreturn NULL;\n').replace('s4o.print("");\n','') |
574 |
577 |
575 if fdecl["extensible"]: |
578 if fdecl["extensible"]: |