# HG changeset patch # User lbessard # Date 1182345908 -7200 # Node ID a765fae3b3618c22ec3e09039ee7cd6ef13f000c # Parent e619d7bea6921dc75c7208fba6ce91569c6f8458 Modifications on structure.py diff -r e619d7bea692 -r a765fae3b361 plcopen/structures.py --- a/plcopen/structures.py Tue Jun 19 08:43:41 2007 +0200 +++ b/plcopen/structures.py Wed Jun 20 15:25:08 2007 +0200 @@ -146,37 +146,37 @@ between type that permits to make a comparison of two types """ TypeHierarchy_list = [ - ("ANY", None), - ("ANY_DERIVED", "ANY"), - ("ANY_ELEMENTARY", "ANY"), - ("ANY_MAGNITUDE", "ANY_ELEMENTARY"), - ("ANY_BIT", "ANY_ELEMENTARY"), - ("ANY_STRING", "ANY_ELEMENTARY"), - ("ANY_DATE", "ANY_ELEMENTARY"), - ("ANY_NUM", "ANY_MAGNITUDE"), - ("ANY_REAL", "ANY_NUM"), - ("ANY_INT", "ANY_NUM"), - ("REAL", "ANY_REAL"), - ("LREAL", "ANY_REAL"), - ("SINT", "ANY_INT"), - ("INT", "ANY_INT"), - ("DINT", "ANY_INT"), - ("LINT", "ANY_INT"), - ("USINT", "ANY_INT"), - ("UINT", "ANY_INT"), - ("UDINT", "ANY_INT"), - ("ULINT", "ANY_INT"), - ("TIME", "ANY_MAGNITUDE"), - ("BOOL", "ANY_BIT"), - ("BYTE", "ANY_BIT"), - ("WORD", "ANY_BIT"), - ("DWORD", "ANY_BIT"), - ("LWORD", "ANY_BIT"), - ("STRING", "ANY_STRING"), - ("WSTRING", "ANY_STRING"), - ("DATE", "ANY_DATE"), - ("TOD", "ANY_DATE"), - ("DT", "ANY_DATE")] + ("ANY", None), + ("ANY_DERIVED", "ANY"), + ("ANY_ELEMENTARY", "ANY"), + ("ANY_MAGNITUDE", "ANY_ELEMENTARY"), + ("ANY_BIT", "ANY_ELEMENTARY"), + ("ANY_STRING", "ANY_ELEMENTARY"), + ("ANY_DATE", "ANY_ELEMENTARY"), + ("ANY_NUM", "ANY_MAGNITUDE"), + ("ANY_REAL", "ANY_NUM"), + ("ANY_INT", "ANY_NUM"), + ("REAL", "ANY_REAL"), + ("LREAL", "ANY_REAL"), + ("SINT", "ANY_INT"), + ("INT", "ANY_INT"), + ("DINT", "ANY_INT"), + ("LINT", "ANY_INT"), + ("USINT", "ANY_INT"), + ("UINT", "ANY_INT"), + ("UDINT", "ANY_INT"), + ("ULINT", "ANY_INT"), + ("TIME", "ANY_MAGNITUDE"), + ("BOOL", "ANY_BIT"), + ("BYTE", "ANY_BIT"), + ("WORD", "ANY_BIT"), + ("DWORD", "ANY_BIT"), + ("LWORD", "ANY_BIT"), + ("STRING", "ANY_STRING"), + ("WSTRING", "ANY_STRING"), + ("DATE", "ANY_DATE"), + ("TOD", "ANY_DATE"), + ("DT", "ANY_DATE")] TypeHierarchy = dict(TypeHierarchy_list) @@ -195,7 +195,7 @@ returns list of all types that correspont to the ANY* meta type """ def GetSubTypes(reference): - return [ typename for typename in TypeHierarchy.iterkeys() if typename[:3] != "ANY" and IsOfType(typename, reference)] + return [ typename for typename, parenttype in TypeHierarchy_list if typename[:3] != "ANY" and IsOfType(typename, reference)] #------------------------------------------------------------------------------- @@ -281,107 +281,76 @@ take a .csv file and translate it it a "csv_table" """ def csv_file_to_table(file): - return [ map(string.strip,line.split(';')) for line in file.xreadlines()] + return [ map(string.strip,line.split(';')) for line in file.xreadlines()] """ seek into the csv table to a section ( section_name match 1st field ) return the matching row without first field """ def find_section(section_name, table): - fields = [None] - while(fields[0] != section_name): - fields = table.pop(0) - return fields[1:] + fields = [None] + while(fields[0] != section_name): + fields = table.pop(0) + return fields[1:] """ extract the standard functions standard parameter names and types... return a { ParameterName: Type, ...} """ def get_standard_funtions_input_variables(table): - variables = find_section("Standard_functions_variables_types", table) - standard_funtions_input_variables = {} - fields = [True,True] - while(fields[1]): - fields = table.pop(0) - variable_from_csv = dict([(champ, val) for champ, val in zip(variables, fields[1:]) if champ!='']) - standard_funtions_input_variables[variable_from_csv['name']] = variable_from_csv['type'] - return standard_funtions_input_variables - + variables = find_section("Standard_functions_variables_types", table) + standard_funtions_input_variables = {} + fields = [True,True] + while(fields[1]): + fields = table.pop(0) + variable_from_csv = dict([(champ, val) for champ, val in zip(variables, fields[1:]) if champ!='']) + standard_funtions_input_variables[variable_from_csv['name']] = variable_from_csv['type'] + return standard_funtions_input_variables + """ translate .csv file input declaration into PLCOpenEditor interessting values in : "(ANY_NUM, ANY_NUM)" and { ParameterName: Type, ...} return [("IN1","ANY_NUM","none"),("IN2","ANY_NUM","none")] """ def csv_input_translate(str_decl, variables, base): - decl = str_decl.replace('(','').replace(')','').replace(' ','').split(',') - param_types = [] - param_names = [] - modifiers = [] - - len_of_not_predifined_variable = 0 - for param_type in decl: - predifined_variable_param_type = variables.get(param_type,None) - if not predifined_variable_param_type : - len_of_not_predifined_variable += 1 - - if len_of_not_predifined_variable>1 : suffix = str(base) - else: suffix = '' - - for param_type in decl: - predifined_variable_param_type = variables.get(param_type,None) - if predifined_variable_param_type : - param_types.append(predifined_variable_param_type) - param_names.append(param_type) - else: - param_types.append(param_type) - param_names.append("IN"+suffix) - base+=1 - suffix = str(base) - - modifiers = ["none"]*len(param_types) - return zip(param_names,param_types,modifiers) - -""" -Fillin the PLCOpenEditor standard function dictionnary -translate input and output declaration to something more pythonesque -and add interface description to comment -""" -def decl_function(dico_from_table, variables): - Function_decl = { "type" : "function" } - for field, val in dico_from_table: - translate = { - "baseinputnumber" : lambda x:int(x), - "extensible" : lambda x: {"yes":True, "no":False}[x], - "inputs" : lambda x:csv_input_translate(x,variables,Function_decl.get("baseinputnumber",1)), - "outputs":lambda x:[("OUT",x,"none")]} - Function_decl[field] = translate.get(field,lambda x:x)(val) - return Function_decl - + decl = str_decl.replace('(','').replace(')','').replace(' ','').split(',') + params = [] + + len_of_not_predifined_variable = len([True for param_type in decl if param_type not in variables]) + + for param_type in decl: + if param_type in variables.keys(): + param_name = param_type + param_type = variables[param_type] + elif len_of_not_predifined_variable > 1: + param_name = "IN%d"%base + base += 1 + else: + param_name = "IN" + params.append((param_name, param_type, "none")) + return params + + +ANY_T0_ANY_LIST=[ + (("ANY_NUM","ANY_BIT"),("ANY_NUM","ANY_BIT"), "(%(return_type)s)%(IN_value)s"), + (("ANY_NUM","ANY_BIT"),("ANY_DATE","TIME"), "(%(return_type)s)real_to_time(%(IN_value)s)"), + (("ANY_DATE","TIME"), ("ANY_NUM","ANY_BIT"), "(%(return_type)s)time_to_real(%(IN_value)s)"), + (("ANY_DATE","TIME"), ("ANY_STRING",), "(%(return_type)s)time_to_string(%(IN_value)s)"), + (("ANY_STRING",), ("ANY_DATE","TIME"), "(%(return_type)s)string_to_time(%(IN_value)s)"), + (("ANY_BIT",), ("ANY_STRING",), "(%(return_type)s)int_to_string(%(IN_value)s, 16)"), + (("ANY_NUM",), ("ANY_STRING",), "(%(return_type)s)int_to_string(%(IN_value)s, 10)"), + (("ANY_STRING",), ("ANY_BIT",), "(%(return_type)s)string_to_int(%(IN_value)s, 16)"), + (("ANY_STRING",), ("ANY_NUM",), "(%(return_type)s)string_to_int(%(IN_value)s, 10)")] def ANY_TO_ANY_FORMAT_GEN(fdecl): - ANY_T0_ANY_LIST=[ - (("ANY_NUM","ANY_BIT"),("ANY_NUM","ANY_BIT"), "(%(return_type)s)%(IN_value)s"), - (("ANY_NUM","ANY_BIT"),("ANY_DATE","TIME"), "(%(return_type)s)real_to_time(%(IN_value)s)"), - (("ANY_DATE","TIME"), ("ANY_NUM","ANY_BIT"), "(%(return_type)s)time_to_real(%(IN_value)s)"), - (("ANY_DATE","TIME"), ("ANY_STRING",), "(%(return_type)s)time_to_string(%(IN_value)s)"), - (("ANY_STRING",), ("ANY_DATE","TIME"), "(%(return_type)s)string_to_time(%(IN_value)s)"), - (("ANY_BIT",), ("ANY_STRING",), "(%(return_type)s)int_to_string(%(IN_value)s, 16)"), - (("ANY_NUM",), ("ANY_STRING",), "(%(return_type)s)int_to_string(%(IN_value)s, 10)"), - (("ANY_STRING",), ("ANY_BIT",), "(%(return_type)s)string_to_int(%(IN_value)s, 16)"), - (("ANY_STRING",), ("ANY_NUM",), "(%(return_type)s)string_to_int(%(IN_value)s, 10)")] - - for (InTypes, OutTypes, Format) in ANY_T0_ANY_LIST: - inps = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["outputs"][0][1],testtype), InTypes)) - #print "IN ",inps , fdecl["outputs"][0][1], InTypes - outs = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["inputs"][0][1],testtype), OutTypes)) - #print "OUT ",outs , fdecl["inputs"][0][1], OutTypes - if (inps and outs ): - return Format - - #print "IN:", fdecl["outputs"][0][1], " OUT:", fdecl["inputs"][0][1] - - return "#error %s_TO_%s not implemented!"%(fdecl["inputs"][0][1],fdecl["outputs"][0][1]) + for (InTypes, OutTypes, Format) in ANY_T0_ANY_LIST: + outs = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["outputs"][0][1],testtype), OutTypes)) + inps = reduce(lambda a,b: a or b, map(lambda testtype : IsOfType(fdecl["inputs"][0][1],testtype), InTypes)) + if inps and outs and fdecl["outputs"][0][1] != fdecl["inputs"][0][1]: + return Format + + return None """ @@ -398,217 +367,224 @@ 'type': 'function'}, ...... ] },.....] """ def get_standard_funtions(table): - - variables = get_standard_funtions_input_variables(table) - - fonctions = find_section("Standard_functions_type",table) - - Standard_Functions_Decl = [] - Current_section = None - for fields in table: - if fields[1]: - # If function section name given - if fields[0] : - if Current_section: - Standard_Functions_Decl.append(Current_section) - Current_section = { "name" : fields[0], "list" : [] } - Function_decl_list = [] - - dico_from_table = [ (champ,val) for champ,val in zip(fonctions, fields[1:]) if champ ] - Function_decl = decl_function(dico_from_table,variables) - if Function_decl["name"].startswith('*') : - input_types = [ GetSubTypes(inpdecl[1]) for inpdecl in Function_decl["inputs"] ] - input_ovrloading_types = input_types[map(len,input_types).index(max(map(len,input_types)))] - else: - input_ovrloading_types = [None] - - if Function_decl["name"].endswith('*') : - output_types = GetSubTypes(Function_decl["outputs"][0][1]) - else: - output_types = [None] - - funcdeclname_orig = Function_decl["name"] - funcdeclname = Function_decl["name"].strip('*_') - fdc = Function_decl["inputs"][:] - for intype in input_ovrloading_types: - if intype != None: - Function_decl["inputs"] = [] - for decl_tpl in fdc: - if IsOfType(intype, decl_tpl[1]): - Function_decl["inputs"] += [(decl_tpl[0], intype, decl_tpl[2])] - else: - Function_decl["inputs"] += [(decl_tpl)] - - if funcdeclname_orig.startswith('*'): - funcdeclin = intype + '_' + funcdeclname - else: - funcdeclin = funcdeclname - else: - funcdeclin = funcdeclname - - - if Function_decl["return_type_rule"] == "copy_input": - output_types = [intype] - elif Function_decl["return_type_rule"] == "defined": - pass - - for outype in output_types: - if outype != None: - decl_tpl = Function_decl["outputs"][0] - Function_decl["outputs"] = [ (decl_tpl[0] , outype, decl_tpl[2])] - if funcdeclname_orig.endswith('*'): - funcdeclout = funcdeclin + '_' + outype - else: - funcdeclout = funcdeclin - else: - funcdeclout = funcdeclin - Function_decl["name"] = funcdeclout - - - try: - fdecl = Function_decl - res = eval(Function_decl["python_eval_c_code_format"]) - except Exception,e: - res = None - - if res != None : - # create the copy of decl dict to be appended to section - Function_decl_copy = Function_decl.copy() - # Have to generate type description in comment with freshly redefined types - Function_decl_copy["comment"] += ( - "\n (" + - str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in Function_decl["inputs"]]).strip("[]").replace("'",'') + - " ) => (" + - str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in Function_decl["outputs"]]).strip("[]").replace("'",'') + - " )") - Current_section["list"].append(Function_decl_copy) - #pp.pprint(Function_decl_copy) - - Standard_Functions_Decl.append(Current_section) - - return Standard_Functions_Decl + + variables = get_standard_funtions_input_variables(table) + + fonctions = find_section("Standard_functions_type",table) + + Standard_Functions_Decl = [] + Current_section = None + + translate = { + "extensible" : lambda x: {"yes":True, "no":False}[x], + "inputs" : lambda x:csv_input_translate(x,variables,baseinputnumber), + "outputs":lambda x:[("OUT",x,"none")]} + + for fields in table: + if fields[1]: + # If function section name given + if fields[0]: + Current_section = {"name" : fields[0], "list" : []} + Standard_Functions_Decl.append(Current_section) + Function_decl_list = [] + if Current_section: + Function_decl = dict([(champ, val) for champ, val in zip(fonctions, fields[1:]) if champ]) + baseinputnumber = int(Function_decl.get("baseinputnumber",1)) + Function_decl["baseinputnumber"] = baseinputnumber + for param, value in Function_decl.iteritems(): + if param in translate: + Function_decl[param] = translate[param](value) + Function_decl["type"] = "function" + + if Function_decl["name"].startswith('*') : + input_ovrloading_types = GetSubTypes(Function_decl["inputs"][0][1]) + else: + input_ovrloading_types = [None] + + if Function_decl["name"].endswith('*') : + output_types = GetSubTypes(Function_decl["outputs"][0][1]) + else: + output_types = [None] + + funcdeclname_orig = Function_decl["name"] + funcdeclname = Function_decl["name"].strip('*_') + fdc = Function_decl["inputs"][:] + for intype in input_ovrloading_types: + if intype != None: + Function_decl["inputs"] = [] + for decl_tpl in fdc: + if IsOfType(intype, decl_tpl[1]): + Function_decl["inputs"] += [(decl_tpl[0], intype, decl_tpl[2])] + else: + Function_decl["inputs"] += [(decl_tpl)] + + if funcdeclname_orig.startswith('*'): + funcdeclin = intype + '_' + funcdeclname + else: + funcdeclin = funcdeclname + else: + funcdeclin = funcdeclname + + for outype in output_types: + if outype != None: + decl_tpl = Function_decl["outputs"][0] + Function_decl["outputs"] = [ (decl_tpl[0] , outype, decl_tpl[2])] + if funcdeclname_orig.endswith('*'): + funcdeclout = funcdeclin + '_' + outype + else: + funcdeclout = funcdeclin + else: + funcdeclout = funcdeclin + Function_decl["name"] = funcdeclout + + + fdecl = Function_decl + res = eval(Function_decl["python_eval_c_code_format"]) + + if res != None : + # create the copy of decl dict to be appended to section + Function_decl_copy = Function_decl.copy() + # Have to generate type description in comment with freshly redefined types + Function_decl_copy["comment"] += ( + "\n (" + + str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in Function_decl["inputs"]]).strip("[]").replace("'",'') + + " ) => (" + + str([ " " + fctdecl[1]+":"+fctdecl[0] for fctdecl in Function_decl["outputs"]]).strip("[]").replace("'",'') + + " )") + Current_section["list"].append(Function_decl_copy) + #pp.pprint(Function_decl_copy) + else: + raise "First function must be in a category" + + return Standard_Functions_Decl if __name__ == '__main__': - - import pprint - pp = pprint.PrettyPrinter(indent=4) - - def ANY_to_compiler_test_type_GEN(typename, paramname): - return {"ANY" : "", - "ANY_BIT" : "if(search_expression_type->is_binary_type(%(paramname)s_type_symbol))", - "ANY_NUM" : "if(search_expression_type->is_num_type(%(paramname)s_type_symbol))", - "ANY_REAL" : "if(search_expression_type->is_real_type(%(paramname)s_type_symbol))", - "ANY_INT" : "if(search_expression_type->is_integer_type(%(paramname)s_type_symbol))" - }.get(typename, - "if (typeid(*last_type_symbol) == typeid(%(typename)s_type_name_c))")%{ - "paramname" : paramname, "typename": typename.lower()} - - def recurse_and_indent(fdecls, indent, do_type_search_only = False): - if type(fdecls) != type(tuple()): - res = "" - for Paramname, ParamTypes in fdecls.iteritems(): - res += (""" + + import pprint + pp = pprint.PrettyPrinter(indent=4) + + def ANY_to_compiler_test_type_GEN(typename, paramname): + return {"ANY" : "", + "ANY_BIT" : "if(search_expression_type->is_binary_type(%(paramname)s_type_symbol))", + "ANY_NUM" : "if(search_expression_type->is_num_type(%(paramname)s_type_symbol))", + "ANY_REAL" : "if(search_expression_type->is_real_type(%(paramname)s_type_symbol))", + "ANY_INT" : "if(search_expression_type->is_integer_type(%(paramname)s_type_symbol))" + }.get(typename, + "if (typeid(*last_type_symbol) == typeid(%(typename)s_type_name_c))")%{ + "paramname" : paramname, "typename": typename.lower()} + + def recurse_and_indent(fdecls, indent, do_type_search_only = False, do_il = False): + if type(fdecls) != type(tuple()): + res = "" + for Paramname, ParamTypes in fdecls.iteritems(): + if do_il: + res += """ { - identifier_c param_name("%(input_name)s"); - /* Get the value from a foo( = ) style call */ - symbol_c *%(input_name)s_param_value = function_call_param_iterator.search(¶m_name); - - /* Get the value from a foo() style call */ - if (%(input_name)s_param_value == NULL) - %(input_name)s_param_value = function_call_param_iterator.next(); - symbol_c *%(input_name)s_type_symbol = search_expression_type->get_type(%(input_name)s_param_value); - 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 ; -"""%{"input_name":Paramname}) - - for ParamType,NextParamDecl in ParamTypes.iteritems(): - - res += (""" - %(type_test)s - { + /* Get the value from a foo( = ) style call */ + symbol_c *%(input_name)s_param_value = &this->default_variable_name; + + last_type_symbol = param_data_type; +"""%{"input_name":Paramname} + else: + res += """ +{ + identifier_c param_name("%(input_name)s"); + /* Get the value from a foo( = ) style call */ + symbol_c *%(input_name)s_param_value = function_call_param_iterator.search(¶m_name); + + /* Get the value from a foo() style call */ + if (%(input_name)s_param_value == NULL) + %(input_name)s_param_value = function_call_param_iterator.next(); + symbol_c *%(input_name)s_type_symbol = search_expression_type->get_type(%(input_name)s_param_value); + 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 ; +"""%{"input_name":Paramname} + + for ParamType,NextParamDecl in ParamTypes.iteritems(): + + res += """ + %(type_test)s + { %(if_good_type_code)s - } + } """%{ - "type_test":ANY_to_compiler_test_type_GEN(ParamType,Paramname), - "if_good_type_code":recurse_and_indent(NextParamDecl,indent,do_type_search_only).replace('\n','\n ')}) - - res += """ - ERROR; + "type_test":ANY_to_compiler_test_type_GEN(ParamType,Paramname), + "if_good_type_code":recurse_and_indent(NextParamDecl,indent,do_type_search_only).replace('\n','\n ')} + + res += """ + ERROR; } """ - - return res.replace('\n','\n'+indent) - else: - res = "\n" - fdecl=fdecls[0] - - result_type_rule = fdecl["return_type_rule"] - res += { - "copy_input" : "symbol_c * return_type_symbol = last_type_symbol;\n", - "defined" : "symbol_c * return_type_symbol = &search_constant_type_c::%s_type_name;\n"%fdecl["outputs"][0][1].lower(), - }.get(result_type_rule, "symbol_c * return_type_symbol = %s;\n"%result_type_rule) - - if not do_type_search_only: - try: - code_gen = eval(fdecl["python_eval_c_code_format"]) - except Exception: - code_gen = "#error in eval of " + fdecl["name"] - - code_gen_dic_decl = {} - for paramname,paramtype,unused in fdecl["inputs"]: - code_gen_dic_decl[paramname+"_value"] = '");\n%s_param_value->accept(*this);\ns4o.print("'%(paramname) - code_gen_dic_decl[paramname+"_type"] = '");\n%s_type_symbol->accept(*this);\ns4o.print("'%(paramname) - code_gen_dic_decl["return_type"] = '");\nreturn_type_symbol->accept(*this);\ns4o.print("' - code_gen_dic_decl["param_count"] = '");\ns4o.print_integer(nb_param);\ns4o.print("' - code_gen_dic_decl["start_bool_filter"] = '");\nif (search_expression_type->is_bool_type(last_type_symbol))\n s4o.print("(' - 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("' + + return res.replace('\n','\n'+indent) + else: + res = "\n" + fdecl=fdecls[0] + + result_type_rule = fdecl["return_type_rule"] + res += { + "copy_input" : "symbol_c * return_type_symbol = last_type_symbol;\n", + "defined" : "symbol_c * return_type_symbol = &search_constant_type_c::%s_type_name;\n"%fdecl["outputs"][0][1].lower(), + }.get(result_type_rule, "symbol_c * return_type_symbol = %s;\n"%result_type_rule) + + if not do_type_search_only: + code_gen = eval(fdecl["python_eval_c_code_format"]) + + code_gen_dic_decl = {} + for paramname,paramtype,unused in fdecl["inputs"]: + code_gen_dic_decl[paramname+"_value"] = '");\n%s_param_value->accept(*this);\ns4o.print("'%(paramname) + code_gen_dic_decl[paramname+"_type"] = '");\n%s_type_symbol->accept(*this);\ns4o.print("'%(paramname) + code_gen_dic_decl["return_type"] = '");\nreturn_type_symbol->accept(*this);\ns4o.print("' + code_gen_dic_decl["param_count"] = '");\ns4o.print_integer(nb_param);\ns4o.print("' + code_gen_dic_decl["start_bool_filter"] = '");\nif (search_expression_type->is_bool_type(last_type_symbol))\n s4o.print("(' + 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("' - if type(code_gen) == type(tuple()): - res += 's4o.print("%s");\n'%(code_gen[0]%code_gen_dic_decl) - static_param_accept_list = [] - for paramname,paramtype,unused in fdecl["inputs"]: - static_param_accept_list.append("%s_param_value->accept(*this);\n"%(paramname)) - res += ('s4o.print("%s");\n'%(code_gen[1])).join(static_param_accept_list) - code = 's4o.print("%s");\nparam_value->accept(*this);\n'%(code_gen[1]) - end_code = 's4o.print("%s");\nreturn NULL;\n'%(code_gen[2]%code_gen_dic_decl) - else: - code = '' - end_code = ('s4o.print("' + code_gen%code_gen_dic_decl + '");\nreturn NULL;\n').replace('s4o.print("");\n','') - - if fdecl["extensible"]: - res += (""" + if type(code_gen) == type(tuple()): + res += 's4o.print("%s");\n'%(code_gen[0]%code_gen_dic_decl) + static_param_accept_list = [] + for paramname,paramtype,unused in fdecl["inputs"]: + static_param_accept_list.append("%s_param_value->accept(*this);\n"%(paramname)) + res += ('s4o.print("%s");\n'%(code_gen[1])).join(static_param_accept_list) + code = 's4o.print("%s");\nparam_value->accept(*this);\n'%(code_gen[1]) + end_code = 's4o.print("%s");\nreturn NULL;\n'%(code_gen[2]%code_gen_dic_decl) + else: + code = '' + end_code = ('s4o.print("' + code_gen%code_gen_dic_decl + '");\nreturn NULL;\n').replace('s4o.print("");\n','') + + if fdecl["extensible"]: + res += (""" int base_num = %d; symbol_c *param_value = NULL; do{ - char my_name[10]; - sprintf(my_name, "IN%%d", base_num++); - identifier_c param_name(my_name); - - /* Get the value from a foo( = ) style call */ - param_value = function_call_param_iterator.search(¶m_name); - - /* Get the value from a foo() style call */ - if (param_value == NULL) - param_value = function_call_param_iterator.next(); - if (param_value != NULL){ - symbol_c *current_type_symbol = search_expression_type->get_type(param_value); - 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 ; - - /*Function specific CODE */ - %s - } - + char my_name[10]; + sprintf(my_name, "IN%%d", base_num++); + identifier_c param_name(my_name); + + /* Get the value from a foo( = ) style call */ + param_value = function_call_param_iterator.search(¶m_name); + + /* Get the value from a foo() style call */ + if (param_value == NULL) + param_value = function_call_param_iterator.next(); + if (param_value != NULL){ + symbol_c *current_type_symbol = search_expression_type->get_type(param_value); + 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 ; + + /*Function specific CODE */ + %s + } + }while(param_value != NULL); %s -"""%(fdecl["baseinputnumber"]+2, code.replace('\n','\n '), end_code)) - else: - #res += code + end_code - res += end_code - else: - res += "return return_type_symbol;\n" - - - return res.replace('\n','\n'+indent) +"""%(fdecl["baseinputnumber"]+2, code.replace('\n','\n '), end_code)) + else: + #res += code + end_code + res += end_code + else: + res += "return return_type_symbol;\n" + + + return res.replace('\n','\n'+indent) ################################################################### ### ### @@ -616,145 +592,180 @@ ### ### ################################################################### - # Get definitions - std_decl = get_standard_funtions(csv_file_to_table(open("iec_std.csv")))#, True) - - # Reorganize into a dict of dict, according - # fname : paramname : paramtype : paraname : paramtype... - # Keep ptrack of original order in a separated list - std_fdecls = {} - official_order = [] - for section in std_decl: - for fdecl in section["list"]: - if len(official_order)==0 or official_order[-1] != fdecl["name"]: - official_order.append(fdecl["name"]) - # store all func by name in a dict - std_fdecls_fdecl_name = std_fdecls.get(fdecl["name"], {}) - current = std_fdecls_fdecl_name - for i in fdecl["inputs"]: - current[i[0]] = current.get(i[0], {}) - current = current[i[0]] - last = current - current[i[1]] = current.get(i[1], {}) - current = current[i[1]] - last[i[1]]=(fdecl,) - std_fdecls[fdecl["name"]] = std_fdecls_fdecl_name - - # Generate the long enumeration of std function types - function_type_decl = """ + # Get definitions + std_decl = get_standard_funtions(csv_file_to_table(open("iec_std.csv")))#, True) + + # Reorganize into a dict of dict, according + # fname : paramname : paramtype : paraname : paramtype... + # Keep ptrack of original order in a separated list + std_fdecls = {} + official_order = [] + for section in std_decl: + for fdecl in section["list"]: + if len(official_order)==0 or official_order[-1] != fdecl["name"]: + official_order.append(fdecl["name"]) + # store all func by name in a dict + std_fdecls_fdecl_name = std_fdecls.get(fdecl["name"], {}) + current = std_fdecls_fdecl_name + for i in fdecl["inputs"]: + current[i[0]] = current.get(i[0], {}) + current = current[i[0]] + last = current + current[i[1]] = current.get(i[1], {}) + current = current[i[1]] + last[i[1]]=(fdecl,) + std_fdecls[fdecl["name"]] = std_fdecls_fdecl_name + + # Generate the long enumeration of std function types + function_type_decl = """ /**** * IEC 61131-3 standard function lib * generated code, do not edit by hand */ typedef enum { """ - for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: - function_type_decl += " function_"+fname.lower()+",\n" - - function_type_decl += """ function_none + for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: + function_type_decl += " function_"+fname.lower()+",\n" + + function_type_decl += """ function_none } function_type_t; """ - # Generate the funct thaat return enumerated according function name - get_function_type_decl = """ + # Generate the funct thaat return enumerated according function name + get_function_type_decl = """ /**** * IEC 61131-3 standard function lib * generated code, do not edit by hand */ function_type_t get_function_type(identifier_c *function_name) { """ - for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: - get_function_type_decl += """ - if (!strcasecmp(function_name->value, "%s")) - return function_%s; + for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: + get_function_type_decl += """ + if (!strcasecmp(function_name->value, "%s")) + return function_%s; """%(fname,fname.lower()) - get_function_type_decl += """ - else return function_none; + get_function_type_decl += """ + else return function_none; } """ - # Generate the part of generate_cc_st_c::visit(function_invocation) - # that is responsible to generate C code for std lib calls. - st_code_gen = """ + # Generate the part of generate_cc_st_c::visit(function_invocation) + # that is responsible to generate C code for std lib calls. + st_code_gen = """ /**** * IEC 61131-3 standard function lib * generated code, do not edit by hand */ switch(current_function_type){ """ - - for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: - st_code_gen += """ + + for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: + st_code_gen += """ /**** *%s */ - case function_%s : - { - symbol_c *last_type_symbol = NULL; -""" %(fname, fname.lower()) - indent = " " - - st_code_gen += recurse_and_indent(fdecls, indent).replace('\n','\n ') - - st_code_gen += """ - }/*function_%s*/ - break; -""" %(fname.lower()) - st_code_gen += """ - case function_none : - ERROR; + case function_%s : + { + symbol_c *last_type_symbol = NULL; +""" %(fname, fname.lower()) + indent = " " + + st_code_gen += recurse_and_indent(fdecls, indent).replace('\n','\n ') + + st_code_gen += """ + }/*function_%s*/ + break; +""" %(fname.lower()) + st_code_gen += """ + case function_none : + ERROR; } return NULL; """ - - # Generate the part of search_expression_type_c::visit(function_invocation) - # that is responsible of returning type symbol for function invocation. - search_type_code = """ + # Generate the part of generate_cc_il_c::visit(il_function_call) + # that is responsible to generate C code for std lib calls. + il_code_gen = """ /**** * IEC 61131-3 standard function lib * generated code, do not edit by hand */ switch(current_function_type){ """ - - for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: - search_type_code += """ + + for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: + il_code_gen += """ /**** *%s */ - case function_%s : - { - symbol_c *last_type_symbol = NULL; -""" %(fname, fname.lower()) - indent = " " - - search_type_code += recurse_and_indent(fdecls, indent, True).replace('\n','\n ') - - search_type_code += """ - }/*function_%s*/ - break; -""" %(fname.lower()) - search_type_code += """ - case function_none : - ERROR; + case function_%s : + { + symbol_c *last_type_symbol = NULL; +""" %(fname, fname.lower()) + indent = " " + + il_code_gen += recurse_and_indent(fdecls, indent).replace('\n','\n ') + + il_code_gen += """ + }/*function_%s*/ + break; +""" %(fname.lower()) + st_code_gen += """ + case function_none : + ERROR; } return NULL; """ - - # Now, print that out, or write to files from sys.argv - for name, ext in [ - ('function_type_decl','h'), - ('get_function_type_decl','c'), - ('st_code_gen','c'), - ('search_type_code','c')]: - fd = open(os.path.join(sys.argv[1],name+'.'+ext),'w') - fd.write(eval(name)) - fd.close() + # Generate the part of search_expression_type_c::visit(function_invocation) + # that is responsible of returning type symbol for function invocation. + search_type_code = """ +/**** + * IEC 61131-3 standard function lib + * generated code, do not edit by hand + */ +switch(current_function_type){ +""" + + for fname, fdecls in [ (fname,std_fdecls[fname]) for fname in official_order ]: + search_type_code += """ +/**** + *%s + */ + case function_%s : + { + symbol_c *last_type_symbol = NULL; +""" %(fname, fname.lower()) + indent = " " + + search_type_code += recurse_and_indent(fdecls, indent, True).replace('\n','\n ') + + search_type_code += """ + }/*function_%s*/ + break; +""" %(fname.lower()) + search_type_code += """ + case function_none : + ERROR; +} +return NULL; +""" + + + # Now, print that out, or write to files from sys.argv + for name, ext in [ + ('function_type_decl','h'), + ('get_function_type_decl','c'), + ('st_code_gen','c'), + ('il_code_gen','c'), + ('search_type_code','c')]: + fd = open(os.path.join(sys.argv[1],name+'.'+ext),'w') + fd.write(eval(name)) + fd.close() else: - # Put standard functions declaration in Bloktypes - BlockTypes.extend(get_standard_funtions(csv_file_to_table(open(os.path.join(sys.path[0], "plcopen/iec_std.csv"))))) - \ No newline at end of file + # Put standard functions declaration in Bloktypes + BlockTypes.extend(get_standard_funtions(csv_file_to_table(open(os.path.join(sys.path[0], "plcopen/iec_std.csv"))))) + + \ No newline at end of file