--- a/plcopen/structures.py Mon Aug 21 20:17:19 2017 +0000
+++ b/plcopen/structures.py Mon Aug 21 23:22:58 2017 +0300
@@ -22,17 +22,19 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-import string, re
+import string
+import re
from plcopen import LoadProject
from collections import OrderedDict
from definitions import *
TypeHierarchy = dict(TypeHierarchy_list)
-"""
-returns true if the given data type is the same that "reference" meta-type or one of its types.
-"""
+
def IsOfType(type, reference):
+ """
+ Returns true if the given data type is the same that "reference" meta-type or one of its types.
+ """
if reference is None:
return True
elif type == reference:
@@ -43,12 +45,14 @@
return IsOfType(parent_type, reference)
return False
-"""
-returns list of all types that correspont to the ANY* meta type
-"""
+
def GetSubTypes(type):
+ """
+ Returns list of all types that correspont to the ANY* meta type
+ """
return [typename for typename, parenttype in TypeHierarchy.items() if not typename.startswith("ANY") and IsOfType(typename, type)]
+
DataTypeRange = dict(DataTypeRange_list)
"""
@@ -67,76 +71,82 @@
- The default modifier which can be "none", "negated", "rising" or "falling"
"""
-StdBlckLibs = {libname : LoadProject(tc6fname)[0]
- for libname, tc6fname in StdTC6Libs}
-StdBlckLst = [{"name" : libname, "list":
+StdBlckLibs = {libname: LoadProject(tc6fname)[0]
+ for libname, tc6fname in StdTC6Libs}
+StdBlckLst = [{"name": libname, "list":
[GetBlockInfos(pous) for pous in lib.getpous()]}
- for libname, lib in StdBlckLibs.iteritems()]
-
-#-------------------------------------------------------------------------------
+ for libname, lib in StdBlckLibs.iteritems()]
+
+# -------------------------------------------------------------------------------
# Test identifier
-#-------------------------------------------------------------------------------
+# -------------------------------------------------------------------------------
IDENTIFIER_MODEL = re.compile(
"(?:%(letter)s|_(?:%(letter)s|%(digit)s))(?:_?(?:%(letter)s|%(digit)s))*$" %
{"letter": "[a-zA-Z]", "digit": "[0-9]"})
-# Test if identifier is valid
+
def TestIdentifier(identifier):
- return IDENTIFIER_MODEL.match(identifier) is not None
-
-#-------------------------------------------------------------------------------
+ """
+ Test if identifier is valid
+ """
+ return IDENTIFIER_MODEL.match(identifier) is not None
+
+# -------------------------------------------------------------------------------
# Standard functions list generation
-#-------------------------------------------------------------------------------
-
-
-"""
-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()]
-
-"""
-seek into the csv table to a section ( section_name match 1st field )
-return the matching row without first field
-"""
+ """
+ take a .csv file and translate it it a "csv_table"
+ """
+ return [map(string.strip, line.split(';')) for line in file.xreadlines()]
+
+
def find_section(section_name, table):
+ """
+ seek into the csv table to a section ( section_name match 1st field )
+ return the matching row without first field
+ """
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):
+ """
+ extract the standard functions standard parameter names and types...
+ return a { ParameterName: Type, ...}
+ """
variables = find_section("Standard_functions_variables_types", table)
standard_funtions_input_variables = {}
- fields = [True,True]
+ 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!=''])
+ 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(',')
+ """
+ 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")]
+ """
+ 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
+ param_name = "IN%d" % base
base += 1
else:
param_name = "IN"
@@ -144,10 +154,11 @@
return params
-"""
-Returns this kind of declaration for all standard functions
-
- [{"name" : "Numerical", 'list': [ {
+def get_standard_funtions(table):
+ """
+ Returns this kind of declaration for all standard functions
+
+ [{"name" : "Numerical", 'list': [ {
'baseinputnumber': 1,
'comment': 'Addition',
'extensible': True,
@@ -156,21 +167,20 @@
'name': 'ADD',
'outputs': [('OUT', 'ANY_NUM', 'none')],
'type': 'function'}, ...... ] },.....]
-"""
-def get_standard_funtions(table):
-
+ """
+
variables = get_standard_funtions_input_variables(table)
-
- fonctions = find_section("Standard_functions_type",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")]}
-
+ "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
@@ -180,82 +190,83 @@
section_name = words[1]
else:
section_name = fields[0]
- Current_section = {"name" : section_name, "list" : []}
+ Current_section = {"name": section_name, "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))
+ 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('*') or Function_decl["name"].endswith('*') :
+
+ if Function_decl["name"].startswith('*') or Function_decl["name"].endswith('*'):
input_ovrloading_types = GetSubTypes(Function_decl["inputs"][0][1])
output_types = GetSubTypes(Function_decl["outputs"][0][1])
else:
input_ovrloading_types = [None]
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:
+ if intype is not 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
+ funcdeclin = intype + '_' + funcdeclname
else:
funcdeclin = funcdeclname
else:
funcdeclin = funcdeclname
-
+
for outype in output_types:
- if outype != None:
+ if outype is not None:
decl_tpl = Function_decl["outputs"][0]
- Function_decl["outputs"] = [ (decl_tpl[0] , outype, decl_tpl[2])]
+ Function_decl["outputs"] = [(decl_tpl[0], outype, decl_tpl[2])]
if funcdeclname_orig.endswith('*'):
- funcdeclout = funcdeclin + '_' + outype
+ funcdeclout = funcdeclin + '_' + outype
else:
- funcdeclout = funcdeclin
+ funcdeclout = funcdeclin
else:
- funcdeclout = funcdeclin
+ funcdeclout = funcdeclin
Function_decl["name"] = funcdeclout
# apply filter given in "filter" column
filter_name = Function_decl["filter"]
store = True
- for (InTypes, OutTypes) in ANY_TO_ANY_FILTERS.get(filter_name,[]):
- outs = reduce(lambda a,b: a or b,
- map(lambda testtype : IsOfType(
- Function_decl["outputs"][0][1],
- testtype), OutTypes))
- inps = reduce(lambda a,b: a or b,
- map(lambda testtype : IsOfType(
- Function_decl["inputs"][0][1],
- testtype), InTypes))
+ for (InTypes, OutTypes) in ANY_TO_ANY_FILTERS.get(filter_name, []):
+ outs = reduce(lambda a, b: a or b,
+ map(lambda testtype: IsOfType(
+ Function_decl["outputs"][0][1],
+ testtype), OutTypes))
+ inps = reduce(lambda a, b: a or b,
+ map(lambda testtype: IsOfType(
+ Function_decl["inputs"][0][1],
+ testtype), InTypes))
if inps and outs and Function_decl["outputs"][0][1] != Function_decl["inputs"][0][1]:
store = True
break
else:
store = False
- if store :
+ if store:
# create the copy of decl dict to be appended to section
Function_decl_copy = Function_decl.copy()
Current_section["list"].append(Function_decl_copy)
else:
raise "First function must be in a category"
-
+
return Standard_Functions_Decl
+
StdBlckLst.extend(get_standard_funtions(csv_file_to_table(open(StdFuncsCSV))))
# Dictionary to speedup block type fetching by name
@@ -266,17 +277,17 @@
words = desc["comment"].split('"')
if len(words) > 1:
desc["comment"] = words[1]
- desc["usage"] = ("\n (%s) => (%s)" %
- (", ".join(["%s:%s" % (input[1], input[0])
- for input in desc["inputs"]]),
- ", ".join(["%s:%s" % (output[1], output[0])
- for output in desc["outputs"]])))
- BlkLst = StdBlckDct.setdefault(desc["name"],[])
+ desc["usage"] = ("\n (%s) => (%s)" %
+ (", ".join(["%s:%s" % (input[1], input[0])
+ for input in desc["inputs"]]),
+ ", ".join(["%s:%s" % (output[1], output[0])
+ for output in desc["outputs"]])))
+ BlkLst = StdBlckDct.setdefault(desc["name"], [])
BlkLst.append((section["name"], desc))
-#-------------------------------------------------------------------------------
+# -------------------------------------------------------------------------------
# Languages Keywords
-#-------------------------------------------------------------------------------
+# -------------------------------------------------------------------------------
# Keywords for Pou Declaration
POU_BLOCK_START_KEYWORDS = ["FUNCTION", "FUNCTION_BLOCK", "PROGRAM"]
@@ -313,16 +324,20 @@
# Keywords for Instruction List
-IL_KEYWORDS = ["TRUE", "FALSE", "LD", "LDN", "ST", "STN", "S", "R", "AND", "ANDN", "OR", "ORN",
- "XOR", "XORN", "NOT", "ADD", "SUB", "MUL", "DIV", "MOD", "GT", "GE", "EQ", "NE",
- "LE", "LT", "JMP", "JMPC", "JMPCN", "CAL", "CALC", "CALCN", "RET", "RETC", "RETCN"]
+IL_KEYWORDS = [
+ "TRUE", "FALSE", "LD", "LDN", "ST", "STN", "S", "R", "AND", "ANDN", "OR", "ORN",
+ "XOR", "XORN", "NOT", "ADD", "SUB", "MUL", "DIV", "MOD", "GT", "GE", "EQ", "NE",
+ "LE", "LT", "JMP", "JMPC", "JMPCN", "CAL", "CALC", "CALCN", "RET", "RETC", "RETCN"
+]
# Keywords for Structured Text
ST_BLOCK_START_KEYWORDS = ["IF", "ELSIF", "ELSE", "CASE", "FOR", "WHILE", "REPEAT"]
ST_BLOCK_END_KEYWORDS = ["END_IF", "END_CASE", "END_FOR", "END_WHILE", "END_REPEAT"]
-ST_KEYWORDS = ["TRUE", "FALSE", "THEN", "OF", "TO", "BY", "DO", "DO", "UNTIL", "EXIT",
- "RETURN", "NOT", "MOD", "AND", "XOR", "OR"] + ST_BLOCK_START_KEYWORDS + ST_BLOCK_END_KEYWORDS
+ST_KEYWORDS = [
+ "TRUE", "FALSE", "THEN", "OF", "TO", "BY", "DO", "DO", "UNTIL", "EXIT",
+ "RETURN", "NOT", "MOD", "AND", "XOR", "OR"
+] + ST_BLOCK_START_KEYWORDS + ST_BLOCK_END_KEYWORDS
# All the keywords of IEC
IEC_BLOCK_START_KEYWORDS = []
@@ -338,5 +353,3 @@
SFC_KEYWORDS, IL_KEYWORDS, ST_KEYWORDS])]:
for keywords in keywords_list:
all_keywords.extend([keyword for keyword in keywords if keyword not in all_keywords])
-
-