public static string TranspileTypeString(this TokenNode tokenNode, TokenTranspileFlags flags = (TokenTranspileFlags)0)
        {
            _ = tokenNode ?? throw new ArgumentNullException(nameof(tokenNode));

            switch (tokenNode.TokenType)
            {
            // TODO: don't use hardcoded strings
            case SyntaxTokenType.HandleKeyword: return("object");    // SyntaxFactory.PredefinedType(SyntaxFactory.Token(Microsoft.CodeAnalysis.CSharp.SyntaxKind.ObjectKeyword))

            case SyntaxTokenType.IntegerKeyword: return("int");

            case SyntaxTokenType.RealKeyword: return("float");

            case SyntaxTokenType.StringKeyword: return("string");

            case SyntaxTokenType.BooleanKeyword: return("bool");

            case SyntaxTokenType.CodeKeyword: return(flags.HasFlag(TokenTranspileFlags.ReturnBoolFunc) ? "System.Func<bool>" : "System.Action");

            case SyntaxTokenType.AlphanumericIdentifier: return(tokenNode.TranspileIdentifier());

            default:
                throw new ArgumentException($"Cannot transpile token of type {tokenNode.TokenType} to a C# type.");
            }
        }
        public static TypeSyntax TranspileType(this TokenNode tokenNode, TokenTranspileFlags flags = (TokenTranspileFlags)0)
        {
            _ = tokenNode ?? throw new ArgumentNullException(nameof(tokenNode));

            return(SyntaxFactory.ParseTypeName(flags.HasFlag(TokenTranspileFlags.ReturnArray)
                ? $"{tokenNode.TranspileTypeString(flags)}[]"
                : tokenNode.TranspileTypeString(flags)));
        }