/// <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 codelines 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 var includeIndex = fileIndex; while (currentLineIndex < visitedLines.Lines.Count) { var line = visitedLines.Lines[currentLineIndex]; if (line is ModelPragma modelPragma) { ProcessModelPragma(modelPragma); } else if (line is IncludeDirective incDirective) { includeIndex++; // --- Parse the included file if (ApplyIncludeDirective(includeIndex, 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; 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); }
/// <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); }