Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions tests/libprojectM/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ test_api_headers(TestMainAPIHeaders
)

add_executable(projectM-unittest
HLSLParserTest.cpp
LoggingTest.cpp
PresetFileParserTest.cpp
WaveformAlignerTest.cpp
Expand All @@ -50,6 +51,7 @@ target_include_directories(projectM-unittest
PRIVATE
"${PROJECTM_SOURCE_DIR}/src/libprojectM"
"${PROJECTM_SOURCE_DIR}"
"${PROJECTM_SOURCE_DIR}/vendor/hlslparser/src"
)

target_link_libraries(projectM-unittest
Expand Down
64 changes: 64 additions & 0 deletions tests/libprojectM/HLSLParserTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <gtest/gtest.h>

#include <HLSLParser.h>
#include <HLSLTree.h>

#include <cstring>

namespace {

bool ParseHLSL(const char* code)
{
M4::Allocator allocator;
M4::HLSLTree tree(&allocator);
M4::HLSLParser parser(&allocator, &tree);
return parser.Parse("test.hlsl", code, strlen(code));
}

} // namespace

// Regression test for issue #940: parenthesized constructor with binary operator
// was rejected with "expected ';'" error.
TEST(HLSLParser, ParenthesizedConstructorWithMultiply)
{
EXPECT_TRUE(ParseHLSL(
"float scalar = 2.0;\n"
"float2 var = (float2(1.0, 2.0)) * scalar;\n"
));
}

TEST(HLSLParser, ParenthesizedConstructorWithAdd)
{
EXPECT_TRUE(ParseHLSL(
"float2 var = (float2(1.0, 2.0)) + float2(3.0, 4.0);\n"
));
}

TEST(HLSLParser, DoubleNestedParensWithOperator)
{
EXPECT_TRUE(ParseHLSL(
"float2 var = ((float2(1.0, 2.0))) * 2.0;\n"
));
}

TEST(HLSLParser, BothOperandsParenthesized)
{
EXPECT_TRUE(ParseHLSL(
"float2 var = (float2(1.0, 2.0)) * (float2(3.0, 4.0));\n"
));
}

TEST(HLSLParser, ChainedOperatorsAfterParens)
{
EXPECT_TRUE(ParseHLSL(
"float a = 1.0; float b = 2.0; float c = 3.0;\n"
"float x = (a) * b + c;\n"
));
}

TEST(HLSLParser, ConstructorWithoutParensStillWorks)
{
EXPECT_TRUE(ParseHLSL(
"float2 var = float2(1.0, 2.0) * 2.0;\n"
));
}
14 changes: 14 additions & 0 deletions vendor/hlslparser/src/HLSLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2283,6 +2283,20 @@ bool HLSLParser::ParseBinaryExpression(int priority, HLSLExpression*& expression
}
else
{
// Before breaking, consume end char if needed and check for more operators
if( needsExpressionEndChar != 0 )
{
if( !Expect(needsExpressionEndChar) )
return false;
needsExpressionEndChar = 0;

// After consuming end char, check if there's a binary operator to continue
if (AcceptBinaryOperator(priority, binaryOp))
{
acceptBinaryOp = true;
continue;
}
}
break;
}

Expand Down
Loading