118 self.SetSelBackground(1, "#E0E0E0") |
119 self.SetSelBackground(1, "#E0E0E0") |
119 |
120 |
120 # Highlighting styles |
121 # Highlighting styles |
121 self.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces) |
122 self.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces) |
122 self.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces) |
123 self.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces) |
|
124 self.StyleSetSpec(STC_PLC_PARAMETER, "fore:#7F007F,size:%(size)d" % faces) |
123 self.StyleSetSpec(STC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces) |
125 self.StyleSetSpec(STC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces) |
124 self.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces) |
126 self.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces) |
125 self.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces) |
127 self.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces) |
126 self.StyleSetSpec(STC_PLC_STRING, "fore:#7F007F,size:%(size)d" % faces) |
128 self.StyleSetSpec(STC_PLC_STRING, "fore:#007F00,size:%(size)d" % faces) |
127 self.StyleSetSpec(STC_PLC_JUMP, "fore:#007F00,size:%(size)d" % faces) |
129 self.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces) |
128 self.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces) |
130 self.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces) |
129 |
131 |
130 # Indicators styles |
132 # Indicators styles |
131 self.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE) |
133 self.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE) |
132 if window and controler: |
134 if window and controler: |
337 self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()] |
339 self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()] |
338 |
340 |
339 self.Functions = {} |
341 self.Functions = {} |
340 for category in self.Controler.GetBlockTypes(self.TagName, self.Debug): |
342 for category in self.Controler.GetBlockTypes(self.TagName, self.Debug): |
341 for blocktype in category["list"]: |
343 for blocktype in category["list"]: |
342 if blocktype["type"] == "function" and blocktype["name"] not in self.Keywords and blocktype["name"] not in self.Variables.keys(): |
344 blockname = blocktype["name"].upper() |
343 if self.Functions.has_key(blocktype["name"]): |
345 if blocktype["type"] == "function" and blockname not in self.Keywords and blockname not in self.Variables.keys(): |
344 for name, type, modifier in blocktype["inputs"]: |
346 interface = dict([(name, {}) for name, type, modifier in blocktype["inputs"] + blocktype["outputs"] if name != '']) |
345 if name not in self.Functions[blocktype["name"]]["inputs"]: |
347 if self.Functions.has_key(blockname): |
346 self.Functions[blocktype["name"]]["inputs"].append(name) |
348 self.Functions[blockname]["interface"].update(interface) |
347 for name, type, modifier in blocktype["outputs"]: |
349 self.Functions[blockname]["extensible"] |= blocktype["extensible"] |
348 if name not in self.Functions[blocktype["name"]]["outputs"]: |
350 else: |
349 self.Functions[blocktype["name"]]["outputs"].append(name) |
351 self.Functions[blockname] = {"interface": interface, |
350 self.Functions[blocktype["name"]]["extensible"] |= blocktype["extensible"] |
352 "extensible": blocktype["extensible"]} |
351 else: |
|
352 self.Functions[blocktype["name"]] = {"inputs": [name for name, type, modifier in blocktype["inputs"]], |
|
353 "outputs": [name for name, type, modifier in blocktype["outputs"]], |
|
354 "extensible": blocktype["extensible"]} |
|
355 |
|
356 self.Colourise(0, -1) |
353 self.Colourise(0, -1) |
357 |
354 |
358 def RefreshVariableTree(self): |
355 def RefreshVariableTree(self): |
359 words = self.TagName.split("::") |
356 words = self.TagName.split("::") |
360 self.Variables = self.GenerateVariableTree([(variable["Name"], variable["Type"], variable["Tree"]) for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)]) |
357 self.Variables = self.GenerateVariableTree([(variable["Name"], variable["Type"], variable["Tree"]) for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)]) |
361 if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL": |
358 if self.Controler.GetEditedElementType(self.TagName, self.Debug)[1] == "function" or words[0] == "T" and self.TextSyntax == "IL": |
362 self.Variables[words[-1].upper()] = {} |
359 return_type = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug) |
|
360 if return_type is not None: |
|
361 var_tree, var_dimension = self.Controler.GenerateVarTree(return_type, self.Debug) |
|
362 self.Variables[words[-1].upper()] = self.GenerateVariableTree(var_tree) |
|
363 else: |
|
364 self.Variables[words[-1].upper()] = {} |
363 |
365 |
364 def GenerateVariableTree(self, list): |
366 def GenerateVariableTree(self, list): |
365 tree = {} |
367 tree = {} |
366 for var_name, var_type, (var_tree, var_dimension) in list: |
368 for var_name, var_type, (var_tree, var_dimension) in list: |
367 tree[var_name.upper()] = self.GenerateVariableTree(var_tree) |
369 tree[var_name.upper()] = self.GenerateVariableTree(var_tree) |
368 return tree |
370 return tree |
369 |
371 |
370 def RefreshScaling(self, refresh=True): |
372 def RefreshScaling(self, refresh=True): |
371 pass |
373 pass |
372 |
374 |
373 def IsValidVariable(self, name_list, var_tree): |
375 def IsValidVariable(self, name, context): |
374 if len(name_list) == 0: |
376 return context is not None and context.get(name, None) is not None |
375 return True |
377 |
376 else: |
378 def IsCallParameter(self, name, call): |
377 sub_tree = var_tree.get(name_list[0].upper(), None) |
379 if call is not None: |
378 if sub_tree is not None: |
380 return (call["interface"].get(name.upper(), None) is not None or |
379 return self.IsValidVariable(name_list[1:], sub_tree) |
381 call["extensible"] and EXTENSIBLE_PARAMETER.match(name.upper()) is not None) |
380 return False |
|
381 |
|
382 def IsFunctionParameter(self, param_name, func_name): |
|
383 if func_name is not None: |
|
384 func_decl = self.Functions.get(func_name, None) |
|
385 if func_decl is not None: |
|
386 return (param_name.upper() in func_decl["inputs"] or |
|
387 param_name.upper() in func_decl["outputs"] or |
|
388 func_decl["extensible"] and EXTENSIBLE_PARAMETER.match(param_name.upper()) is not None) |
|
389 return False |
382 return False |
390 |
383 |
391 def OnStyleNeeded(self, event): |
384 def OnStyleNeeded(self, event): |
392 self.TextChanged = True |
385 self.TextChanged = True |
393 line = self.LineFromPosition(self.GetEndStyled()) |
386 line = self.LineFromPosition(self.GetEndStyled()) |
396 else: |
389 else: |
397 start_pos = last_styled_pos = self.GetLineEndPosition(line - 1) + 1 |
390 start_pos = last_styled_pos = self.GetLineEndPosition(line - 1) + 1 |
398 end_pos = event.GetPosition() |
391 end_pos = event.GetPosition() |
399 self.StartStyling(start_pos, 0xff) |
392 self.StartStyling(start_pos, 0xff) |
400 |
393 |
401 struct_elements = [] |
394 current_context = self.Variables |
402 current_function = None |
395 current_call = None |
403 |
396 |
404 current_pos = last_styled_pos |
397 current_pos = last_styled_pos |
405 state = SPACE |
398 state = SPACE |
406 line = "" |
399 line = "" |
407 word = "" |
400 word = "" |
408 while current_pos < end_pos: |
401 while current_pos < end_pos: |
409 char = chr(self.GetCharAt(current_pos)).upper() |
402 char = chr(self.GetCharAt(current_pos)).upper() |
410 line += char |
403 line += char |
411 if char == NEWLINE: |
404 if char == NEWLINE: |
412 self.StructElementsStack = [] |
405 self.ContextStack = [] |
|
406 current_context = self.Variables |
413 if state == COMMENT: |
407 if state == COMMENT: |
414 self.SetStyling(current_pos - last_styled_pos + 1, STC_PLC_COMMENT) |
408 self.SetStyling(current_pos - last_styled_pos + 1, STC_PLC_COMMENT) |
415 elif state == NUMBER: |
409 elif state == NUMBER: |
416 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
410 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
417 elif state == WORD: |
411 elif state == WORD: |
418 if word in self.Keywords or word in self.TypeNames: |
412 if word in self.Keywords or word in self.TypeNames: |
419 self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD) |
413 self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD) |
420 elif self.IsValidVariable(struct_elements + [word], self.Variables) or self.IsFunctionParameter(word, current_function): |
414 elif self.IsValidVariable(word, current_context): |
421 self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE) |
415 self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE) |
|
416 elif self.IsCallParameter(word, current_call): |
|
417 self.SetStyling(current_pos - last_styled_pos, STC_PLC_PARAMETER) |
422 elif word in self.Functions: |
418 elif word in self.Functions: |
423 self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION) |
419 self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION) |
424 elif self.TextSyntax == "IL" and word in self.Jumps: |
420 elif self.TextSyntax == "IL" and word in self.Jumps: |
425 self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP) |
421 self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP) |
426 elif word in self.EnumeratedValues: |
422 elif word in self.EnumeratedValues: |
427 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
423 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
428 else: |
424 else: |
429 self.SetStyling(current_pos - last_styled_pos, 31) |
425 self.SetStyling(current_pos - last_styled_pos, 31) |
430 if word != "]" and (self.GetCurrentPos() < last_styled_pos or self.GetCurrentPos() > current_pos): |
426 if word not in ["]", ")"] and (self.GetCurrentPos() < last_styled_pos or self.GetCurrentPos() > current_pos): |
431 self.StartStyling(last_styled_pos, wx.stc.STC_INDICS_MASK) |
427 self.StartStyling(last_styled_pos, wx.stc.STC_INDICS_MASK) |
432 self.SetStyling(current_pos - last_styled_pos, wx.stc.STC_INDIC0_MASK) |
428 self.SetStyling(current_pos - last_styled_pos, wx.stc.STC_INDIC0_MASK) |
433 self.StartStyling(current_pos, 0xff) |
429 self.StartStyling(current_pos, 0xff) |
434 struct_elements = [] |
|
435 else: |
430 else: |
436 self.SetStyling(current_pos - last_styled_pos, 31) |
431 self.SetStyling(current_pos - last_styled_pos, 31) |
437 last_styled_pos = current_pos |
432 last_styled_pos = current_pos |
438 state = SPACE |
433 state = SPACE |
439 line = "" |
434 line = "" |
440 elif line.endswith("(*") and state != COMMENT: |
435 elif line.endswith("(*") and state != COMMENT: |
441 self.SetStyling(current_pos - last_styled_pos - 1, 31) |
436 self.SetStyling(current_pos - last_styled_pos - 1, 31) |
442 last_styled_pos = current_pos |
437 last_styled_pos = current_pos |
443 if state == WORD: |
438 if state == WORD: |
444 struct_elements = [] |
439 current_context = self.Variables |
445 state = COMMENT |
440 state = COMMENT |
446 elif state == COMMENT: |
441 elif state == COMMENT: |
447 if line.endswith("*)"): |
442 if line.endswith("*)"): |
448 self.SetStyling(current_pos - last_styled_pos + 2, STC_PLC_COMMENT) |
443 self.SetStyling(current_pos - last_styled_pos + 2, STC_PLC_COMMENT) |
449 last_styled_pos = current_pos + 1 |
444 last_styled_pos = current_pos + 1 |
450 state = SPACE |
445 state = SPACE |
451 elif (line.endswith("'") or line.endswith('"')) and state not in [COMMENT, STRING, WSTRING]: |
446 elif (line.endswith("'") or line.endswith('"')) and state not in [COMMENT, STRING, WSTRING]: |
452 self.SetStyling(current_pos - last_styled_pos, 31) |
447 self.SetStyling(current_pos - last_styled_pos, 31) |
453 last_styled_pos = current_pos |
448 last_styled_pos = current_pos |
454 if state == WORD: |
449 if state == WORD: |
455 struct_elements = [] |
450 current_context = self.Variables |
456 if line.endswith("'"): |
451 if line.endswith("'"): |
457 state = STRING |
452 state = STRING |
458 else: |
453 else: |
459 state = WSTRING |
454 state = WSTRING |
460 elif state == STRING: |
455 elif state == STRING: |
484 last_styled_pos = current_pos |
479 last_styled_pos = current_pos |
485 state = NUMBER |
480 state = NUMBER |
486 if state == WORD and char != '.': |
481 if state == WORD and char != '.': |
487 word += char |
482 word += char |
488 elif char == '(' and state == SPACE: |
483 elif char == '(' and state == SPACE: |
489 self.FunctionCallStack.append(current_function) |
484 self.CallStack.append(current_call) |
490 current_function = None |
485 current_call = None |
491 else: |
486 else: |
492 if state == WORD: |
487 if state == WORD: |
493 if word in self.Keywords or word in self.TypeNames: |
488 if word in self.Keywords or word in self.TypeNames: |
494 self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD) |
489 self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD) |
495 elif self.IsValidVariable(struct_elements + [word], self.Variables) or self.IsFunctionParameter(word, current_function): |
490 elif self.IsValidVariable(word, current_context): |
496 self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE) |
491 self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE) |
|
492 elif self.IsCallParameter(word, current_call): |
|
493 self.SetStyling(current_pos - last_styled_pos, STC_PLC_PARAMETER) |
497 elif word in self.Functions: |
494 elif word in self.Functions: |
498 self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION) |
495 self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION) |
499 elif self.TextSyntax == "IL" and word in self.Jumps: |
496 elif self.TextSyntax == "IL" and word in self.Jumps: |
500 self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP) |
497 self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP) |
501 elif word in self.EnumeratedValues: |
498 elif word in self.EnumeratedValues: |
502 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
499 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
503 else: |
500 else: |
504 self.SetStyling(current_pos - last_styled_pos, 31) |
501 self.SetStyling(current_pos - last_styled_pos, 31) |
505 if word != "]" and (self.GetCurrentPos() < last_styled_pos or self.GetCurrentPos() > current_pos): |
502 if word not in ["]", ")"] and (self.GetCurrentPos() < last_styled_pos or self.GetCurrentPos() > current_pos): |
506 self.StartStyling(last_styled_pos, wx.stc.STC_INDICS_MASK) |
503 self.StartStyling(last_styled_pos, wx.stc.STC_INDICS_MASK) |
507 self.SetStyling(current_pos - last_styled_pos, wx.stc.STC_INDIC0_MASK) |
504 self.SetStyling(current_pos - last_styled_pos, wx.stc.STC_INDIC0_MASK) |
508 self.StartStyling(current_pos, 0xff) |
505 self.StartStyling(current_pos, 0xff) |
509 if char == '.': |
506 if char == '.': |
510 if word != "]": |
507 if word != "]": |
511 struct_elements.append(word) |
508 if current_context is not None: |
|
509 current_context = current_context.get(word, None) |
|
510 else: |
|
511 current_context = None |
512 elif char == '(': |
512 elif char == '(': |
513 self.FunctionCallStack.append(current_function) |
513 self.CallStack.append(current_call) |
514 if word in self.Functions: |
514 current_call = self.Functions.get(word, None) |
515 current_function = word |
515 if current_call is None and self.IsValidVariable(word, current_context): |
516 struct_elements = [] |
516 current_call = {"interface": current_context.get(word, {}), |
517 else: |
517 "extensible": False} |
518 if self.IsValidVariable(struct_elements + [word], self.Variables): |
518 current_context = self.Variables |
519 struct_elements.append(word) |
|
520 current_function = None |
|
521 else: |
519 else: |
522 if char == '[': |
520 if char == '[': |
523 self.StructElementsStack.append(struct_elements + [word]) |
521 self.ContextStack.append(current_context.get(word, None)) |
524 struct_elements = [] |
522 current_context = self.Variables |
525 |
523 |
526 word = "" |
524 word = "" |
527 last_styled_pos = current_pos |
525 last_styled_pos = current_pos |
528 state = SPACE |
526 state = SPACE |
529 elif state == NUMBER: |
527 elif state == NUMBER: |
530 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
528 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
531 last_styled_pos = current_pos |
529 last_styled_pos = current_pos |
532 state = SPACE |
530 state = SPACE |
533 if char == ']': |
531 if char == ']': |
534 if len(self.StructElementsStack) > 0: |
532 if len(self.ContextStack) > 0: |
535 struct_elements = self.StructElementsStack.pop() |
533 current_context = self.ContextStack.pop() |
536 else: |
534 else: |
537 struct_elements = [] |
535 current_context = self.Variables |
538 word = char |
536 word = char |
539 state = WORD |
537 state = WORD |
540 elif char == ')': |
538 elif char == ')': |
541 struct_elements = [] |
539 current_context = self.Variables |
542 if len(self.FunctionCallStack) > 0: |
540 if len(self.CallStack) > 0: |
543 current_function = self.FunctionCallStack.pop() |
541 current_call = self.CallStack.pop() |
544 else: |
542 else: |
545 current_function = None |
543 current_call = None |
|
544 word = char |
|
545 state = WORD |
546 current_pos += 1 |
546 current_pos += 1 |
547 if state == COMMENT: |
547 if state == COMMENT: |
548 self.SetStyling(current_pos - last_styled_pos + 2, STC_PLC_COMMENT) |
548 self.SetStyling(current_pos - last_styled_pos + 2, STC_PLC_COMMENT) |
549 elif state == NUMBER: |
549 elif state == NUMBER: |
550 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
550 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER) |
551 elif state == WORD: |
551 elif state == WORD: |
552 if word in self.Keywords or word in self.TypeNames: |
552 if word in self.Keywords or word in self.TypeNames: |
553 self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD) |
553 self.SetStyling(current_pos - last_styled_pos, STC_PLC_WORD) |
554 elif self.IsValidVariable(struct_elements + [word], self.Variables) or self.IsFunctionParameter(word, current_function): |
554 elif self.IsValidVariable(word, current_context): |
555 self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE) |
555 self.SetStyling(current_pos - last_styled_pos, STC_PLC_VARIABLE) |
|
556 elif self.IsCallParameter(word, current_call): |
|
557 self.SetStyling(current_pos - last_styled_pos, STC_PLC_PARAMETER) |
556 elif self.TextSyntax == "IL" and word in self.Functions: |
558 elif self.TextSyntax == "IL" and word in self.Functions: |
557 self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION) |
559 self.SetStyling(current_pos - last_styled_pos, STC_PLC_FUNCTION) |
558 elif word in self.Jumps: |
560 elif word in self.Jumps: |
559 self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP) |
561 self.SetStyling(current_pos - last_styled_pos, STC_PLC_JUMP) |
560 elif word in self.EnumeratedValues: |
562 elif word in self.EnumeratedValues: |