649 lines
24 KiB
C++
649 lines
24 KiB
C++
|
//
|
||
|
//Copyright (C) 2016 Google, Inc.
|
||
|
//Copyright (C) 2016 LunarG, 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.
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// HLSL scanning, leveraging the scanning done by the preprocessor.
|
||
|
//
|
||
|
|
||
|
#include <string.h>
|
||
|
#include <unordered_map>
|
||
|
#include <unordered_set>
|
||
|
|
||
|
#include "../glslang/Include/Types.h"
|
||
|
#include "../glslang/MachineIndependent/SymbolTable.h"
|
||
|
#include "../glslang/MachineIndependent/ParseHelper.h"
|
||
|
#include "hlslScanContext.h"
|
||
|
#include "hlslTokens.h"
|
||
|
//#include "Scan.h"
|
||
|
|
||
|
// preprocessor includes
|
||
|
#include "../glslang/MachineIndependent/preprocessor/PpContext.h"
|
||
|
#include "../glslang/MachineIndependent/preprocessor/PpTokens.h"
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
struct str_eq
|
||
|
{
|
||
|
bool operator()(const char* lhs, const char* rhs) const
|
||
|
{
|
||
|
return strcmp(lhs, rhs) == 0;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct str_hash
|
||
|
{
|
||
|
size_t operator()(const char* str) const
|
||
|
{
|
||
|
// djb2
|
||
|
unsigned long hash = 5381;
|
||
|
int c;
|
||
|
|
||
|
while ((c = *str++) != 0)
|
||
|
hash = ((hash << 5) + hash) + c;
|
||
|
|
||
|
return hash;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
// A single global usable by all threads, by all versions, by all languages.
|
||
|
// After a single process-level initialization, this is read only and thread safe
|
||
|
std::unordered_map<const char*, glslang::EHlslTokenClass, str_hash, str_eq>* KeywordMap = nullptr;
|
||
|
std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
|
||
|
|
||
|
};
|
||
|
|
||
|
namespace glslang {
|
||
|
|
||
|
void HlslScanContext::fillInKeywordMap()
|
||
|
{
|
||
|
if (KeywordMap != nullptr) {
|
||
|
// this is really an error, as this should called only once per process
|
||
|
// but, the only risk is if two threads called simultaneously
|
||
|
return;
|
||
|
}
|
||
|
KeywordMap = new std::unordered_map<const char*, EHlslTokenClass, str_hash, str_eq>;
|
||
|
|
||
|
(*KeywordMap)["static"] = EHTokStatic;
|
||
|
(*KeywordMap)["const"] = EHTokConst;
|
||
|
(*KeywordMap)["unorm"] = EHTokUnorm;
|
||
|
(*KeywordMap)["snorm"] = EHTokSNorm;
|
||
|
(*KeywordMap)["extern"] = EHTokExtern;
|
||
|
(*KeywordMap)["uniform"] = EHTokUniform;
|
||
|
(*KeywordMap)["volatile"] = EHTokVolatile;
|
||
|
(*KeywordMap)["precise"] = EHTokPrecise;
|
||
|
(*KeywordMap)["shared"] = EHTokShared;
|
||
|
(*KeywordMap)["groupshared"] = EHTokGroupShared;
|
||
|
(*KeywordMap)["linear"] = EHTokLinear;
|
||
|
(*KeywordMap)["centroid"] = EHTokCentroid;
|
||
|
(*KeywordMap)["nointerpolation"] = EHTokNointerpolation;
|
||
|
(*KeywordMap)["noperspective"] = EHTokNoperspective;
|
||
|
(*KeywordMap)["sample"] = EHTokSample;
|
||
|
(*KeywordMap)["row_major"] = EHTokRowMajor;
|
||
|
(*KeywordMap)["column_major"] = EHTokColumnMajor;
|
||
|
(*KeywordMap)["packoffset"] = EHTokPackOffset;
|
||
|
(*KeywordMap)["in"] = EHTokIn;
|
||
|
(*KeywordMap)["out"] = EHTokOut;
|
||
|
(*KeywordMap)["inout"] = EHTokInOut;
|
||
|
|
||
|
(*KeywordMap)["Buffer"] = EHTokBuffer;
|
||
|
(*KeywordMap)["vector"] = EHTokVector;
|
||
|
(*KeywordMap)["matrix"] = EHTokMatrix;
|
||
|
|
||
|
(*KeywordMap)["void"] = EHTokVoid;
|
||
|
(*KeywordMap)["bool"] = EHTokBool;
|
||
|
(*KeywordMap)["int"] = EHTokInt;
|
||
|
(*KeywordMap)["uint"] = EHTokUint;
|
||
|
(*KeywordMap)["dword"] = EHTokDword;
|
||
|
(*KeywordMap)["half"] = EHTokHalf;
|
||
|
(*KeywordMap)["float"] = EHTokFloat;
|
||
|
(*KeywordMap)["double"] = EHTokDouble;
|
||
|
(*KeywordMap)["min16float"] = EHTokMin16float;
|
||
|
(*KeywordMap)["min10float"] = EHTokMin10float;
|
||
|
(*KeywordMap)["min16int"] = EHTokMin16int;
|
||
|
(*KeywordMap)["min12int"] = EHTokMin12int;
|
||
|
(*KeywordMap)["min16uint"] = EHTokMin16int;
|
||
|
|
||
|
(*KeywordMap)["bool1"] = EHTokBool1;
|
||
|
(*KeywordMap)["bool2"] = EHTokBool2;
|
||
|
(*KeywordMap)["bool3"] = EHTokBool3;
|
||
|
(*KeywordMap)["bool4"] = EHTokBool4;
|
||
|
(*KeywordMap)["float1"] = EHTokFloat1;
|
||
|
(*KeywordMap)["float2"] = EHTokFloat2;
|
||
|
(*KeywordMap)["float3"] = EHTokFloat3;
|
||
|
(*KeywordMap)["float4"] = EHTokFloat4;
|
||
|
(*KeywordMap)["int1"] = EHTokInt1;
|
||
|
(*KeywordMap)["int2"] = EHTokInt2;
|
||
|
(*KeywordMap)["int3"] = EHTokInt3;
|
||
|
(*KeywordMap)["int4"] = EHTokInt4;
|
||
|
(*KeywordMap)["double1"] = EHTokDouble1;
|
||
|
(*KeywordMap)["double2"] = EHTokDouble2;
|
||
|
(*KeywordMap)["double3"] = EHTokDouble3;
|
||
|
(*KeywordMap)["double4"] = EHTokDouble4;
|
||
|
(*KeywordMap)["uint1"] = EHTokUint1;
|
||
|
(*KeywordMap)["uint2"] = EHTokUint2;
|
||
|
(*KeywordMap)["uint3"] = EHTokUint3;
|
||
|
(*KeywordMap)["uint4"] = EHTokUint4;
|
||
|
|
||
|
(*KeywordMap)["int1x1"] = EHTokInt1x1;
|
||
|
(*KeywordMap)["int1x2"] = EHTokInt1x2;
|
||
|
(*KeywordMap)["int1x3"] = EHTokInt1x3;
|
||
|
(*KeywordMap)["int1x4"] = EHTokInt1x4;
|
||
|
(*KeywordMap)["int2x1"] = EHTokInt2x1;
|
||
|
(*KeywordMap)["int2x2"] = EHTokInt2x2;
|
||
|
(*KeywordMap)["int2x3"] = EHTokInt2x3;
|
||
|
(*KeywordMap)["int2x4"] = EHTokInt2x4;
|
||
|
(*KeywordMap)["int3x1"] = EHTokInt3x1;
|
||
|
(*KeywordMap)["int3x2"] = EHTokInt3x2;
|
||
|
(*KeywordMap)["int3x3"] = EHTokInt3x3;
|
||
|
(*KeywordMap)["int3x4"] = EHTokInt3x4;
|
||
|
(*KeywordMap)["int4x1"] = EHTokInt4x1;
|
||
|
(*KeywordMap)["int4x2"] = EHTokInt4x2;
|
||
|
(*KeywordMap)["int4x3"] = EHTokInt4x3;
|
||
|
(*KeywordMap)["int4x4"] = EHTokInt4x4;
|
||
|
(*KeywordMap)["uint1x1"] = EHTokUint1x1;
|
||
|
(*KeywordMap)["uint1x2"] = EHTokUint1x2;
|
||
|
(*KeywordMap)["uint1x3"] = EHTokUint1x3;
|
||
|
(*KeywordMap)["uint1x4"] = EHTokUint1x4;
|
||
|
(*KeywordMap)["uint2x1"] = EHTokUint2x1;
|
||
|
(*KeywordMap)["uint2x2"] = EHTokUint2x2;
|
||
|
(*KeywordMap)["uint2x3"] = EHTokUint2x3;
|
||
|
(*KeywordMap)["uint2x4"] = EHTokUint2x4;
|
||
|
(*KeywordMap)["uint3x1"] = EHTokUint3x1;
|
||
|
(*KeywordMap)["uint3x2"] = EHTokUint3x2;
|
||
|
(*KeywordMap)["uint3x3"] = EHTokUint3x3;
|
||
|
(*KeywordMap)["uint3x4"] = EHTokUint3x4;
|
||
|
(*KeywordMap)["uint4x1"] = EHTokUint4x1;
|
||
|
(*KeywordMap)["uint4x2"] = EHTokUint4x2;
|
||
|
(*KeywordMap)["uint4x3"] = EHTokUint4x3;
|
||
|
(*KeywordMap)["uint4x4"] = EHTokUint4x4;
|
||
|
(*KeywordMap)["bool1x1"] = EHTokBool1x1;
|
||
|
(*KeywordMap)["bool1x2"] = EHTokBool1x2;
|
||
|
(*KeywordMap)["bool1x3"] = EHTokBool1x3;
|
||
|
(*KeywordMap)["bool1x4"] = EHTokBool1x4;
|
||
|
(*KeywordMap)["bool2x1"] = EHTokBool2x1;
|
||
|
(*KeywordMap)["bool2x2"] = EHTokBool2x2;
|
||
|
(*KeywordMap)["bool2x3"] = EHTokBool2x3;
|
||
|
(*KeywordMap)["bool2x4"] = EHTokBool2x4;
|
||
|
(*KeywordMap)["bool3x1"] = EHTokBool3x1;
|
||
|
(*KeywordMap)["bool3x2"] = EHTokBool3x2;
|
||
|
(*KeywordMap)["bool3x3"] = EHTokBool3x3;
|
||
|
(*KeywordMap)["bool3x4"] = EHTokBool3x4;
|
||
|
(*KeywordMap)["bool4x1"] = EHTokBool4x1;
|
||
|
(*KeywordMap)["bool4x2"] = EHTokBool4x2;
|
||
|
(*KeywordMap)["bool4x3"] = EHTokBool4x3;
|
||
|
(*KeywordMap)["bool4x4"] = EHTokBool4x4;
|
||
|
(*KeywordMap)["float1x1"] = EHTokFloat1x1;
|
||
|
(*KeywordMap)["float1x2"] = EHTokFloat1x2;
|
||
|
(*KeywordMap)["float1x3"] = EHTokFloat1x3;
|
||
|
(*KeywordMap)["float1x4"] = EHTokFloat1x4;
|
||
|
(*KeywordMap)["float2x1"] = EHTokFloat2x1;
|
||
|
(*KeywordMap)["float2x2"] = EHTokFloat2x2;
|
||
|
(*KeywordMap)["float2x3"] = EHTokFloat2x3;
|
||
|
(*KeywordMap)["float2x4"] = EHTokFloat2x4;
|
||
|
(*KeywordMap)["float3x1"] = EHTokFloat3x1;
|
||
|
(*KeywordMap)["float3x2"] = EHTokFloat3x2;
|
||
|
(*KeywordMap)["float3x3"] = EHTokFloat3x3;
|
||
|
(*KeywordMap)["float3x4"] = EHTokFloat3x4;
|
||
|
(*KeywordMap)["float4x1"] = EHTokFloat4x1;
|
||
|
(*KeywordMap)["float4x2"] = EHTokFloat4x2;
|
||
|
(*KeywordMap)["float4x3"] = EHTokFloat4x3;
|
||
|
(*KeywordMap)["float4x4"] = EHTokFloat4x4;
|
||
|
(*KeywordMap)["double1x1"] = EHTokDouble1x1;
|
||
|
(*KeywordMap)["double1x2"] = EHTokDouble1x2;
|
||
|
(*KeywordMap)["double1x3"] = EHTokDouble1x3;
|
||
|
(*KeywordMap)["double1x4"] = EHTokDouble1x4;
|
||
|
(*KeywordMap)["double2x1"] = EHTokDouble2x1;
|
||
|
(*KeywordMap)["double2x2"] = EHTokDouble2x2;
|
||
|
(*KeywordMap)["double2x3"] = EHTokDouble2x3;
|
||
|
(*KeywordMap)["double2x4"] = EHTokDouble2x4;
|
||
|
(*KeywordMap)["double3x1"] = EHTokDouble3x1;
|
||
|
(*KeywordMap)["double3x2"] = EHTokDouble3x2;
|
||
|
(*KeywordMap)["double3x3"] = EHTokDouble3x3;
|
||
|
(*KeywordMap)["double3x4"] = EHTokDouble3x4;
|
||
|
(*KeywordMap)["double4x1"] = EHTokDouble4x1;
|
||
|
(*KeywordMap)["double4x2"] = EHTokDouble4x2;
|
||
|
(*KeywordMap)["double4x3"] = EHTokDouble4x3;
|
||
|
(*KeywordMap)["double4x4"] = EHTokDouble4x4;
|
||
|
|
||
|
(*KeywordMap)["sampler"] = EHTokSampler;
|
||
|
(*KeywordMap)["sampler1D"] = EHTokSampler1d;
|
||
|
(*KeywordMap)["sampler2D"] = EHTokSampler2d;
|
||
|
(*KeywordMap)["sampler3D"] = EHTokSampler3d;
|
||
|
(*KeywordMap)["samplerCube"] = EHTokSamplerCube;
|
||
|
(*KeywordMap)["sampler_state"] = EHTokSamplerState;
|
||
|
(*KeywordMap)["SamplerState"] = EHTokSamplerState;
|
||
|
(*KeywordMap)["SamplerComparisonState"] = EHTokSamplerComparisonState;
|
||
|
(*KeywordMap)["texture"] = EHTokTexture;
|
||
|
(*KeywordMap)["Texture1D"] = EHTokTexture1d;
|
||
|
(*KeywordMap)["Texture1DArray"] = EHTokTexture1darray;
|
||
|
(*KeywordMap)["Texture2D"] = EHTokTexture2d;
|
||
|
(*KeywordMap)["Texture2DArray"] = EHTokTexture2darray;
|
||
|
(*KeywordMap)["Texture3D"] = EHTokTexture3d;
|
||
|
(*KeywordMap)["TextureCube"] = EHTokTextureCube;
|
||
|
(*KeywordMap)["TextureCubeArray"] = EHTokTextureCubearray;
|
||
|
(*KeywordMap)["Texture2DMS"] = EHTokTexture2DMS;
|
||
|
(*KeywordMap)["Texture2DMSArray"] = EHTokTexture2DMSarray;
|
||
|
|
||
|
(*KeywordMap)["struct"] = EHTokStruct;
|
||
|
(*KeywordMap)["typedef"] = EHTokTypedef;
|
||
|
|
||
|
(*KeywordMap)["true"] = EHTokBoolConstant;
|
||
|
(*KeywordMap)["false"] = EHTokBoolConstant;
|
||
|
|
||
|
(*KeywordMap)["for"] = EHTokFor;
|
||
|
(*KeywordMap)["do"] = EHTokDo;
|
||
|
(*KeywordMap)["while"] = EHTokWhile;
|
||
|
(*KeywordMap)["break"] = EHTokBreak;
|
||
|
(*KeywordMap)["continue"] = EHTokContinue;
|
||
|
(*KeywordMap)["if"] = EHTokIf;
|
||
|
(*KeywordMap)["else"] = EHTokElse;
|
||
|
(*KeywordMap)["discard"] = EHTokDiscard;
|
||
|
(*KeywordMap)["return"] = EHTokReturn;
|
||
|
(*KeywordMap)["switch"] = EHTokSwitch;
|
||
|
(*KeywordMap)["case"] = EHTokCase;
|
||
|
(*KeywordMap)["default"] = EHTokDefault;
|
||
|
|
||
|
// TODO: get correct set here
|
||
|
ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
|
||
|
|
||
|
ReservedSet->insert("auto");
|
||
|
ReservedSet->insert("catch");
|
||
|
ReservedSet->insert("char");
|
||
|
ReservedSet->insert("class");
|
||
|
ReservedSet->insert("const_cast");
|
||
|
ReservedSet->insert("enum");
|
||
|
ReservedSet->insert("explicit");
|
||
|
ReservedSet->insert("friend");
|
||
|
ReservedSet->insert("goto");
|
||
|
ReservedSet->insert("long");
|
||
|
ReservedSet->insert("mutable");
|
||
|
ReservedSet->insert("new");
|
||
|
ReservedSet->insert("operator");
|
||
|
ReservedSet->insert("private");
|
||
|
ReservedSet->insert("protected");
|
||
|
ReservedSet->insert("public");
|
||
|
ReservedSet->insert("reinterpret_cast");
|
||
|
ReservedSet->insert("short");
|
||
|
ReservedSet->insert("signed");
|
||
|
ReservedSet->insert("sizeof");
|
||
|
ReservedSet->insert("static_cast");
|
||
|
ReservedSet->insert("template");
|
||
|
ReservedSet->insert("this");
|
||
|
ReservedSet->insert("throw");
|
||
|
ReservedSet->insert("try");
|
||
|
ReservedSet->insert("typename");
|
||
|
ReservedSet->insert("union");
|
||
|
ReservedSet->insert("unsigned");
|
||
|
ReservedSet->insert("using");
|
||
|
ReservedSet->insert("virtual");
|
||
|
}
|
||
|
|
||
|
void HlslScanContext::deleteKeywordMap()
|
||
|
{
|
||
|
delete KeywordMap;
|
||
|
KeywordMap = nullptr;
|
||
|
delete ReservedSet;
|
||
|
ReservedSet = nullptr;
|
||
|
}
|
||
|
|
||
|
// Wrapper for tokenizeClass()"] = to get everything inside the token.
|
||
|
void HlslScanContext::tokenize(HlslToken& token)
|
||
|
{
|
||
|
EHlslTokenClass tokenClass = tokenizeClass(token);
|
||
|
token.tokenClass = tokenClass;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Fill in token information for the next token, except for the token class.
|
||
|
// Returns the enum value of the token class of the next token found.
|
||
|
// Return 0 (EndOfTokens) on end of input.
|
||
|
//
|
||
|
EHlslTokenClass HlslScanContext::tokenizeClass(HlslToken& token)
|
||
|
{
|
||
|
do {
|
||
|
parserToken = &token;
|
||
|
TPpToken ppToken;
|
||
|
tokenText = ppContext.tokenize(&ppToken);
|
||
|
if (tokenText == nullptr)
|
||
|
return EHTokNone;
|
||
|
|
||
|
loc = ppToken.loc;
|
||
|
parserToken->loc = loc;
|
||
|
switch (ppToken.token) {
|
||
|
case ';': return EHTokSemicolon;
|
||
|
case ',': return EHTokComma;
|
||
|
case ':': return EHTokColon;
|
||
|
case '=': return EHTokAssign;
|
||
|
case '(': return EHTokLeftParen;
|
||
|
case ')': return EHTokRightParen;
|
||
|
case '.': return EHTokDot;
|
||
|
case '!': return EHTokBang;
|
||
|
case '-': return EHTokDash;
|
||
|
case '~': return EHTokTilde;
|
||
|
case '+': return EHTokPlus;
|
||
|
case '*': return EHTokStar;
|
||
|
case '/': return EHTokSlash;
|
||
|
case '%': return EHTokPercent;
|
||
|
case '<': return EHTokLeftAngle;
|
||
|
case '>': return EHTokRightAngle;
|
||
|
case '|': return EHTokVerticalBar;
|
||
|
case '^': return EHTokCaret;
|
||
|
case '&': return EHTokAmpersand;
|
||
|
case '?': return EHTokQuestion;
|
||
|
case '[': return EHTokLeftBracket;
|
||
|
case ']': return EHTokRightBracket;
|
||
|
case '{': return EHTokLeftBrace;
|
||
|
case '}': return EHTokRightBrace;
|
||
|
case '\\':
|
||
|
parseContext.error(loc, "illegal use of escape character", "\\", "");
|
||
|
break;
|
||
|
|
||
|
case PpAtomAdd: return EHTokAddAssign;
|
||
|
case PpAtomSub: return EHTokSubAssign;
|
||
|
case PpAtomMul: return EHTokMulAssign;
|
||
|
case PpAtomDiv: return EHTokDivAssign;
|
||
|
case PpAtomMod: return EHTokModAssign;
|
||
|
|
||
|
case PpAtomRight: return EHTokRightOp;
|
||
|
case PpAtomLeft: return EHTokLeftOp;
|
||
|
|
||
|
case PpAtomRightAssign: return EHTokRightAssign;
|
||
|
case PpAtomLeftAssign: return EHTokLeftAssign;
|
||
|
case PpAtomAndAssign: return EHTokAndAssign;
|
||
|
case PpAtomOrAssign: return EHTokOrAssign;
|
||
|
case PpAtomXorAssign: return EHTokXorAssign;
|
||
|
|
||
|
case PpAtomAnd: return EHTokAndOp;
|
||
|
case PpAtomOr: return EHTokOrOp;
|
||
|
case PpAtomXor: return EHTokXorOp;
|
||
|
|
||
|
case PpAtomEQ: return EHTokEqOp;
|
||
|
case PpAtomGE: return EHTokGeOp;
|
||
|
case PpAtomNE: return EHTokNeOp;
|
||
|
case PpAtomLE: return EHTokLeOp;
|
||
|
|
||
|
case PpAtomDecrement: return EHTokDecOp;
|
||
|
case PpAtomIncrement: return EHTokIncOp;
|
||
|
|
||
|
case PpAtomConstInt: parserToken->i = ppToken.ival; return EHTokIntConstant;
|
||
|
case PpAtomConstUint: parserToken->i = ppToken.ival; return EHTokUintConstant;
|
||
|
case PpAtomConstFloat: parserToken->d = ppToken.dval; return EHTokFloatConstant;
|
||
|
case PpAtomConstDouble: parserToken->d = ppToken.dval; return EHTokDoubleConstant;
|
||
|
case PpAtomIdentifier:
|
||
|
{
|
||
|
EHlslTokenClass token = tokenizeIdentifier();
|
||
|
return token;
|
||
|
}
|
||
|
|
||
|
case EndOfInput: return EHTokNone;
|
||
|
|
||
|
default:
|
||
|
char buf[2];
|
||
|
buf[0] = (char)ppToken.token;
|
||
|
buf[1] = 0;
|
||
|
parseContext.error(loc, "unexpected token", buf, "");
|
||
|
break;
|
||
|
}
|
||
|
} while (true);
|
||
|
}
|
||
|
|
||
|
EHlslTokenClass HlslScanContext::tokenizeIdentifier()
|
||
|
{
|
||
|
if (ReservedSet->find(tokenText) != ReservedSet->end())
|
||
|
return reservedWord();
|
||
|
|
||
|
auto it = KeywordMap->find(tokenText);
|
||
|
if (it == KeywordMap->end()) {
|
||
|
// Should have an identifier of some sort
|
||
|
return identifierOrType();
|
||
|
}
|
||
|
keyword = it->second;
|
||
|
|
||
|
switch (keyword) {
|
||
|
|
||
|
// qualifiers
|
||
|
case EHTokStatic:
|
||
|
case EHTokConst:
|
||
|
case EHTokSNorm:
|
||
|
case EHTokUnorm:
|
||
|
case EHTokExtern:
|
||
|
case EHTokUniform:
|
||
|
case EHTokVolatile:
|
||
|
case EHTokShared:
|
||
|
case EHTokGroupShared:
|
||
|
case EHTokLinear:
|
||
|
case EHTokCentroid:
|
||
|
case EHTokNointerpolation:
|
||
|
case EHTokNoperspective:
|
||
|
case EHTokSample:
|
||
|
case EHTokRowMajor:
|
||
|
case EHTokColumnMajor:
|
||
|
case EHTokPackOffset:
|
||
|
case EHTokIn:
|
||
|
case EHTokOut:
|
||
|
case EHTokInOut:
|
||
|
return keyword;
|
||
|
|
||
|
// template types
|
||
|
case EHTokBuffer:
|
||
|
case EHTokVector:
|
||
|
case EHTokMatrix:
|
||
|
return keyword;
|
||
|
|
||
|
// scalar types
|
||
|
case EHTokVoid:
|
||
|
case EHTokBool:
|
||
|
case EHTokInt:
|
||
|
case EHTokUint:
|
||
|
case EHTokDword:
|
||
|
case EHTokHalf:
|
||
|
case EHTokFloat:
|
||
|
case EHTokDouble:
|
||
|
case EHTokMin16float:
|
||
|
case EHTokMin10float:
|
||
|
case EHTokMin16int:
|
||
|
case EHTokMin12int:
|
||
|
case EHTokMin16uint:
|
||
|
|
||
|
// vector types
|
||
|
case EHTokBool1:
|
||
|
case EHTokBool2:
|
||
|
case EHTokBool3:
|
||
|
case EHTokBool4:
|
||
|
case EHTokFloat1:
|
||
|
case EHTokFloat2:
|
||
|
case EHTokFloat3:
|
||
|
case EHTokFloat4:
|
||
|
case EHTokInt1:
|
||
|
case EHTokInt2:
|
||
|
case EHTokInt3:
|
||
|
case EHTokInt4:
|
||
|
case EHTokDouble1:
|
||
|
case EHTokDouble2:
|
||
|
case EHTokDouble3:
|
||
|
case EHTokDouble4:
|
||
|
case EHTokUint1:
|
||
|
case EHTokUint2:
|
||
|
case EHTokUint3:
|
||
|
case EHTokUint4:
|
||
|
|
||
|
// matrix types
|
||
|
case EHTokInt1x1:
|
||
|
case EHTokInt1x2:
|
||
|
case EHTokInt1x3:
|
||
|
case EHTokInt1x4:
|
||
|
case EHTokInt2x1:
|
||
|
case EHTokInt2x2:
|
||
|
case EHTokInt2x3:
|
||
|
case EHTokInt2x4:
|
||
|
case EHTokInt3x1:
|
||
|
case EHTokInt3x2:
|
||
|
case EHTokInt3x3:
|
||
|
case EHTokInt3x4:
|
||
|
case EHTokInt4x1:
|
||
|
case EHTokInt4x2:
|
||
|
case EHTokInt4x3:
|
||
|
case EHTokInt4x4:
|
||
|
case EHTokFloat1x1:
|
||
|
case EHTokFloat1x2:
|
||
|
case EHTokFloat1x3:
|
||
|
case EHTokFloat1x4:
|
||
|
case EHTokFloat2x1:
|
||
|
case EHTokFloat2x2:
|
||
|
case EHTokFloat2x3:
|
||
|
case EHTokFloat2x4:
|
||
|
case EHTokFloat3x1:
|
||
|
case EHTokFloat3x2:
|
||
|
case EHTokFloat3x3:
|
||
|
case EHTokFloat3x4:
|
||
|
case EHTokFloat4x1:
|
||
|
case EHTokFloat4x2:
|
||
|
case EHTokFloat4x3:
|
||
|
case EHTokFloat4x4:
|
||
|
case EHTokDouble1x1:
|
||
|
case EHTokDouble1x2:
|
||
|
case EHTokDouble1x3:
|
||
|
case EHTokDouble1x4:
|
||
|
case EHTokDouble2x1:
|
||
|
case EHTokDouble2x2:
|
||
|
case EHTokDouble2x3:
|
||
|
case EHTokDouble2x4:
|
||
|
case EHTokDouble3x1:
|
||
|
case EHTokDouble3x2:
|
||
|
case EHTokDouble3x3:
|
||
|
case EHTokDouble3x4:
|
||
|
case EHTokDouble4x1:
|
||
|
case EHTokDouble4x2:
|
||
|
case EHTokDouble4x3:
|
||
|
case EHTokDouble4x4:
|
||
|
return keyword;
|
||
|
|
||
|
// texturing types
|
||
|
case EHTokSampler:
|
||
|
case EHTokSampler1d:
|
||
|
case EHTokSampler2d:
|
||
|
case EHTokSampler3d:
|
||
|
case EHTokSamplerCube:
|
||
|
case EHTokSamplerState:
|
||
|
case EHTokSamplerComparisonState:
|
||
|
case EHTokTexture:
|
||
|
case EHTokTexture1d:
|
||
|
case EHTokTexture1darray:
|
||
|
case EHTokTexture2d:
|
||
|
case EHTokTexture2darray:
|
||
|
case EHTokTexture3d:
|
||
|
case EHTokTextureCube:
|
||
|
case EHTokTextureCubearray:
|
||
|
case EHTokTexture2DMS:
|
||
|
case EHTokTexture2DMSarray:
|
||
|
return keyword;
|
||
|
|
||
|
// variable, user type, ...
|
||
|
case EHTokStruct:
|
||
|
case EHTokTypedef:
|
||
|
|
||
|
case EHTokBoolConstant:
|
||
|
if (strcmp("true", tokenText) == 0)
|
||
|
parserToken->b = true;
|
||
|
else
|
||
|
parserToken->b = false;
|
||
|
return keyword;
|
||
|
|
||
|
// control flow
|
||
|
case EHTokFor:
|
||
|
case EHTokDo:
|
||
|
case EHTokWhile:
|
||
|
case EHTokBreak:
|
||
|
case EHTokContinue:
|
||
|
case EHTokIf:
|
||
|
case EHTokElse:
|
||
|
case EHTokDiscard:
|
||
|
case EHTokReturn:
|
||
|
case EHTokCase:
|
||
|
case EHTokSwitch:
|
||
|
case EHTokDefault:
|
||
|
return keyword;
|
||
|
|
||
|
default:
|
||
|
parseContext.infoSink.info.message(EPrefixInternalError, "Unknown glslang keyword", loc);
|
||
|
return EHTokNone;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
EHlslTokenClass HlslScanContext::identifierOrType()
|
||
|
{
|
||
|
parserToken->string = NewPoolTString(tokenText);
|
||
|
|
||
|
return EHTokIdentifier;
|
||
|
}
|
||
|
|
||
|
// Give an error for use of a reserved symbol.
|
||
|
// However, allow built-in declarations to use reserved words, to allow
|
||
|
// extension support before the extension is enabled.
|
||
|
EHlslTokenClass HlslScanContext::reservedWord()
|
||
|
{
|
||
|
if (! parseContext.symbolTable.atBuiltInLevel())
|
||
|
parseContext.error(loc, "Reserved word.", tokenText, "", "");
|
||
|
|
||
|
return EHTokNone;
|
||
|
}
|
||
|
|
||
|
EHlslTokenClass HlslScanContext::identifierOrReserved(bool reserved)
|
||
|
{
|
||
|
if (reserved) {
|
||
|
reservedWord();
|
||
|
|
||
|
return EHTokNone;
|
||
|
}
|
||
|
|
||
|
if (parseContext.forwardCompatible)
|
||
|
parseContext.warn(loc, "using future reserved keyword", tokenText, "");
|
||
|
|
||
|
return identifierOrType();
|
||
|
}
|
||
|
|
||
|
// For a keyword that was never reserved, until it suddenly
|
||
|
// showed up.
|
||
|
EHlslTokenClass HlslScanContext::nonreservedKeyword(int version)
|
||
|
{
|
||
|
if (parseContext.version < version)
|
||
|
return identifierOrType();
|
||
|
|
||
|
return keyword;
|
||
|
}
|
||
|
|
||
|
} // end namespace glslang
|