From c97d1aad8308807231361fe39bf7252d7e278624 Mon Sep 17 00:00:00 2001 From: Eldritch Conundrum Date: Tue, 30 Jan 2024 01:24:04 +0100 Subject: [PATCH 01/78] Fix case parsing problem (#319) Fixes #318. --------- Co-authored-by: Laurent Le Brun --- src/builtin.fs | 8 ++++++++ src/parse.fs | 1 + tests/unit/float.frag | 2 +- tests/unit/float.frag.expected | 2 +- tests/unit/switch.expected | 25 +++++++++++++++++++++++++ tests/unit/switch.frag | 16 ++++++++++++++++ 6 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/builtin.fs b/src/builtin.fs index c36c0333..7506afa6 100644 --- a/src/builtin.fs +++ b/src/builtin.fs @@ -2,6 +2,14 @@ module Builtin // source: https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.pdf +let keywords = System.Collections.Generic.HashSet<_>([ + "if"; "else"; "break"; "continue"; "do"; "for"; "while"; "switch"; "case"; "default"; + "in"; "out"; "inout"; "discard"; "return"; "lowp"; "mediump"; "highp"; "precision"; + "struct"; "layout"; "centroid"; "flat"; "smooth"; "noperspective"; "patch"; "sample"; "invariant"; + "precise"; "subroutine"; "coherent"; "volatile"; "restrict"; "readonly"; "writeonly"; + "const"; "uniform"; "buffer"; "shared"; "attribute"; "varying" +]) + let builtinTypes = set([ yield! [ "void"; "bool"; "int"; "uint"; "float"; "double" ] for p in [""; "d"; "b"; "i"; "u"] do diff --git a/src/parse.fs b/src/parse.fs index d7f538d2..c45b1667 100644 --- a/src/parse.fs +++ b/src/parse.fs @@ -37,6 +37,7 @@ type private ParseImpl() = let ident = let nonDigit = asciiLetter <|> pchar '_' let p = pipe2 nonDigit (manyChars (nonDigit <|> digit "")) (fun c s -> Ast.Ident (c.ToString() + s)) + let p = p >>= (fun s -> if Builtin.keywords.Contains(s.Name) then fail "ident is a keyword" else preturn s) (p .>> ws) "identifier" let opp = new OperatorPrecedenceParser<_,_,_>() diff --git a/tests/unit/float.frag b/tests/unit/float.frag index 64a0fd28..92f778b0 100644 --- a/tests/unit/float.frag +++ b/tests/unit/float.frag @@ -1,4 +1,4 @@ -void precision() { +void floatPrecision() { float a = 0.00000012345; float b = 1.234567891234; float c = 1234567.891234; diff --git a/tests/unit/float.frag.expected b/tests/unit/float.frag.expected index 39f85f4b..9f92e86e 100644 --- a/tests/unit/float.frag.expected +++ b/tests/unit/float.frag.expected @@ -7,7 +7,7 @@ #else // if SHADER_MINIFIER_IMPL // tests/unit/float.frag -"void precision()" +"void floatPrecision()" "{" "float a=1.2345e-7,b=1.234567891234,c=1234567.891234,d=1.234567e14;" "}" diff --git a/tests/unit/switch.expected b/tests/unit/switch.expected index 633521f7..5cf2fc91 100644 --- a/tests/unit/switch.expected +++ b/tests/unit/switch.expected @@ -43,3 +43,28 @@ float D() return 0.; } } +void c() +{} +int D(int G) +{ + switch(G){ + case 1: + c(); + case 2: + c(); + case 3: + { + c(); + break; + } + case 4: + c(); + c(); + break; + case 5: + c(); + c(); + return 18; + } + return 1; +} diff --git a/tests/unit/switch.frag b/tests/unit/switch.frag index 1e9b3cd0..7a7cd06f 100644 --- a/tests/unit/switch.frag +++ b/tests/unit/switch.frag @@ -40,3 +40,19 @@ float switchMultiple() { return 0.0; } } + +const int LBL1 = 1, LBL2 = 2, LBL3 = 3, LBL4 = 4, LBL5 = 5; +void foo() {} + +int switchStringLabels(int value) +{ + switch (value) + { + case LBL1: foo(); + case LBL2: foo(); + case LBL3: { foo(); break; } + case LBL4: foo(); foo(); break; + case LBL5: foo(); foo(); return 18; + } + return 1; +} From 8bce238db39e288d5ae0e818471b68ba313e9399 Mon Sep 17 00:00:00 2001 From: Eldritch Conundrum Date: Sat, 9 Mar 2024 20:04:55 +0100 Subject: [PATCH 02/78] Fix #324, compilation on linux (#325) This makes it compile and run on my machine with dotnet 8.0.2. --- compile.bash | 3 +-- run-from-source.bash | 3 +++ shader-minifier-linux.fsproj | 38 ++++++++++++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100755 run-from-source.bash create mode 100644 shader-minifier-linux.fsproj diff --git a/compile.bash b/compile.bash index c8f99f4f..d6dabdfc 100755 --- a/compile.bash +++ b/compile.bash @@ -1,4 +1,3 @@ #! /bin/bash -references='-r lib/Argu.dll -r lib/FParsec.dll -r lib/FParsecCS.dll' -fsharpc --standalone $references src/{options.fs,ast.fs,printer.fs,formatter.fs,renamer.fs,rewriter.fs,parse.fs,main.fs} -o shader_minifier.exe +dotnet build shader-minifier-linux.fsproj diff --git a/run-from-source.bash b/run-from-source.bash new file mode 100755 index 00000000..30d03d97 --- /dev/null +++ b/run-from-source.bash @@ -0,0 +1,3 @@ +#! /bin/bash + +dotnet run --project shader-minifier-linux.fsproj -- "$@" diff --git a/shader-minifier-linux.fsproj b/shader-minifier-linux.fsproj new file mode 100644 index 00000000..6d043fd4 --- /dev/null +++ b/shader-minifier-linux.fsproj @@ -0,0 +1,38 @@ + + + + Exe + net8.0 + + + + + + + + + + + + + + + + + + + + lib\Argu.dll + + + lib\FParsec.dll + + + lib\FParsecCS.dll + + + lib\FSharp.Core.dll + + + + From 9516659e3722d4c7f26e1cce9d4180ace954d88d Mon Sep 17 00:00:00 2001 From: Eldritch Conundrum Date: Sun, 31 Mar 2024 19:29:57 +0200 Subject: [PATCH 03/78] Make Checker work on linux (#326) --- Checker/checker-linux.fsproj | 28 ++++++++++++++++++++++++++++ check.bash | 3 +++ 2 files changed, 31 insertions(+) create mode 100644 Checker/checker-linux.fsproj create mode 100755 check.bash diff --git a/Checker/checker-linux.fsproj b/Checker/checker-linux.fsproj new file mode 100644 index 00000000..5dd13db6 --- /dev/null +++ b/Checker/checker-linux.fsproj @@ -0,0 +1,28 @@ + + + + Exe + net8.0 + + + + + + + + + ..\lib\Argu.dll + + + ..\lib\FSharp.Core.dll + + + ..\lib\OpenTK.dll + + + Shader Minifier Library + True + + + + \ No newline at end of file diff --git a/check.bash b/check.bash new file mode 100755 index 00000000..af30fe1c --- /dev/null +++ b/check.bash @@ -0,0 +1,3 @@ +#! /bin/bash + +dotnet run --project Checker/checker-linux.fsproj From 0b3f50cc247cee0d796a41d330854051214bd28c Mon Sep 17 00:00:00 2001 From: Laurent Le Brun Date: Sun, 31 Mar 2024 19:32:23 +0200 Subject: [PATCH 04/78] Website: show shader size in the UI (#330) --- SMBolero.Client/Main.fs | 11 +++++++---- SMBolero.Client/wwwroot/css/index.css | 5 +++++ SMBolero.Client/wwwroot/main.html | 1 + src/api.fs | 7 +++++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/SMBolero.Client/Main.fs b/SMBolero.Client/Main.fs index c2e9f943..6df40f9a 100644 --- a/SMBolero.Client/Main.fs +++ b/SMBolero.Client/Main.fs @@ -18,6 +18,7 @@ type Model = page: Page shaderInput: string shaderOutput: string + shaderSize: int flags: string error: string option } @@ -27,6 +28,7 @@ let initModel = page = Home shaderInput = "out vec4 fragColor;\nvoid main() {\n fragColor = vec4(1.,1.,1.,1.);\n}" shaderOutput = "" + shaderSize = 0 flags = "--format text" error = None } @@ -46,9 +48,9 @@ let minify flags content = let shaders, exportedNames = ShaderMinifier.minify [|"input", content|] let out = new System.IO.StringWriter() Formatter.print out shaders exportedNames Options.Globals.options.outputFormat - out.ToString() + out.ToString(), ShaderMinifier.getSize shaders with - | e -> e.Message + | e -> e.Message, 0 let update message model = match message with @@ -56,8 +58,8 @@ let update message model = { model with page = page }, Cmd.none | Minify -> printfn "Minify %s" model.flags - let out = minify (model.flags.Split(' ')) model.shaderInput - { model with shaderOutput = out }, Cmd.none + let out, size = minify (model.flags.Split(' ')) model.shaderInput + { model with shaderOutput = out ; shaderSize = size }, Cmd.none | SetShader value -> { model with shaderInput = value }, Cmd.none | SetFlags value -> @@ -87,6 +89,7 @@ let homePage model dispatch = .Minify(fun _ -> dispatch Minify) .ShaderInput(model.shaderInput, fun v -> dispatch (SetShader v)) .ShaderOutput(model.shaderOutput) + .ShaderSize(if model.shaderSize = 0 then "" else $"size: {model.shaderSize}") .Flags(model.flags, fun v -> dispatch (SetFlags v)) .Elt() diff --git a/SMBolero.Client/wwwroot/css/index.css b/SMBolero.Client/wwwroot/css/index.css index 346ef354..6a79b14f 100644 --- a/SMBolero.Client/wwwroot/css/index.css +++ b/SMBolero.Client/wwwroot/css/index.css @@ -276,6 +276,11 @@ img { background: transparent; } +.size { + text-align: right; + font-size: 0.8em; +} + diff --git a/SMBolero.Client/wwwroot/main.html b/SMBolero.Client/wwwroot/main.html index 174a6c7a..0fe57991 100644 --- a/SMBolero.Client/wwwroot/main.html +++ b/SMBolero.Client/wwwroot/main.html @@ -29,6 +29,7 @@

Shader Minifier

+
${ShaderSize}

Tip: use the flags --format indented --no-renaming for debugging.

diff --git a/src/api.fs b/src/api.fs index 2adf5aa5..e5dc16ed 100644 --- a/src/api.fs +++ b/src/api.fs @@ -5,10 +5,13 @@ open System.IO open Microsoft.FSharp.Text open Options.Globals +let getSize (shaders: Ast.Shader[]) = + shaders |> Array.map (fun s -> Printer.printText s.code) + |> Array.sumBy (fun s -> s.Length) + let private printSize (shaders: Ast.Shader[]) = if options.verbose then - let length = shaders |> Array.map (fun s -> Printer.printText s.code) - |> Array.sumBy (fun s -> s.Length) + let length = getSize shaders printfn "Shader size is: %d" length let private readFile file = From e959c1dc0698652baa72d55fbfea1febb238a355 Mon Sep 17 00:00:00 2001 From: Laurent Le Brun Date: Sun, 31 Mar 2024 19:40:22 +0200 Subject: [PATCH 05/78] Website UX (#331) - change theme to dark mode - set autofocus to textarea - make the Minify button more prominent - rename menu item Help to About - set ID to html items (for ev...vil) --- SMBolero.Client/Main.fs | 6 +- SMBolero.Client/wwwroot/css/index.css | 128 ++++++-------------------- SMBolero.Client/wwwroot/main.html | 22 +++-- 3 files changed, 45 insertions(+), 111 deletions(-) diff --git a/SMBolero.Client/Main.fs b/SMBolero.Client/Main.fs index 6df40f9a..c17973f8 100644 --- a/SMBolero.Client/Main.fs +++ b/SMBolero.Client/Main.fs @@ -10,7 +10,7 @@ open Bolero.Templating.Client type Page = | [] Home | [] FlagPage - | [] Help + | [] About /// The Elmish application's model. type Model = @@ -104,12 +104,12 @@ let view model dispatch = .Menu(concat { menuItem model Home "Minifier" menuItem model FlagPage "Flags" - menuItem model Help "Help" + menuItem model About "About" }) .Body( cond model.page <| function | Home -> homePage model dispatch - | Help -> aboutPage model dispatch + | About -> aboutPage model dispatch | FlagPage -> flagPage model dispatch ) .Error( diff --git a/SMBolero.Client/wwwroot/css/index.css b/SMBolero.Client/wwwroot/css/index.css index 6a79b14f..2a6bfecd 100644 --- a/SMBolero.Client/wwwroot/css/index.css +++ b/SMBolero.Client/wwwroot/css/index.css @@ -1,7 +1,8 @@ :root { - --bg-main: #f1b99c; - --bg-light: #ffece3; - --border: #971f1f; + --bg-main: #101020; + --bg-light: #202040; + --border: #404080; + --text-color: #f0f0f0; } body { @@ -9,7 +10,7 @@ body { font-size: 1em; margin: 0px; margin-bottom: 10px; - color: #333; + color: var(--text-color); background-color: var(--bg-main); } @@ -19,7 +20,7 @@ body { .header { background-color: black; - color: var(--bg-light); + color: #eee; padding-left: 188px; padding-right: 0px; line-height: 1.6em; @@ -35,11 +36,8 @@ body { .left { font-size: 1em; width: 164px; - background: var(--bg-light) repeat-x top; - border-bottom: solid 3px black; - border-right: solid 3px black; - border-left: solid 1px black; - border-top: none; + background-color: var(--bg-light); + border: solid 1px #000; position: absolute; padding-top: 6px; top: 0px; @@ -107,11 +105,6 @@ label { } #content { - background-color: white; - border-left: solid 1px black; - border-top: solid 1px black; - border-right: solid 3px black; - border-bottom: solid 3px black; max-width: 800px; margin: 0px auto; padding: 10px 20px; @@ -126,21 +119,14 @@ label { #menu a { display: block; margin: 0; - margin-left: 4px; - /* border-left: 4px transparent solid; */ - border-bottom: 1px dashed #A0C0F0; text-decoration: none; - color: #333; - padding-left: 5px; + color: var(--text-color); } - #menu a:hover { - margin-left: 0px; - border-left: 4px solid #002299; - border-bottom: 1px solid #3388AA; - background-color: var(--bg-main); - color: black; - } +#menu a:hover { + background-color: var(--bg-main); + color: var(--text-color); +} .field legend:hover { color: white; @@ -149,19 +135,17 @@ label { } .center a { - color: #338; + color: #88f; text-decoration: none; font-weight: bold; } .center a:visited { - color: #068; text-decoration: none; font-weight: bold; } .center a:hover { - color: black; text-decoration: underline; font-weight: bold; } @@ -170,11 +154,6 @@ label { text-decoration: none; } -.center p { - margin-right: 10px; - margin-left: 10px; -} - .center .item, .center .block, fieldset { margin-bottom: 20px; margin-left: 20px; @@ -193,33 +172,24 @@ label { content: ':'; } +button, textarea, input { + background-color: #1a1a2a; + border: 1px solid var(--border); + color: var(--text-color); + padding: 4px; +} textarea { box-sizing: border-box; width: 100%; } -#display { - width: 50em; - background-color: black; - display: block; - color: white; - font-family: monospace; - font-size: 11px; - border: 1px solid white; -} - -.code { - font-size: 11px; - white-space: pre; - font-family: monospace; - border-left: 3px double black; - margin: 5px; - padding-left: 5px; +code { + color: #ccf; + padding: 8px; } .center pre { - font-size: 11px; white-space: pre; font-family: monospace; border-left: solid 3px #666; @@ -228,52 +198,16 @@ textarea { padding-left: 8px; } -.box { - border: 2px black solid; - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 0.8em; - padding: 6px; - background-color: #EEEEEE; - color: black; - font-variant: normal; -} - -.box h4 { - font-family: Verdana, Arial, Helvetica, sans-serif; - font-size: 1em; - border: 0px black; - font-variant: normal; - color: white; - background-color: #AAAAAA; - text-align: center; -} - -.box2 { - border: 1px black solid; - font-family: Verdana, Arial, Helvetica, sans-serif; +.size { + text-align: right; font-size: 0.8em; - padding: 4px; - background-color: #EEEEEE; - color: black; - font-variant: normal; } -.center ul { - list-style-type: square; -} - -legend { - font-weight: bold; - border: solid 1px var(--border); -} - -.clickable { - cursor: pointer; -} - -img { - border: none; - background: transparent; +#minify-btn { + background-color: #4e2d9d; + margin: 8px 0; + padding: 8px; + float: right; } .size { @@ -282,8 +216,6 @@ img { } - - /* Let's be modern and support mobile*/ @media (max-width: 750px) { .left { diff --git a/SMBolero.Client/wwwroot/main.html b/SMBolero.Client/wwwroot/main.html index 0fe57991..5511c304 100644 --- a/SMBolero.Client/wwwroot/main.html +++ b/SMBolero.Client/wwwroot/main.html @@ -23,16 +23,18 @@

Menu