Пример #1
0
 /// <summary>
 /// Visit a parse tree produced by <see cref="ZxBasicParser.asm_section"/>.
 /// <para>
 /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/>
 /// on <paramref name="context"/>.
 /// </para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 /// <return>The visitor result.</return>
 public virtual Result VisitAsm_section([NotNull] ZxBasicParser.Asm_sectionContext context)
 {
     return(VisitChildren(context));
 }
Пример #2
0
 /// <summary>
 /// Exit a parse tree produced by <see cref="ZxBasicParser.asm_section"/>.
 /// <para>The default implementation does nothing.</para>
 /// </summary>
 /// <param name="context">The parse tree.</param>
 public virtual void ExitAsm_section([NotNull] ZxBasicParser.Asm_sectionContext context)
 {
 }
Пример #3
0
        public override void ExitAsm_section([NotNull] ZxBasicParser.Asm_sectionContext context)
        {
            // --- Mark the delimiting tokens
            if (context.asm_start() != null)
            {
                AddSpan(TokenType.ZxbAsm, context.asm_start());
            }
            if (context.asm_end() != null)
            {
                AddSpan(TokenType.ZxbAsm, context.asm_end());
            }

            var bodyContext = context.asm_body();

            if (bodyContext == null)
            {
                return;
            }

            // --- Create the Z80 Asm body text
            var bodyStart       = bodyContext.Start.StartIndex;
            var bodyEnd         = bodyContext.Stop.StopIndex;
            var startLine       = bodyContext.Start.Line;
            var currentSnapshot = _buffer.CurrentSnapshot;
            var snapshotLength  = currentSnapshot.Length;
            var length          = bodyEnd - bodyStart + 1;

            if (bodyStart + length > snapshotLength)
            {
                length = snapshotLength - bodyStart;
            }
            if (length < 0)
            {
                length = 0;
            }
            var body = bodyEnd > bodyStart
                ? currentSnapshot.GetText(bodyStart, length)
                : string.Empty;

            // --- Parse the embedded Z80 assembly code
            var parts   = Regex.Split(body, "\r\n");
            var visitor = Z80AsmVisitor.VisitSource(body);
            var lines   = visitor.Compilation.Lines;

            // --- Iterate through lines
            for (var i = 0; i < parts.Length; i++)
            {
                var offset     = i == 0 ? bodyContext.Start.Column : 0;
                var asmLineIdx = Z80AsmVisitor.GetAsmLineIndex(lines, i + 1);
                if (asmLineIdx == null)
                {
                    continue;
                }

                // --- Handle block comments
                var textOfLine     = parts[i];
                var lastStartIndex = 0;
                while (true)
                {
                    var blockBeginsPos = textOfLine.IndexOf("/*", lastStartIndex, StringComparison.Ordinal);
                    if (blockBeginsPos < 0)
                    {
                        break;
                    }
                    var blockEndsPos = textOfLine.IndexOf("*/", blockBeginsPos, StringComparison.Ordinal);
                    if (blockEndsPos <= blockBeginsPos)
                    {
                        break;
                    }

                    // --- Block comment found
                    lastStartIndex = blockEndsPos + 2;
                    AddSpan(TokenType.Comment, i + startLine, offset + blockBeginsPos, lastStartIndex - blockBeginsPos);
                }

                // --- Get the parsed line
                var asmLine = lines[asmLineIdx.Value];

                if (asmLine.LabelSpan != null)
                {
                    AddSpan(TokenType.Label, i + startLine, offset, asmLine, asmLine.LabelSpan);
                }

                // --- Create keywords
                if (asmLine.KeywordSpan != null)
                {
                    var type = TokenType.Instruction;
                    switch (asmLine)
                    {
                    case PragmaBase _:
                        type = TokenType.Pragma;
                        break;

                    case Directive _:
                        type = TokenType.Directive;
                        break;

                    case IncludeDirective _:
                        type = TokenType.IncludeDirective;
                        break;

                    case MacroOrStructInvocation _:
                        type = TokenType.MacroInvocation;
                        break;

                    case ModuleStatement _:
                    case ModuleEndStatement _:
                        type = TokenType.Module;
                        break;

                    case StatementBase _:
                        type = TokenType.Statement;
                        break;
                    }

                    // --- Retrieve a pragma/directive/instruction
                    AddSpan(type, i + startLine, offset, asmLine, asmLine.KeywordSpan);
                }

                // --- Create comments
                if (asmLine.CommentSpan != null)
                {
                    AddSpan(TokenType.Comment, i + startLine, offset, asmLine, asmLine.CommentSpan);
                }

                // --- Create numbers
                if (asmLine.NumberSpans != null)
                {
                    foreach (var numberSpan in asmLine.NumberSpans)
                    {
                        AddSpan(TokenType.Number, i + startLine, offset, asmLine, numberSpan);
                    }
                }

                // --- Create strings
                if (asmLine.StringSpans != null)
                {
                    foreach (var stringSpan in asmLine.StringSpans)
                    {
                        AddSpan(TokenType.String, i + startLine, offset, asmLine, stringSpan);
                    }
                }

                // --- Create functions
                if (asmLine.FunctionSpans != null)
                {
                    foreach (var functionSpan in asmLine.FunctionSpans)
                    {
                        AddSpan(TokenType.Function, i + startLine, offset, asmLine, functionSpan);
                    }
                }

                // --- Create semi-variables
                if (asmLine.SemiVarSpans != null)
                {
                    foreach (var semiVarSpan in asmLine.SemiVarSpans)
                    {
                        AddSpan(TokenType.SemiVar, i + startLine, offset, asmLine, semiVarSpan);
                    }
                }

                // --- Create macro parameters
                if (asmLine.MacroParamSpans != null)
                {
                    foreach (var macroParamSpan in asmLine.MacroParamSpans)
                    {
                        AddSpan(TokenType.MacroParam, i + startLine, offset, asmLine, macroParamSpan);
                    }
                }

                // --- Create identifiers
                if (asmLine.IdentifierSpans != null)
                {
                    foreach (var id in asmLine.IdentifierSpans)
                    {
                        AddSpan(TokenType.Identifier, i + startLine, offset, asmLine, id);
                    }
                }

                // --- Create statements
                if (asmLine.StatementSpans != null)
                {
                    foreach (var statement in asmLine.StatementSpans)
                    {
                        AddSpan(TokenType.Statement, i + startLine, offset, asmLine, statement);
                    }
                }

                // --- Create operands
                if (asmLine.OperandSpans != null)
                {
                    foreach (var operand in asmLine.OperandSpans)
                    {
                        AddSpan(TokenType.Operand, i + startLine, offset, asmLine, operand);
                    }
                }

                // --- Create mnemonics
                if (asmLine.MnemonicSpans != null)
                {
                    foreach (var mnemonic in asmLine.MnemonicSpans)
                    {
                        AddSpan(TokenType.Operand, i + startLine, offset, asmLine, mnemonic);
                    }
                }
            }
        }