stride3d/stride · error · NotImplementedException

Exception of type 'System.NotImplementedException' was…

Error message

Exception of type 'System.NotImplementedException' was thrown.

What it means

Terminals.FloatSuffix scans and classifies a floating-point literal suffix. Recognized suffixes are f16/h, f32/f, f64/d; any other scanned suffix falls through the switch and throws NotImplementedException, meaning the suffix grammar is incomplete and hits an unhandled parser state.

Solutions

  1. Use a supported suffix: h/f16, f/f32, or d/f64 (lowercase) in the shader source
  2. Add the missing suffix mapping to the switch in Terminals.cs:88
  3. Replace the throw with a parser diagnostic (ParseError) for unknown float suffixes

Example fix

// before
_ => throw new NotImplementedException()
// after
"F" => new(32, true, true),
_ => throw new ArgumentException($"Unknown float suffix '{matched}'")
Defensive patterns

Strategy: validation

Validate before calling

static readonly System.Text.RegularExpressions.Regex FloatSuffixRe = new("^(f16|h|f32|f|f64|d)$");
bool HasSupportedFloatSuffix(string lexeme) => FloatSuffixRe.IsMatch(lexeme);

Type guard

bool IsKnownFloatSuffix(string s) => s is "f16" or "h" or "f32" or "f" or "f64" or "d";

Try / catch

try { ok = Terminals.FloatSuffix(ref scanner, out suffix, advance); }
catch (NotImplementedException) { orError?.Add(new ParseError(ParseErrorCode.NotImplemented, $"Unsupported float suffix near {scanner.Position}")); suffix = null; ok = false; }

Prevention

When it happens

Trigger: Parsing a float literal whose suffix is not f16/h/f32/f/f64/d — e.g. 'lf', 'F', or an unexpected token right after digits that the suffix scanner consumed.

Common situations: Porting shaders that use alternate float suffixes (HLSL 'F', GLSL 'LF'); case-sensitivity assumptions (only lowercase 'f'/'h'/'d' accepted); typos in numeric literals.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/c4f9b5f1f3a6a8ef. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/Parsing/SDSL/Parsers/Terminals/Terminals.cs:88

        => new EOLTokenParser().Match(ref scanner, advance);
    public static bool EOF<TScanner>(ref TScanner scanner)
        where TScanner : struct, IScanner
        => new EOFTokenParser().Match(ref scanner, false);



    public static bool FloatSuffix<TScanner>(ref TScanner scanner, out Suffix? suffix, bool advance = false)
        where TScanner : struct, IScanner
    {
        suffix = null;
        if (AnyOf(["f16", "h", "f32", "f", "f64", "d"], ref scanner, out var matched, advance: advance))
        {
            suffix = matched switch
            {
                "f16" or "h" => new(16, true, true),
                "f32" or "f" => new(32, true, true),
                "f64" or "d" => new(64, true, true),
                _ => throw new NotImplementedException()
            };
            return true;
        }
        else return false;
    }
    public static bool IntSuffix<TScanner>(ref TScanner scanner, out Suffix? suffix, bool advance = false)
        where TScanner : struct, IScanner
    {
        suffix = null;
        if (AnyOf(["u32", "u", "U", "i64", "l", "L", "u64", "ul", "UL"], ref scanner, out var matched, advance: advance))
        {
            suffix = matched switch
            {
                "u32" or "u" or "U" => new(32, false, false),
                "i64" or "l" or "L" => new(64, false, true),
                "u64" or "ul" or "UL" => new(64, false, false),
                _ => throw new NotImplementedException()
            };

View on GitHub (pinned to 96fad776d2)