diff -r cce4903be769 -r 2f660878c2a7 TextViewer.py --- 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)