diff --git a/example/program.nub b/example/program.nub index 2da8f81..6a1e761 100644 --- a/example/program.nub +++ b/example/program.nub @@ -9,7 +9,7 @@ struct Human { export func main(args: []^string) { let i: i64 - c::printf("%d\n", args.count) + c:printf("%d\n", args.count) while i < args.count { c::printf("%s\n", args[i]) diff --git a/src/lang/Nub.Lang/Frontend/Diagnostics/ConsoleColors.cs b/src/lang/Nub.Lang/Frontend/Diagnostics/ConsoleColors.cs index 149296b..eaa1791 100644 --- a/src/lang/Nub.Lang/Frontend/Diagnostics/ConsoleColors.cs +++ b/src/lang/Nub.Lang/Frontend/Diagnostics/ConsoleColors.cs @@ -139,8 +139,9 @@ public static class ConsoleColors } } - public static string ColorizeSource(SourceText sourceText) + public static string ColorizeSource(string source) { + var sourceText = new SourceText(string.Empty, source); var tokens = Lexer.Tokenize(sourceText).Value; var result = new StringBuilder(); var lastCharIndex = 0; diff --git a/src/lang/Nub.Lang/Frontend/Diagnostics/Diagnostic.cs b/src/lang/Nub.Lang/Frontend/Diagnostics/Diagnostic.cs index 6d9455a..9517681 100644 --- a/src/lang/Nub.Lang/Frontend/Diagnostics/Diagnostic.cs +++ b/src/lang/Nub.Lang/Frontend/Diagnostics/Diagnostic.cs @@ -77,18 +77,18 @@ public class Diagnostic } sb.Append(": "); - sb.AppendLine(ConsoleColors.Colorize(Message, ConsoleColors.BrightWhite)); + sb.Append(ConsoleColors.Colorize(Message, ConsoleColors.BrightWhite)); if (Span.HasValue) { + sb.AppendLine(); AppendSourceContext(sb, Span.Value); } if (!string.IsNullOrEmpty(Help)) { sb.AppendLine(); - var helpText = $"help: {Help}"; - sb.AppendLine(ConsoleColors.Colorize(helpText, ConsoleColors.Cyan)); + sb.Append(ConsoleColors.Colorize($"help: {Help}", ConsoleColors.Cyan)); } return sb.ToString(); @@ -113,50 +113,61 @@ public class Diagnostic const int contextLines = 3; - if (startLine < 1 || startLine > lines.Length || endLine < 1 || endLine > lines.Length) - { - return; - } - - var maxLineNum = Math.Min(endLine + contextLines, lines.Length); - var lineNumWidth = maxLineNum.ToString().Length; + var lineNumWidth = Math.Min(endLine + contextLines, lines.Length).ToString().Length; var contextStart = Math.Max(1, startLine - contextLines); + var contextEnd = Math.Min(lines.Length, endLine + contextLines); + + var contextWidth = 0; + for (var i = contextStart; i < contextEnd; i++) + { + if (lines[i - 1].Length > contextWidth) + { + contextWidth = lines[i - 1].Length; + } + } + + sb.AppendLine(ConsoleColors.Colorize('╭' + new string('─', lineNumWidth + 2) + '┬' + new string('─', contextWidth + 2) + '╮', ConsoleColors.Faint)); for (var lineNum = contextStart; lineNum < startLine; lineNum++) { - var line = ConsoleColors.ColorizeSource(new SourceText(span.Text.Name, lines[lineNum - 1])); - AppendContextLine(sb, lineNum, line, lineNumWidth); + AppendContextLine(sb, lineNum, lines[lineNum - 1], lineNumWidth, contextWidth); } for (var lineNum = startLine; lineNum <= endLine; lineNum++) { - var line = ConsoleColors.ColorizeSource(new SourceText(span.Text.Name, lines[lineNum - 1])); - AppendContextLine(sb, lineNum, line, lineNumWidth); - AppendErrorIndicators(sb, span, lineNum, line, lineNumWidth); + AppendContextLine(sb, lineNum, lines[lineNum - 1], lineNumWidth, contextWidth); + AppendErrorIndicators(sb, span, lineNum, lines[lineNum - 1], lineNumWidth, contextWidth); } - var contextEnd = Math.Min(lines.Length, endLine + contextLines); for (var lineNum = endLine + 1; lineNum <= contextEnd; lineNum++) { - var line = ConsoleColors.ColorizeSource(new SourceText(span.Text.Name, lines[lineNum - 1])); - AppendContextLine(sb, lineNum, line, lineNumWidth); + AppendContextLine(sb, lineNum, lines[lineNum - 1], lineNumWidth, contextWidth); } + + sb.Append(ConsoleColors.Colorize('╰' + new string('─', lineNumWidth + 2) + '┴' + new string('─', contextWidth + 2) + '╯', ConsoleColors.Faint)); } - private static void AppendContextLine(StringBuilder sb, int lineNum, string line, int lineNumWidth) + private static void AppendContextLine(StringBuilder sb, int lineNum, string line, int lineNumWidth, int contextWidth) { + sb.Append(ConsoleColors.Colorize('│' + " ", ConsoleColors.Faint)); var lineNumStr = lineNum.ToString().PadLeft(lineNumWidth); sb.Append(ConsoleColors.Colorize(lineNumStr, ConsoleColors.Faint)); - sb.Append(ConsoleColors.Colorize(" | ", ConsoleColors.Faint)); - sb.AppendLine(line); + sb.Append(ConsoleColors.Colorize(" │ ", ConsoleColors.Faint)); + sb.Append(ConsoleColors.ColorizeSource(line.PadRight(contextWidth))); + sb.Append(ConsoleColors.Colorize(" " + '│', ConsoleColors.Faint)); + sb.AppendLine(); } - private static void AppendErrorIndicators(StringBuilder sb, SourceSpan span, int lineNum, string line, int lineNumWidth) + private static void AppendErrorIndicators(StringBuilder sb, SourceSpan span, int lineNum, string line, int lineNumWidth, int contextWidth) { - sb.Append(new string(' ', lineNumWidth + 3)); + sb.Append(ConsoleColors.Colorize('│' + " ", ConsoleColors.Faint)); + sb.Append(new string(' ', lineNumWidth)); + sb.Append(ConsoleColors.Colorize(" │ ", ConsoleColors.Faint)); var indicators = GetIndicatorsForLine(span, lineNum, line); - sb.AppendLine(ConsoleColors.Colorize(indicators, ConsoleColors.Red)); + sb.Append(ConsoleColors.Colorize(indicators.PadRight(contextWidth), ConsoleColors.Red)); + sb.Append(ConsoleColors.Colorize(" " + '│', ConsoleColors.Faint)); + sb.AppendLine(); } private static string GetIndicatorsForLine(SourceSpan span, int lineNum, string line) diff --git a/src/lang/Nub.Lang/Frontend/Diagnostics/DiagnosticsResult.cs b/src/lang/Nub.Lang/Frontend/Diagnostics/DiagnosticsResult.cs index 18f93f5..c2af33d 100644 --- a/src/lang/Nub.Lang/Frontend/Diagnostics/DiagnosticsResult.cs +++ b/src/lang/Nub.Lang/Frontend/Diagnostics/DiagnosticsResult.cs @@ -9,6 +9,7 @@ public class DiagnosticsResult(List diagnostics) foreach (var diagnostic in diagnostics) { Console.Error.WriteLine(diagnostic.Format()); + Console.Error.WriteLine(); } } }