Ejemplo n.º 1
0
        public IEnumerable <ITagSpan <AsmTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans)
        {
            DateTime time1 = DateTime.Now;

            if (spans.Count == 0)
            {  //there is no content in the buffer
                yield break;
            }

            foreach (SnapshotSpan curSpan in spans)
            {
                ITextSnapshotLine containingLine = curSpan.Start.GetContainingLine();

                string line = containingLine.GetText().ToUpper();
                IList <(int beginPos, int length, bool isLabel)> pos = AsmSourceTools.SplitIntoKeywordPos(line);

                int offset    = containingLine.Start.Position;
                int nKeywords = pos.Count;

                for (int k = 0; k < nKeywords; k++)
                {
                    string asmToken = NasmTokenTagger.Keyword(pos[k], line);
                    // keyword starts with a remark char
                    if (AsmSourceTools.IsRemarkChar(asmToken[0]))
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._remark));

                        continue;
                    }

                    // keyword k is a label definition
                    if (pos[k].isLabel)
                    {
                        SnapshotSpan labelDefSpan = NasmTokenTagger.New_Span(pos[k], offset, curSpan);
                        //AsmDudeToolsStatic.Output_INFO("MasmTokenTagger:GetTags: found label " + asmToken +" at line "+containingLine.LineNumber);
                        if (asmToken.Equals("@@"))
                        {
                            // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc.
                        }
                        else
                        {
                            yield return(new TagSpan <AsmTokenTag>(labelDefSpan, Make_AsmTokenTag_LabelDef(containingLine.LineNumber)));
                        }
                        continue;
                    }


                    AsmTokenType keywordType = this._asmDudeTools.Get_Token_Type(asmToken);
                    switch (keywordType)
                    {
                    case AsmTokenType.Jump:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._jump));

                        k++;     // goto the next word
                        if (k == nKeywords)
                        {
                            break;
                        }

                        string asmToken2 = NasmTokenTagger.Keyword(pos[k], line);
                        switch (asmToken2)
                        {
                        case "$":
                        case "@B":
                        case "@F":
                        {
                            // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc.
                            break;
                        }

                        case "WORD":
                        case "DWORD":
                        case "QWORD":
                        case "SHORT":
                        case "NEAR":
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._misc));

                            k++;
                            if (k == nKeywords)
                            {
                                break;
                            }
                            string asmToken3 = NasmTokenTagger.Keyword(pos[k], line);
                            switch (asmToken3)
                            {
                            case "$":
                            case "@B":
                            case "@F":
                            {
                                // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc.
                                break;
                            }

                            case "PTR":
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._misc));

                                break;
                            }

                            default:
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), Make_AsmTokenTag_Label(containingLine.LineNumber)));

                                break;
                            }
                            }
                            break;
                        }

                        default:
                        {
                            if (RegisterTools.IsRegister(asmToken2))
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._register));
                            }
                            else
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), Make_AsmTokenTag_Label(containingLine.LineNumber)));
                            }
                            break;
                        }
                        }
                        break;
                    }

                    case AsmTokenType.UNKNOWN:     // asmToken is not a known keyword, check if it is numerical
                    {
                        if (AsmTools.AsmSourceTools.IsConstant(asmToken))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._constant));
                        }
                        else if (asmToken.StartsWith("\"") && asmToken.EndsWith("\""))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._constant));
                        }
                        else
                        {
                            bool isUnknown = true;

                            // do one word lookahead; see whether we can understand the current unknown word
                            if ((k + 1) < nKeywords)
                            {
                                k++;
                                string nextKeyword = NasmTokenTagger.Keyword(pos[k], line);
                                switch (nextKeyword)
                                {
                                case "PROC":
                                case "EQU":
                                case "LABEL":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k - 1], offset, curSpan), this._labelDef));

                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._directive));

                                    isUnknown = false;
                                    break;
                                }

                                case "PROTO":
                                {         // a proto is considered a label definition but it should not clash with other label definitions
                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k - 1], offset, curSpan), this._labelDef_PROTO));

                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._directive));

                                    isUnknown = false;
                                    break;
                                }

                                default:
                                {
                                    k--;
                                    break;
                                }
                                }
                            }

                            // do one word look back; see whether we can understand the current unknown word
                            if (k > 0)
                            {
                                string previousKeyword = NasmTokenTagger.Keyword(pos[k - 1], line);
                                switch (previousKeyword)
                                {
                                case "ALIAS":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._labelDef));

                                    isUnknown = false;
                                    break;
                                }

                                default:
                                {
                                    break;
                                }
                                }
                            }

                            if (isUnknown)
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._UNKNOWN));
                            }
                        }
                        break;
                    }

                    case AsmTokenType.Directive:
                    {
                        AssemblerEnum assember = this._asmDudeTools.Get_Assembler(asmToken);
                        if (assember.HasFlag(AssemblerEnum.MASM))     // this MASM token-tagger only tags MASM directives
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._directive));

                            if (asmToken.Equals("INVOKE"))
                            {
                                k++;     // goto the next word
                                if (k == nKeywords)
                                {
                                    break;
                                }

                                string asmToken2 = NasmTokenTagger.Keyword(pos[k], line);
                                yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), Make_AsmTokenTag_Label(containingLine.LineNumber)));
                                //yield return new TagSpan<AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._label); // do not use full qualified label!
                            }
                        }
                        break;
                    }

                    default:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), new AsmTokenTag(keywordType)));

                        break;
                    }
                    }
                }
            }
            AsmDudeToolsStatic.Print_Speed_Warning(time1, "MasmTokenTagger");
        }
Ejemplo n.º 2
0
        public IEnumerable <ITagSpan <AsmTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans)
        {
            DateTime time1 = DateTime.Now;

            if (spans.Count == 0)
            {  //there is no content in the buffer
                yield break;
            }

            foreach (SnapshotSpan curSpan in spans)
            {
                ITextSnapshotLine containingLine = curSpan.Start.GetContainingLine();

                string line = containingLine.GetText().ToUpper();
                IList <(int, int, bool)> pos = AsmSourceTools.SplitIntoKeywordPos(line);

                int offset    = containingLine.Start.Position;
                int nKeywords = pos.Count;

                for (int k = 0; k < nKeywords; k++)
                {
                    string asmToken = NasmTokenTagger.Keyword(pos[k], line);
                    // keyword starts with a remark char
                    if (AsmSourceTools.IsRemarkChar(asmToken[0]))
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._remark));

                        continue;
                    }

                    // keyword k is a label definition
                    if (pos[k].Item3)
                    {
                        //AsmDudeToolsStatic.Output_INFO("NasmTokenTagger:GetTags: found label " +asmToken);
                        if (IsProperLabelDef(asmToken, containingLine.LineNumber, out AsmTokenTag asmTokenTag))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), asmTokenTag));

                            continue;
                        }
                    }

                    AsmTokenType keywordType = this._asmDudeTools.Get_Token_Type(asmToken);
                    switch (keywordType)
                    {
                    case AsmTokenType.Jump:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._jump));

                        k++;     // goto the next word
                        if (k == nKeywords)
                        {
                            break;                     // there are no next words
                        }
                        string asmToken2 = NasmTokenTagger.Keyword(pos[k], line);
                        switch (asmToken2)
                        {
                        case "WORD":
                        case "DWORD":
                        case "QWORD":
                        case "SHORT":
                        case "NEAR":
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._misc));

                            k++;
                            if (k == nKeywords)
                            {
                                break;
                            }
                            string asmToken3 = NasmTokenTagger.Keyword(pos[k], line);
                            if (asmToken3.Equals("PTR"))
                            {
                                yield return(new TagSpan <AsmTokenTag>(New_Span(pos[k], offset, curSpan), this._misc));
                            }
                            else
                            {
                                if (IsProperLabel(asmToken3, containingLine.LineNumber, out AsmTokenTag asmTokenTag))
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), asmTokenTag));
                                }
                            }
                            break;
                        }

                        default:
                        {
                            if (RegisterTools.IsRegister(asmToken2))
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._register));
                            }
                            else
                            {
                                if (IsProperLabel(asmToken2, containingLine.LineNumber, out AsmTokenTag asmTokenTag))
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), asmTokenTag));
                                }
                            }
                            break;
                        }
                        }
                        break;
                    }

                    case AsmTokenType.UNKNOWN:     // asmToken is not a known keyword, check if it is numerical
                    {
                        if (AsmTools.AsmSourceTools.IsConstant(asmToken))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._constant));
                        }
                        else if (asmToken.StartsWith("\"") && asmToken.EndsWith("\""))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._constant));
                        }
                        else
                        {
                            bool isUnknown = true;

                            // do one word lookahead; see whether we can understand the current unknown word
                            if ((k + 1) < nKeywords)
                            {
                                k++;
                                string nextKeyword = NasmTokenTagger.Keyword(pos[k], line);
                                switch (nextKeyword)
                                {
                                case "LABEL":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k - 1], offset, curSpan), this._labelDef));

                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._directive));

                                    isUnknown = false;
                                    break;
                                }

                                default:
                                {
                                    k--;
                                    break;
                                }
                                }
                            }

                            // do one word look back; see whether we can understand the current unknown word
                            if (k > 0)
                            {
                                string previousKeyword = NasmTokenTagger.Keyword(pos[k - 1], line);
                                switch (previousKeyword)
                                {
                                case "ALIAS":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._labelDef));

                                    isUnknown = false;
                                    break;
                                }

                                default:
                                {
                                    break;
                                }
                                }
                            }

                            if (isUnknown)
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._UNKNOWN));
                            }
                        }
                        break;
                    }

                    case AsmTokenType.Directive:
                    {
                        AssemblerEnum assember = this._asmDudeTools.Get_Assembler(asmToken);
                        if (assember.HasFlag(AssemblerEnum.NASM))     // this NASM token-tagger only tags NASM directives
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), this._directive));
                        }
                        break;
                    }

                    default:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmTokenTagger.New_Span(pos[k], offset, curSpan), new AsmTokenTag(keywordType)));

                        break;
                    }
                    }
                }
            }
            AsmDudeToolsStatic.Print_Speed_Warning(time1, "NasmTokenTagger");
        }