Commit 00957f81 by John Kessenich

HLSL: Implement ?: grammar productions.

Missing are implicit conversions between int/bool/etc.
parent b783d712
float4 PixelShaderFunction(float4 input) : COLOR0
{
int a = 1 < 2 ? 3 < 4 ? 5 : 6 : 7;
int b = 1 < 2 ? 3 > 4 ? 5 : 6 : 7;
int c = 1 > 2 ? 3 > 4 ? 5 : 6 : 7;
int d = 1 > 2 ? 3 < 4 ? 5 : 6 : 7;
float4 ret = a * input +
b * input +
c * input +
d * input;
int e;
e = a = b ? c = d : 10, b = a ? d = c : 11;
float4 f;
f = ret.x < input.y ? c * input : d * input;
return e * ret + f;
}
......@@ -77,6 +77,7 @@ INSTANTIATE_TEST_CASE_P(
{"hlsl.attribute.frag", "PixelShaderFunction"},
{"hlsl.buffer.frag", "PixelShaderFunction"},
{"hlsl.cast.frag", "PixelShaderFunction"},
{"hlsl.conditional.frag", "PixelShaderFunction"},
{"hlsl.discard.frag", "PixelShaderFunction"},
{"hlsl.doLoop.frag", "PixelShaderFunction"},
{"hlsl.float1.frag", "PixelShaderFunction"},
......
......@@ -1548,8 +1548,9 @@ bool HlslGrammar::acceptInitializer(TIntermTyped*& node)
// a op (b op (c op d))
//
// assigment_expression
// : binary_expression op binary_expression op binary_expression ...
// | initializer
// : initializer
// | conditional_expression
// | conditional_expression assign_op conditional_expression assign_op conditional_expression ...
//
bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
{
......@@ -1562,8 +1563,8 @@ bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
return false;
}
// binary_expression
if (! acceptBinaryExpression(node, PlLogicalOr))
// conditional_expression
if (! acceptConditionalExpression(node))
return false;
// assignment operation?
......@@ -1571,12 +1572,12 @@ bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
if (assignOp == EOpNull)
return true;
// assignment op
// assign_op
TSourceLoc loc = token.loc;
advanceToken();
// binary_expression
// But, done by recursing this function, which automatically
// conditional_expression assign_op conditional_expression ...
// Done by recursing this function, which automatically
// gets the right-to-left associativity.
TIntermTyped* rightNode = nullptr;
if (! acceptAssignmentExpression(rightNode)) {
......@@ -1595,6 +1596,46 @@ bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
return true;
}
// Accept a conditional expression, which associates right-to-left,
// accomplished by the "true" expression calling down to lower
// precedence levels than this level.
//
// conditional_expression
// : binary_expression
// | binary_expression QUESTION expression COLON assignment_expression
//
bool HlslGrammar::acceptConditionalExpression(TIntermTyped*& node)
{
// binary_expression
if (! acceptBinaryExpression(node, PlLogicalOr))
return false;
if (! acceptTokenClass(EHTokQuestion))
return true;
TIntermTyped* trueNode = nullptr;
if (! acceptExpression(trueNode)) {
expected("expression after ?");
return false;
}
TSourceLoc loc = token.loc;
if (! acceptTokenClass(EHTokColon)) {
expected(":");
return false;
}
TIntermTyped* falseNode = nullptr;
if (! acceptAssignmentExpression(falseNode)) {
expected("expression after :");
return false;
}
node = intermediate.addSelection(node, trueNode, falseNode, loc);
return true;
}
// Accept a binary expression, for binary operations that
// associate left-to-right. This is, it is implicit, for example
//
......
......@@ -83,6 +83,7 @@ namespace glslang {
bool acceptExpression(TIntermTyped*&);
bool acceptInitializer(TIntermTyped*&);
bool acceptAssignmentExpression(TIntermTyped*&);
bool acceptConditionalExpression(TIntermTyped*&);
bool acceptBinaryExpression(TIntermTyped*&, PrecedenceLevel);
bool acceptUnaryExpression(TIntermTyped*&);
bool acceptPostfixExpression(TIntermTyped*&);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment