This repository has been archived on 2025-10-24. You can view files and clone it, but cannot push or open issues or pull requests.
Files
nub-lang-archive-2/src/Nub.Lang/Diagnostics/ConsoleColors.cs
2025-06-12 23:37:28 +02:00

178 lines
6.2 KiB
C#

using System.Text;
using Nub.Lang.Frontend.Lexing;
using Nub.Lang.Frontend.Typing;
namespace Nub.Lang.Diagnostics;
public static class ConsoleColors
{
public const string Reset = "\e[0m";
public const string Bold = "\e[1m";
public const string Faint = "\e[2m";
public const string Italic = "\e[3m";
public const string Underline = "\e[4m";
public const string SlowBlink = "\e[5m";
public const string RapidBlink = "\e[6m";
public const string SwapBgAndFg = "\e[7m";
public const string Conceal = "\e[8m";
public const string CrossedOut = "\e[9m";
public const string DefaultFont = "\e[10m";
public const string AltFont1 = "\e[11m";
public const string AltFont2 = "\e[12m";
public const string AltFont3 = "\e[13m";
public const string AltFont4 = "\e[14m";
public const string AltFont5 = "\e[15m";
public const string AltFont6 = "\e[16m";
public const string AltFont7 = "\e[17m";
public const string AltFont8 = "\e[18m";
public const string AltFont9 = "\e[19m";
public const string Black = "\e[30m";
public const string Red = "\e[31m";
public const string Green = "\e[32m";
public const string Yellow = "\e[33m";
public const string Blue = "\e[34m";
public const string Magenta = "\e[35m";
public const string Cyan = "\e[36m";
public const string White = "\e[37m";
public const string BrightBlack = "\e[90m";
public const string BrightRed = "\e[91m";
public const string BrightGreen = "\e[92m";
public const string BrightYellow = "\e[93m";
public const string BrightBlue = "\e[94m";
public const string BrightMagenta = "\e[95m";
public const string BrightCyan = "\e[96m";
public const string BrightWhite = "\e[97m";
private static bool IsColorSupported()
{
var term = Environment.GetEnvironmentVariable("TERM");
var colorTerm = Environment.GetEnvironmentVariable("COLORTERM");
return !string.IsNullOrEmpty(term) || !string.IsNullOrEmpty(colorTerm) || !Console.IsOutputRedirected;
}
public static string Colorize(string text, string color)
{
return IsColorSupported() ? $"{color}{text}{Reset}" : text;
}
private static string GetTokenColor(Token token)
{
switch (token)
{
case DocumentationToken:
return Faint;
case IdentifierToken:
return White;
case LiteralToken literal:
return literal.Kind switch
{
LiteralKind.String => Green,
LiteralKind.Integer or LiteralKind.Float => BrightBlue,
LiteralKind.Bool => Blue,
_ => White
};
case ModifierToken:
return White;
case SymbolToken symbol:
switch (symbol.Symbol)
{
case Symbol.If:
case Symbol.Else:
case Symbol.While:
case Symbol.Break:
case Symbol.Continue:
case Symbol.Return:
return Magenta;
case Symbol.Func:
case Symbol.Struct:
case Symbol.Namespace:
case Symbol.Let:
case Symbol.Alloc:
return Blue;
case Symbol.Assign:
case Symbol.Bang:
case Symbol.Equal:
case Symbol.NotEqual:
case Symbol.LessThan:
case Symbol.LessThanOrEqual:
case Symbol.GreaterThan:
case Symbol.GreaterThanOrEqual:
case Symbol.Plus:
case Symbol.Minus:
case Symbol.Star:
case Symbol.ForwardSlash:
case Symbol.Caret:
case Symbol.Ampersand:
return White;
case Symbol.Semicolon:
case Symbol.Colon:
case Symbol.Comma:
case Symbol.Period:
case Symbol.DoubleColon:
return Faint;
case Symbol.OpenParen:
case Symbol.CloseParen:
case Symbol.OpenBrace:
case Symbol.CloseBrace:
case Symbol.OpenBracket:
case Symbol.CloseBracket:
return Yellow;
default:
return White;
}
default:
return White;
}
}
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;
foreach (var token in tokens)
{
var tokenStartIndex = GetCharacterIndex(sourceText, token.Span.Start);
var tokenEndIndex = GetCharacterIndex(sourceText, token.Span.End);
if (tokenStartIndex > lastCharIndex)
{
var between = sourceText.Content.Substring(lastCharIndex, tokenStartIndex - lastCharIndex);
result.Append(between);
}
var tokenText = sourceText.Content.Substring(tokenStartIndex, tokenEndIndex - tokenStartIndex);
result.Append(Colorize(tokenText, GetTokenColor(token)));
lastCharIndex = tokenEndIndex;
}
if (lastCharIndex < sourceText.Content.Length)
{
var remaining = sourceText.Content[lastCharIndex..];
result.Append(Colorize(remaining, Faint));
}
return result.ToString();
}
private static int GetCharacterIndex(SourceText sourceText, SourceLocation location)
{
var lines = sourceText.Content.Split('\n');
var index = 0;
for (var i = 0; i < location.Line - 1 && i < lines.Length; i++)
{
index += lines[i].Length + 1;
}
index += location.Column - 1;
return Math.Min(index, sourceText.Content.Length);
}
}