示例#1
0
        /// <summary>
        /// Parses the source code passed to the compiler
        /// </summary>
        /// <param name="fileIndex">Source file index</param>
        /// <param name="sourceItem">Source file item</param>
        /// <param name="sourceText">Source text to parse</param>
        /// <param name="parsedLines"></param>
        /// <returns>True, if parsing was successful</returns>
        private bool ExecuteParse(int fileIndex, SourceFileItem sourceItem, string sourceText,
                                  out List <SourceLineBase> parsedLines)
        {
            // --- No lines has been parsed yet
            parsedLines = new List <SourceLineBase>();

            // --- Parse all source code lines
            var inputStream = new AntlrInputStream(sourceText);
            var lexer       = new Z80AsmLexer(inputStream);
            var tokenStream = new CommonTokenStream(lexer);
            var parser      = new Z80AsmParser(tokenStream);
            var context     = parser.compileUnit();
            var visitor     = new Z80AsmVisitor();

            visitor.Visit(context);
            var visitedLines = visitor.Compilation;

            // --- Store any tasks defined by the user
            StoreTasks(sourceItem, visitedLines.Lines);

            // --- Collect syntax errors
            foreach (var error in parser.SyntaxErrors)
            {
                ReportError(sourceItem, error);
            }

            // --- Exit if there are any errors
            if (Output.ErrorCount != 0)
            {
                return(false);
            }

            // --- Now, process directives and the .model pragma
            var currentLineIndex = 0;
            var ifdefStack       = new Stack <bool?>();
            var processOps       = true;

            parsedLines = new List <SourceLineBase>();

            // --- Traverse through parsed lines
            while (currentLineIndex < visitedLines.Lines.Count)
            {
                var line = visitedLines.Lines[currentLineIndex];
                if (line is ModelPragma modelPragma)
                {
                    ProcessModelPragma(modelPragma);
                }
                else if (line is IncludeDirective incDirective)
                {
                    // --- Parse the included file
                    if (ApplyIncludeDirective(incDirective, sourceItem,
                                              out var includedLines))
                    {
                        // --- Add the parse result of the include file to the result
                        parsedLines.AddRange(includedLines);
                    }
                }
                else if (line is Directive preProc)
                {
                    ApplyDirective(preProc, ifdefStack, ref processOps);
                }
                else if (processOps)
                {
                    line.FileIndex  = fileIndex;
                    line.SourceText = sourceText.Substring(line.FirstPosition,
                                                           line.LastPosition - line.FirstPosition + 1);
                    parsedLines.Add(line);
                }
                currentLineIndex++;
            }

            // --- Check if all #if and #ifdef has a closing #endif tag
            if (ifdefStack.Count > 0 && visitedLines.Lines.Count > 0)
            {
                ReportError(Errors.Z0062, visitedLines.Lines.Last());
            }

            return(Output.ErrorCount == 0);
        }
示例#2
0
        /// <summary>
        /// Gets all the tags that intersect the specified spans.
        /// </summary>
        /// <param name="spans">The spans to visit.</param>
        /// <returns>
        /// A <see cref="T:Microsoft.VisualStudio.Text.Tagging.TagSpan`1" /> for each tag.
        /// </returns>
        public IEnumerable <ITagSpan <Z80AsmTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans)
        {
            // --- Obtain the breakpoints that may affect this view
            var affectedLines = new List <int>();

            if (Package != null)
            {
                foreach (Breakpoint bp in Package.ApplicationObject.Debugger.Breakpoints)
                {
                    if (string.Compare(bp.File, FilePath, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        // --- Breakpoints start lines at 1, ITextBuffer starts from 0
                        affectedLines.Add(bp.FileLine - 1);
                    }
                }
            }

            foreach (var curSpan in spans)
            {
                var currentLine = curSpan.Start.GetContainingLine();
                var textOfLine  = currentLine.GetText();

                // --- Just to be sure...
                if (textOfLine == null)
                {
                    yield break;
                }

                // --- Let's use the Z80 assembly parser to obtain tags
                var inputStream = new AntlrInputStream(textOfLine);
                var lexer       = new Z80AsmLexer(inputStream);
                var tokenStream = new CommonTokenStream(lexer);
                var parser      = new Z80AsmParser(tokenStream);
                var context     = parser.asmline();
                var visitor     = new Z80AsmVisitor(inputStream);
                visitor.Visit(context);

                // --- Check for a block comment
                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;
                    yield return(CreateSpan(currentLine, new TextSpan(blockBeginsPos, blockEndsPos + 2), Z80AsmTokenType.Comment));
                }

                // --- No code line, no tagging
                if (!(visitor.LastAsmLine is SourceLineBase asmline))
                {
                    continue;
                }

                if (asmline is EmittingOperationBase && asmline.InstructionSpan != null)
                {
                    // --- This line contains executable instruction,
                    // --- So it might have a breakpoint
                    if (affectedLines.IndexOf(currentLine.LineNumber) >= 0)
                    {
                        // --- Check for the any preset breakpoint
                        yield return(CreateSpan(currentLine, asmline.InstructionSpan, Z80AsmTokenType.Breakpoint));
                    }
                }

                if (asmline.LabelSpan != null)
                {
                    // --- Retrieve a label
                    yield return(CreateSpan(currentLine, asmline.LabelSpan, Z80AsmTokenType.Label));
                }

                if (asmline.KeywordSpan != null)
                {
                    var type = Z80AsmTokenType.Instruction;
                    switch (asmline)
                    {
                    case PragmaBase _:
                        type = Z80AsmTokenType.Pragma;
                        break;

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

                    case IncludeDirective _:
                        type = Z80AsmTokenType.Include;
                        break;

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

                    case ModuleStatement _:
                    case ModuleEndStatement _:
                        type = Z80AsmTokenType.ModuleKeyword;
                        break;

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

                    // --- Retrieve a pragma/directive/instruction
                    yield return(CreateSpan(currentLine, asmline.KeywordSpan, type));
                }

                if (asmline.CommentSpan != null)
                {
                    yield return(CreateSpan(currentLine, asmline.CommentSpan, Z80AsmTokenType.Comment));
                }

                if (asmline.NumberSpans != null)
                {
                    foreach (var numberSpan in asmline.NumberSpans)
                    {
                        yield return(CreateSpan(currentLine, numberSpan, Z80AsmTokenType.Number));
                    }
                }

                if (asmline.StringSpans != null)
                {
                    foreach (var stringSpan in asmline.StringSpans)
                    {
                        yield return(CreateSpan(currentLine, stringSpan, Z80AsmTokenType.String));
                    }
                }

                if (asmline.FunctionSpans != null)
                {
                    foreach (var functionSpan in asmline.FunctionSpans)
                    {
                        yield return(CreateSpan(currentLine, functionSpan, Z80AsmTokenType.Function));
                    }
                }

                if (asmline.SemiVarSpans != null)
                {
                    foreach (var semiVarSpan in asmline.SemiVarSpans)
                    {
                        yield return(CreateSpan(currentLine, semiVarSpan, Z80AsmTokenType.SemiVar));
                    }
                }

                if (asmline.MacroParamSpans != null)
                {
                    foreach (var macroParamSpan in asmline.MacroParamSpans)
                    {
                        yield return(CreateSpan(currentLine, macroParamSpan, Z80AsmTokenType.MacroParam));
                    }
                }

                if (asmline.IdentifierSpans != null)
                {
                    foreach (var id in asmline.IdentifierSpans)
                    {
                        yield return(CreateSpan(currentLine, id, Z80AsmTokenType.Identifier));
                    }
                }

                if (asmline.StatementSpans != null)
                {
                    foreach (var statement in asmline.StatementSpans)
                    {
                        yield return(CreateSpan(currentLine, statement, Z80AsmTokenType.Statement));
                    }
                }

                if (asmline.OperandSpans != null)
                {
                    foreach (var operand in asmline.OperandSpans)
                    {
                        yield return(CreateSpan(currentLine, operand, Z80AsmTokenType.Operand));
                    }
                }

                if (asmline.MnemonicSpans != null)
                {
                    foreach (var mnemonic in asmline.MnemonicSpans)
                    {
                        yield return(CreateSpan(currentLine, mnemonic, Z80AsmTokenType.Instruction));
                    }
                }
            }
        }
示例#3
0
 public CaseInsensitiveEqualOperationNode(Z80AsmParser.EquExprContext context, Z80AsmVisitor visitor)
     : base(context, visitor)
 {
 }
示例#4
0
        public IList <ClassificationSpan> GetClassificationSpans(SnapshotSpan span)
        {
            var list = new List <ClassificationSpan>();

            List <SourceLineBase> lines;

            lock (_locker)
            {
                if (_z80SyntaxTreeVisitor == null || span.IsEmpty)
                {
                    return(list);
                }
                lines = _z80SyntaxTreeVisitor.Compilation.Lines;
            }

            // --- Get document and breakpoint information
            string filePath        = GetFilePath();
            var    breakpointLines = new List <int>();
            var    package         = SpectNetPackage.Default;

            if (package != null)
            {
                foreach (Breakpoint bp in package.ApplicationObject.Debugger.Breakpoints)
                {
                    if (string.Compare(bp.File, filePath, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        // --- Breakpoints start lines at 1, ITextBuffer starts from 0
                        breakpointLines.Add(bp.FileLine);
                    }
                }
            }

            // --- We'll use this snapshot to create classifications for
            var snapshot    = span.Snapshot;
            var currentLine = span.Start.GetContainingLine();
            var textOfLine  = currentLine.GetText();

            // --- Get line indexes
            var firstLineNo = span.Start.GetContainingLine().LineNumber;
            var lastLineNo  = span.End.GetContainingLine().LineNumber;

            int  firstAsmLine;
            int  lastAsmLine;
            bool partialCompile;

            if (lastLineNo - firstLineNo < 50)
            {
                partialCompile = true;
                lines          = new List <SourceLineBase>();
                for (var line = firstLineNo; line <= lastLineNo; line++)
                {
                    var source  = span.Snapshot.GetLineFromLineNumber(line).GetText();
                    var visitor = Z80AsmVisitor.VisitSource(source);
                    if (visitor.Compilation.Lines.Count > 0)
                    {
                        lines.Add(visitor.Compilation.Lines[0]);
                    }
                    else
                    {
                        lines.Add(new NoInstructionLine());
                    }
                }
                firstAsmLine = 0;
                lastAsmLine  = lines.Count - 1;
            }
            else
            {
                partialCompile = false;
                firstAsmLine   = Z80AsmVisitor.GetAsmLineIndex(lines, span.Start.GetContainingLine().LineNumber + 1) ?? 0;
                lastAsmLine    = Z80AsmVisitor.GetAsmLineIndex(lines, span.End.GetContainingLine().LineNumber + 1) ?? lines.Count - 1;
            }

            // --- Get the range of lines
            for (var line = firstAsmLine; line <= lastAsmLine; line++)
            {
                var sourceLine  = lines[line];
                var startOffset = partialCompile
                    ? span.Snapshot.GetLineFromLineNumber(firstLineNo + line).Start.Position
                    : 0;

                // --- Check for a block comment
                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;
                    AddClassificationSpan(list, snapshot,
                                          new TextSpan(sourceLine.FirstPosition + blockBeginsPos - 1, sourceLine.FirstPosition + blockEndsPos + 1),
                                          _comment, startOffset);
                }

                // --- Create labels
                if (sourceLine.LabelSpan != null)
                {
                    AddClassificationSpan(list, snapshot, sourceLine.LabelSpan, _label, startOffset);
                }

                // --- Create keywords
                if (sourceLine.KeywordSpan != null)
                {
                    var type = _instruction;
                    switch (sourceLine)
                    {
                    case PragmaBase _:
                        type = _pragma;
                        break;

                    case Directive _:
                        type = _directive;
                        break;

                    case IncludeDirective _:
                        type = _includeDirective;
                        break;

                    case MacroOrStructInvocation _:
                        type = _macroInvocation;
                        break;

                    case ModuleStatement _:
                    case ModuleEndStatement _:
                        type = _module;
                        break;

                    case StatementBase _:
                        type = _statement;
                        break;
                    }

                    // --- Retrieve a pragma/directive/instruction
                    AddClassificationSpan(list, snapshot, sourceLine.KeywordSpan, type, startOffset);
                }

                // --- Create comments
                if (sourceLine.CommentSpan != null)
                {
                    AddClassificationSpan(list, snapshot, sourceLine.CommentSpan, _comment, startOffset);
                }

                // --- Create numbers
                if (sourceLine.NumberSpans != null)
                {
                    foreach (var numberSpan in sourceLine.NumberSpans)
                    {
                        AddClassificationSpan(list, snapshot, numberSpan, _number, startOffset);
                    }
                }

                // --- Create strings
                if (sourceLine.StringSpans != null)
                {
                    foreach (var stringSpan in sourceLine.StringSpans)
                    {
                        AddClassificationSpan(list, snapshot, stringSpan, _string, startOffset);
                    }
                }

                // --- Create functions
                if (sourceLine.FunctionSpans != null)
                {
                    foreach (var functionSpan in sourceLine.FunctionSpans)
                    {
                        AddClassificationSpan(list, snapshot, functionSpan, _function, startOffset);
                    }
                }

                // --- Create semi-variables
                if (sourceLine.SemiVarSpans != null)
                {
                    foreach (var semiVarSpan in sourceLine.SemiVarSpans)
                    {
                        AddClassificationSpan(list, snapshot, semiVarSpan, _semiVar, startOffset);
                    }
                }

                // --- Create macro parameters
                if (sourceLine.MacroParamSpans != null)
                {
                    foreach (var macroParamSpan in sourceLine.MacroParamSpans)
                    {
                        AddClassificationSpan(list, snapshot, macroParamSpan, _macroParam, startOffset);
                    }
                }

                // --- Create identifiers
                if (sourceLine.IdentifierSpans != null)
                {
                    foreach (var id in sourceLine.IdentifierSpans)
                    {
                        AddClassificationSpan(list, snapshot, id, _identifier, startOffset);
                    }
                }

                // --- Create statements
                if (sourceLine.StatementSpans != null)
                {
                    foreach (var statement in sourceLine.StatementSpans)
                    {
                        AddClassificationSpan(list, snapshot, statement, _statement, startOffset);
                    }
                }

                // --- Create operands
                if (sourceLine.OperandSpans != null)
                {
                    foreach (var operand in sourceLine.OperandSpans)
                    {
                        AddClassificationSpan(list, snapshot, operand, _operand, startOffset);
                    }
                }

                // --- Create mnemonics
                if (sourceLine.MnemonicSpans != null)
                {
                    foreach (var mnemonic in sourceLine.MnemonicSpans)
                    {
                        AddClassificationSpan(list, snapshot, mnemonic, _operand, startOffset);
                    }
                }
            }

            return(list);
        }
        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);
                    }
                }
            }
        }
 public ShiftRightOperationNode(Z80AsmParser.ShiftExprContext context, Z80AsmVisitor visitor)
     : base(context, context.expr()[0], context.expr()[1], visitor)
 {
 }
示例#7
0
 public MultiplyOperationNode(Z80AsmParser.MultExprContext context, Z80AsmVisitor visitor)
     : base(context, context.expr()[0], context.expr()[1], visitor)
 {
 }
 public BitwiseXorOperationNode(Z80AsmParser.XorExprContext context, Z80AsmVisitor visitor)
     : base(context, context.expr()[0], context.expr()[1], visitor)
 {
 }
示例#9
0
        /// <summary>
        /// Parses the source code passed to the compiler
        /// </summary>
        /// <param name="fileIndex">Source file index</param>
        /// <param name="sourceItem">Source file item</param>
        /// <param name="sourceText">Source text to parse</param>
        /// <param name="parsedLines"></param>
        /// <returns>True, if parsing was successful</returns>
        private bool ExecuteParse(int fileIndex, SourceFileItem sourceItem, string sourceText,
                                  out List <SourceLineBase> parsedLines)
        {
            // --- No lines has been parsed yet
            parsedLines = new List <SourceLineBase>();

            // --- Parse all source code lines
            var inputStream = new AntlrInputStream(sourceText);
            var lexer       = new Z80AsmLexer(inputStream);
            var tokenStream = new CommonTokenStream(lexer);
            var parser      = new Z80AsmParser(tokenStream);
            var context     = parser.compileUnit();
            var visitor     = new Z80AsmVisitor(inputStream);

            visitor.Visit(context);
            var visitedLines = visitor.Compilation;

            // --- Store any tasks defined by the user
            StoreTasks(sourceItem, visitedLines.Lines);

            // --- Collect syntax errors
            foreach (var error in parser.SyntaxErrors)
            {
                ReportError(sourceItem, error);
            }

            // --- Exit if there are any errors
            if (Output.ErrorCount != 0)
            {
                return(false);
            }

            // --- Now, process directives and the .model pragma
            var currentLineIndex = 0;
            var ifdefStack       = new Stack <bool?>();
            var processOps       = true;

            parsedLines = new List <SourceLineBase>();
            var anyProcessed = false;

            // --- Traverse through parsed lines
            while (currentLineIndex < visitedLines.Lines.Count)
            {
                var line = visitedLines.Lines[currentLineIndex];
                switch (line)
                {
                case ZxBasicPragma _:
                {
                    if (anyProcessed)
                    {
                        ReportError(Errors.Z0450, line);
                        break;
                    }

                    _options.UseCaseSensitiveSymbols = true;
                    _options.ProcExplicitLocalsOnly  = true;
                    _options.FlexibleDefPragmas      = true;
                    CurrentModule     = Output = new AssemblerOutput(sourceItem, true);
                    Output.SourceType = "zxbasic";
                    anyProcessed      = true;
                    break;
                }

                case ModelPragma modelPragma:
                    ProcessModelPragma(modelPragma);
                    anyProcessed = true;
                    break;

                case IncludeDirective incDirective:
                {
                    // --- Parse the included file
                    if (ApplyIncludeDirective(incDirective, sourceItem,
                                              out var includedLines))
                    {
                        // --- Add the parse result of the include file to the result
                        parsedLines.AddRange(includedLines);
                        anyProcessed = true;
                    }

                    break;
                }

                case LineDirective lineDirective:
                    // TODO: Process a #line directive
                    break;

                case Directive preProc:
                    ApplyDirective(preProc, ifdefStack, ref processOps);
                    anyProcessed = true;
                    break;

                default:
                {
                    if (processOps)
                    {
                        line.FileIndex       = fileIndex;
                        line.MacroSourceText = sourceText.Substring(line.FirstPosition,
                                                                    line.LastPosition - line.FirstPosition + 1);
                        parsedLines.Add(line);
                        anyProcessed = true;
                    }

                    break;
                }
                }
                currentLineIndex++;
            }

            // --- Check if all #if and #ifdef has a closing #endif tag
            if (ifdefStack.Count > 0 && visitedLines.Lines.Count > 0)
            {
                ReportError(Errors.Z0062, visitedLines.Lines.Last());
            }

            return(Output.ErrorCount == 0);
        }
 public NotEqualOperationNode(Z80AsmParser.EquExprContext context, Z80AsmVisitor visitor)
     : base(context, context.expr()[0], context.expr()[1], visitor)
 {
 }
示例#11
0
        /// <summary>
        /// Gets all the tags that intersect the specified spans.
        /// </summary>
        /// <param name="spans">The spans to visit.</param>
        /// <returns>
        /// A <see cref="T:Microsoft.VisualStudio.Text.Tagging.TagSpan`1" /> for each tag.
        /// </returns>
        public IEnumerable <ITagSpan <Z80AsmTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans)
        {
            // --- Obtain the breakpoints that may affect this view
            var affectedLines = new List <int>();

            foreach (Breakpoint bp in Package.ApplicationObject.Debugger.Breakpoints)
            {
                if (string.Compare(bp.File, FilePath, StringComparison.InvariantCultureIgnoreCase) == 0)
                {
                    // --- Breakpoints start lines at 1, ITextBuffer starts from 0
                    affectedLines.Add(bp.FileLine - 1);
                }
            }

            foreach (var curSpan in spans)
            {
                var currentLine = curSpan.Start.GetContainingLine();
                var textOfLine  = currentLine.GetText();

                // --- Let's use the Z80 assembly parser to obtain tags
                var inputStream = new AntlrInputStream(textOfLine);
                var lexer       = new Z80AsmLexer(inputStream);
                var tokenStream = new CommonTokenStream(lexer);
                var parser      = new Z80AsmParser(tokenStream);
                var context     = parser.asmline();
                var visitor     = new Z80AsmVisitor();
                visitor.Visit(context);
                if (!(visitor.LastAsmLine is SourceLineBase asmline))
                {
                    continue;
                }

                if (asmline is EmittingOperationBase && asmline.InstructionSpan != null)
                {
                    // --- This line contains executable instruction,
                    // --- So it might have a breakpoint
                    if (affectedLines.IndexOf(currentLine.LineNumber) >= 0)
                    {
                        // --- Check for the any preset breakpoint
                        yield return(CreateSpan(currentLine, asmline.InstructionSpan, Z80AsmTokenType.Breakpoint));
                    }
                }

                if (asmline.LabelSpan != null)
                {
                    // --- Retrieve a label
                    yield return(CreateSpan(currentLine, asmline.LabelSpan, Z80AsmTokenType.Label));
                }

                if (asmline.KeywordSpan != null)
                {
                    var type = Z80AsmTokenType.Instruction;
                    if (asmline is PragmaBase)
                    {
                        type = Z80AsmTokenType.Pragma;
                    }
                    else if (asmline is Directive)
                    {
                        type = Z80AsmTokenType.Directive;
                    }
                    else if (asmline is IncludeDirective)
                    {
                        type = Z80AsmTokenType.Include;
                    }

                    // --- Retrieve a pragma/directive/instruction
                    yield return(CreateSpan(currentLine, asmline.KeywordSpan, type));
                }

                if (asmline.CommentSpan != null)
                {
                    // --- Retrieve a comment
                    yield return(CreateSpan(currentLine, asmline.CommentSpan, Z80AsmTokenType.Comment));
                }

                if (asmline.Numbers != null)
                {
                    foreach (var numberSpan in asmline.Numbers)
                    {
                        // --- Retrieve a number
                        yield return(CreateSpan(currentLine, numberSpan, Z80AsmTokenType.Number));
                    }
                }

                if (asmline.Identifiers == null)
                {
                    continue;
                }

                foreach (var idSpan in asmline.Identifiers)
                {
                    // --- Retrieve a number
                    yield return(CreateSpan(currentLine, idSpan, Z80AsmTokenType.Identifier));
                }
            }
        }
示例#12
0
 protected UnaryExpressionNode(Z80AsmParser.ExprContext context, Z80AsmVisitor visitor)
     : base(context)
 {
     Operand = (ExpressionNode)visitor.VisitExpr(context);
 }
示例#13
0
        /// <summary>
        /// Gets all the tags that intersect the specified spans.
        /// </summary>
        /// <param name="spans">The spans to visit.</param>
        /// <returns>
        /// A <see cref="T:Microsoft.VisualStudio.Text.Tagging.TagSpan`1" /> for each tag.
        /// </returns>
        public IEnumerable <ITagSpan <Z80AsmTokenTag> > GetTags(NormalizedSnapshotSpanCollection spans)
        {
            foreach (var curSpan in spans)
            {
                var currentLine = curSpan.Start.GetContainingLine();
                var textOfLine  = currentLine.GetText();

                // --- Let's use the Z80 assembly parser to obtain tags
                var inputStream = new AntlrInputStream(textOfLine);
                var lexer       = new Z80AsmLexer(inputStream);
                var tokenStream = new CommonTokenStream(lexer);
                var parser      = new Z80AsmParser(tokenStream);
                var context     = parser.asmline();
                var visitor     = new Z80AsmVisitor();
                visitor.Visit(context);
                if (!(visitor.LastAsmLine is SourceLineBase asmline))
                {
                    continue;
                }

                if (asmline.LabelSpan != null)
                {
                    // --- Retrieve a label
                    yield return(CreateSpan(currentLine, asmline.LabelSpan, Z80AsmTokenType.Label));
                }

                if (asmline.KeywordSpan != null)
                {
                    var type = Z80AsmTokenType.Instruction;
                    if (asmline is PragmaBase)
                    {
                        type = Z80AsmTokenType.Pragma;
                    }
                    else if (asmline is Directive)
                    {
                        type = Z80AsmTokenType.Directive;
                    }

                    // --- Retrieve a pragma/directive/instruction
                    yield return(CreateSpan(currentLine, asmline.KeywordSpan, type));
                }

                if (asmline.CommentSpan != null)
                {
                    // --- Retrieve a comment
                    yield return(CreateSpan(currentLine, asmline.CommentSpan, Z80AsmTokenType.Comment));
                }

                if (asmline.Numbers != null)
                {
                    foreach (var numberSpan in asmline.Numbers)
                    {
                        // --- Retrieve a number
                        yield return(CreateSpan(currentLine, numberSpan, Z80AsmTokenType.Number));
                    }
                }

                if (asmline.Identifiers == null)
                {
                    continue;
                }

                foreach (var idSpan in asmline.Identifiers)
                {
                    // --- Retrieve a number
                    yield return(CreateSpan(currentLine, idSpan, Z80AsmTokenType.Identifier));
                }
            }
        }
示例#14
0
 public GreaterThanOperationNode(Z80AsmParser.RelExprContext context, Z80AsmVisitor visitor)
     : base(context, context.expr()[0], context.expr()[1], visitor)
 {
 }
示例#15
0
 public AddOperationNode(Z80AsmParser.AddExprContext context, Z80AsmVisitor visitor)
     : base(context, context.expr()[0], context.expr()[1], visitor)
 {
 }
示例#16
0
 public UnaryLogicalNotNode(Z80AsmParser.LogicalNotExprContext context, Z80AsmVisitor visitor)
     : base(context.expr(), visitor)
 {
 }
示例#17
0
 public LessThanOrEqualOperationNode(Z80AsmParser.RelExprContext context, Z80AsmVisitor visitor)
     : base(context, context.expr()[0], context.expr()[1], visitor)
 {
 }
示例#18
0
 public MinOperationNode(Z80AsmParser.MinMaxExprContext context, Z80AsmVisitor visitor)
     : base(context, context.expr()[0], context.expr()[1], visitor)
 {
 }