From cb8d30543ec5197c0bea496eda8550b76c135642 Mon Sep 17 00:00:00 2001 From: Dave Smith Date: Tue, 2 Jan 2024 12:28:14 +0000 Subject: [PATCH] Fixed #103: Missing != operator --- .../ultraviolet/macros/CreateShaderAST.scala | 36 +++++++++++++++++-- .../acceptance/GLSLIfStatementTests.scala | 26 ++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/ultraviolet/shared/src/main/scala/ultraviolet/macros/CreateShaderAST.scala b/ultraviolet/shared/src/main/scala/ultraviolet/macros/CreateShaderAST.scala index 7d18638..526481a 100644 --- a/ultraviolet/shared/src/main/scala/ultraviolet/macros/CreateShaderAST.scala +++ b/ultraviolet/shared/src/main/scala/ultraviolet/macros/CreateShaderAST.scala @@ -1184,7 +1184,23 @@ class CreateShaderAST[Q <: Quotes](using val qq: Q) extends ShaderMacroUtils: case Apply(Select(term, op), xs) => op match - case "+" | "-" | "*" | "/" | "<" | ">" | "==" | "<=" | ">=" | "&&" | "||" => + case "<" | "<=" | ">" | ">=" | "==" | "!=" => + // Vector Relational Functions, according to the spec TL;DR: the left and right side types must be the same. + // However, we don't have a nice way to do that check yet. + val lhs = walkTerm(term, envVarName) + val rhs = xs.headOption.map(tt => walkTerm(tt, envVarName)).getOrElse(ShaderAST.Empty()) + val rt = findReturnType(lhs) + ShaderAST.Infix(op, lhs, rhs, rt) + + case "+" | "-" | "*" | "/" => + // Math operators. + val lhs = walkTerm(term, envVarName) + val rhs = xs.headOption.map(tt => walkTerm(tt, envVarName)).getOrElse(ShaderAST.Empty()) + val rt = findReturnType(lhs) + ShaderAST.Infix(op, lhs, rhs, rt) + + case "&&" | "||" => + // Logical operators. val lhs = walkTerm(term, envVarName) val rhs = xs.headOption.map(tt => walkTerm(tt, envVarName)).getOrElse(ShaderAST.Empty()) val rt = findReturnType(lhs) @@ -1210,7 +1226,23 @@ class CreateShaderAST[Q <: Quotes](using val qq: Q) extends ShaderMacroUtils: case Apply(Apply(Ident(op), List(l)), List(r)) => op match - case "+" | "-" | "*" | "/" | "<" | ">" | "==" | "<=" | ">=" | "&&" | "||" => + case "<" | "<=" | ">" | ">=" | "==" | "!=" => + // Vector Relational Functions, according to the spec. TL;DR: the left and right side types must be the same. + // However, we don't have a nice way to do that check yet. + val lhs = walkTerm(l, envVarName) + val rhs = walkTerm(r, envVarName) + val rt = findReturnType(lhs) + ShaderAST.Infix(op, lhs, rhs, rt) + + case "+" | "-" | "*" | "/" => + // Math operators. + val lhs = walkTerm(l, envVarName) + val rhs = walkTerm(r, envVarName) + val rt = findReturnType(lhs) + ShaderAST.Infix(op, lhs, rhs, rt) + + case "&&" | "||" => + // Logical operators. val lhs = walkTerm(l, envVarName) val rhs = walkTerm(r, envVarName) val rt = findReturnType(lhs) diff --git a/ultraviolet/shared/src/test/scala/ultraviolet/acceptance/GLSLIfStatementTests.scala b/ultraviolet/shared/src/test/scala/ultraviolet/acceptance/GLSLIfStatementTests.scala index 5d5c646..1213324 100644 --- a/ultraviolet/shared/src/test/scala/ultraviolet/acceptance/GLSLIfStatementTests.scala +++ b/ultraviolet/shared/src/test/scala/ultraviolet/acceptance/GLSLIfStatementTests.scala @@ -371,4 +371,30 @@ class GLSLIfStatementTests extends munit.FunSuite { ) } + test("if statement with not operator comparison") { + inline def fragment: Shader[FragEnv, vec4] = + Shader { _ => + val x = 1.0f + if x != 2.0f then vec4(10.0f) else vec4(20.0f) + } + + val actual = + fragment.toGLSL[WebGL2].toOutput.code + + // DebugAST.toAST(fragment) + // println(actual) + + assertEquals( + actual, + s""" + |float x=1.0; + |if(x!=2.0){ + | vec4(10.0); + |}else{ + | vec4(20.0); + |} + |""".stripMargin.trim + ) + } + }