plcopen/structures.py
changeset 21 e619d7bea692
parent 19 0b499416ebd7
child 22 a765fae3b361
equal deleted inserted replaced
20:1ac28118c322 21:e619d7bea692
    25 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    25 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    26 
    26 
    27 
    27 
    28 LANGUAGES = ["IL","ST","FBD","LD","SFC"]
    28 LANGUAGES = ["IL","ST","FBD","LD","SFC"]
    29 
    29 
       
    30 
    30 #-------------------------------------------------------------------------------
    31 #-------------------------------------------------------------------------------
    31 #                        Function Block Types definitions
    32 #                        Function Block Types definitions
    32 #-------------------------------------------------------------------------------
    33 #-------------------------------------------------------------------------------
       
    34 
    33 
    35 
    34 """
    36 """
    35 Ordored list of common Function Blocks defined in the IEC 61131-3
    37 Ordored list of common Function Blocks defined in the IEC 61131-3
    36 Each block have this attributes:
    38 Each block have this attributes:
    37     - "name" : The block name
    39     - "name" : The block name
   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"]: