/// <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)); }
/// <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) { }
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); } } } }