示例#1
0
 private void PopSpanStack()
 {
     currentSpanStack.RemoveAt(currentSpanStack.Count - 1);
     inSpan        = (currentSpanStack != null && currentSpanStack.Count > 0);
     activeSpan    = inSpan ? currentSpanStack[currentSpanStack.Count - 1] : null;
     activeRuleSet = new HighlightRuleSet();
 }
示例#2
0
        public Ca65Highlighting(ProjectType projectType)
        {
            Extensions = new[] { "s", "h" };
            opcodes    = new HashSet <string>(nesOpcodes);
            if (projectType == ProjectType.Snes)
            {
                opcodes.UnionWith(snesOpcodes);
            }
            Properties = new Dictionary <string, string>();
            Properties.Add("LineComment", ";");
            Rule = new HighlightRuleSet();

            NumberWord = new Ca65WordType
            {
                Type  = AsmWord.AsmWordType.NumberWord,
                Match = NumberMatch
            };
            StringWord = new Ca65WordType
            {
                Type  = AsmWord.AsmWordType.String,
                Match = StringMatch
            };
            AddressWord = new Ca65WordType
            {
                Type  = AsmWord.AsmWordType.AddressReference,
                Match = AddressMatch
            };
            CommandWord = new Ca65WordType
            {
                Type  = AsmWord.AsmWordType.Command,
                Match = CommandMatch
            };
            CommentSpan = new Ca65Span
            {
                Begin = new char[] { ';' },
                End   = new char[] { '\n' },
                Type  = AsmWord.AsmWordType.Comment
            };

            UpdateColorsFromDefault();

            Type = new List <Ca65WordType> {
                NumberWord, StringWord, CommandWord
            };                                                                                 //, AddressWord };
            Spans = new List <Ca65Span> {
                CommentSpan
            };
        }
示例#3
0
        List <TextWord> ParseLine(IDocument document)
        {
            List <TextWord> words    = new List <TextWord>();
            HighlightColor  markNext = null;

            currentOffset = 0;
            currentLength = 0;
            inSpan        = (currentSpanStack != null && currentSpanStack.Count > 0);
            activeSpan    = inSpan ? currentSpanStack[currentSpanStack.Count - 1] : null;
            activeRuleSet = Rule;

            int currentLineLength = currentLine.Length;
            int currentLineOffset = currentLine.Offset;
            var firstWord         = true;
            var isWord            = false;
            var opcodeParams      = false;
            var absoluteValue     = false;

            for (int i = 0; i < currentLineLength; ++i)
            {
                char ch = document.GetCharAt(currentLineOffset + i);
                switch (ch)
                {
                case '\n':
                case '\r':
                    PushCurWord(document, ref markNext, words, firstWord);
                    if (isWord)
                    {
                        firstWord = false;
                    }
                    ++currentOffset;
                    break;

                case ' ':
                    PushCurWord(document, ref markNext, words, firstWord);
                    if (isWord)
                    {
                        firstWord = false;
                    }
                    if (activeSpan != null && activeSpan.Color.HasBackground)
                    {
                        words.Add(new TextWord.SpaceTextWord(activeSpan.Color));
                    }
                    else
                    {
                        words.Add(TextWord.Space);
                    }
                    ++currentOffset;
                    break;

                case '\t':
                    PushCurWord(document, ref markNext, words, firstWord);
                    if (isWord)
                    {
                        firstWord = false;
                    }
                    if (activeSpan != null && activeSpan.Color.HasBackground)
                    {
                        words.Add(new TextWord.TabTextWord(activeSpan.Color));
                    }
                    else
                    {
                        words.Add(TextWord.Tab);
                    }
                    ++currentOffset;
                    break;

                default:
                    var lookAhead = document.GetText(currentLineOffset + i, (currentLineLength - i));

                    var match = Regex.Match(lookAhead, OperatorMatch);
                    if (match.Success)                             // && !Type.Any(t => Regex.IsMatch(lookAhead, t.Match))) ; Condition only necessary if a match type conflicts with operators
                    {
                        PushCurWord(document, ref markNext, words, firstWord);
                        if (isWord)
                        {
                            firstWord = false;
                        }
                        currentLength = match.Length;
                        PushCurWord(document, ref markNext, words, firstWord);
                        isWord = true;
                        i     += match.Length - 1;

                        continue;
                    }

                    isWord = true;

                    // handle escape characters
                    var escapeCharacter = '\0';
                    if (activeSpan != null && activeSpan.EscapeCharacter != '\0')
                    {
                        escapeCharacter = activeSpan.EscapeCharacter;
                    }
                    else if (activeRuleSet != null)
                    {
                        escapeCharacter = activeRuleSet.EscapeCharacter;
                    }
                    if (escapeCharacter != '\0' && escapeCharacter == ch)
                    {
                        // we found the escape character
                        if (activeSpan != null && activeSpan.End != null && activeSpan.End.Length == 1 &&
                            escapeCharacter == activeSpan.End[0])
                        {
                            // the escape character is a end-doubling escape character
                            // it may count as escape only when the next character is the escape, too
                            if (i + 1 < currentLineLength)
                            {
                                if (document.GetCharAt(currentLineOffset + i + 1) == escapeCharacter)
                                {
                                    currentLength += 2;
                                    PushCurWord(document, ref markNext, words);
                                    ++i;
                                    continue;
                                }
                            }
                        }
                        else
                        {
                            // this is a normal \-style escape
                            ++currentLength;
                            if (i + 1 < currentLineLength)
                            {
                                ++currentLength;
                            }
                            PushCurWord(document, ref markNext, words);
                            ++i;
                            continue;
                        }
                    }
                    if (!inSpan && currentLength == 0)
                    {
                        // Handle new words from the beginning
                        if (ch == '#')
                        {
                            currentLength += 1;
                            words.Add(new AsmWord(document, currentLine, currentOffset, currentLength, DigitColor, false, AsmWord.AsmWordType.None));
                            if (opcodeParams)
                            {
                                absoluteValue = true;
                            }
                            i             += currentLength - 1;
                            currentOffset += currentLength;
                            currentLength  = 0;
                            continue;
                        }

                        foreach (var type in Type)
                        {
                            var typeMatch = Regex.Match(lookAhead, type.Match);
                            if (typeMatch.Success)
                            {
                                currentLength = typeMatch.Length;
                                words.Add(new AsmWord(document, currentLine, currentOffset, currentLength, type.Color, false, type.Type));
                                i             += currentLength - 1;
                                currentOffset += currentLength;
                                currentLength  = 0;
                                goto @skip;
                            }
                        }


                        // highlight opcodes
                        if (i + 2 < currentLineLength &&
                            (i + 3 == currentLineLength || Char.IsWhiteSpace(document.GetCharAt(currentLineOffset + i + 3))))
                        {
                            var potentialOpcode = new string(new []
                            {
                                document.GetCharAt(currentLineOffset + i + 0),
                                document.GetCharAt(currentLineOffset + i + 1),
                                document.GetCharAt(currentLineOffset + i + 2)
                            });
                            if (opcodes.Contains(potentialOpcode.ToUpperInvariant()))
                            {
                                currentLength += 3;                             // add 3 letter word
                                i             += 2;                             // skip the next two letters
                                words.Add(new AsmWord(document, currentLine, currentOffset, currentLength, OpcodeColor, false, AsmWord.AsmWordType.Opcode));
                                opcodeParams   = true;                          // Anything after this will be treated as parameters to the opcode
                                currentOffset += currentLength;
                                currentLength  = 0;
                                continue;                                         // If opcode, we have already completed the word, so move on to next word
                            }
                        }
                    }

                    // Check for SPAN ENDs
                    if (inSpan)
                    {
                        if (activeSpan.End != null && activeSpan.End.Length > 0)
                        {
                            if (MatchExpr(currentLine, activeSpan.End, i, document, activeSpan.IgnoreCase))
                            {
                                PushCurWord(document, ref markNext, words);
                                string regex = GetRegString(currentLine, activeSpan.End, i, document);
                                currentLength += regex.Length;
                                words.Add(new TextWord(document, currentLine, currentOffset, currentLength, activeSpan.EndColor ?? activeSpan.Color, false));
                                currentOffset += currentLength;
                                currentLength  = 0;
                                i             += regex.Length - 1;
                                PopSpanStack();

                                continue;
                            }
                        }
                    }

                    // check for SPAN BEGIN
                    foreach (var span in Spans)
                    {
                        if ((!span.IsBeginSingleWord || currentLength == 0)
                            &&
                            (!span.IsBeginStartOfLine.HasValue ||
                             span.IsBeginStartOfLine.Value ==
                             (currentLength == 0 &&
                              words.TrueForAll(textWord => textWord.Type != TextWordType.Word))) &&
                            MatchExpr(currentLine, span.Begin, i, document, activeRuleSet.IgnoreCase))
                        {
                            PushCurWord(document, ref markNext, words, firstWord);
                            string regex = GetRegString(currentLine, span.Begin, i, document);

                            //if (!OverrideSpan(regex, document, words, span, ref i)) {

                            currentLength += regex.Length;
                            words.Add(new TextWord(document, currentLine, currentOffset, currentLength, span.BeginColor ?? span.Color, false));
                            currentOffset += currentLength;
                            currentLength  = 0;

                            i += regex.Length - 1;
                            if (currentSpanStack == null)
                            {
                                currentSpanStack = new List <Ca65Span>();
                            }
                            currentSpanStack.Add(span);
                            span.IgnoreCase = activeRuleSet.IgnoreCase;

                            inSpan        = currentSpanStack != null && currentSpanStack.Count > 0;
                            activeSpan    = inSpan ? currentSpanStack[currentSpanStack.Count - 1] : null;
                            activeRuleSet = new HighlightRuleSet();

                            goto @skip;
                        }
                    }

                    // check if the char is a delimiter
                    if (activeRuleSet != null && (int)ch < 256 && activeRuleSet.Delimiters[(int)ch])
                    {
                        PushCurWord(document, ref markNext, words);
                        if (currentOffset + currentLength + 1 < currentLine.Length)
                        {
                            ++currentLength;
                            PushCurWord(document, ref markNext, words);
                            continue;
                        }
                    }

                    ++currentLength;
                    @skip :  continue;
                }
            }

            PushCurWord(document, ref markNext, words, firstWord);
            while (activeSpan != null && activeSpan.End != null && activeSpan.End[0] == '\n')
            {
                PopSpanStack();
            }

            //OnParsedLine(document, currentLine, words);

            return(words);
        }