--- a/TextViewer.py Wed Jun 08 18:35:28 2011 +0200
+++ b/TextViewer.py Wed Jun 08 18:44:25 2011 +0200
@@ -40,9 +40,9 @@
LETTERS.append(chr(ord('a') + i))
LETTERS.append(chr(ord('A') + i))
-[STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_VARIABLE,
- STC_PLC_FUNCTION, STC_PLC_JUMP, STC_PLC_ERROR] = range(7)
-[SPACE, WORD, NUMBER, COMMENT] = range(4)
+[STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_STRING,
+ STC_PLC_VARIABLE, STC_PLC_FUNCTION, STC_PLC_JUMP, STC_PLC_ERROR] = range(8)
+[SPACE, WORD, NUMBER, STRING, WSTRING, COMMENT] = range(6)
[ID_TEXTVIEWER,
] = [wx.NewId() for _init_ctrls in range(1)]
@@ -67,6 +67,7 @@
re_texts["identifier"] = "((?:%(letter)s|(?:_(?:%(letter)s|%(digit)s)))(?:_?(?:%(letter)s|%(digit)s))*)"%re_texts
IDENTIFIER_MODEL = re.compile(re_texts["identifier"])
LABEL_MODEL = re.compile("[ \t\n]%(identifier)s:[ \t\n]"%re_texts)
+EXTENSIBLE_PARAMETER = re.compile("IN[1-9][0-9]*$")
def GetCursorPos(old, new):
old_length = len(old)
@@ -122,6 +123,7 @@
self.StyleSetSpec(STC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces)
self.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces)
self.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
+ self.StyleSetSpec(STC_PLC_STRING, "fore:#7F007F,size:%(size)d" % faces)
self.StyleSetSpec(STC_PLC_JUMP, "fore:#007F00,size:%(size)d" % faces)
self.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
@@ -142,7 +144,8 @@
self.Keywords = []
self.Variables = {}
- self.Functions = []
+ self.Functions = {}
+ self.TypeNames = []
self.Jumps = []
self.EnumeratedValues = []
self.DisableEvents = True
@@ -153,6 +156,7 @@
self.Debug = debug
self.InstancePath = instancepath
self.StructElementsStack = []
+ self.FunctionCallStack = []
self.ParentWindow = window
self.Controler = controler
@@ -286,8 +290,9 @@
self.Colourise(0, -1)
def RefreshJumpList(self):
- self.Jumps = [jump.upper() for jump in LABEL_MODEL.findall(self.GetText())]
- self.Colourise(0, -1)
+ if self.TextSyntax != "IL":
+ self.Jumps = [jump.upper() for jump in LABEL_MODEL.findall(self.GetText())]
+ self.Colourise(0, -1)
# Buffer the last model state
def RefreshBuffer(self):
@@ -328,15 +333,25 @@
self.RefreshVariableTree()
- self.Functions = []
+ self.TypeNames = [typename.upper() for typename in self.Controler.GetDataTypes(self.TagName, True, self.Debug)]
+ self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()]
+
+ self.Functions = {}
for category in self.Controler.GetBlockTypes(self.TagName, self.Debug):
for blocktype in category["list"]:
if blocktype["type"] == "function" and blocktype["name"] not in self.Keywords and blocktype["name"] not in self.Variables.keys():
- self.Functions.append(blocktype["name"].upper())
-
- self.EnumeratedValues = []
- for value in self.Controler.GetEnumeratedDataValues():
- self.EnumeratedValues.append(value.upper())
+ if self.Functions.has_key(blocktype["name"]):
+ for name, type, modifier in blocktype["inputs"]:
+ if name not in self.Functions[blocktype["name"]]["inputs"]:
+ self.Functions[blocktype["name"]]["inputs"].append(name)
+ for name, type, modifier in blocktype["outputs"]:
+ if name not in self.Functions[blocktype["name"]]["outputs"]:
+ self.Functions[blocktype["name"]]["outputs"].append(name)
+ self.Functions[blocktype["name"]]["extensible"] |= blocktype["extensible"]
+ else:
+ self.Functions[blocktype["name"]] = {"inputs": [name for name, type, modifier in blocktype["inputs"]],
+ "outputs": [name for name, type, modifier in blocktype["outputs"]],
+ "extensible": blocktype["extensible"]}
self.Colourise(0, -1)
@@ -364,6 +379,15 @@
return self.IsValidVariable(name_list[1:], sub_tree)
return False
+ def IsFunctionParameter(self, param_name, func_name):
+ if func_name is not None:
+ func_decl = self.Functions.get(func_name, None)
+ if func_decl is not None:
+ return (param_name.upper() in func_decl["inputs"] or
+ param_name.upper() in func_decl["outputs"] or
+ func_decl["extensible"] and EXTENSIBLE_PARAMETER.match(param_name.upper()) is not None)
+ return False
+
def OnStyleNeeded(self, event):
self.TextChanged = True
line = self.LineFromPosition(self.GetEndStyled())
@@ -375,6 +399,7 @@
self.StartStyling(start_pos, 0xff)
struct_elements = []
+ current_function = None
current_pos = last_styled_pos
state = SPACE
@@ -384,18 +409,19 @@
char = chr(self.GetCharAt(current_pos)).upper()
line += char
if char == NEWLINE:
+ self.StructElementsStack = []
if state == COMMENT:
self.SetStyling(current_pos - last_styled_pos + 1, STC_PLC_COMMENT)
elif state == NUMBER:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER)
elif state == WORD:
- if word in self.Keywords:
+ if word in self.Keywords or word in self.TypeNames:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD)
- elif self.IsValidVariable(struct_elements + [word], self.Variables):
+ elif self.IsValidVariable(struct_elements + [word], self.Variables) or self.IsFunctionParameter(word, current_function):
self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE)
elif word in self.Functions:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION)
- elif word in self.Jumps:
+ elif self.TextSyntax == "IL" and word in self.Jumps:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP)
elif word in self.EnumeratedValues:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER)
@@ -422,6 +448,25 @@
self.SetStyling(current_pos - last_styled_pos + 2, STC_PLC_COMMENT)
last_styled_pos = current_pos + 1
state = SPACE
+ elif (line.endswith("'") or line.endswith('"')) and state not in [COMMENT, STRING, WSTRING]:
+ self.SetStyling(current_pos - last_styled_pos, 31)
+ last_styled_pos = current_pos
+ if state == WORD:
+ struct_elements = []
+ if line.endswith("'"):
+ state = STRING
+ else:
+ state = WSTRING
+ elif state == STRING:
+ if line.endswith("'") and not line.endswith("$'"):
+ self.SetStyling(current_pos - last_styled_pos + 1, STC_PLC_STRING)
+ last_styled_pos = current_pos + 1
+ state = SPACE
+ elif state == WSTRING:
+ if line.endswith('"') and not line.endswith('$"'):
+ self.SetStyling(current_pos - last_styled_pos + 1, STC_PLC_STRING)
+ last_styled_pos = current_pos + 1
+ state = SPACE
elif char in LETTERS:
if state == NUMBER:
word = "#"
@@ -440,15 +485,18 @@
state = NUMBER
if state == WORD and char != '.':
word += char
+ elif char == '(' and state == SPACE:
+ self.FunctionCallStack.append(current_function)
+ current_function = None
else:
if state == WORD:
- if word in self.Keywords:
+ if word in self.Keywords or word in self.TypeNames:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD)
- elif self.IsValidVariable(struct_elements + [word], self.Variables):
+ elif self.IsValidVariable(struct_elements + [word], self.Variables) or self.IsFunctionParameter(word, current_function):
self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE)
elif word in self.Functions:
- self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION)
- elif word in self.Jumps:
+ self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION)
+ elif self.TextSyntax == "IL" and word in self.Jumps:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP)
elif word in self.EnumeratedValues:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER)
@@ -461,10 +509,20 @@
if char == '.':
if word != "]":
struct_elements.append(word)
+ elif char == '(':
+ self.FunctionCallStack.append(current_function)
+ if word in self.Functions:
+ current_function = word
+ struct_elements = []
+ else:
+ if self.IsValidVariable(struct_elements + [word], self.Variables):
+ struct_elements.append(word)
+ current_function = None
else:
if char == '[':
self.StructElementsStack.append(struct_elements + [word])
struct_elements = []
+
word = ""
last_styled_pos = current_pos
state = SPACE
@@ -475,19 +533,27 @@
if char == ']':
if len(self.StructElementsStack) > 0:
struct_elements = self.StructElementsStack.pop()
+ else:
+ struct_elements = []
word = char
state = WORD
+ elif char == ')':
+ struct_elements = []
+ if len(self.FunctionCallStack) > 0:
+ current_function = self.FunctionCallStack.pop()
+ else:
+ current_function = None
current_pos += 1
if state == COMMENT:
self.SetStyling(current_pos - last_styled_pos + 2, STC_PLC_COMMENT)
elif state == NUMBER:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER)
elif state == WORD:
- if word in self.Keywords:
+ if word in self.Keywords or word in self.TypeNames:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD)
- elif self.IsValidVariable(struct_elements + [word], self.Variables):
+ elif self.IsValidVariable(struct_elements + [word], self.Variables) or self.IsFunctionParameter(word, current_function):
self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE)
- elif word in self.Functions:
+ elif self.TextSyntax == "IL" and word in self.Functions:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION)
elif word in self.Jumps:
self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP)