XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
namespace XFESystem.Desktop;

public readonly record struct SyntaxSpan(int Start, string Text, uint Color);

/// <summary>A bounded native-view lexer. The full website highlighter is separately available in document HTML previews.</summary>
public static class SyntaxHighlighter
{
    private static readonly string[] Keywords = ["using", "namespace", "public", "private", "protected", "internal", "static", "class", "struct", "record", "void", "string", "int", "bool", "var", "const", "let", "function", "return", "if", "else", "for", "while", "new", "async", "await", "true", "false", "null", "export", "import", "from", "throw", "try", "catch"];
    public static SyntaxSpan[] Tokenize(string line)
    {
        if (line.Length > 4096) throw new ArgumentException("Visible source line exceeds the lexer limit.", nameof(line));
        var result = new List<SyntaxSpan>();
        int at = 0;
        while (at < line.Length)
        {
            int start = at; char c = line[at++]; uint color = 0xDCEAF4;
            if (c == '/' && at < line.Length && line[at] == '/') { at = line.Length; color = 0x739D81; }
            else if (c is '"' or '\'' or '`')
            {
                color = 0xD6BB80;
                while (at < line.Length) { char next = line[at++]; if (next == '\\' && at < line.Length) at++; else if (next == c) break; }
            }
            else if (char.IsLetter(c) || c is '_' or '$')
            {
                while (at < line.Length && (char.IsLetterOrDigit(line[at]) || line[at] is '_' or '$')) at++;
                string word = line[start..at];
                foreach (string keyword in Keywords) if (keyword == word) { color = 0xB99AEE; break; }
            }
            else if (char.IsDigit(c))
            {
                while (at < line.Length && (char.IsLetterOrDigit(line[at]) || line[at] is '.' or '_')) at++;
                color = 0x77D7CE;
            }
            result.Add(new(start, line[start..at], color));
        }
        return result.ToArray();
    }
}