Shader version: 100
gl_FragCoord origin is upper left
0:? Sequence
-0:1 move second child to first child (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:12 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
0:5 Function Parameters:
0:5 'input' (temp 4-component vector of float)
0:? Sequence
-0:6 Branch: Return with expression
-0:6 add (temp 4-component vector of float)
-0:6 'input' (temp 4-component vector of float)
-0:6 'AmbientColor' (temp 4-component vector of float)
+0:7 Branch: Return with expression
+0:7 add (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: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:? 'AmbientColor' (temp 4-component vector of float)
Linked fragment stage:
Shader version: 100
gl_FragCoord origin is upper left
0:? Sequence
-0:1 move second child to first child (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:12 Function Definition: PixelShaderFunction(vf4; (temp 4-component vector of float)
0:5 Function Parameters:
0:5 'input' (temp 4-component vector of float)
0:? Sequence
-0:6 Branch: Return with expression
-0:6 add (temp 4-component vector of float)
-0:6 'input' (temp 4-component vector of float)
-0:6 'AmbientColor' (temp 4-component vector of float)
+0:7 Branch: Return with expression
+0:7 add (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: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:? 'AmbientColor' (temp 4-component vector of float)
// Module Version 10000
// Generated by (magic number): 80001
-// Id's are bound by 15
+// Id's are bound by 45
Capability Shader
1: ExtInstImport "GLSL.std.450"
Source HLSL 100
Name 4 "PixelShaderFunction"
Name 9 "input"
- Name 11 "AmbientColor"
2: TypeVoid
3: TypeFunction 2
6: TypeFloat 32
7: TypeVector 6(float) 4
8: TypePointer Function 7(fvec4)
+ 27: 6(float) Constant 1065353216
4(PixelShaderFunction): 2 Function None 3
5: Label
9(input): 8(ptr) Variable Function
-11(AmbientColor): 8(ptr) Variable Function
10: 7(fvec4) Load 9(input)
- 12: 7(fvec4) Load 11(AmbientColor)
- 13: 7(fvec4) FAdd 10 12
- ReturnValue 13
+ 11: 7(fvec4) Load 9(input)
+ 12: 7(fvec4) FMul 10 11
+ 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
-float4 AmbientColor = float4(1, 0.5, 0, 1);
+//float4 AmbientColor = float4(1, 0.5, 0, 1);
//float AmbientIntensity = 0.1;
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;
}
set(SOURCES
hlslParseHelper.cpp
hlslScanContext.cpp
+ hlslOpMap.cpp
hlslTokenStream.cpp
hlslGrammar.cpp)
hlslParseHelper.h
hlslTokens.h
hlslScanContext.h
+ hlslOpMap.h
hlslTokenStream.h
hlslGrammar.h)
if (acceptIdentifier(idToken)) {
// = expression
TIntermTyped* expressionNode = nullptr;
- if (acceptTokenClass(EHTokEqual)) {
+ if (acceptTokenClass(EHTokAssign)) {
if (! acceptExpression(expressionNode)) {
expected("initializer");
return false;
return false;
}
+// The top-level full expression recognizer.
+//
// expression
-// : identifier
-// | identifier operator identifier // todo: generalize to all expressions
-// | LEFT_PAREN expression RIGHT_PAREN
-// | constructor
-// | literal
+// : assignment_expression COMMA assignment_expression COMMA assignment_expression ...
//
bool HlslGrammar::acceptExpression(TIntermTyped*& node)
{
- // identifier
- HlslToken idToken;
- if (acceptIdentifier(idToken)) {
- TIntermTyped* left = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
+ // assignment_expression
+ if (! acceptAssignmentExpression(node))
+ return false;
- // operator?
- TOperator op;
- if (! acceptOperator(op))
- return true;
+ if (! peekTokenClass(EHTokComma))
+ return true;
+
+ do {
+ // ... COMMA
TSourceLoc loc = token.loc;
+ advanceToken();
- // identifier
- if (acceptIdentifier(idToken)) {
- TIntermTyped* right = parseContext.handleVariable(idToken.loc, idToken.symbol, token.string);
- node = intermediate.addBinaryMath(op, left, right, loc);
- return true;
+ // ... assignment_expression
+ TIntermTyped* rightNode = nullptr;
+ if (! acceptAssignmentExpression(rightNode)) {
+ expected("assignment expression");
+ 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;
}
+ 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
if (acceptTokenClass(EHTokLeftParen)) {
if (! acceptExpression(node)) {
expected("right parenthesis");
return false;
}
-
- return true;
+ } else if (acceptLiteral(node)) {
+ // 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
- if (acceptLiteral(node))
- return true;
-
- // constructor
- if (acceptConstructor(node))
- return true;
+ do {
+ TSourceLoc loc = token.loc;
+ TOperator postOp = HlslOpMap::postUnary(peek());
+
+ // Consume only a valid post-unary operator, otherwise we are done.
+ switch (postOp) {
+ 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
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
// : LEFT_PAREN expression COMMA expression COMMA ... RIGHT_PAREN
//
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
-// : { statement statement ... }
+// : LEFT_CURLY statement statement ... RIGHT_CURLY
//
bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement)
{
- // {
+ // LEFT_CURLY
if (! acceptTokenClass(EHTokLeftBrace))
return false;
// hook it up
compoundStatement = intermediate.growAggregate(compoundStatement, statement);
}
- compoundStatement->setOperator(EOpSequence);
+ if (compoundStatement)
+ compoundStatement->setOperator(EOpSequence);
- // }
+ // RIGHT_CURLY
return acceptTokenClass(EHTokRightBrace);
}
#define HLSLGRAMMAR_H_
#include "hlslParseHelper.h"
+#include "hlslOpMap.h"
#include "hlslTokenStream.h"
namespace glslang {
bool acceptParameterDeclaration(TFunction&);
bool acceptFunctionDefinition(TFunction&, TIntermNode*&);
bool acceptExpression(TIntermTyped*&);
+ bool acceptAssignmentExpression(TIntermTyped*&);
+ bool acceptBinaryExpression(TIntermTyped*&, PrecedenceLevel);
+ bool acceptUnaryExpression(TIntermTyped*&);
+ bool acceptPostfixExpression(TIntermTyped*&);
bool acceptConstructor(TIntermTyped*&);
+ bool acceptFunctionCall(HlslToken, TIntermTyped*&);
bool acceptArguments(TFunction*, TIntermAggregate*&);
bool acceptLiteral(TIntermTyped*&);
- bool acceptOperator(TOperator& op);
bool acceptCompoundStatement(TIntermAggregate*&);
bool acceptStatement(TIntermNode*&);
bool acceptSemantic();
--- /dev/null
+//
+//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
--- /dev/null
+//
+//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_
case ';': afterType = false; return EHTokSemicolon;
case ',': afterType = false; return EHTokComma;
case ':': return EHTokColon;
- case '=': afterType = false; return EHTokEqual;
+ case '=': afterType = false; return EHTokAssign;
case '(': afterType = false; return EHTokLeftParen;
case ')': afterType = false; return EHTokRightParen;
case '.': field = true; return EHTokDot;
class HlslTokenStream {
public:
- HlslTokenStream(HlslScanContext& scanner)
+ explicit HlslTokenStream(HlslScanContext& scanner)
: scanner(scanner) { }
virtual ~HlslTokenStream() { }
EHTokAndOp,
EHTokOrOp,
EHTokXorOp,
+ EHTokAssign,
EHTokMulAssign,
EHTokDivAssign,
EHTokAddAssign,
EHTokDot,
EHTokComma,
EHTokColon,
- EHTokEqual,
EHTokSemicolon,
EHTokBang,
EHTokDash,