Hello o/

I have been trying to get my forth interpreter working but I can’t even parse it properly without error. here is what I have done so for ( it’s my 3rd attempt ). if you know any good resources to learn compiler design then please link it. Thank you in advance!

namespace test;

public enum TokenType
{
    Number,
    Operator,
    String,
    Identifier,
    FunctionStart,
    FunctionEnd,
}
public class Token
{
    public TokenType Type { get; set; }
    public string Value { get; set; }

    public override string ToString()
    {
        return $"{Type}: {Value}";
    }
}

public class Program
{
    public static void Err()
    {
        Console.WriteLine("error");
    }
    public static void Main(string[] args)
    {
        string code = "12 12  : abc 10 . ;          23 - + ";

        List<Token> tokens = new List<Token>();
        bool stringMode = false;
        int startStringIndex = 0;
        for (int cur = 0; cur < code.Length; cur++)
        {
            char ch = code[cur];
            if (stringMode)
            {
                if (ch == '"' && code[cur-1] != '\\')
                {
                    stringMode = false;
                    string strValue = code.Substring(startStringIndex, cur - startStringIndex);
                    tokens.Add(new Token { Type = TokenType.String, Value = strValue });
                }
            }
            switch (ch)
            {
                case '+':
                case '-':
                case '*':
                case '/':
                    {
                        tokens.Add(new Token { Type = TokenType.Operator, Value = ch.ToString() });
                        break;
                    }
                case '.':
                    {
                        if (cur + 1 < code.Length && code[cur+1] == '"') 
                        {
                            stringMode = true;
                            cur+=2; // Skip the opening quote
                            startStringIndex = cur;
                        } else
                        {
                            tokens.Add(new Token { Type = TokenType.Operator, Value = ch.ToString() });
                        }
                        break;
                    }
                case >= '0' and <= '9':
                    {
                        int start = cur;
                        while (cur + 1 < code.Length && code[cur + 1] >= '0' && code[cur + 1] <= '9')
                        {
                            cur++;
                        }
                        string numberValue = code.Substring(start, cur - start + 1);
                        tokens.Add(new Token { Type = TokenType.Number, Value = numberValue });
                        break;
                    }
                case (>= 'a' and <= 'z') or (>= 'A' and <= 'Z'):
                    {
                        int start = cur;
                        while (cur + 1 < code.Length && ((code[cur + 1] >= 'a' && code[cur + 1] <= 'z') || (code[cur + 1] >= 'A' && code[cur + 1] <= 'Z') || (code[cur + 1] >= '0' && code[cur + 1] <= '9') || code[cur + 1] == '_'))
                        {
                            cur++;
                        }
                        string identifierValue = code.Substring(start, cur - start + 1);
                        tokens.Add(new Token { Type = TokenType.Identifier, Value = identifierValue });
                        break;
                    }
                case ':':
                    {
                        tokens.Add(new Token { Type = TokenType.FunctionStart, Value = ch.ToString() });
                        break;
                    }
                case ';':
                    {
                        tokens.Add(new Token { Type = TokenType.FunctionEnd, Value = ch.ToString() });
                        break;
                    }
                case ' ':
                case '\n':
                    {
                        break;
                    }
                default:
                    {
                        Err();
                        Console.WriteLine("Something went wrong!");
                        break;
                    }
            }
        }

        foreach (var token in tokens)
        {
            Console.WriteLine(token);
        }
    }
}