HLSL: Add (almost) full expression grammar: Binary, unary (pre/post-fix), assign, ...
This commit is contained in:
parent
9c86c6ab5b
commit
34fb036a9c
@ -2,23 +2,41 @@ hlsl.frag
|
|||||||
Shader version: 100
|
Shader version: 100
|
||||||
gl_FragCoord origin is upper left
|
gl_FragCoord origin is upper left
|
||||||
0:? Sequence
|
0:? Sequence
|
||||||
0:1 move second child to first child (temp 4-component vector of float)
|
0:12 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
|
||||||
0:1 'AmbientColor' (temp 4-component vector of float)
|
|
||||||
0:? Constant:
|
|
||||||
0:? 1.000000
|
|
||||||
0:? 0.500000
|
|
||||||
0:? 0.000000
|
|
||||||
0:? 1.000000
|
|
||||||
0:8 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
|
|
||||||
0:5 Function Parameters:
|
0:5 Function Parameters:
|
||||||
0:5 'input' (temp 4-component vector of float)
|
0:5 'input' (temp 4-component vector of float)
|
||||||
0:? Sequence
|
0:? Sequence
|
||||||
0:6 Branch: Return with expression
|
0:7 Branch: Return with expression
|
||||||
0:6 add (temp 4-component vector of float)
|
0:7 add (temp 4-component vector of float)
|
||||||
0:6 'input' (temp 4-component vector of float)
|
0:7 component-wise multiply (temp 4-component vector of float)
|
||||||
0:6 'AmbientColor' (temp 4-component vector of float)
|
0:7 'input' (temp 4-component vector of float)
|
||||||
|
0:7 'input' (temp 4-component vector of float)
|
||||||
|
0:7 component-wise multiply (temp 4-component vector of float)
|
||||||
|
0:7 'input' (temp 4-component vector of float)
|
||||||
|
0:7 'input' (temp 4-component vector of float)
|
||||||
|
0:8 Branch: Return with expression
|
||||||
|
0:8 add (temp 4-component vector of float)
|
||||||
|
0:8 add (temp 4-component vector of float)
|
||||||
|
0:8 'input' (temp 4-component vector of float)
|
||||||
|
0:8 component-wise multiply (temp 4-component vector of float)
|
||||||
|
0:8 'input' (temp 4-component vector of float)
|
||||||
|
0:8 'input' (temp 4-component vector of float)
|
||||||
|
0:8 'input' (temp 4-component vector of float)
|
||||||
|
0:9 Branch: Return with expression
|
||||||
|
0:9 component-wise multiply (temp 4-component vector of float)
|
||||||
|
0:9 Pre-Increment (temp 4-component vector of float)
|
||||||
|
0:9 'input' (temp 4-component vector of float)
|
||||||
|
0:9 Negate value (temp 4-component vector of float)
|
||||||
|
0:9 Negate value (temp 4-component vector of float)
|
||||||
|
0:9 Pre-Decrement (temp 4-component vector of float)
|
||||||
|
0:9 'input' (temp 4-component vector of float)
|
||||||
|
0:10 Branch: Return with expression
|
||||||
|
0:10 add (temp 4-component vector of float)
|
||||||
|
0:10 Post-Increment (temp 4-component vector of float)
|
||||||
|
0:10 'input' (temp 4-component vector of float)
|
||||||
|
0:10 Pre-Increment (temp 4-component vector of float)
|
||||||
|
0:10 'input' (temp 4-component vector of float)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? 'AmbientColor' (temp 4-component vector of float)
|
|
||||||
|
|
||||||
|
|
||||||
Linked fragment stage:
|
Linked fragment stage:
|
||||||
@ -27,27 +45,45 @@ Linked fragment stage:
|
|||||||
Shader version: 100
|
Shader version: 100
|
||||||
gl_FragCoord origin is upper left
|
gl_FragCoord origin is upper left
|
||||||
0:? Sequence
|
0:? Sequence
|
||||||
0:1 move second child to first child (temp 4-component vector of float)
|
0:12 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
|
||||||
0:1 'AmbientColor' (temp 4-component vector of float)
|
|
||||||
0:? Constant:
|
|
||||||
0:? 1.000000
|
|
||||||
0:? 0.500000
|
|
||||||
0:? 0.000000
|
|
||||||
0:? 1.000000
|
|
||||||
0:8 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
|
|
||||||
0:5 Function Parameters:
|
0:5 Function Parameters:
|
||||||
0:5 'input' (temp 4-component vector of float)
|
0:5 'input' (temp 4-component vector of float)
|
||||||
0:? Sequence
|
0:? Sequence
|
||||||
0:6 Branch: Return with expression
|
0:7 Branch: Return with expression
|
||||||
0:6 add (temp 4-component vector of float)
|
0:7 add (temp 4-component vector of float)
|
||||||
0:6 'input' (temp 4-component vector of float)
|
0:7 component-wise multiply (temp 4-component vector of float)
|
||||||
0:6 'AmbientColor' (temp 4-component vector of float)
|
0:7 'input' (temp 4-component vector of float)
|
||||||
|
0:7 'input' (temp 4-component vector of float)
|
||||||
|
0:7 component-wise multiply (temp 4-component vector of float)
|
||||||
|
0:7 'input' (temp 4-component vector of float)
|
||||||
|
0:7 'input' (temp 4-component vector of float)
|
||||||
|
0:8 Branch: Return with expression
|
||||||
|
0:8 add (temp 4-component vector of float)
|
||||||
|
0:8 add (temp 4-component vector of float)
|
||||||
|
0:8 'input' (temp 4-component vector of float)
|
||||||
|
0:8 component-wise multiply (temp 4-component vector of float)
|
||||||
|
0:8 'input' (temp 4-component vector of float)
|
||||||
|
0:8 'input' (temp 4-component vector of float)
|
||||||
|
0:8 'input' (temp 4-component vector of float)
|
||||||
|
0:9 Branch: Return with expression
|
||||||
|
0:9 component-wise multiply (temp 4-component vector of float)
|
||||||
|
0:9 Pre-Increment (temp 4-component vector of float)
|
||||||
|
0:9 'input' (temp 4-component vector of float)
|
||||||
|
0:9 Negate value (temp 4-component vector of float)
|
||||||
|
0:9 Negate value (temp 4-component vector of float)
|
||||||
|
0:9 Pre-Decrement (temp 4-component vector of float)
|
||||||
|
0:9 'input' (temp 4-component vector of float)
|
||||||
|
0:10 Branch: Return with expression
|
||||||
|
0:10 add (temp 4-component vector of float)
|
||||||
|
0:10 Post-Increment (temp 4-component vector of float)
|
||||||
|
0:10 'input' (temp 4-component vector of float)
|
||||||
|
0:10 Pre-Increment (temp 4-component vector of float)
|
||||||
|
0:10 'input' (temp 4-component vector of float)
|
||||||
0:? Linker Objects
|
0:? Linker Objects
|
||||||
0:? 'AmbientColor' (temp 4-component vector of float)
|
|
||||||
|
|
||||||
// Module Version 10000
|
// Module Version 10000
|
||||||
// Generated by (magic number): 80001
|
// Generated by (magic number): 80001
|
||||||
// Id's are bound by 15
|
// Id's are bound by 45
|
||||||
|
|
||||||
Capability Shader
|
Capability Shader
|
||||||
1: ExtInstImport "GLSL.std.450"
|
1: ExtInstImport "GLSL.std.450"
|
||||||
@ -57,18 +93,21 @@ gl_FragCoord origin is upper left
|
|||||||
Source HLSL 100
|
Source HLSL 100
|
||||||
Name 4 "PixelShaderFunction"
|
Name 4 "PixelShaderFunction"
|
||||||
Name 9 "input"
|
Name 9 "input"
|
||||||
Name 11 "AmbientColor"
|
|
||||||
2: TypeVoid
|
2: TypeVoid
|
||||||
3: TypeFunction 2
|
3: TypeFunction 2
|
||||||
6: TypeFloat 32
|
6: TypeFloat 32
|
||||||
7: TypeVector 6(float) 4
|
7: TypeVector 6(float) 4
|
||||||
8: TypePointer Function 7(fvec4)
|
8: TypePointer Function 7(fvec4)
|
||||||
|
27: 6(float) Constant 1065353216
|
||||||
4(PixelShaderFunction): 2 Function None 3
|
4(PixelShaderFunction): 2 Function None 3
|
||||||
5: Label
|
5: Label
|
||||||
9(input): 8(ptr) Variable Function
|
9(input): 8(ptr) Variable Function
|
||||||
11(AmbientColor): 8(ptr) Variable Function
|
|
||||||
10: 7(fvec4) Load 9(input)
|
10: 7(fvec4) Load 9(input)
|
||||||
12: 7(fvec4) Load 11(AmbientColor)
|
11: 7(fvec4) Load 9(input)
|
||||||
13: 7(fvec4) FAdd 10 12
|
12: 7(fvec4) FMul 10 11
|
||||||
ReturnValue 13
|
13: 7(fvec4) Load 9(input)
|
||||||
|
14: 7(fvec4) Load 9(input)
|
||||||
|
15: 7(fvec4) FMul 13 14
|
||||||
|
16: 7(fvec4) FAdd 12 15
|
||||||
|
ReturnValue 16
|
||||||
FunctionEnd
|
FunctionEnd
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
float4 AmbientColor = float4(1, 0.5, 0, 1);
|
//float4 AmbientColor = float4(1, 0.5, 0, 1);
|
||||||
//float AmbientIntensity = 0.1;
|
//float AmbientIntensity = 0.1;
|
||||||
|
|
||||||
float4 PixelShaderFunction(float4 input) : COLOR0
|
float4 PixelShaderFunction(float4 input) : COLOR0
|
||||||
{
|
{
|
||||||
return input /* * AmbientIntensity */ + AmbientColor;
|
// return input * AmbientIntensity + AmbientColor;
|
||||||
|
return input * input + input * input;
|
||||||
|
return input + input * input + input;
|
||||||
|
return ++input * -+-+--input;
|
||||||
|
return input++ + ++input;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
set(SOURCES
|
set(SOURCES
|
||||||
hlslParseHelper.cpp
|
hlslParseHelper.cpp
|
||||||
hlslScanContext.cpp
|
hlslScanContext.cpp
|
||||||
|
hlslOpMap.cpp
|
||||||
hlslTokenStream.cpp
|
hlslTokenStream.cpp
|
||||||
hlslGrammar.cpp)
|
hlslGrammar.cpp)
|
||||||
|
|
||||||
@ -10,6 +11,7 @@ set(HEADERS
|
|||||||
hlslParseHelper.h
|
hlslParseHelper.h
|
||||||
hlslTokens.h
|
hlslTokens.h
|
||||||
hlslScanContext.h
|
hlslScanContext.h
|
||||||
|
hlslOpMap.h
|
||||||
hlslTokenStream.h
|
hlslTokenStream.h
|
||||||
hlslGrammar.h)
|
hlslGrammar.h)
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
|||||||
if (acceptIdentifier(idToken)) {
|
if (acceptIdentifier(idToken)) {
|
||||||
// = expression
|
// = expression
|
||||||
TIntermTyped* expressionNode = nullptr;
|
TIntermTyped* expressionNode = nullptr;
|
||||||
if (acceptTokenClass(EHTokEqual)) {
|
if (acceptTokenClass(EHTokAssign)) {
|
||||||
if (! acceptExpression(expressionNode)) {
|
if (! acceptExpression(expressionNode)) {
|
||||||
expected("initializer");
|
expected("initializer");
|
||||||
return false;
|
return false;
|
||||||
@ -362,36 +362,171 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The top-level full expression recognizer.
|
||||||
|
//
|
||||||
// expression
|
// expression
|
||||||
// : identifier
|
// : assignment_expression COMMA assignment_expression COMMA assignment_expression ...
|
||||||
// | identifier operator identifier // todo: generalize to all expressions
|
|
||||||
// | LEFT_PAREN expression RIGHT_PAREN
|
|
||||||
// | constructor
|
|
||||||
// | literal
|
|
||||||
//
|
//
|
||||||
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
||||||
{
|
{
|
||||||
// identifier
|
// assignment_expression
|
||||||
HlslToken idToken;
|
if (! acceptAssignmentExpression(node))
|
||||||
if (acceptIdentifier(idToken)) {
|
return false;
|
||||||
TIntermTyped* left = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
|
|
||||||
|
|
||||||
// operator?
|
if (! peekTokenClass(EHTokComma))
|
||||||
TOperator op;
|
return true;
|
||||||
if (! acceptOperator(op))
|
|
||||||
return true;
|
do {
|
||||||
|
// ... COMMA
|
||||||
TSourceLoc loc = token.loc;
|
TSourceLoc loc = token.loc;
|
||||||
|
advanceToken();
|
||||||
|
|
||||||
// identifier
|
// ... assignment_expression
|
||||||
if (acceptIdentifier(idToken)) {
|
TIntermTyped* rightNode = nullptr;
|
||||||
TIntermTyped* right = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
|
if (! acceptAssignmentExpression(rightNode)) {
|
||||||
node = intermediate.addBinaryMath(op, left, right, loc);
|
expected("assignment expression");
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node = intermediate.addComma(node, rightNode, loc);
|
||||||
|
|
||||||
|
if (! peekTokenClass(EHTokComma))
|
||||||
|
return true;
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept an assignment expression, where assignment operations
|
||||||
|
// associate right-to-left. This is, it is implicit, for example
|
||||||
|
//
|
||||||
|
// a op (b op (c op d))
|
||||||
|
//
|
||||||
|
// assigment_expression
|
||||||
|
// : binary_expression op binary_expression op binary_expression ...
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptAssignmentExpression(TIntermTyped*& node)
|
||||||
|
{
|
||||||
|
if (! acceptBinaryExpression(node, PlLogicalOr))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TOperator assignOp = HlslOpMap::assignment(peek());
|
||||||
|
if (assignOp == EOpNull)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// ... op
|
||||||
|
TSourceLoc loc = token.loc;
|
||||||
|
advanceToken();
|
||||||
|
|
||||||
|
// ... binary_expression
|
||||||
|
// But, done by recursing this function, which automatically
|
||||||
|
// gets the right-to-left associativity.
|
||||||
|
TIntermTyped* rightNode = nullptr;
|
||||||
|
if (! acceptAssignmentExpression(rightNode)) {
|
||||||
|
expected("assignment expression");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
node = intermediate.addAssign(assignOp, node, rightNode, loc);
|
||||||
|
|
||||||
|
if (! peekTokenClass(EHTokComma))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accept a binary expression, for binary operations that
|
||||||
|
// associate left-to-right. This is, it is implicit, for example
|
||||||
|
//
|
||||||
|
// ((a op b) op c) op d
|
||||||
|
//
|
||||||
|
// binary_expression
|
||||||
|
// : expression op expression op expression ...
|
||||||
|
//
|
||||||
|
// where 'expression' is the next higher level in precedence.
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptBinaryExpression(TIntermTyped*& node, PrecedenceLevel precedenceLevel)
|
||||||
|
{
|
||||||
|
if (precedenceLevel > PlMul)
|
||||||
|
return acceptUnaryExpression(node);
|
||||||
|
|
||||||
|
// assignment_expression
|
||||||
|
if (! acceptBinaryExpression(node, (PrecedenceLevel)(precedenceLevel + 1)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
TOperator op = HlslOpMap::binary(peek());
|
||||||
|
PrecedenceLevel tokenLevel = HlslOpMap::precedenceLevel(op);
|
||||||
|
if (tokenLevel < precedenceLevel)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
do {
|
||||||
|
// ... op
|
||||||
|
TSourceLoc loc = token.loc;
|
||||||
|
advanceToken();
|
||||||
|
|
||||||
|
// ... expression
|
||||||
|
TIntermTyped* rightNode = nullptr;
|
||||||
|
if (! acceptBinaryExpression(rightNode, (PrecedenceLevel)(precedenceLevel + 1))) {
|
||||||
|
expected("expression");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
node = intermediate.addBinaryMath(op, node, rightNode, loc);
|
||||||
|
|
||||||
|
if (! peekTokenClass(EHTokComma))
|
||||||
|
return true;
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// unary_expression
|
||||||
|
// : + unary_expression
|
||||||
|
// | - unary_expression
|
||||||
|
// | ! unary_expression
|
||||||
|
// | ~ unary_expression
|
||||||
|
// | ++ unary_expression
|
||||||
|
// | -- unary_expression
|
||||||
|
// | postfix_expression
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptUnaryExpression(TIntermTyped*& node)
|
||||||
|
{
|
||||||
|
TOperator unaryOp = HlslOpMap::preUnary(peek());
|
||||||
|
|
||||||
|
// postfix_expression
|
||||||
|
if (unaryOp == EOpNull)
|
||||||
|
return acceptPostfixExpression(node);
|
||||||
|
|
||||||
|
// op unary_expression
|
||||||
|
TSourceLoc loc = token.loc;
|
||||||
|
advanceToken();
|
||||||
|
if (! acceptUnaryExpression(node))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// + is a no-op
|
||||||
|
if (unaryOp == EOpAdd)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
node = intermediate.addUnaryMath(unaryOp, node, loc);
|
||||||
|
|
||||||
|
return node != nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// postfix_expression
|
||||||
|
// : LEFT_PAREN expression RIGHT_PAREN
|
||||||
|
// | literal
|
||||||
|
// | constructor
|
||||||
|
// | identifier
|
||||||
|
// | function_call
|
||||||
|
// | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET
|
||||||
|
// | postfix_expression DOT IDENTIFIER
|
||||||
|
// | postfix_expression INC_OP
|
||||||
|
// | postfix_expression DEC_OP
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptPostfixExpression(TIntermTyped*& node)
|
||||||
|
{
|
||||||
|
// Not implemented as self-recursive:
|
||||||
|
// The logical "right recursion" is done with an loop at the end
|
||||||
|
|
||||||
|
// idToken will pick up either a variable or a function name in a function call
|
||||||
|
HlslToken idToken;
|
||||||
|
|
||||||
// LEFT_PAREN expression RIGHT_PAREN
|
// LEFT_PAREN expression RIGHT_PAREN
|
||||||
if (acceptTokenClass(EHTokLeftParen)) {
|
if (acceptTokenClass(EHTokLeftParen)) {
|
||||||
if (! acceptExpression(node)) {
|
if (! acceptExpression(node)) {
|
||||||
@ -402,19 +537,62 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& node)
|
|||||||
expected("right parenthesis");
|
expected("right parenthesis");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else if (acceptLiteral(node)) {
|
||||||
return true;
|
// literal (nothing else to do yet), go on to the
|
||||||
|
} else if (acceptConstructor(node)) {
|
||||||
|
// constructor (nothing else to do yet)
|
||||||
|
} else if (acceptIdentifier(idToken)) {
|
||||||
|
// identifier or function_call name
|
||||||
|
if (! peekTokenClass(EHTokLeftParen)) {
|
||||||
|
node = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
|
||||||
|
} else if (acceptFunctionCall(idToken, node)) {
|
||||||
|
// function_call (nothing else to do yet)
|
||||||
|
} else {
|
||||||
|
expected("function call arguments");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// literal
|
do {
|
||||||
if (acceptLiteral(node))
|
TSourceLoc loc = token.loc;
|
||||||
return true;
|
TOperator postOp = HlslOpMap::postUnary(peek());
|
||||||
|
|
||||||
// constructor
|
// Consume only a valid post-unary operator, otherwise we are done.
|
||||||
if (acceptConstructor(node))
|
switch (postOp) {
|
||||||
return true;
|
case EOpIndexDirectStruct:
|
||||||
|
case EOpIndexIndirect:
|
||||||
|
case EOpPostIncrement:
|
||||||
|
case EOpPostDecrement:
|
||||||
|
advanceToken();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
// We have a valid post-unary operator, process it.
|
||||||
|
switch (postOp) {
|
||||||
|
case EOpIndexDirectStruct:
|
||||||
|
// todo
|
||||||
|
break;
|
||||||
|
case EOpIndexIndirect:
|
||||||
|
{
|
||||||
|
TIntermTyped* indexNode = nullptr;
|
||||||
|
if (! acceptExpression(indexNode) ||
|
||||||
|
! peekTokenClass(EHTokRightBracket)) {
|
||||||
|
expected("expression followed by ']'");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// todo: node = intermediate.addBinaryMath(
|
||||||
|
}
|
||||||
|
case EOpPostIncrement:
|
||||||
|
case EOpPostDecrement:
|
||||||
|
node = intermediate.addUnaryMath(postOp, node, loc);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
@ -445,6 +623,17 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The function_call identifier was already recognized, and passed in as idToken.
|
||||||
|
//
|
||||||
|
// function_call
|
||||||
|
// : [idToken] arguments
|
||||||
|
//
|
||||||
|
bool HlslGrammar::acceptFunctionCall(HlslToken idToken, TIntermTyped*&)
|
||||||
|
{
|
||||||
|
// todo
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// arguments
|
// arguments
|
||||||
// : LEFT_PAREN expression COMMA expression COMMA ... RIGHT_PAREN
|
// : LEFT_PAREN expression COMMA expression COMMA ... RIGHT_PAREN
|
||||||
//
|
//
|
||||||
@ -505,41 +694,12 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// operator
|
|
||||||
// : PLUS | DASH | STAR | SLASH | ...
|
|
||||||
bool HlslGrammar::acceptOperator(TOperator& op)
|
|
||||||
{
|
|
||||||
switch (token.tokenClass) {
|
|
||||||
case EHTokEqual:
|
|
||||||
op = EOpAssign;
|
|
||||||
break;
|
|
||||||
case EHTokPlus:
|
|
||||||
op = EOpAdd;
|
|
||||||
break;
|
|
||||||
case EHTokDash:
|
|
||||||
op = EOpSub;
|
|
||||||
break;
|
|
||||||
case EHTokStar:
|
|
||||||
op = EOpMul;
|
|
||||||
break;
|
|
||||||
case EHTokSlash:
|
|
||||||
op = EOpDiv;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
advanceToken();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// compound_statement
|
// compound_statement
|
||||||
// : { statement statement ... }
|
// : LEFT_CURLY statement statement ... RIGHT_CURLY
|
||||||
//
|
//
|
||||||
bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
|
bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
|
||||||
{
|
{
|
||||||
// {
|
// LEFT_CURLY
|
||||||
if (! acceptTokenClass(EHTokLeftBrace))
|
if (! acceptTokenClass(EHTokLeftBrace))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -549,9 +709,10 @@ bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
|
|||||||
// hook it up
|
// hook it up
|
||||||
compoundStatement = intermediate.growAggregate(compoundStatement, statement);
|
compoundStatement = intermediate.growAggregate(compoundStatement, statement);
|
||||||
}
|
}
|
||||||
compoundStatement->setOperator(EOpSequence);
|
if (compoundStatement)
|
||||||
|
compoundStatement->setOperator(EOpSequence);
|
||||||
|
|
||||||
// }
|
// RIGHT_CURLY
|
||||||
return acceptTokenClass(EHTokRightBrace);
|
return acceptTokenClass(EHTokRightBrace);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
#define HLSLGRAMMAR_H_
|
#define HLSLGRAMMAR_H_
|
||||||
|
|
||||||
#include "hlslParseHelper.h"
|
#include "hlslParseHelper.h"
|
||||||
|
#include "hlslOpMap.h"
|
||||||
#include "hlslTokenStream.h"
|
#include "hlslTokenStream.h"
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
@ -64,10 +65,14 @@ namespace glslang {
|
|||||||
bool acceptParameterDeclaration(TFunction&);
|
bool acceptParameterDeclaration(TFunction&);
|
||||||
bool acceptFunctionDefinition(TFunction&, TIntermNode*&);
|
bool acceptFunctionDefinition(TFunction&, TIntermNode*&);
|
||||||
bool acceptExpression(TIntermTyped*&);
|
bool acceptExpression(TIntermTyped*&);
|
||||||
|
bool acceptAssignmentExpression(TIntermTyped*&);
|
||||||
|
bool acceptBinaryExpression(TIntermTyped*&, PrecedenceLevel);
|
||||||
|
bool acceptUnaryExpression(TIntermTyped*&);
|
||||||
|
bool acceptPostfixExpression(TIntermTyped*&);
|
||||||
bool acceptConstructor(TIntermTyped*&);
|
bool acceptConstructor(TIntermTyped*&);
|
||||||
|
bool acceptFunctionCall(HlslToken, TIntermTyped*&);
|
||||||
bool acceptArguments(TFunction*, TIntermAggregate*&);
|
bool acceptArguments(TFunction*, TIntermAggregate*&);
|
||||||
bool acceptLiteral(TIntermTyped*&);
|
bool acceptLiteral(TIntermTyped*&);
|
||||||
bool acceptOperator(TOperator& op);
|
|
||||||
bool acceptCompoundStatement(TIntermAggregate*&);
|
bool acceptCompoundStatement(TIntermAggregate*&);
|
||||||
bool acceptStatement(TIntermNode*&);
|
bool acceptStatement(TIntermNode*&);
|
||||||
bool acceptSemantic();
|
bool acceptSemantic();
|
||||||
|
171
hlsl/hlslOpMap.cpp
Executable file
171
hlsl/hlslOpMap.cpp
Executable file
@ -0,0 +1,171 @@
|
|||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google, Inc., nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
// Map from physical token form (e.g. '-') to logical operator
|
||||||
|
// form (e.g., binary subtract or unary negate).
|
||||||
|
|
||||||
|
#include "hlslOpMap.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
// Map parsing tokens that could be assignments into assignment operators.
|
||||||
|
TOperator HlslOpMap::assignment(EHlslTokenClass op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case EHTokAssign: return EOpAssign;
|
||||||
|
case EHTokMulAssign: return EOpMulAssign;
|
||||||
|
case EHTokDivAssign: return EOpDivAssign;
|
||||||
|
case EHTokAddAssign: return EOpAddAssign;
|
||||||
|
case EHTokModAssign: return EOpModAssign;
|
||||||
|
case EHTokLeftAssign: return EOpLeftShiftAssign;
|
||||||
|
case EHTokRightAssign: return EOpRightShiftAssign;
|
||||||
|
case EHTokAndAssign: return EOpAndAssign;
|
||||||
|
case EHTokXorAssign: return EOpExclusiveOrAssign;
|
||||||
|
case EHTokOrAssign: return EOpInclusiveOrAssign;
|
||||||
|
case EHTokSubAssign: return EOpSubAssign;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EOpNull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map parsing tokens that could be binary operations into binary operators.
|
||||||
|
TOperator HlslOpMap::binary(EHlslTokenClass op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case EHTokPlus: return EOpAdd;
|
||||||
|
case EHTokDash: return EOpSub;
|
||||||
|
case EHTokStar: return EOpMul;
|
||||||
|
case EHTokSlash: return EOpDiv;
|
||||||
|
case EHTokPercent: return EOpMod;
|
||||||
|
case EHTokRightOp: return EOpRightShift;
|
||||||
|
case EHTokLeftOp: return EOpLeftShift;
|
||||||
|
case EHTokAmpersand: return EOpAnd;
|
||||||
|
case EHTokVerticalBar: return EOpInclusiveOr;
|
||||||
|
case EHTokCaret: return EOpExclusiveOr;
|
||||||
|
case EHTokEqOp: return EOpEqual;
|
||||||
|
case EHTokNeOp: return EOpNotEqual;
|
||||||
|
case EHTokLeftAngle: return EOpLessThan;
|
||||||
|
case EHTokRightAngle: return EOpGreaterThan;
|
||||||
|
case EHTokLeOp: return EOpLessThanEqual;
|
||||||
|
case EHTokGeOp: return EOpGreaterThanEqual;
|
||||||
|
case EHTokOrOp: return EOpLogicalOr;
|
||||||
|
case EHTokXorOp: return EOpLogicalXor;
|
||||||
|
case EHTokAndOp: return EOpLogicalAnd;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return EOpNull;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map parsing tokens that could be unary operations into unary operators.
|
||||||
|
// These are just the ones that can appear in front of its operand.
|
||||||
|
TOperator HlslOpMap::preUnary(EHlslTokenClass op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case EHTokPlus: return EOpAdd; // means no-op, but still a unary op was present
|
||||||
|
case EHTokDash: return EOpNegative;
|
||||||
|
case EHTokBang: return EOpLogicalNot;
|
||||||
|
case EHTokTilde: return EOpBitwiseNot;
|
||||||
|
|
||||||
|
case EHTokIncOp: return EOpPreIncrement;
|
||||||
|
case EHTokDecOp: return EOpPreDecrement;
|
||||||
|
|
||||||
|
default: return EOpNull; // means not a pre-unary op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map parsing tokens that could be unary operations into unary operators.
|
||||||
|
// These are just the ones that can appear behind its operand.
|
||||||
|
TOperator HlslOpMap::postUnary(EHlslTokenClass op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case EHTokDot: return EOpIndexDirectStruct;
|
||||||
|
case EHTokLeftBracket: return EOpIndexIndirect; // may need to change later to EOpIndexDirect
|
||||||
|
|
||||||
|
case EHTokIncOp: return EOpPostIncrement;
|
||||||
|
case EHTokDecOp: return EOpPostDecrement;
|
||||||
|
|
||||||
|
default: return EOpNull; // means not a post-unary op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map operators into their level of precedence.
|
||||||
|
PrecedenceLevel HlslOpMap::precedenceLevel(TOperator op)
|
||||||
|
{
|
||||||
|
switch (op) {
|
||||||
|
case EOpLogicalOr:
|
||||||
|
return PlLogicalOr;
|
||||||
|
case EOpLogicalXor:
|
||||||
|
return PlLogicalXor;
|
||||||
|
case EOpLogicalAnd:
|
||||||
|
return PlLogicalAnd;
|
||||||
|
|
||||||
|
case EOpInclusiveOr:
|
||||||
|
return PlBitwiseOr;
|
||||||
|
case EOpExclusiveOr:
|
||||||
|
return PlBitwiseXor;
|
||||||
|
case EOpAnd:
|
||||||
|
return PlBitwiseAnd;
|
||||||
|
|
||||||
|
case EOpEqual:
|
||||||
|
case EOpNotEqual:
|
||||||
|
return PlEquality;
|
||||||
|
|
||||||
|
case EOpLessThan:
|
||||||
|
case EOpGreaterThan:
|
||||||
|
case EOpLessThanEqual:
|
||||||
|
case EOpGreaterThanEqual:
|
||||||
|
return PlRelational;
|
||||||
|
|
||||||
|
case EOpRightShift:
|
||||||
|
case EOpLeftShift:
|
||||||
|
return PlShift;
|
||||||
|
|
||||||
|
case EOpAdd:
|
||||||
|
case EOpSub:
|
||||||
|
return PlAdd;
|
||||||
|
|
||||||
|
case EOpMul:
|
||||||
|
case EOpDiv:
|
||||||
|
case EOpMod:
|
||||||
|
return PlMul;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return PlBad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace glslang
|
69
hlsl/hlslOpMap.h
Executable file
69
hlsl/hlslOpMap.h
Executable file
@ -0,0 +1,69 @@
|
|||||||
|
//
|
||||||
|
//Copyright (C) 2016 Google, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of Google, Inc., nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef HLSLOPMAP_H_
|
||||||
|
#define HLSLOPMAP_H_
|
||||||
|
|
||||||
|
#include "hlslScanContext.h"
|
||||||
|
|
||||||
|
namespace glslang {
|
||||||
|
|
||||||
|
enum PrecedenceLevel {
|
||||||
|
PlBad,
|
||||||
|
PlLogicalOr,
|
||||||
|
PlLogicalXor,
|
||||||
|
PlLogicalAnd,
|
||||||
|
PlBitwiseOr,
|
||||||
|
PlBitwiseXor,
|
||||||
|
PlBitwiseAnd,
|
||||||
|
PlEquality,
|
||||||
|
PlRelational,
|
||||||
|
PlShift,
|
||||||
|
PlAdd,
|
||||||
|
PlMul
|
||||||
|
};
|
||||||
|
|
||||||
|
class HlslOpMap {
|
||||||
|
public:
|
||||||
|
static TOperator assignment(EHlslTokenClass op);
|
||||||
|
static TOperator binary(EHlslTokenClass op);
|
||||||
|
static TOperator preUnary(EHlslTokenClass op);
|
||||||
|
static TOperator postUnary(EHlslTokenClass op);
|
||||||
|
static PrecedenceLevel precedenceLevel(TOperator);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace glslang
|
||||||
|
|
||||||
|
#endif // HLSLOPMAP_H_
|
@ -309,7 +309,7 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
|
|||||||
case ';': afterType = false; return EHTokSemicolon;
|
case ';': afterType = false; return EHTokSemicolon;
|
||||||
case ',': afterType = false; return EHTokComma;
|
case ',': afterType = false; return EHTokComma;
|
||||||
case ':': return EHTokColon;
|
case ':': return EHTokColon;
|
||||||
case '=': afterType = false; return EHTokEqual;
|
case '=': afterType = false; return EHTokAssign;
|
||||||
case '(': afterType = false; return EHTokLeftParen;
|
case '(': afterType = false; return EHTokLeftParen;
|
||||||
case ')': afterType = false; return EHTokRightParen;
|
case ')': afterType = false; return EHTokRightParen;
|
||||||
case '.': field = true; return EHTokDot;
|
case '.': field = true; return EHTokDot;
|
||||||
|
@ -42,7 +42,7 @@ namespace glslang {
|
|||||||
|
|
||||||
class HlslTokenStream {
|
class HlslTokenStream {
|
||||||
public:
|
public:
|
||||||
HlslTokenStream(HlslScanContext& scanner)
|
explicit HlslTokenStream(HlslScanContext& scanner)
|
||||||
: scanner(scanner) { }
|
: scanner(scanner) { }
|
||||||
virtual ~HlslTokenStream() { }
|
virtual ~HlslTokenStream() { }
|
||||||
|
|
||||||
|
@ -207,6 +207,7 @@ enum EHlslTokenClass {
|
|||||||
EHTokAndOp,
|
EHTokAndOp,
|
||||||
EHTokOrOp,
|
EHTokOrOp,
|
||||||
EHTokXorOp,
|
EHTokXorOp,
|
||||||
|
EHTokAssign,
|
||||||
EHTokMulAssign,
|
EHTokMulAssign,
|
||||||
EHTokDivAssign,
|
EHTokDivAssign,
|
||||||
EHTokAddAssign,
|
EHTokAddAssign,
|
||||||
@ -226,7 +227,6 @@ enum EHlslTokenClass {
|
|||||||
EHTokDot,
|
EHTokDot,
|
||||||
EHTokComma,
|
EHTokComma,
|
||||||
EHTokColon,
|
EHTokColon,
|
||||||
EHTokEqual,
|
|
||||||
EHTokSemicolon,
|
EHTokSemicolon,
|
||||||
EHTokBang,
|
EHTokBang,
|
||||||
EHTokDash,
|
EHTokDash,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user