commit
71e04d62a4
@ -293,10 +293,33 @@ int yylex(YYSTYPE* glslangTokenDesc, glslang::TParseContext& parseContext)
|
|||||||
|
|
||||||
namespace {
|
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++)
|
||||||
|
hash = ((hash << 5) + hash) + c;
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// A single global usable by all threads, by all versions, by all languages.
|
// 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
|
// After a single process-level initialization, this is read only and thread safe
|
||||||
std::unordered_map<std::string, int>* KeywordMap = nullptr;
|
std::unordered_map<const char*, int, str_hash, str_eq>* KeywordMap = nullptr;
|
||||||
std::unordered_set<std::string>* ReservedSet = nullptr;
|
std::unordered_set<const char*, str_hash, str_eq>* ReservedSet = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -309,7 +332,7 @@ void TScanContext::fillInKeywordMap()
|
|||||||
// but, the only risk is if two threads called simultaneously
|
// but, the only risk is if two threads called simultaneously
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
KeywordMap = new std::unordered_map<std::string, int>;
|
KeywordMap = new std::unordered_map<const char*, int, str_hash, str_eq>;
|
||||||
|
|
||||||
(*KeywordMap)["const"] = CONST;
|
(*KeywordMap)["const"] = CONST;
|
||||||
(*KeywordMap)["uniform"] = UNIFORM;
|
(*KeywordMap)["uniform"] = UNIFORM;
|
||||||
@ -481,7 +504,7 @@ void TScanContext::fillInKeywordMap()
|
|||||||
(*KeywordMap)["resource"] = RESOURCE;
|
(*KeywordMap)["resource"] = RESOURCE;
|
||||||
(*KeywordMap)["superp"] = SUPERP;
|
(*KeywordMap)["superp"] = SUPERP;
|
||||||
|
|
||||||
ReservedSet = new std::unordered_set<std::string>;
|
ReservedSet = new std::unordered_set<const char*, str_hash, str_eq>;
|
||||||
|
|
||||||
ReservedSet->insert("common");
|
ReservedSet->insert("common");
|
||||||
ReservedSet->insert("partition");
|
ReservedSet->insert("partition");
|
||||||
|
@ -242,11 +242,11 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
|
|
||||||
ppToken->ival = 0;
|
ppToken->ival = 0;
|
||||||
ppToken->space = false;
|
ppToken->space = false;
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (ch == ' ' || ch == '\t') {
|
while (ch == ' ' || ch == '\t') {
|
||||||
ppToken->space = true;
|
ppToken->space = true;
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
}
|
}
|
||||||
|
|
||||||
ppToken->loc = pp->parseContext.getCurrentLoc();
|
ppToken->loc = pp->parseContext.getCurrentLoc();
|
||||||
@ -271,13 +271,13 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
do {
|
do {
|
||||||
if (len < MaxTokenLength) {
|
if (len < MaxTokenLength) {
|
||||||
tokenText[len++] = (char)ch;
|
tokenText[len++] = (char)ch;
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
} else {
|
} else {
|
||||||
if (! AlreadyComplained) {
|
if (! AlreadyComplained) {
|
||||||
pp->parseContext.ppError(ppToken->loc, "name too long", "", "");
|
pp->parseContext.ppError(ppToken->loc, "name too long", "", "");
|
||||||
AlreadyComplained = 1;
|
AlreadyComplained = 1;
|
||||||
}
|
}
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
}
|
}
|
||||||
} while ((ch >= 'a' && ch <= 'z') ||
|
} while ((ch >= 'a' && ch <= 'z') ||
|
||||||
(ch >= 'A' && ch <= 'Z') ||
|
(ch >= 'A' && ch <= 'Z') ||
|
||||||
@ -289,18 +289,18 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
ppToken->atom = pp->LookUpAddString(tokenText);
|
ppToken->atom = pp->LookUpAddString(tokenText);
|
||||||
return PpAtomIdentifier;
|
return PpAtomIdentifier;
|
||||||
case '0':
|
case '0':
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == 'x' || ch == 'X') {
|
if (ch == 'x' || ch == 'X') {
|
||||||
// must be hexidecimal
|
// must be hexidecimal
|
||||||
|
|
||||||
bool isUnsigned = false;
|
bool isUnsigned = false;
|
||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if ((ch >= '0' && ch <= '9') ||
|
if ((ch >= '0' && ch <= '9') ||
|
||||||
(ch >= 'A' && ch <= 'F') ||
|
(ch >= 'A' && ch <= 'F') ||
|
||||||
(ch >= 'a' && ch <= 'f')) {
|
(ch >= 'a' && ch <= 'f')) {
|
||||||
@ -325,7 +325,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
}
|
}
|
||||||
ival = 0xffffffff;
|
ival = 0xffffffff;
|
||||||
}
|
}
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
} while ((ch >= '0' && ch <= '9') ||
|
} while ((ch >= '0' && ch <= '9') ||
|
||||||
(ch >= 'A' && ch <= 'F') ||
|
(ch >= 'A' && ch <= 'F') ||
|
||||||
(ch >= 'a' && ch <= 'f'));
|
(ch >= 'a' && ch <= 'f'));
|
||||||
@ -337,7 +337,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isUnsigned = true;
|
isUnsigned = true;
|
||||||
} else
|
} else
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
ppToken->name[len] = '\0';
|
ppToken->name[len] = '\0';
|
||||||
ppToken->ival = (int)ival;
|
ppToken->ival = (int)ival;
|
||||||
|
|
||||||
@ -366,7 +366,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
ival = (ival << 3) | ii;
|
ival = (ival << 3) | ii;
|
||||||
} else
|
} else
|
||||||
octalOverflow = true;
|
octalOverflow = true;
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
}
|
}
|
||||||
|
|
||||||
// could be part of a float...
|
// could be part of a float...
|
||||||
@ -379,7 +379,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
|
pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
|
||||||
AlreadyComplained = 1;
|
AlreadyComplained = 1;
|
||||||
}
|
}
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
} while (ch >= '0' && ch <= '9');
|
} while (ch >= '0' && ch <= '9');
|
||||||
}
|
}
|
||||||
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L')
|
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L')
|
||||||
@ -394,7 +394,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
isUnsigned = true;
|
isUnsigned = true;
|
||||||
} else
|
} else
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
ppToken->name[len] = '\0';
|
ppToken->name[len] = '\0';
|
||||||
|
|
||||||
if (octalOverflow)
|
if (octalOverflow)
|
||||||
@ -419,7 +419,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
|
pp->parseContext.ppError(ppToken->loc, "numeric literal too long", "", "");
|
||||||
AlreadyComplained = 1;
|
AlreadyComplained = 1;
|
||||||
}
|
}
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
} while (ch >= '0' && ch <= '9');
|
} while (ch >= '0' && ch <= '9');
|
||||||
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') {
|
if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') {
|
||||||
return pp->lFloatConst(len, ch, ppToken);
|
return pp->lFloatConst(len, ch, ppToken);
|
||||||
@ -432,7 +432,7 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
ppToken->name[len++] = (char)ch;
|
ppToken->name[len++] = (char)ch;
|
||||||
uint = true;
|
uint = true;
|
||||||
} else
|
} else
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
|
|
||||||
ppToken->name[len] = '\0';
|
ppToken->name[len] = '\0';
|
||||||
ival = 0;
|
ival = 0;
|
||||||
@ -456,153 +456,153 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '-') {
|
if (ch == '-') {
|
||||||
return PpAtomDecrement;
|
return PpAtomDecrement;
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return PpAtomSub;
|
return PpAtomSub;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '-';
|
return '-';
|
||||||
}
|
}
|
||||||
case '+':
|
case '+':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '+') {
|
if (ch == '+') {
|
||||||
return PpAtomIncrement;
|
return PpAtomIncrement;
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return PpAtomAdd;
|
return PpAtomAdd;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '+';
|
return '+';
|
||||||
}
|
}
|
||||||
case '*':
|
case '*':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return PpAtomMul;
|
return PpAtomMul;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '*';
|
return '*';
|
||||||
}
|
}
|
||||||
case '%':
|
case '%':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return PpAtomMod;
|
return PpAtomMod;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '%';
|
return '%';
|
||||||
}
|
}
|
||||||
case '^':
|
case '^':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '^') {
|
if (ch == '^') {
|
||||||
return PpAtomXor;
|
return PpAtomXor;
|
||||||
} else {
|
} else {
|
||||||
if (ch == '=')
|
if (ch == '=')
|
||||||
return PpAtomXorAssign;
|
return PpAtomXorAssign;
|
||||||
else{
|
else{
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '^';
|
return '^';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case '=':
|
case '=':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return PpAtomEQ;
|
return PpAtomEQ;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '=';
|
return '=';
|
||||||
}
|
}
|
||||||
case '!':
|
case '!':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '=') {
|
if (ch == '=') {
|
||||||
return PpAtomNE;
|
return PpAtomNE;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '!';
|
return '!';
|
||||||
}
|
}
|
||||||
case '|':
|
case '|':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '|') {
|
if (ch == '|') {
|
||||||
return PpAtomOr;
|
return PpAtomOr;
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return PpAtomOrAssign;
|
return PpAtomOrAssign;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '|';
|
return '|';
|
||||||
}
|
}
|
||||||
case '&':
|
case '&':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '&') {
|
if (ch == '&') {
|
||||||
return PpAtomAnd;
|
return PpAtomAnd;
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return PpAtomAndAssign;
|
return PpAtomAndAssign;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '&';
|
return '&';
|
||||||
}
|
}
|
||||||
case '<':
|
case '<':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '<') {
|
if (ch == '<') {
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '=')
|
if (ch == '=')
|
||||||
return PpAtomLeftAssign;
|
return PpAtomLeftAssign;
|
||||||
else {
|
else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return PpAtomLeft;
|
return PpAtomLeft;
|
||||||
}
|
}
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return PpAtomLE;
|
return PpAtomLE;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '<';
|
return '<';
|
||||||
}
|
}
|
||||||
case '>':
|
case '>':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '>') {
|
if (ch == '>') {
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '=')
|
if (ch == '=')
|
||||||
return PpAtomRightAssign;
|
return PpAtomRightAssign;
|
||||||
else {
|
else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return PpAtomRight;
|
return PpAtomRight;
|
||||||
}
|
}
|
||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return PpAtomGE;
|
return PpAtomGE;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '>';
|
return '>';
|
||||||
}
|
}
|
||||||
case '.':
|
case '.':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch >= '0' && ch <= '9') {
|
if (ch >= '0' && ch <= '9') {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return pp->lFloatConst(0, '.', ppToken);
|
return pp->lFloatConst(0, '.', ppToken);
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '.';
|
return '.';
|
||||||
}
|
}
|
||||||
case '/':
|
case '/':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == '/') {
|
if (ch == '/') {
|
||||||
pp->inComment = true;
|
pp->inComment = true;
|
||||||
do {
|
do {
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
} while (ch != '\n' && ch != EndOfInput);
|
} while (ch != '\n' && ch != EndOfInput);
|
||||||
ppToken->space = true;
|
ppToken->space = true;
|
||||||
pp->inComment = false;
|
pp->inComment = false;
|
||||||
|
|
||||||
return ch;
|
return ch;
|
||||||
} else if (ch == '*') {
|
} else if (ch == '*') {
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
do {
|
do {
|
||||||
while (ch != '*') {
|
while (ch != '*') {
|
||||||
if (ch == EndOfInput) {
|
if (ch == EndOfInput) {
|
||||||
pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", "");
|
pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", "");
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
}
|
}
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
if (ch == EndOfInput) {
|
if (ch == EndOfInput) {
|
||||||
pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", "");
|
pp->parseContext.ppError(ppToken->loc, "End of input in comment", "comment", "");
|
||||||
return ch;
|
return ch;
|
||||||
@ -614,29 +614,29 @@ int TPpContext::tStringInput::scan(TPpToken* ppToken)
|
|||||||
} else if (ch == '=') {
|
} else if (ch == '=') {
|
||||||
return PpAtomDiv;
|
return PpAtomDiv;
|
||||||
} else {
|
} else {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
return '/';
|
return '/';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '"':
|
case '"':
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
while (ch != '"' && ch != '\n' && ch != EndOfInput) {
|
while (ch != '"' && ch != '\n' && ch != EndOfInput) {
|
||||||
if (len < MaxTokenLength) {
|
if (len < MaxTokenLength) {
|
||||||
tokenText[len] = (char)ch;
|
tokenText[len] = (char)ch;
|
||||||
len++;
|
len++;
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
if (ch != '"') {
|
if (ch != '"') {
|
||||||
pp->ungetChar();
|
ungetch();
|
||||||
pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
|
pp->parseContext.ppError(ppToken->loc, "End of line in string", "string", "");
|
||||||
}
|
}
|
||||||
return PpAtomConstString;
|
return PpAtomConstString;
|
||||||
}
|
}
|
||||||
|
|
||||||
ch = pp->getChar();
|
ch = getch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user