diff --git a/Test/baseResults/hlsl.frag.out b/Test/baseResults/hlsl.frag.out index 0fae4aea..9afecf12 100644 --- a/Test/baseResults/hlsl.frag.out +++ b/Test/baseResults/hlsl.frag.out @@ -2,23 +2,41 @@ hlsl.frag 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: @@ -27,27 +45,45 @@ 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" @@ -57,18 +93,21 @@ gl_FragCoord origin is upper left 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 diff --git a/Test/hlsl.frag b/Test/hlsl.frag index 7ee58499..ac6aa230 100644 --- a/Test/hlsl.frag +++ b/Test/hlsl.frag @@ -1,7 +1,11 @@ -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; } diff --git a/hlsl/CMakeLists.txt b/hlsl/CMakeLists.txt index 96028f6f..6dd84fa3 100755 --- a/hlsl/CMakeLists.txt +++ b/hlsl/CMakeLists.txt @@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 2.8) set(SOURCES hlslParseHelper.cpp hlslScanContext.cpp + hlslOpMap.cpp hlslTokenStream.cpp hlslGrammar.cpp) @@ -10,6 +11,7 @@ set(HEADERS hlslParseHelper.h hlslTokens.h hlslScanContext.h + hlslOpMap.h hlslTokenStream.h hlslGrammar.h) diff --git a/hlsl/hlslGrammar.cpp b/hlsl/hlslGrammar.cpp index 40c35cae..2339c2d4 100755 --- a/hlsl/hlslGrammar.cpp +++ b/hlsl/hlslGrammar.cpp @@ -129,7 +129,7 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node) if (acceptIdentifier(idToken)) { // = expression TIntermTyped* expressionNode = nullptr; - if (acceptTokenClass(EHTokEqual)) { + if (acceptTokenClass(EHTokAssign)) { if (! acceptExpression(expressionNode)) { expected("initializer"); return false; @@ -362,36 +362,171 @@ bool HlslGrammar::acceptFunctionDefinition(TFunction& function, TIntermNode*& no 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)) { @@ -402,19 +537,62 @@ bool HlslGrammar::acceptExpression(TIntermTyped*& 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; + do { + TSourceLoc loc = token.loc; + TOperator postOp = HlslOpMap::postUnary(peek()); - // constructor - if (acceptConstructor(node)) - return true; + // 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 @@ -445,6 +623,17 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node) 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 // @@ -505,41 +694,12 @@ bool HlslGrammar::acceptLiteral(TIntermTyped*& node) 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; @@ -549,9 +709,10 @@ bool HlslGrammar::acceptCompoundStatement(TIntermAggregate*& compoundStatement) // hook it up compoundStatement = intermediate.growAggregate(compoundStatement, statement); } - compoundStatement->setOperator(EOpSequence); + if (compoundStatement) + compoundStatement->setOperator(EOpSequence); - // } + // RIGHT_CURLY return acceptTokenClass(EHTokRightBrace); } diff --git a/hlsl/hlslGrammar.h b/hlsl/hlslGrammar.h index 8b9b2897..61d30aff 100755 --- a/hlsl/hlslGrammar.h +++ b/hlsl/hlslGrammar.h @@ -37,6 +37,7 @@ #define HLSLGRAMMAR_H_ #include "hlslParseHelper.h" +#include "hlslOpMap.h" #include "hlslTokenStream.h" namespace glslang { @@ -64,10 +65,14 @@ 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(); diff --git a/hlsl/hlslOpMap.cpp b/hlsl/hlslOpMap.cpp new file mode 100755 index 00000000..c31dd7cf --- /dev/null +++ b/hlsl/hlslOpMap.cpp @@ -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 diff --git a/hlsl/hlslOpMap.h b/hlsl/hlslOpMap.h new file mode 100755 index 00000000..92463787 --- /dev/null +++ b/hlsl/hlslOpMap.h @@ -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_ diff --git a/hlsl/hlslScanContext.cpp b/hlsl/hlslScanContext.cpp index 50277cfd..ab96bad6 100755 --- a/hlsl/hlslScanContext.cpp +++ b/hlsl/hlslScanContext.cpp @@ -309,7 +309,7 @@ EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token) 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; diff --git a/hlsl/hlslTokenStream.h b/hlsl/hlslTokenStream.h index 4fad8148..9139df07 100755 --- a/hlsl/hlslTokenStream.h +++ b/hlsl/hlslTokenStream.h @@ -42,7 +42,7 @@ namespace glslang { class HlslTokenStream { public: - HlslTokenStream(HlslScanContext& scanner) + explicit HlslTokenStream(HlslScanContext& scanner) : scanner(scanner) { } virtual ~HlslTokenStream() { } diff --git a/hlsl/hlslTokens.h b/hlsl/hlslTokens.h index b118f2e0..bc472fec 100755 --- a/hlsl/hlslTokens.h +++ b/hlsl/hlslTokens.h @@ -207,6 +207,7 @@ enum EHlslTokenClass { EHTokAndOp, EHTokOrOp, EHTokXorOp, + EHTokAssign, EHTokMulAssign, EHTokDivAssign, EHTokAddAssign, @@ -226,7 +227,6 @@ enum EHlslTokenClass { EHTokDot, EHTokComma, EHTokColon, - EHTokEqual, EHTokSemicolon, EHTokBang, EHTokDash,