plcopen/structures.py
changeset 1730 64d8f52bc8c8
parent 1571 486f94a8032c
child 1732 94ffe74e6895
equal deleted inserted replaced
1726:d51af006fa6b 1730:64d8f52bc8c8
    90 #-------------------------------------------------------------------------------
    90 #-------------------------------------------------------------------------------
    91 
    91 
    92 
    92 
    93 """
    93 """
    94 take a .csv file and translate it it a "csv_table"
    94 take a .csv file and translate it it a "csv_table"
    95 """            
    95 """
    96 def csv_file_to_table(file):
    96 def csv_file_to_table(file):
    97     return [ map(string.strip,line.split(';')) for line in file.xreadlines()]
    97     return [ map(string.strip,line.split(';')) for line in file.xreadlines()]
    98 
    98 
    99 """
    99 """
   100 seek into the csv table to a section ( section_name match 1st field )
   100 seek into the csv table to a section ( section_name match 1st field )
   117     while(fields[1]):
   117     while(fields[1]):
   118         fields = table.pop(0)
   118         fields = table.pop(0)
   119         variable_from_csv = dict([(champ, val) for champ, val in zip(variables, fields[1:]) if champ!=''])
   119         variable_from_csv = dict([(champ, val) for champ, val in zip(variables, fields[1:]) if champ!=''])
   120         standard_funtions_input_variables[variable_from_csv['name']] = variable_from_csv['type']
   120         standard_funtions_input_variables[variable_from_csv['name']] = variable_from_csv['type']
   121     return standard_funtions_input_variables
   121     return standard_funtions_input_variables
   122     
   122 
   123 """
   123 """
   124 translate .csv file input declaration into PLCOpenEditor interessting values
   124 translate .csv file input declaration into PLCOpenEditor interessting values
   125 in : "(ANY_NUM, ANY_NUM)" and { ParameterName: Type, ...}
   125 in : "(ANY_NUM, ANY_NUM)" and { ParameterName: Type, ...}
   126 return [("IN1","ANY_NUM","none"),("IN2","ANY_NUM","none")] 
   126 return [("IN1","ANY_NUM","none"),("IN2","ANY_NUM","none")]
   127 """
   127 """
   128 def csv_input_translate(str_decl, variables, base):
   128 def csv_input_translate(str_decl, variables, base):
   129     decl = str_decl.replace('(','').replace(')','').replace(' ','').split(',')
   129     decl = str_decl.replace('(','').replace(')','').replace(' ','').split(',')
   130     params = []
   130     params = []
   131     
   131 
   132     len_of_not_predifined_variable = len([True for param_type in decl if param_type not in variables])
   132     len_of_not_predifined_variable = len([True for param_type in decl if param_type not in variables])
   133     
   133 
   134     for param_type in decl:
   134     for param_type in decl:
   135         if param_type in variables.keys():
   135         if param_type in variables.keys():
   136             param_name = param_type
   136             param_name = param_type
   137             param_type = variables[param_type]
   137             param_type = variables[param_type]
   138         elif len_of_not_predifined_variable > 1:
   138         elif len_of_not_predifined_variable > 1:
   145 
   145 
   146 
   146 
   147 """
   147 """
   148 Returns this kind of declaration for all standard functions
   148 Returns this kind of declaration for all standard functions
   149 
   149 
   150             [{"name" : "Numerical", 'list': [   {   
   150             [{"name" : "Numerical", 'list': [   {
   151                 'baseinputnumber': 1,
   151                 'baseinputnumber': 1,
   152                 'comment': 'Addition',
   152                 'comment': 'Addition',
   153                 'extensible': True,
   153                 'extensible': True,
   154                 'inputs': [   ('IN1', 'ANY_NUM', 'none'),
   154                 'inputs': [   ('IN1', 'ANY_NUM', 'none'),
   155                               ('IN2', 'ANY_NUM', 'none')],
   155                               ('IN2', 'ANY_NUM', 'none')],
   156                 'name': 'ADD',
   156                 'name': 'ADD',
   157                 'outputs': [('OUT', 'ANY_NUM', 'none')],
   157                 'outputs': [('OUT', 'ANY_NUM', 'none')],
   158                 'type': 'function'}, ...... ] },.....]
   158                 'type': 'function'}, ...... ] },.....]
   159 """
   159 """
   160 def get_standard_funtions(table):
   160 def get_standard_funtions(table):
   161     
   161 
   162     variables = get_standard_funtions_input_variables(table)
   162     variables = get_standard_funtions_input_variables(table)
   163     
   163 
   164     fonctions = find_section("Standard_functions_type",table)
   164     fonctions = find_section("Standard_functions_type",table)
   165 
   165 
   166     Standard_Functions_Decl = []
   166     Standard_Functions_Decl = []
   167     Current_section = None
   167     Current_section = None
   168     
   168 
   169     translate = {
   169     translate = {
   170             "extensible" : lambda x: {"yes":True, "no":False}[x],
   170             "extensible" : lambda x: {"yes":True, "no":False}[x],
   171             "inputs" : lambda x:csv_input_translate(x,variables,baseinputnumber),
   171             "inputs" : lambda x:csv_input_translate(x,variables,baseinputnumber),
   172             "outputs":lambda x:[("OUT",x,"none")]}
   172             "outputs":lambda x:[("OUT",x,"none")]}
   173     
   173 
   174     for fields in table:
   174     for fields in table:
   175         if fields[1]:
   175         if fields[1]:
   176             # If function section name given
   176             # If function section name given
   177             if fields[0]:
   177             if fields[0]:
   178                 words = fields[0].split('"')
   178                 words = fields[0].split('"')
   189                 Function_decl["baseinputnumber"] = baseinputnumber
   189                 Function_decl["baseinputnumber"] = baseinputnumber
   190                 for param, value in Function_decl.iteritems():
   190                 for param, value in Function_decl.iteritems():
   191                     if param in translate:
   191                     if param in translate:
   192                         Function_decl[param] = translate[param](value)
   192                         Function_decl[param] = translate[param](value)
   193                 Function_decl["type"] = "function"
   193                 Function_decl["type"] = "function"
   194                 
   194 
   195                 if Function_decl["name"].startswith('*') or Function_decl["name"].endswith('*') :
   195                 if Function_decl["name"].startswith('*') or Function_decl["name"].endswith('*') :
   196                     input_ovrloading_types = GetSubTypes(Function_decl["inputs"][0][1])
   196                     input_ovrloading_types = GetSubTypes(Function_decl["inputs"][0][1])
   197                     output_types = GetSubTypes(Function_decl["outputs"][0][1])
   197                     output_types = GetSubTypes(Function_decl["outputs"][0][1])
   198                 else:
   198                 else:
   199                     input_ovrloading_types = [None]
   199                     input_ovrloading_types = [None]
   200                     output_types = [None]
   200                     output_types = [None]
   201                 
   201 
   202                 funcdeclname_orig = Function_decl["name"]
   202                 funcdeclname_orig = Function_decl["name"]
   203                 funcdeclname = Function_decl["name"].strip('*_')
   203                 funcdeclname = Function_decl["name"].strip('*_')
   204                 fdc = Function_decl["inputs"][:]
   204                 fdc = Function_decl["inputs"][:]
   205                 for intype in input_ovrloading_types:
   205                 for intype in input_ovrloading_types:
   206                     if intype != None:
   206                     if intype != None:
   208                         for decl_tpl in fdc:
   208                         for decl_tpl in fdc:
   209                             if IsOfType(intype, decl_tpl[1]):
   209                             if IsOfType(intype, decl_tpl[1]):
   210                                 Function_decl["inputs"] += [(decl_tpl[0], intype, decl_tpl[2])]
   210                                 Function_decl["inputs"] += [(decl_tpl[0], intype, decl_tpl[2])]
   211                             else:
   211                             else:
   212                                 Function_decl["inputs"] += [(decl_tpl)]
   212                                 Function_decl["inputs"] += [(decl_tpl)]
   213                             
   213 
   214                             if funcdeclname_orig.startswith('*'):
   214                             if funcdeclname_orig.startswith('*'):
   215                                 funcdeclin = intype + '_' + funcdeclname 
   215                                 funcdeclin = intype + '_' + funcdeclname
   216                             else:
   216                             else:
   217                                 funcdeclin = funcdeclname
   217                                 funcdeclin = funcdeclname
   218                     else:
   218                     else:
   219                         funcdeclin = funcdeclname
   219                         funcdeclin = funcdeclname
   220                         
   220 
   221                     for outype in output_types:
   221                     for outype in output_types:
   222                         if outype != None:
   222                         if outype != None:
   223                             decl_tpl = Function_decl["outputs"][0]
   223                             decl_tpl = Function_decl["outputs"][0]
   224                             Function_decl["outputs"] = [ (decl_tpl[0] , outype,  decl_tpl[2])]
   224                             Function_decl["outputs"] = [ (decl_tpl[0] , outype,  decl_tpl[2])]
   225                             if funcdeclname_orig.endswith('*'):
   225                             if funcdeclname_orig.endswith('*'):
   232 
   232 
   233                         # apply filter given in "filter" column
   233                         # apply filter given in "filter" column
   234                         filter_name = Function_decl["filter"]
   234                         filter_name = Function_decl["filter"]
   235                         store = True
   235                         store = True
   236                         for (InTypes, OutTypes) in ANY_TO_ANY_FILTERS.get(filter_name,[]):
   236                         for (InTypes, OutTypes) in ANY_TO_ANY_FILTERS.get(filter_name,[]):
   237                             outs = reduce(lambda a,b: a or b, 
   237                             outs = reduce(lambda a,b: a or b,
   238                                        map(lambda testtype : IsOfType(
   238                                        map(lambda testtype : IsOfType(
   239                                            Function_decl["outputs"][0][1],
   239                                            Function_decl["outputs"][0][1],
   240                                            testtype), OutTypes))
   240                                            testtype), OutTypes))
   241                             inps = reduce(lambda a,b: a or b,
   241                             inps = reduce(lambda a,b: a or b,
   242                                        map(lambda testtype : IsOfType(
   242                                        map(lambda testtype : IsOfType(
   251                             # create the copy of decl dict to be appended to section
   251                             # create the copy of decl dict to be appended to section
   252                             Function_decl_copy = Function_decl.copy()
   252                             Function_decl_copy = Function_decl.copy()
   253                             Current_section["list"].append(Function_decl_copy)
   253                             Current_section["list"].append(Function_decl_copy)
   254             else:
   254             else:
   255                 raise "First function must be in a category"
   255                 raise "First function must be in a category"
   256     
   256 
   257     return Standard_Functions_Decl
   257     return Standard_Functions_Decl
   258 
   258 
   259 StdBlckLst.extend(get_standard_funtions(csv_file_to_table(open(StdFuncsCSV))))
   259 StdBlckLst.extend(get_standard_funtions(csv_file_to_table(open(StdFuncsCSV))))
   260 
   260 
   261 # Dictionary to speedup block type fetching by name
   261 # Dictionary to speedup block type fetching by name
   264 for section in StdBlckLst:
   264 for section in StdBlckLst:
   265     for desc in section["list"]:
   265     for desc in section["list"]:
   266         words = desc["comment"].split('"')
   266         words = desc["comment"].split('"')
   267         if len(words) > 1:
   267         if len(words) > 1:
   268             desc["comment"] = words[1]
   268             desc["comment"] = words[1]
   269         desc["usage"] = ("\n (%s) => (%s)" % 
   269         desc["usage"] = ("\n (%s) => (%s)" %
   270             (", ".join(["%s:%s" % (input[1], input[0]) 
   270             (", ".join(["%s:%s" % (input[1], input[0])
   271                         for input in desc["inputs"]]),
   271                         for input in desc["inputs"]]),
   272              ", ".join(["%s:%s" % (output[1], output[0]) 
   272              ", ".join(["%s:%s" % (output[1], output[0])
   273                         for output in desc["outputs"]])))
   273                         for output in desc["outputs"]])))
   274         BlkLst = StdBlckDct.setdefault(desc["name"],[])
   274         BlkLst = StdBlckDct.setdefault(desc["name"],[])
   275         BlkLst.append((section["name"], desc))
   275         BlkLst.append((section["name"], desc))
   276 
   276 
   277 #-------------------------------------------------------------------------------
   277 #-------------------------------------------------------------------------------
   319 
   319 
   320 
   320 
   321 # Keywords for Structured Text
   321 # Keywords for Structured Text
   322 ST_BLOCK_START_KEYWORDS = ["IF", "ELSIF", "ELSE", "CASE", "FOR", "WHILE", "REPEAT"]
   322 ST_BLOCK_START_KEYWORDS = ["IF", "ELSIF", "ELSE", "CASE", "FOR", "WHILE", "REPEAT"]
   323 ST_BLOCK_END_KEYWORDS = ["END_IF", "END_CASE", "END_FOR", "END_WHILE", "END_REPEAT"]
   323 ST_BLOCK_END_KEYWORDS = ["END_IF", "END_CASE", "END_FOR", "END_WHILE", "END_REPEAT"]
   324 ST_KEYWORDS = ["TRUE", "FALSE", "THEN", "OF", "TO", "BY", "DO", "DO", "UNTIL", "EXIT", 
   324 ST_KEYWORDS = ["TRUE", "FALSE", "THEN", "OF", "TO", "BY", "DO", "DO", "UNTIL", "EXIT",
   325  "RETURN", "NOT", "MOD", "AND", "XOR", "OR"] + ST_BLOCK_START_KEYWORDS + ST_BLOCK_END_KEYWORDS
   325  "RETURN", "NOT", "MOD", "AND", "XOR", "OR"] + ST_BLOCK_START_KEYWORDS + ST_BLOCK_END_KEYWORDS
   326 
   326 
   327 # All the keywords of IEC
   327 # All the keywords of IEC
   328 IEC_BLOCK_START_KEYWORDS = []
   328 IEC_BLOCK_START_KEYWORDS = []
   329 IEC_BLOCK_END_KEYWORDS = []
   329 IEC_BLOCK_END_KEYWORDS = []
   336                                                               SFC_BLOCK_END_KEYWORDS, ST_BLOCK_END_KEYWORDS]),
   336                                                               SFC_BLOCK_END_KEYWORDS, ST_BLOCK_END_KEYWORDS]),
   337                                     (IEC_KEYWORDS, [POU_KEYWORDS, TYPE_KEYWORDS, VAR_KEYWORDS, CONFIG_KEYWORDS,
   337                                     (IEC_KEYWORDS, [POU_KEYWORDS, TYPE_KEYWORDS, VAR_KEYWORDS, CONFIG_KEYWORDS,
   338                                                     SFC_KEYWORDS, IL_KEYWORDS, ST_KEYWORDS])]:
   338                                                     SFC_KEYWORDS, IL_KEYWORDS, ST_KEYWORDS])]:
   339     for keywords in keywords_list:
   339     for keywords in keywords_list:
   340         all_keywords.extend([keyword for keyword in keywords if keyword not in all_keywords])
   340         all_keywords.extend([keyword for keyword in keywords if keyword not in all_keywords])
   341 
       
   342