Exemple #1
0
        private string Get_Procedure_Name(int lineNumber)
        {
            //AsmDudeToolsStatic.Output_INFO("MasmTokenTagger:Get_Procedure_Name: lineNumber=" + lineNumber);

            for (int i = lineNumber; i >= 0; --i)
            {
                string line = this._buffer.CurrentSnapshot.GetLineFromLineNumber(i).GetText();
                IList <(int, int, bool)> positions = new List <(int, int, bool)>(AsmSourceTools.SplitIntoKeywordPos(line));
                if (positions.Count > 1)
                {
                    string keywordStr = NasmIntelTokenTagger.Keyword(positions[1], line).ToUpper();
                    switch (keywordStr)
                    {
                    case "PROC": return(NasmIntelTokenTagger.Keyword(positions[0], line));

                    case "ENDP": return(null);

                    default: break;
                    }
                }
            }
            //AsmDudeToolsStatic.Output_INFO("MasmTokenTagger:Get_Procedure_Name: could not find regular label before lineNumber " + lineNumber);
            return("");
        }
        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();
                var    pos  = new List <(int BeginPos, int Length, bool IsLabel)>(AsmSourceTools.SplitIntoKeywordPos(line));

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

                // if the line does not contain a Mnemonic, assume it is a source code line and make it a remark
                #region Check source code line
                if (IsSourceCode(line, pos))
                {
                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span((0, line.Length, false), offset, curSpan), this._remark));

                    continue; // go to the next line
                }
                #endregion

                for (int k = 0; k < nKeywords; k++)
                {
                    string asmToken = NasmIntelTokenTagger.Keyword(pos[k], line);

                    // keyword k is a label definition
                    if (pos[k].IsLabel)
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._labelDef));

                        continue;
                    }

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

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

                            k++;
                            if (k == nKeywords)
                            {
                                break;
                            }
                            string asmToken3 = NasmIntelTokenTagger.Keyword(pos[k], line);
                            switch (asmToken3)
                            {
                            case "PTR":
                            {
                                yield return(new TagSpan <AsmTokenTag>(New_Span(pos[k], offset, curSpan), this._misc));

                                break;
                            }
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._label));

                                break;
                            }
                            break;
                        }

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

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

                    case AsmTokenType.Directive:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._directive));

                        break;
                    }

                    case AsmTokenType.Mnemonic:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._mnemonic));

                        break;
                    }

                    case AsmTokenType.Register:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._register));

                        break;
                    }

                    default: break;
                    }
                }
            }
            AsmDudeToolsStatic.Print_Speed_Warning(time1, "NasmAttDisassemblyTokenTagger");
        }
Exemple #3
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();
                var    pos  = new List <(int BeginPos, int Length, bool IsLabel)>(AsmSourceTools.SplitIntoKeywordPos(line));

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

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

                        continue;
                    }

                    // keyword k is a label definition
                    if (pos[k].IsLabel)
                    {
                        SnapshotSpan labelDefSpan = NasmIntelTokenTagger.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
                        {
                            var v = this.Make_AsmTokenTag_LabelDef(containingLine.LineNumber);
                            yield return(new TagSpan <AsmTokenTag>(labelDefSpan, v));
                        }
                        continue;
                    }

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

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

                        string asmToken2 = NasmIntelTokenTagger.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>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._misc));

                            k++;
                            if (k == nKeywords)
                            {
                                break;
                            }
                            string asmToken3 = NasmIntelTokenTagger.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>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._misc));

                                break;
                            }

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

                                break;
                            }
                            }
                            break;
                        }

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

                    case AsmTokenType.UNKNOWN:     // asmToken is not a known keyword, check if it is numerical
                    {
                        if (AsmTools.AsmSourceTools.Evaluate_Constant(asmToken, true).Valid)
                        //if (AsmTools.AsmSourceTools.Parse_Constant(asmToken, true).Valid)
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._constant));
                        }
                        else if (asmToken.StartsWith("\"") && asmToken.EndsWith("\""))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.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 = NasmIntelTokenTagger.Keyword(pos[k], line);
                                switch (nextKeyword)
                                {
                                case "PROC":
                                case "EQU":
                                case "LABEL":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k - 1], offset, curSpan), this._labelDef));

                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.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>(NasmIntelTokenTagger.New_Span(pos[k - 1], offset, curSpan), this._labelDef_PROTO));

                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.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 = NasmIntelTokenTagger.Keyword(pos[k - 1], line);
                                switch (previousKeyword)
                                {
                                case "ALIAS":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._labelDef));

                                    isUnknown = false;
                                    break;
                                }

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

                                    isUnknown = false;
                                    break;
                                }

                                default:
                                {
                                    break;
                                }
                                }
                            }

                            if (isUnknown)
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.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>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._directive));

                            switch (asmToken)
                            {
                            case "INVOKE":
                            {
                                k++;                 // goto the next word
                                if (k == nKeywords)
                                {
                                    break;
                                }

                                string asmToken2 = NasmIntelTokenTagger.Keyword(pos[k], line);
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.Make_AsmTokenTag_Label(containingLine.LineNumber)));

                                break;
                            }

                            case "EXTRN":
                            case "EXTERN":
                            {
                                k++;                 // goto the next word
                                if (k == nKeywords)
                                {
                                    break;
                                }

                                string asmToken2 = NasmIntelTokenTagger.Keyword(pos[k], line);
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._labelDef_PROTO));

                                break;
                            }
                            }
                        }
                    }
                    break;

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

                        break;
                    }
                    }
                }
            }
            AsmDudeToolsStatic.Print_Speed_Warning(time1, "MasmTokenTagger");
        }
Exemple #4
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_capitals = containingLine.GetText().ToUpper();
                List <(int BeginPos, int Length, bool IsLabel)> pos = new List <(int BeginPos, int Length, bool IsLabel)>(AsmSourceTools.SplitIntoKeywordPos(line_capitals));

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

                for (int k = 0; k < nKeywords; k++)
                {
                    string asmToken = AsmSourceTools.Keyword(pos[k], line_capitals);

                    // keyword starts with a remark char
                    if (AsmSourceTools.IsRemarkChar(asmToken[0]))
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._remark));

                        continue;
                    }

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

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

                        k++;         // goto the next word
                        if (k == nKeywords)
                        {
                            break;         // there are no next words
                            //TODO HJ 01-06-19 should be a warning that there is no label
                        }

                        string asmToken2 = AsmSourceTools.Keyword(pos[k], line_capitals);

                        if (AsmSourceTools.IsRemarkChar(asmToken2[0]))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._remark));

                            continue;
                            //TODO HJ 01-06-19 should be a warning that there is no label
                        }

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

                            k++;
                            if (k == nKeywords)
                            {
                                break;
                            }

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

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

                    case AsmTokenType.UNKNOWN:     // asmToken is not a known keyword, check if it is numerical
                    {
                        if (AsmSourceTools.Evaluate_Constant(asmToken, true).Valid)
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._constant));
                        }
                        else if (asmToken.StartsWith("\"") && asmToken.EndsWith("\""))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._constant));
                        }
                        else if (asmToken.StartsWith("$"))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset + 1, 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 = AsmSourceTools.Keyword(pos[k], line_capitals);
                                switch (nextKeyword)
                                {
                                case "LABEL":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k - 1], offset, curSpan), this._labelDef));

                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.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 = AsmSourceTools.Keyword(pos[k - 1], line_capitals);
                                switch (previousKeyword)
                                {
                                case "ALIAS":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._labelDef));

                                    isUnknown = false;
                                    break;
                                }

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

                                    isUnknown = false;
                                    break;
                                }

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

                    case AsmTokenType.Directive:
                    {
                        AssemblerEnum assember = this._asmDudeTools.Get_Assembler(asmToken);
                        if (assember.HasFlag(AssemblerEnum.NASM_INTEL) || assember.HasFlag(AssemblerEnum.NASM_ATT))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._directive));
                        }
                        break;
                    }

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

                        break;
                    }
                    }
                }
            }
            AsmDudeToolsStatic.Print_Speed_Warning(time1, "NasmAttTokenTagger");
        }
Exemple #5
0
        public IEnumerable <ITagSpan <AsmTokenTag> > GetTags_NEW(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_upcase = containingLine.GetText().ToUpper(CultureInfo.InvariantCulture);
                int    offset      = containingLine.Start.Position;
                IEnumerator <(int beginPos, int length, bool isLabel)> enumerator = AsmSourceTools.SplitIntoKeywordPos(line_upcase).GetEnumerator();

                bool needToAdvance = false;
                bool hasNext       = enumerator.MoveNext();
                if (!hasNext)
                {
                    break;
                }

                (int beginPos, int length, bool isLabel)prev    = (0, 0, false);
                (int beginPos, int length, bool isLabel)current = enumerator.Current;

                while (hasNext)
                {
                    string asmToken = AsmSourceTools.Keyword(current, line_upcase);
                    // keyword starts with a remark char
                    if (AsmSourceTools.IsRemarkChar(asmToken[0]))
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.remark_));

                        continue;
                    }

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

                    AsmTokenType keywordType = this.asmDudeTools_.Get_Token_Type_Intel(asmToken);
                    switch (keywordType)
                    {
                    case AsmTokenType.Jump:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.jump_));

                        {         // go to the next word
                            if (needToAdvance)
                            {
                                hasNext = enumerator.MoveNext();
                                prev    = current;
                                current = enumerator.Current;
                            }
                            needToAdvance = true;
                        }
                        string asmToken2 = AsmSourceTools.Keyword(current, line_upcase);
                        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>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.misc_));

                            {                 // go to the next word
                                if (needToAdvance)
                                {
                                    hasNext = enumerator.MoveNext();
                                    prev    = current;
                                    current = enumerator.Current;
                                }
                                needToAdvance = true;
                            }
                            switch (AsmSourceTools.Keyword(current, line_upcase))
                            {
                            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>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.misc_));

                                break;
                            }

                            default:
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.Make_AsmTokenTag_Label(containingLine.LineNumber)));

                                break;
                            }
                            }
                            break;
                        }

                        default:
                        {
                            if (RegisterTools.IsRegister(asmToken2))
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.register_));
                            }
                            else
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.Make_AsmTokenTag_Label(containingLine.LineNumber)));
                            }
                            break;
                        }
                        }
                        break;
                    }

                    case AsmTokenType.UNKNOWN:     // asmToken is not a known keyword, check if it is numerical
                    {
                        //if (AsmTools.AsmSourceTools.Evaluate_Constant(asmToken, true).valid)
                        if (AsmSourceTools.Parse_Constant(asmToken, true).valid)
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.constant_));
                        }
                        else if (asmToken.StartsWith("\"", StringComparison.Ordinal) && asmToken.EndsWith("\"", StringComparison.Ordinal))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.constant_));
                        }
                        else
                        {
                            // do one word look back; see whether we can understand the current unknown word
                            string previousKeyword = AsmSourceTools.Keyword(prev, line_upcase);
                            switch (previousKeyword)
                            {
                            case "ALIAS":
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.labelDef_));

                                break;
                            }

                            default:
                            {
                                break;
                            }
                            }

                            // do one word lookahead; see whether we can understand the current unknown word
                            // go to the next word
                            needToAdvance = false;

                            if (enumerator.MoveNext())
                            {
                                prev    = current;
                                current = enumerator.Current;

                                string nextKeyword = AsmSourceTools.Keyword(current, line_upcase);
                                switch (nextKeyword)
                                {
                                case "PROC":
                                case "EQU":
                                case "LABEL":
                                {
                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(prev, offset, curSpan), this.labelDef_));

                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.directive_));

                                    break;
                                }

                                case "PROTO":
                                {                 // a proto is considered a label definition but it should not clash with other label definitions
                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(prev, offset, curSpan), this.labelDef_PROTO_));

                                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.directive_));

                                    break;
                                }

                                default:
                                    break;
                                }
                            }
                            else
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, 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>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.directive_));

                            if (asmToken.Equals("INVOKE", StringComparison.Ordinal))
                            {
                                {         // go to the next word
                                    if (needToAdvance)
                                    {
                                        hasNext = enumerator.MoveNext();
                                        prev    = current;
                                        current = enumerator.Current;
                                    }
                                    needToAdvance = true;
                                }
                                //string asmToken2 = NasmTokenTagger.Keyword(current, line);
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.Make_AsmTokenTag_Label(containingLine.LineNumber)));
                            }
                        }
                        break;
                    }

                    default:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), new AsmTokenTag(keywordType)));

                        break;
                    }
                    }
                    { // go to the next word
                        if (needToAdvance)
                        {
                            hasNext = enumerator.MoveNext();
                            prev    = current;
                            current = enumerator.Current;
                        }
                        needToAdvance = true;
                    }
                }
            }
            AsmDudeToolsStatic.Print_Speed_Warning(time1, "MasmTokenTagger");
        }
        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_upcase = containingLine.GetText().ToUpperInvariant();
                List <(int beginPos, int length, bool isLabel)> pos = new List <(int beginPos, int length, bool isLabel)>(AsmSourceTools.SplitIntoKeywordPos(line_upcase));

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

                #region Check if the current line is a line of source code
                if (IsSourceCode(line_upcase, pos))
                {
                    yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span((0, line_upcase.Length, false), offset, curSpan), this.remark_));

                    continue; // go to the next line
                }
                #endregion

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

                        continue;
                    }

                    // keyword k is a label definition
                    if (pos[k].isLabel)
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.labelDef_));

                        continue;
                    }

                    AsmTokenType keywordType = this.asmDudeTools_.Get_Token_Type_Att(asmToken);
                    switch (keywordType)
                    {
                    case AsmTokenType.Jump:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.jump_));

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

                        string asmToken2 = AsmSourceTools.Keyword(pos[k], line_upcase);
                        switch (asmToken2)
                        {
                        case "WORD":
                        case "DWORD":
                        case "QWORD":
                        case "SHORT":
                        case "NEAR":
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.misc_));

                            k++;
                            if (k == nKeywords)
                            {
                                break;
                            }

                            string asmToken3 = AsmSourceTools.Keyword(pos[k], line_upcase);
                            switch (asmToken3)
                            {
                            case "PTR":
                            {
                                yield return(new TagSpan <AsmTokenTag>(New_Span(pos[k], offset, curSpan), this.misc_));

                                break;
                            }
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.label_));

                                break;
                            }
                            break;
                        }

                        default:
                        {
                            if (RegisterTools.IsRegister(asmToken2))
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.register_));
                            }
                            else if (AsmSourceTools.Evaluate_Constant(asmToken2, true).valid)
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.constant_));
                            }
                            else
                            {
                                yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.label_));
                            }
                            break;
                        }
                        }
                        break;
                    }

                    case AsmTokenType.UNKNOWN:     // asmToken is not a known keyword, check if it is numerical
                    {
                        if (AsmSourceTools.Evaluate_Constant(asmToken, true).valid)
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.constant_));
                        }
                        else if (asmToken.StartsWith("$", StringComparison.Ordinal))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.constant_));
                        }
                        else if (asmToken.StartsWith("\"", StringComparison.Ordinal) && asmToken.EndsWith("\"", StringComparison.Ordinal))
                        {
                            yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.constant_));
                        }
                        else
                        {
                            //yield return new TagSpan<AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this._UNKNOWN);
                        }
                        break;
                    }

                    case AsmTokenType.Directive:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.directive_));

                        break;
                    }

                    case AsmTokenType.Mnemonic:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.mnemonic_));

                        break;
                    }

                    case AsmTokenType.Register:
                    {
                        yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(pos[k], offset, curSpan), this.register_));

                        break;
                    }

                    default: break;
                    }
                }
            }
            AsmDudeToolsStatic.Print_Speed_Warning(time1, "NasmAttDisassemblyTokenTagger");
        }