private static void EnterInteractiveMode() { Logger.Info( "Axion code editor & interpreter mode.\n" + "Type 'exit' or 'quit' to exit mode, 'cls' to clear screen." ); while (true) { // code editor header string rawInput = ConsoleUI.Read("i>> "); string input = rawInput.Trim().ToUpper(); switch (input) { case "": // skip empty commands ConsoleUI.ClearLine(); continue; case "EXIT": case "QUIT": // exit from interpreter to main loop Logger.Info("\nInteractive interpreter closed."); return; } // TODO (UI) parse "help(module)" argument // initialize editor var editor = new ConsoleCodeEditor( false, true, firstCodeLine: rawInput, highlighter: new AxionSyntaxHighlighter() ); string[] codeLines = editor.RunSession(); // interpret as source code and output result Process(new SourceUnit(codeLines), SourceProcessingMode.Interpret); } }
/// <summary> /// Creates visual representation of occurred error in console. /// </summary> internal void Print(SourceUnit unit) { //--------Error templates-------- // // Error: Invalid operator. // // | 8 | variable ~~ "string" // -----------------^^ // ... // // Error: Mismatching parenthesis. // | 1 | func("string", // ------------^ // | 2 | 'c', // | 3 | 123 // ... // ConsoleColor color = Severity == BlameSeverity.Error ? ConsoleColor.Red : ConsoleColor.DarkYellow; // Write message ConsoleUI.WriteLine((Message, color)); // Append file name if it's exists. ConsoleUI.WriteLine("In file '" + unit.SourceFilePath + "'."); Console.WriteLine(); string[] codeLines = unit.Code.Split(Spec.EndOfLines, StringSplitOptions.None); var lines = new List <string>(); // limit rest of code by 5 lines for (int i = Span.Start.Line; i < codeLines.Length && lines.Count < 4; i++) { lines.Add(codeLines[i].TrimEnd('\n', Spec.EndOfCode)); } if (lines.Count > codeLines.Length - Span.Start.Line) { lines.Add("..."); } // first line // <line number>| <code line> int pointerTailLength = ConsoleCodeEditor.LineNumberWidth + Span.Start.Column; int errorTokenLength; if (Span.End.Line > Span.Start.Line) { errorTokenLength = lines[0].Length - Span.Start.Column; } else { errorTokenLength = Span.End.Column - Span.Start.Column; } // upside arrows (^), should be red-colored string pointer = // tail of pointer new string(' ', pointerTailLength) + // pointer arrows new string( '^', // TODO (UI) compute token value length: include tab lengths errorTokenLength ); // Drawing ========== // line with error ConsoleCodeEditor.PrintLineNumber(Span.Start.Line + 1); ConsoleUI.WriteLine(lines[0]); // error pointer ConsoleUI.WriteLine((pointer, color)); // next lines for (int i = Span.Start.Line + 1; i < lines.Count; i++) { ConsoleCodeEditor.PrintLineNumber(i + 1); ConsoleUI.WriteLine(lines[i]); } Console.WriteLine(); }