plcopen/structures.py
changeset 25 8dc68e669d99
parent 23 cce8d5662738
child 27 dae55dd9ee14
equal deleted inserted replaced
24:364320323b4d 25:8dc68e669d99
   149     ("ANY", None),
   149     ("ANY", None),
   150     ("ANY_DERIVED", "ANY"),
   150     ("ANY_DERIVED", "ANY"),
   151     ("ANY_ELEMENTARY", "ANY"),
   151     ("ANY_ELEMENTARY", "ANY"),
   152     ("ANY_MAGNITUDE", "ANY_ELEMENTARY"),
   152     ("ANY_MAGNITUDE", "ANY_ELEMENTARY"),
   153     ("ANY_BIT", "ANY_ELEMENTARY"),
   153     ("ANY_BIT", "ANY_ELEMENTARY"),
       
   154     ("ANY_NBIT", "ANY_BIT"),
   154     ("ANY_STRING", "ANY_ELEMENTARY"),
   155     ("ANY_STRING", "ANY_ELEMENTARY"),
   155     ("ANY_DATE", "ANY_ELEMENTARY"),
   156     ("ANY_DATE", "ANY_ELEMENTARY"),
   156     ("ANY_NUM", "ANY_MAGNITUDE"),
   157     ("ANY_NUM", "ANY_MAGNITUDE"),
   157     ("ANY_REAL", "ANY_NUM"),
   158     ("ANY_REAL", "ANY_NUM"),
   158     ("ANY_INT", "ANY_NUM"),
   159     ("ANY_INT", "ANY_NUM"),
       
   160     ("ANY_SINT", "ANY_INT"),
       
   161     ("ANY_UINT", "ANY_INT"),
   159     ("REAL", "ANY_REAL"),
   162     ("REAL", "ANY_REAL"),
   160     ("LREAL", "ANY_REAL"),
   163     ("LREAL", "ANY_REAL"),
   161     ("SINT", "ANY_INT"),
   164     ("SINT", "ANY_SINT"),
   162     ("INT", "ANY_INT"),
   165     ("INT", "ANY_SINT"),
   163     ("DINT", "ANY_INT"),
   166     ("DINT", "ANY_SINT"),
   164     ("LINT", "ANY_INT"),
   167     ("LINT", "ANY_SINT"),
   165     ("USINT", "ANY_INT"),
   168     ("USINT", "ANY_UINT"),
   166     ("UINT", "ANY_INT"),
   169     ("UINT", "ANY_UINT"),
   167     ("UDINT", "ANY_INT"),
   170     ("UDINT", "ANY_UINT"),
   168     ("ULINT", "ANY_INT"),
   171     ("ULINT", "ANY_UINT"),
   169     ("TIME", "ANY_MAGNITUDE"),
   172     ("TIME", "ANY_MAGNITUDE"),
   170     ("BOOL", "ANY_BIT"),
   173     ("BOOL", "ANY_BIT"),
   171     ("BYTE", "ANY_BIT"),
   174     ("BYTE", "ANY_NBIT"),
   172     ("WORD", "ANY_BIT"),
   175     ("WORD", "ANY_NBIT"),
   173     ("DWORD", "ANY_BIT"),
   176     ("DWORD", "ANY_NBIT"),
   174     ("LWORD", "ANY_BIT"),
   177     ("LWORD", "ANY_NBIT"),
   175     ("STRING", "ANY_STRING"),
   178     ("STRING", "ANY_STRING"),
   176     ("WSTRING", "ANY_STRING"),
   179     #("WSTRING", "ANY_STRING"), # TODO
   177     ("DATE", "ANY_DATE"),
   180     ("DATE", "ANY_DATE"),
   178     ("TOD", "ANY_DATE"),
   181     ("TOD", "ANY_DATE"),
   179     ("DT", "ANY_DATE")]
   182     ("DT", "ANY_DATE")]
   180 
   183 
   181 TypeHierarchy = dict(TypeHierarchy_list)
   184 TypeHierarchy = dict(TypeHierarchy_list)
   329             param_name = "IN"
   332             param_name = "IN"
   330         params.append((param_name, param_type, "none"))
   333         params.append((param_name, param_type, "none"))
   331     return params
   334     return params
   332 
   335 
   333 
   336 
   334 ANY_T0_ANY_LIST=[
   337 ANY_TO_ANY_LIST=[
       
   338         # simple type conv are let as C cast
   335         (("ANY_NUM","ANY_BIT"),("ANY_NUM","ANY_BIT"), "(%(return_type)s)%(IN_value)s"),
   339         (("ANY_NUM","ANY_BIT"),("ANY_NUM","ANY_BIT"), "(%(return_type)s)%(IN_value)s"),
   336         (("ANY_NUM","ANY_BIT"),("ANY_DATE","TIME"), "(%(return_type)s)real_to_time(%(IN_value)s)"), 
   340         # TO_TIME
   337         (("ANY_DATE","TIME"), ("ANY_NUM","ANY_BIT"), "(%(return_type)s)time_to_real(%(IN_value)s)"), 
   341         (("ANY_INT","ANY_BIT"),("ANY_DATE","TIME"), "(%(return_type)s)__int_to_time(%(IN_value)s)"),
   338         (("ANY_DATE","TIME"), ("ANY_STRING",), "(%(return_type)s)time_to_string(%(IN_value)s)"),
   342         (("ANY_REAL",),("ANY_DATE","TIME"), "(%(return_type)s)__real_to_time(%(IN_value)s)"),
   339         (("ANY_STRING",), ("ANY_DATE","TIME"), "(%(return_type)s)string_to_time(%(IN_value)s)"),
   343         (("ANY_STRING",), ("ANY_DATE","TIME"), "(%(return_type)s)__string_to_time(%(IN_value)s)"),
   340         (("ANY_BIT",), ("ANY_STRING",), "(%(return_type)s)int_to_string(%(IN_value)s, 16)"),
   344         # FROM_TIME
   341         (("ANY_NUM",), ("ANY_STRING",), "(%(return_type)s)int_to_string(%(IN_value)s, 10)"),
   345         (("ANY_DATE","TIME"), ("ANY_REAL",), "(%(return_type)s)__time_to_real(%(IN_value)s)"),
   342         (("ANY_STRING",), ("ANY_BIT",), "(%(return_type)s)string_to_int(%(IN_value)s, 16)"),
   346         (("ANY_DATE","TIME"), ("ANY_INT","ANY_BIT"), "(%(return_type)s)__time_to_int(%(IN_value)s)"),
   343         (("ANY_STRING",), ("ANY_NUM",), "(%(return_type)s)string_to_int(%(IN_value)s, 10)")]
   347         (("TIME",), ("ANY_STRING",), "(%(return_type)s)__time_to_string(%(IN_value)s)"),
   344 
   348         (("DATE",), ("ANY_STRING",), "(%(return_type)s)__date_to_string(%(IN_value)s)"),
   345 def ANY_TO_ANY_FORMAT_GEN(fdecl):
   349         (("TOD",), ("ANY_STRING",), "(%(return_type)s)__tod_to_string(%(IN_value)s)"),
   346 
   350         (("DT",), ("ANY_STRING",), "(%(return_type)s)__dt_to_string(%(IN_value)s)"),
   347     for (InTypes, OutTypes, Format) in ANY_T0_ANY_LIST:
   351         # TO_STRING
       
   352         (("BOOL",), ("ANY_STRING",), "(%(return_type)s)__bool_to_string(%(IN_value)s)"),
       
   353         (("ANY_BIT",), ("ANY_STRING",), "(%(return_type)s)__bit_to_string(%(IN_value)s)"),
       
   354         (("ANY_REAL",), ("ANY_STRING",), "(%(return_type)s)__real_to_string(%(IN_value)s)"),
       
   355         (("ANY_SINT",), ("ANY_STRING",), "(%(return_type)s)__sint_to_string(%(IN_value)s)"),
       
   356         (("ANY_UINT",), ("ANY_STRING",), "(%(return_type)s)__uint_to_string(%(IN_value)s)"),
       
   357         # FROM_STRING
       
   358         (("ANY_STRING",), ("BOOL",), "(%(return_type)s)__string_to_bool(%(IN_value)s)"),
       
   359         (("ANY_STRING",), ("ANY_BIT",), "(%(return_type)s)__string_to_bit(%(IN_value)s)"),
       
   360         (("ANY_STRING",), ("ANY_SINT",), "(%(return_type)s)__string_to_sint(%(IN_value)s)"),
       
   361         (("ANY_STRING",), ("ANY_UINT",), "(%(return_type)s)__string_to_uint(%(IN_value)s)"),
       
   362         (("ANY_STRING",), ("ANY_REAL",), "(%(return_type)s)__string_to_real(%(IN_value)s)")]
       
   363 
       
   364 
       
   365 BCD_TO_ANY_LIST=[
       
   366         (("BYTE",),("USINT",), "(%(return_type)s)__bcd_to_uint(%(IN_value)s)"),
       
   367         (("WORD",),("UINT",), "(%(return_type)s)__bcd_to_uint(%(IN_value)s)"),
       
   368         (("DWORD",),("UDINT",), "(%(return_type)s)__bcd_to_uint(%(IN_value)s)"),
       
   369         (("LWORD",),("ULINT",), "(%(return_type)s)__bcd_to_uint(%(IN_value)s)")]
       
   370 
       
   371 
       
   372 ANY_TO_BCD_LIST=[
       
   373         (("USINT",),("BYTE",), "(%(return_type)s)__uint_to_bcd(%(IN_value)s)"),
       
   374         (("UINT",),("WORD",), "(%(return_type)s)__uint_to_bcd(%(IN_value)s)"),
       
   375         (("UDINT",),("DWORD",), "(%(return_type)s)__uint_to_bcd(%(IN_value)s)"),
       
   376         (("ULINT",),("LWORD",), "(%(return_type)s)__uint_to_bcd(%(IN_value)s)")]
       
   377 
       
   378 
       
   379 def ANY_TO_ANY_FORMAT_GEN(any_to_any_list, fdecl):
       
   380 
       
   381     for (InTypes, OutTypes, Format) in any_to_any_list:
   348         outs = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["outputs"][0][1],testtype), OutTypes))
   382         outs = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["outputs"][0][1],testtype), OutTypes))
   349         inps = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["inputs"][0][1],testtype), InTypes))
   383         inps = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["inputs"][0][1],testtype), InTypes))
   350         if inps and outs and fdecl["outputs"][0][1] != fdecl["inputs"][0][1]:
   384         if inps and outs and fdecl["outputs"][0][1] != fdecl["inputs"][0][1]:
   351              return Format
   385              return Format
   352     
   386     
   394                 for param, value in Function_decl.iteritems():
   428                 for param, value in Function_decl.iteritems():
   395                     if param in translate:
   429                     if param in translate:
   396                         Function_decl[param] = translate[param](value)
   430                         Function_decl[param] = translate[param](value)
   397                 Function_decl["type"] = "function"
   431                 Function_decl["type"] = "function"
   398                 
   432                 
   399                 if Function_decl["name"].startswith('*') :
   433                 if Function_decl["name"].startswith('*') or Function_decl["name"].endswith('*') :
   400                     input_ovrloading_types = GetSubTypes(Function_decl["inputs"][0][1])
   434                     input_ovrloading_types = GetSubTypes(Function_decl["inputs"][0][1])
       
   435                     output_types = GetSubTypes(Function_decl["outputs"][0][1])
   401                 else:
   436                 else:
   402                     input_ovrloading_types = [None]
   437                     input_ovrloading_types = [None]
   403                     
       
   404                 if Function_decl["name"].endswith('*') :
       
   405                     output_types = GetSubTypes(Function_decl["outputs"][0][1])
       
   406                 else:
       
   407                     output_types = [None]
   438                     output_types = [None]
   408                     
   439                     
   409                 funcdeclname_orig = Function_decl["name"]
   440                 funcdeclname_orig = Function_decl["name"]
   410                 funcdeclname = Function_decl["name"].strip('*_')
   441                 funcdeclname = Function_decl["name"].strip('*_')
   411                 fdc = Function_decl["inputs"][:]
   442                 fdc = Function_decl["inputs"][:]
   456             else:
   487             else:
   457                 raise "First function must be in a category"
   488                 raise "First function must be in a category"
   458     
   489     
   459     return Standard_Functions_Decl
   490     return Standard_Functions_Decl
   460 
   491 
   461 
   492 std_decl = get_standard_funtions(csv_file_to_table(open(os.path.join(os.path.split(__file__)[0],"iec_std.csv"))))#, True)
   462 if __name__ == '__main__':
   493 
   463     
   494 BlockTypes.extend(std_decl)
   464     import pprint
   495 
   465     pp = pprint.PrettyPrinter(indent=4)
       
   466 
       
   467     def ANY_to_compiler_test_type_GEN(typename, paramname):
       
   468         return {"ANY" : "",
       
   469         "ANY_BIT" : "if(search_expression_type->is_binary_type(%(paramname)s_type_symbol))",
       
   470         "ANY_NUM" : "if(search_expression_type->is_num_type(%(paramname)s_type_symbol))",
       
   471         "ANY_REAL" : "if(search_expression_type->is_real_type(%(paramname)s_type_symbol))",
       
   472         "ANY_INT" : "if(search_expression_type->is_integer_type(%(paramname)s_type_symbol))"
       
   473         }.get(typename,
       
   474             "if (typeid(*last_type_symbol) == typeid(%(typename)s_type_name_c))")%{
       
   475                     "paramname" : paramname, "typename": typename.lower()}
       
   476     
       
   477     def recurse_and_indent(fdecls, indent, do_type_search_only = False, do_il = False):
       
   478         if type(fdecls) != type(tuple()):
       
   479             res = ""
       
   480             for Paramname, ParamTypes in fdecls.iteritems():
       
   481                 if do_il:
       
   482                     res += """
       
   483 {"""
       
   484                     if not do_type_search_only:
       
   485                         res += """
       
   486     /* Get the value from a foo(<param_name> = <param_value>) style call */
       
   487     symbol_c *%(input_name)s_param_value = &this->default_variable_name;
       
   488 """%{"input_name":Paramname}
       
   489                     res += """
       
   490     symbol_c *%(input_name)s_type_symbol = param_data_type;
       
   491     last_type_symbol = param_data_type;
       
   492 """%{"input_name":Paramname}
       
   493                 else:
       
   494                     res += """
       
   495 {
       
   496     identifier_c param_name("%(input_name)s");
       
   497     /* Get the value from a foo(<param_name> = <param_value>) style call */
       
   498     symbol_c *%(input_name)s_param_value = function_call_param_iterator.search(&param_name);
       
   499     
       
   500     /* Get the value from a foo(<param_value>) style call */
       
   501     if (%(input_name)s_param_value == NULL)
       
   502       %(input_name)s_param_value = function_call_param_iterator.next();
       
   503     symbol_c *%(input_name)s_type_symbol = search_expression_type->get_type(%(input_name)s_param_value);
       
   504     last_type_symbol = last_type_symbol && search_expression_type->is_same_type(%(input_name)s_type_symbol, last_type_symbol) ? search_expression_type->common_type(%(input_name)s_type_symbol, last_type_symbol) : %(input_name)s_type_symbol ;
       
   505 """%{"input_name":Paramname}
       
   506                 
       
   507                 for ParamType,NextParamDecl in ParamTypes.iteritems():
       
   508                 
       
   509                     res += """    
       
   510     %(type_test)s
       
   511     {
       
   512 %(if_good_type_code)s
       
   513     }
       
   514 """%{
       
   515     "type_test":ANY_to_compiler_test_type_GEN(ParamType,Paramname), 
       
   516     "if_good_type_code":recurse_and_indent(NextParamDecl,indent,do_type_search_only).replace('\n','\n    ')}
       
   517 
       
   518                 res += """    
       
   519     ERROR;
       
   520 }
       
   521 """
       
   522             
       
   523             return res.replace('\n','\n'+indent)
       
   524         else:
       
   525             res = "\n"
       
   526             fdecl=fdecls[0]
       
   527             
       
   528             result_type_rule = fdecl["return_type_rule"]
       
   529             res += {
       
   530                 "copy_input" : "symbol_c * return_type_symbol = last_type_symbol;\n",
       
   531                 "defined" : "symbol_c * return_type_symbol = &search_constant_type_c::%s_type_name;\n"%fdecl["outputs"][0][1].lower(),
       
   532                 }.get(result_type_rule, "symbol_c * return_type_symbol = %s;\n"%result_type_rule)
       
   533             
       
   534             if not do_type_search_only:
       
   535                 code_gen = eval(fdecl["python_eval_c_code_format"])
       
   536     
       
   537                 code_gen_dic_decl = {}
       
   538                 for paramname,paramtype,unused in fdecl["inputs"]:
       
   539                     code_gen_dic_decl[paramname+"_value"] = '");\n%s_param_value->accept(*this);\ns4o.print("'%(paramname)
       
   540                     code_gen_dic_decl[paramname+"_type"] = '");\n%s_type_symbol->accept(*this);\ns4o.print("'%(paramname)
       
   541                 code_gen_dic_decl["return_type"] = '");\nreturn_type_symbol->accept(*this);\ns4o.print("'
       
   542                 code_gen_dic_decl["param_count"] = '");\ns4o.print_integer(nb_param);\ns4o.print("'
       
   543                 code_gen_dic_decl["start_bool_filter"] = '");\nif (search_expression_type->is_bool_type(last_type_symbol))\n  s4o.print("('
       
   544                 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("'
       
   545                 
       
   546                 if type(code_gen) == type(tuple()):
       
   547                     res += 's4o.print("%s");\n'%(code_gen[0]%code_gen_dic_decl)
       
   548                     static_param_accept_list = []
       
   549                     for paramname,paramtype,unused in fdecl["inputs"]:
       
   550                         static_param_accept_list.append("%s_param_value->accept(*this);\n"%(paramname))
       
   551                     res += ('s4o.print("%s");\n'%(code_gen[1])).join(static_param_accept_list)
       
   552                     code = 's4o.print("%s");\nparam_value->accept(*this);\n'%(code_gen[1])
       
   553                     end_code = 's4o.print("%s");\nreturn NULL;\n'%(code_gen[2]%code_gen_dic_decl)
       
   554                 else:
       
   555                     code = ''
       
   556                     end_code = ('s4o.print("' + code_gen%code_gen_dic_decl + '");\nreturn NULL;\n').replace('s4o.print("");\n','')
       
   557     
       
   558                 if fdecl["extensible"]:
       
   559                     res += ("""
       
   560 int base_num = %d;
       
   561 symbol_c *param_value = NULL;
       
   562 do{
       
   563     char my_name[10];
       
   564     sprintf(my_name, "IN%%d", base_num++);
       
   565     identifier_c param_name(my_name);
       
   566     
       
   567     /* Get the value from a foo(<param_name> = <param_value>) style call */
       
   568     param_value = function_call_param_iterator.search(&param_name);
       
   569     
       
   570     /* Get the value from a foo(<param_value>) style call */
       
   571     if (param_value == NULL)
       
   572       param_value = function_call_param_iterator.next();
       
   573     if (param_value != NULL){
       
   574         symbol_c *current_type_symbol = search_expression_type->get_type(param_value);
       
   575         last_type_symbol = last_type_symbol && search_expression_type->is_same_type(current_type_symbol, last_type_symbol) ? search_expression_type->common_type(current_type_symbol, last_type_symbol) : current_type_symbol ;
       
   576     
       
   577         /*Function specific CODE */
       
   578         %s
       
   579     }
       
   580     
       
   581 }while(param_value != NULL);
       
   582 %s
       
   583 """%(fdecl["baseinputnumber"]+2, code.replace('\n','\n        '), end_code))
       
   584                 else:
       
   585                     #res += code + end_code
       
   586                     res += end_code
       
   587             else:
       
   588                 res += "return return_type_symbol;\n"
       
   589             
       
   590                     
       
   591             return res.replace('\n','\n'+indent)
       
   592 
       
   593 ###################################################################
       
   594 ###                                                             ###
       
   595 ###                           MAIN                              ###
       
   596 ###                                                             ###
       
   597 ###################################################################
       
   598 
       
   599     # Get definitions
       
   600     std_decl = get_standard_funtions(csv_file_to_table(open("iec_std.csv")))#, True)
       
   601     
       
   602     # Reorganize into a dict of dict, according 
       
   603     # fname : paramname : paramtype : paraname : paramtype...
       
   604     # Keep ptrack of original order in a separated list
       
   605     std_fdecls = {}
       
   606     official_order = []
       
   607     for section in std_decl:
       
   608         for fdecl in section["list"]:
       
   609             if len(official_order)==0 or official_order[-1] != fdecl["name"]:
       
   610                 official_order.append(fdecl["name"])
       
   611             # store all func by name in a dict
       
   612             std_fdecls_fdecl_name = std_fdecls.get(fdecl["name"], {})
       
   613             current = std_fdecls_fdecl_name
       
   614             for i in fdecl["inputs"]:
       
   615                 current[i[0]] = current.get(i[0], {})
       
   616                 current = current[i[0]]
       
   617                 last = current
       
   618                 current[i[1]] = current.get(i[1], {})
       
   619                 current = current[i[1]]
       
   620             last[i[1]]=(fdecl,)
       
   621             std_fdecls[fdecl["name"]] = std_fdecls_fdecl_name
       
   622 
       
   623     # Generate the long enumeration of std function types
       
   624     function_type_decl =  """
       
   625 /****
       
   626  * IEC 61131-3 standard function lib
       
   627  * generated code, do not edit by hand
       
   628  */
       
   629 typedef enum {
       
   630 """
       
   631     for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]:
       
   632         function_type_decl += "    function_"+fname.lower()+",\n"
       
   633 
       
   634     function_type_decl += """    function_none
       
   635 } function_type_t;
       
   636 """
       
   637 
       
   638     # Generate the funct thaat return enumerated according function name
       
   639     get_function_type_decl = """
       
   640 /****
       
   641  * IEC 61131-3 standard function lib
       
   642  * generated code, do not edit by hand
       
   643  */
       
   644 function_type_t get_function_type(identifier_c *function_name) {
       
   645 """
       
   646     for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]:
       
   647         get_function_type_decl += """
       
   648     if (!strcasecmp(function_name->value, "%s"))
       
   649         return function_%s;
       
   650 """%(fname,fname.lower())
       
   651 
       
   652     get_function_type_decl += """
       
   653     else return function_none;
       
   654 }
       
   655 
       
   656 """
       
   657 
       
   658     # Generate the part of generate_cc_st_c::visit(function_invocation)
       
   659     # that is responsible to generate C code for std lib calls.
       
   660     st_code_gen = """
       
   661 /****
       
   662  * IEC 61131-3 standard function lib
       
   663  * generated code, do not edit by hand
       
   664  */
       
   665 switch(current_function_type){
       
   666 """
       
   667     
       
   668     for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]:
       
   669         st_code_gen += """
       
   670 /****
       
   671  *%s
       
   672  */
       
   673     case function_%s :
       
   674     {
       
   675         symbol_c *last_type_symbol = NULL;
       
   676 """    %(fname, fname.lower())
       
   677         indent =  "    "
       
   678 
       
   679         st_code_gen += recurse_and_indent(fdecls, indent).replace('\n','\n    ')
       
   680         
       
   681         st_code_gen += """
       
   682     }/*function_%s*/
       
   683     break;
       
   684 """    %(fname.lower())
       
   685     st_code_gen +=  """
       
   686     case function_none :
       
   687     ERROR;
       
   688 }
       
   689 return NULL;
       
   690 """
       
   691 
       
   692     # Generate the part of generate_cc_il_c::visit(il_function_call)
       
   693     # that is responsible to generate C code for std lib calls.
       
   694     il_code_gen = """
       
   695 /****
       
   696  * IEC 61131-3 standard function lib
       
   697  * generated code, do not edit by hand
       
   698  */
       
   699 switch(current_function_type){
       
   700 """
       
   701     
       
   702     for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]:
       
   703         il_code_gen += """
       
   704 /****
       
   705  *%s
       
   706  */
       
   707     case function_%s :
       
   708     {
       
   709         symbol_c *last_type_symbol = NULL;
       
   710 """    %(fname, fname.lower())
       
   711         indent =  "    "
       
   712 
       
   713         il_code_gen += recurse_and_indent(fdecls, indent, do_il=True).replace('\n','\n    ')
       
   714         
       
   715         il_code_gen += """
       
   716     }/*function_%s*/
       
   717     break;
       
   718 """    %(fname.lower())
       
   719     il_code_gen +=  """
       
   720     case function_none :
       
   721     ERROR;
       
   722 }
       
   723 return NULL;
       
   724 """
       
   725 
       
   726     # Generate the part of search_expression_type_c::visit(function_invocation)
       
   727     # that is responsible of returning type symbol for function invocation.
       
   728     search_type_code =  """
       
   729 /****
       
   730  * IEC 61131-3 standard function lib
       
   731  * generated code, do not edit by hand
       
   732  */
       
   733 
       
   734 void *compute_standard_function_st(function_invocation_c *symbol) {
       
   735 
       
   736   function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
       
   737   function_call_param_iterator_c function_call_param_iterator(symbol);
       
   738   search_expression_type_c* search_expression_type = this;
       
   739 
       
   740   switch(current_function_type){
       
   741 """
       
   742     
       
   743     for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]:
       
   744         search_type_code += """
       
   745 /****
       
   746  *%s
       
   747  */
       
   748     case function_%s :
       
   749     {
       
   750         symbol_c *last_type_symbol = NULL;
       
   751 """    %(fname, fname.lower())
       
   752         indent =  "    "
       
   753 
       
   754         search_type_code += recurse_and_indent(fdecls, indent, True).replace('\n','\n    ')
       
   755         
       
   756         search_type_code += """
       
   757     }/*function_%s*/
       
   758     break;
       
   759 """    %(fname.lower())
       
   760     search_type_code += """
       
   761     case function_none :
       
   762     ERROR;
       
   763   }
       
   764   return NULL;
       
   765 }
       
   766 
       
   767 void *compute_standard_function_il(il_function_call_c *symbol, symbol_c *param_data_type) {
       
   768   
       
   769   function_type_t current_function_type = get_function_type((identifier_c *)symbol->function_name);
       
   770   function_call_param_iterator_c function_call_param_iterator(symbol);  
       
   771   search_expression_type_c* search_expression_type = this;
       
   772 
       
   773   switch(current_function_type){
       
   774 """
       
   775 
       
   776     for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]:
       
   777         search_type_code += """
       
   778 /****
       
   779  *%s
       
   780  */
       
   781     case function_%s :
       
   782     {
       
   783         symbol_c *last_type_symbol = NULL;
       
   784 """    %(fname, fname.lower())
       
   785         indent =  "    "
       
   786 
       
   787         search_type_code += recurse_and_indent(fdecls, indent, True, True).replace('\n','\n    ')
       
   788         
       
   789         search_type_code += """
       
   790     }/*function_%s*/
       
   791     break;
       
   792 """    %(fname.lower())
       
   793     search_type_code += """
       
   794     case function_none :
       
   795     ERROR;
       
   796   }
       
   797   return NULL;
       
   798 }
       
   799 """
       
   800 
       
   801 
       
   802     # Now, print that out, or write to files from sys.argv
       
   803     for name, ext in [
       
   804             ('function_type_decl','h'),
       
   805             ('get_function_type_decl','c'),
       
   806             ('st_code_gen','c'),
       
   807             ('il_code_gen','c'),
       
   808             ('search_type_code','c')]:
       
   809         fd = open(os.path.join(sys.argv[1],name+'.'+ext),'w')
       
   810         fd.write(eval(name))
       
   811         fd.close()
       
   812 else:
       
   813     # Put standard functions declaration in Bloktypes
       
   814     BlockTypes.extend(get_standard_funtions(csv_file_to_table(open(os.path.join(sys.path[0], "plcopen/iec_std.csv")))))
       
   815 
       
   816