diff --git a/src/parse.fs b/src/parse.fs index 815f2735..0a0a6d89 100644 --- a/src/parse.fs +++ b/src/parse.fs @@ -185,8 +185,7 @@ type private ParseImpl() = (structSpecifier .>> semi) |>> Ast.TypeDecl // eg. "const out int", "uniform float", "int[2][3]" - let specifiedTypeGLSL = - let storage = ["const"; "inout"; "in"; "out"; "centroid" + let glslStorage = ["const"; "inout"; "in"; "out"; "centroid" "patch"; "sample"; "uniform"; "buffer"; "shared"; "coherent" "volatile"; "restrict"; "readonly"; "writeonly"; "subroutine" "attribute"; "varying" @@ -195,15 +194,15 @@ type private ParseImpl() = "smooth"; "flat"; "noperspective" ] |> List.map keyword |> choice "Type qualifier" - let layout = keyword "layout" >>. ch '(' >>. manyCharsTill anyChar (ch ')') - |>> (function s -> "layout(" + s + ")") - let qualifier = many (storage <|> layout) + let glslLayout = keyword "layout" >>. ch '(' >>. manyCharsTill anyChar (ch ')') + |>> (function s -> "layout(" + s + ")") + let glslQualifier = many (glslStorage <|> glslLayout) + let specifiedTypeGLSL = let typeSpec = structSpecifier <|> (ident |>> (fun id -> Ast.TypeName id.Name)) let arraySizes = many (between (ch '[') (ch ']') expr) - pipe3 qualifier typeSpec arraySizes (fun tyQ name sizes -> Ast.makeType name tyQ sizes) + pipe3 glslQualifier typeSpec arraySizes (fun tyQ name sizes -> Ast.makeType name tyQ sizes) - let specifiedTypeHLSL = - let storage = ["extern"; "nointerpolation"; "precise"; "shared"; "groupshared" + let hlslStorage = ["extern"; "nointerpolation"; "precise"; "shared"; "groupshared" "static"; "uniform"; "volatile"; "const"; "row_major"; "column_major" "inline"; "target" "out"; "in"; "inout" @@ -213,15 +212,20 @@ type private ParseImpl() = "point"; "line"; "triangle"; "lineadj"; "triangleadj" ] |> List.map keyword |> choice "Type qualifier" - let qualifier = many storage + let hlslQualifier = many hlslStorage + let specifiedTypeHLSL = let generic = ch '<' >>. manyCharsTill anyChar (ch '>') |> opt |>> (function Some s -> "<" + s + ">" | None -> "") let typeName = pipe2 (ident |>> (fun id -> id.Name)) generic (+) let typeSpec = structSpecifier <|> (typeName |>> Ast.TypeName) let arraySizes = many (between (ch '[') (ch ']') expr) - pipe4 qualifier typeSpec generic arraySizes (fun tyQ name _ sizes -> Ast.makeType name tyQ sizes) + pipe4 hlslQualifier typeSpec generic arraySizes (fun tyQ name _ sizes -> Ast.makeType name tyQ sizes) + let qualifier = parse { + let! ret = if options.hlsl then hlslQualifier else glslQualifier + return ret + } let specifiedType = parse { let! ret = if options.hlsl then specifiedTypeHLSL else specifiedTypeGLSL return ret @@ -347,6 +351,9 @@ type private ParseImpl() = let precision = keyword "precision" >>. (specifiedType |>> Ast.Precision) .>> ch ';' + let loneLayoutQualifier = + qualifier .>> ch ';' |>> (fun list -> String.concat " " list + ";") + let toplevel = let decl = declaration .>> ch ';' let item = choice [ @@ -356,6 +363,7 @@ type private ParseImpl() = attempt decl |>> Ast.TLDecl structDecl attempt interfaceBlock + loneLayoutQualifier |>> Ast.TLVerbatim precision pfunction ] diff --git a/tests/unit/precision.frag b/tests/unit/precision.frag index 627c2c08..67d0c2a3 100644 --- a/tests/unit/precision.frag +++ b/tests/unit/precision.frag @@ -4,3 +4,14 @@ precision highp float; precision mediump int; precision lowp sampler2D; precision lowp samplerCube; + +layout(triangles) in; // #29 +layout(triangle_strip, max_vertices = 3) out; // #29 +layout(local_size_x = 32) in; // #22 + +// #17 +layout(location=0) out vec4 f_color; +//subroutine float functionType(int i); +//layout(location = 0) subroutine uniform functionType tbl[2]; +//layout(index = 1) subroutine (functionType) float func1(int i) { return i * 1.0/255.0; } +//layout(index = 2) subroutine (functionType) float func2(int i) { return 1.0 - i * 1.0/255.0; } diff --git a/tests/unit/precision.frag.expected b/tests/unit/precision.frag.expected index 627c2c08..028b62fe 100644 --- a/tests/unit/precision.frag.expected +++ b/tests/unit/precision.frag.expected @@ -4,3 +4,7 @@ precision highp float; precision mediump int; precision lowp sampler2D; precision lowp samplerCube; +layout(triangles)in; +layout(triangle_strip,max_vertices=3)out; +layout(local_size_x=32)in; +layout(location=0) out vec4 t;