Fix memory corruption problem in the preprocessor, removing custom hash-tables/etc. and replacing with std containers.
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@23623 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
ab3080353a
commit
1f4104fbb1
@ -98,67 +98,59 @@ namespace glslang {
|
|||||||
|
|
||||||
int TPpContext::InitCPP()
|
int TPpContext::InitCPP()
|
||||||
{
|
{
|
||||||
TPpContext::AtomTable* atable = &atomTable;
|
|
||||||
// Add various atoms needed by the CPP line scanner:
|
// Add various atoms needed by the CPP line scanner:
|
||||||
bindAtom = LookUpAddString(atable, "bind");
|
bindAtom = LookUpAddString("bind");
|
||||||
constAtom = LookUpAddString(atable, "const");
|
constAtom = LookUpAddString("const");
|
||||||
defaultAtom = LookUpAddString(atable, "default");
|
defaultAtom = LookUpAddString("default");
|
||||||
defineAtom = LookUpAddString(atable, "define");
|
defineAtom = LookUpAddString("define");
|
||||||
definedAtom = LookUpAddString(atable, "defined");
|
definedAtom = LookUpAddString("defined");
|
||||||
elifAtom = LookUpAddString(atable, "elif");
|
elifAtom = LookUpAddString("elif");
|
||||||
elseAtom = LookUpAddString(atable, "else");
|
elseAtom = LookUpAddString("else");
|
||||||
endifAtom = LookUpAddString(atable, "endif");
|
endifAtom = LookUpAddString("endif");
|
||||||
ifAtom = LookUpAddString(atable, "if");
|
ifAtom = LookUpAddString("if");
|
||||||
ifdefAtom = LookUpAddString(atable, "ifdef");
|
ifdefAtom = LookUpAddString("ifdef");
|
||||||
ifndefAtom = LookUpAddString(atable, "ifndef");
|
ifndefAtom = LookUpAddString("ifndef");
|
||||||
includeAtom = LookUpAddString(atable, "include");
|
includeAtom = LookUpAddString("include");
|
||||||
lineAtom = LookUpAddString(atable, "line");
|
lineAtom = LookUpAddString("line");
|
||||||
pragmaAtom = LookUpAddString(atable, "pragma");
|
pragmaAtom = LookUpAddString("pragma");
|
||||||
texunitAtom = LookUpAddString(atable, "texunit");
|
texunitAtom = LookUpAddString("texunit");
|
||||||
undefAtom = LookUpAddString(atable, "undef");
|
undefAtom = LookUpAddString("undef");
|
||||||
errorAtom = LookUpAddString(atable, "error");
|
errorAtom = LookUpAddString("error");
|
||||||
__LINE__Atom = LookUpAddString(atable, "__LINE__");
|
__LINE__Atom = LookUpAddString("__LINE__");
|
||||||
__FILE__Atom = LookUpAddString(atable, "__FILE__");
|
__FILE__Atom = LookUpAddString("__FILE__");
|
||||||
__VERSION__Atom = LookUpAddString(atable, "__VERSION__");
|
__VERSION__Atom = LookUpAddString("__VERSION__");
|
||||||
versionAtom = LookUpAddString(atable, "version");
|
versionAtom = LookUpAddString("version");
|
||||||
coreAtom = LookUpAddString(atable, "core");
|
coreAtom = LookUpAddString("core");
|
||||||
compatibilityAtom = LookUpAddString(atable, "compatibility");
|
compatibilityAtom = LookUpAddString("compatibility");
|
||||||
esAtom = LookUpAddString(atable, "es");
|
esAtom = LookUpAddString("es");
|
||||||
extensionAtom = LookUpAddString(atable, "extension");
|
extensionAtom = LookUpAddString("extension");
|
||||||
macros = NewScopeInPool(mem_CreatePool(0, 0));
|
pool = mem_CreatePool(0, 0);
|
||||||
|
|
||||||
return 1;
|
|
||||||
} // InitCPP
|
|
||||||
|
|
||||||
int TPpContext::FreeCPP()
|
|
||||||
{
|
|
||||||
if (macros) {
|
|
||||||
mem_FreePool(macros->pool);
|
|
||||||
macros = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TPpContext::FinalCPP()
|
int TPpContext::FinalCPP()
|
||||||
{
|
{
|
||||||
|
mem_FreePool(pool);
|
||||||
|
|
||||||
if (ifdepth)
|
if (ifdepth)
|
||||||
parseContext.error(parseContext.currentLoc, "missing #endif", "#if", "");
|
parseContext.error(parseContext.currentLoc, "missing #endif", "#if", "");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int TPpContext::CPPdefine(TPpToken * yylvalpp)
|
int TPpContext::CPPdefine(TPpToken * yylvalpp)
|
||||||
{
|
{
|
||||||
int token, name, args[maxMacroArgs], argc;
|
int token, atom, args[maxMacroArgs], argc;
|
||||||
MacroSymbol mac;
|
MacroSymbol mac;
|
||||||
Symbol *symb;
|
Symbol *symb;
|
||||||
memset(&mac, 0, sizeof(mac));
|
memset(&mac, 0, sizeof(mac));
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (token != CPP_IDENTIFIER) {
|
if (token != CPP_IDENTIFIER) {
|
||||||
parseContext.error(yylvalpp->loc, "must be followed by macro name", "#define", "");
|
parseContext.error(yylvalpp->loc, "must be followed by macro atom", "#define", "");
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
name = yylvalpp->atom;
|
atom = yylvalpp->atom;
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (token == '(' && !yylvalpp->ival) {
|
if (token == '(' && !yylvalpp->ival) {
|
||||||
// gather arguments
|
// gather arguments
|
||||||
@ -182,11 +174,11 @@ int TPpContext::CPPdefine(TPpToken * yylvalpp)
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
mac.argc = argc;
|
mac.argc = argc;
|
||||||
mac.args = (int*)mem_Alloc(macros->pool, argc * sizeof(int));
|
mac.args = (int*)mem_Alloc(pool, argc * sizeof(int));
|
||||||
memcpy(mac.args, args, argc * sizeof(int));
|
memcpy(mac.args, args, argc * sizeof(int));
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
}
|
}
|
||||||
mac.body = NewTokenStream(GetAtomString(&atomTable, name), macros->pool);
|
mac.body = NewTokenStream(GetAtomString(atom), pool);
|
||||||
while (token != '\n') {
|
while (token != '\n') {
|
||||||
while (token == '\\') {
|
while (token == '\\') {
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
@ -199,34 +191,33 @@ int TPpContext::CPPdefine(TPpToken * yylvalpp)
|
|||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
};
|
};
|
||||||
|
|
||||||
symb = LookUpSymbol(macros, name);
|
symb = LookUpSymbol(atom);
|
||||||
if (symb) {
|
if (symb) {
|
||||||
if (!symb->details.mac.undef) {
|
if (!symb->mac.undef) {
|
||||||
// already defined -- need to make sure they are identical
|
// already defined -- need to make sure they are identical
|
||||||
if (symb->details.mac.argc != mac.argc)
|
if (symb->mac.argc != mac.argc)
|
||||||
goto error;
|
goto error;
|
||||||
for (argc=0; argc < mac.argc; argc++)
|
for (argc=0; argc < mac.argc; argc++)
|
||||||
if (symb->details.mac.args[argc] != mac.args[argc])
|
if (symb->mac.args[argc] != mac.args[argc])
|
||||||
goto error;
|
goto error;
|
||||||
RewindTokenStream(symb->details.mac.body);
|
RewindTokenStream(symb->mac.body);
|
||||||
RewindTokenStream(mac.body);
|
RewindTokenStream(mac.body);
|
||||||
do {
|
do {
|
||||||
int old_lval, old_token;
|
int old_lval, old_token;
|
||||||
old_token = ReadToken(symb->details.mac.body, yylvalpp);
|
old_token = ReadToken(symb->mac.body, yylvalpp);
|
||||||
old_lval = yylvalpp->ival;
|
old_lval = yylvalpp->ival;
|
||||||
token = ReadToken(mac.body, yylvalpp);
|
token = ReadToken(mac.body, yylvalpp);
|
||||||
if (token != old_token || yylvalpp->ival != old_lval) {
|
if (token != old_token || yylvalpp->ival != old_lval) {
|
||||||
error:
|
error:
|
||||||
parseContext.error(yylvalpp->loc, "Macro Redefined", "#define", GetStringOfAtom(&atomTable, name));
|
parseContext.error(yylvalpp->loc, "Macro Redefined", "#define", GetAtomString(atom));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (token > 0);
|
} while (token > 0);
|
||||||
}
|
}
|
||||||
//FreeMacro(&symb->details.mac);
|
|
||||||
} else {
|
} else {
|
||||||
symb = AddSymbol(&yylvalpp->loc, macros, name, MACRO_S);
|
symb = AddSymbol(atom);
|
||||||
}
|
}
|
||||||
symb->details.mac = mac;
|
symb->mac = mac;
|
||||||
|
|
||||||
return '\n';
|
return '\n';
|
||||||
} // CPPdefine
|
} // CPPdefine
|
||||||
@ -246,9 +237,9 @@ int TPpContext::CPPundef(TPpToken * yylvalpp)
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
symb = LookUpSymbol(macros, yylvalpp->atom);
|
symb = LookUpSymbol(yylvalpp->atom);
|
||||||
if (symb) {
|
if (symb) {
|
||||||
symb->details.mac.undef = 1;
|
symb->mac.undef = 1;
|
||||||
}
|
}
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (token != '\n')
|
if (token != '\n')
|
||||||
@ -411,8 +402,8 @@ int TPpContext::eval(int token, int prec, int *res, int *err, TPpToken * yylvalp
|
|||||||
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
*res = (s = LookUpSymbol(macros, yylvalpp->atom))
|
*res = (s = LookUpSymbol(yylvalpp->atom))
|
||||||
? !s->details.mac.undef : 0;
|
? !s->mac.undef : 0;
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (needclose) {
|
if (needclose) {
|
||||||
if (token != ')') {
|
if (token != ')') {
|
||||||
@ -539,14 +530,14 @@ int TPpContext::CPPifdef(int defined, TPpToken * yylvalpp)
|
|||||||
else
|
else
|
||||||
parseContext.error(yylvalpp->loc, "must be followed by macro name", "#ifndef", "");
|
parseContext.error(yylvalpp->loc, "must be followed by macro name", "#ifndef", "");
|
||||||
} else {
|
} else {
|
||||||
Symbol *s = LookUpSymbol(macros, name);
|
Symbol *s = LookUpSymbol(name);
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (token != '\n') {
|
if (token != '\n') {
|
||||||
parseContext.error(yylvalpp->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
|
parseContext.error(yylvalpp->loc, "unexpected tokens following #ifdef directive - expected a newline", "#ifdef", "");
|
||||||
while (token != '\n')
|
while (token != '\n')
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
}
|
}
|
||||||
if (((s && !s->details.mac.undef) ? 1 : 0) != defined)
|
if (((s && !s->mac.undef) ? 1 : 0) != defined)
|
||||||
token = CPPelse(1, yylvalpp);
|
token = CPPelse(1, yylvalpp);
|
||||||
}
|
}
|
||||||
return token;
|
return token;
|
||||||
@ -592,9 +583,9 @@ int TPpContext::CPPerror(TPpToken * yylvalpp)
|
|||||||
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT) {
|
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT) {
|
||||||
message.append(yylvalpp->name);
|
message.append(yylvalpp->name);
|
||||||
} else if (token == CPP_IDENTIFIER || token == CPP_STRCONSTANT) {
|
} else if (token == CPP_IDENTIFIER || token == CPP_STRCONSTANT) {
|
||||||
message.append(GetStringOfAtom(&atomTable, yylvalpp->atom));
|
message.append(GetAtomString(yylvalpp->atom));
|
||||||
} else {
|
} else {
|
||||||
message.append(GetStringOfAtom(&atomTable, token));
|
message.append(GetAtomString(token));
|
||||||
}
|
}
|
||||||
message.append(" ");
|
message.append(" ");
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
@ -630,7 +621,7 @@ int TPpContext::CPPpragma(TPpToken * yylvalpp)
|
|||||||
}
|
}
|
||||||
switch (token) {
|
switch (token) {
|
||||||
case CPP_IDENTIFIER:
|
case CPP_IDENTIFIER:
|
||||||
SrcStr = GetAtomString(&atomTable, yylvalpp->atom);
|
SrcStr = GetAtomString(yylvalpp->atom);
|
||||||
allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
|
allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
|
||||||
strcpy(allTokens[tokenCount++], SrcStr);
|
strcpy(allTokens[tokenCount++], SrcStr);
|
||||||
break;
|
break;
|
||||||
@ -720,7 +711,7 @@ int TPpContext::CPPextension(TPpToken * yylvalpp)
|
|||||||
if (token != CPP_IDENTIFIER)
|
if (token != CPP_IDENTIFIER)
|
||||||
parseContext.error(yylvalpp->loc, "extension name expected", "#extension", "");
|
parseContext.error(yylvalpp->loc, "extension name expected", "#extension", "");
|
||||||
|
|
||||||
strcpy(extensionName, GetAtomString(&atomTable, yylvalpp->atom));
|
strcpy(extensionName, GetAtomString(yylvalpp->atom));
|
||||||
|
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (token != ':') {
|
if (token != ':') {
|
||||||
@ -734,7 +725,7 @@ int TPpContext::CPPextension(TPpToken * yylvalpp)
|
|||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
parseContext.updateExtensionBehavior(extensionName, GetAtomString(&atomTable, yylvalpp->atom));
|
parseContext.updateExtensionBehavior(extensionName, GetAtomString(yylvalpp->atom));
|
||||||
|
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (token == '\n')
|
if (token == '\n')
|
||||||
@ -807,7 +798,7 @@ int TPpContext::readCPPline(TPpToken * yylvalpp)
|
|||||||
} else if (yylvalpp->atom == extensionAtom) {
|
} else if (yylvalpp->atom == extensionAtom) {
|
||||||
token = CPPextension(yylvalpp);
|
token = CPPextension(yylvalpp);
|
||||||
} else {
|
} else {
|
||||||
parseContext.error(yylvalpp->loc, "Invalid Directive", "#", GetStringOfAtom(&atomTable, yylvalpp->atom));
|
parseContext.error(yylvalpp->loc, "Invalid Directive", "#", GetAtomString(yylvalpp->atom));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (token != '\n' && token != 0 && token != EOF) {
|
while (token != '\n' && token != 0 && token != EOF) {
|
||||||
@ -853,7 +844,7 @@ TPpContext::TokenStream* TPpContext::PrescanMacroArg(TokenStream *a, TPpToken *
|
|||||||
RewindTokenStream(a);
|
RewindTokenStream(a);
|
||||||
do {
|
do {
|
||||||
token = ReadToken(a, yylvalpp);
|
token = ReadToken(a, yylvalpp);
|
||||||
if (token == CPP_IDENTIFIER && LookUpSymbol(macros, yylvalpp->atom))
|
if (token == CPP_IDENTIFIER && LookUpSymbol(yylvalpp->atom))
|
||||||
break;
|
break;
|
||||||
} while (token > 0);
|
} while (token > 0);
|
||||||
if (token <= 0) return a;
|
if (token <= 0) return a;
|
||||||
@ -934,7 +925,7 @@ int TPpContext::zero_scan(TPpContext* pp, InputSrc *inInput, TPpToken* yylvalpp)
|
|||||||
*/
|
*/
|
||||||
int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
||||||
{
|
{
|
||||||
Symbol *sym = LookUpSymbol(macros, atom);
|
Symbol *sym = LookUpSymbol(atom);
|
||||||
MacroInputSrc *in;
|
MacroInputSrc *in;
|
||||||
int i, j, token;
|
int i, j, token;
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
@ -964,11 +955,11 @@ int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// no recursive expansions
|
// no recursive expansions
|
||||||
if (sym && sym->details.mac.busy)
|
if (sym && sym->mac.busy)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// not expanding of undefined symbols
|
// not expanding of undefined symbols
|
||||||
if ((! sym || sym->details.mac.undef) && ! expandUndef)
|
if ((! sym || sym->mac.undef) && ! expandUndef)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
in = (MacroInputSrc*)malloc(sizeof(*in));
|
in = (MacroInputSrc*)malloc(sizeof(*in));
|
||||||
@ -976,7 +967,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
|||||||
in->base.line = currentInput->line;
|
in->base.line = currentInput->line;
|
||||||
in->base.name = currentInput->name;
|
in->base.name = currentInput->name;
|
||||||
|
|
||||||
if ((! sym || sym->details.mac.undef) && expandUndef) {
|
if ((! sym || sym->mac.undef) && expandUndef) {
|
||||||
// push input
|
// push input
|
||||||
in->base.scan = zero_scan;
|
in->base.scan = zero_scan;
|
||||||
in->base.prev = currentInput;
|
in->base.prev = currentInput;
|
||||||
@ -986,8 +977,8 @@ int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
|||||||
}
|
}
|
||||||
|
|
||||||
in->base.scan = macro_scan;
|
in->base.scan = macro_scan;
|
||||||
in->mac = &sym->details.mac;
|
in->mac = &sym->mac;
|
||||||
if (sym->details.mac.args) {
|
if (sym->mac.args) {
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (token != '(') {
|
if (token != '(') {
|
||||||
UngetToken(token, yylvalpp);
|
UngetToken(token, yylvalpp);
|
||||||
@ -1005,7 +996,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
|||||||
while (1) {
|
while (1) {
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
if (token <= 0) {
|
if (token <= 0) {
|
||||||
parseContext.error(yylvalpp->loc, "EOF in macro", "preprocessor", GetStringOfAtom(&atomTable, atom));
|
parseContext.error(yylvalpp->loc, "EOF in macro", "preprocessor", GetAtomString(atom));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -1026,7 +1017,7 @@ int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
|||||||
} while (i < in->mac->argc);
|
} while (i < in->mac->argc);
|
||||||
|
|
||||||
if (i < in->mac->argc)
|
if (i < in->mac->argc)
|
||||||
parseContext.error(yylvalpp->loc, "Too few args in Macro", "preprocessor", GetStringOfAtom(&atomTable, atom));
|
parseContext.error(yylvalpp->loc, "Too few args in Macro", "preprocessor", GetAtomString(atom));
|
||||||
else if (token != ')') {
|
else if (token != ')') {
|
||||||
depth=0;
|
depth=0;
|
||||||
while (token >= 0 && (depth > 0 || token != ')')) {
|
while (token >= 0 && (depth > 0 || token != ')')) {
|
||||||
@ -1038,11 +1029,11 @@ int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (token <= 0) {
|
if (token <= 0) {
|
||||||
parseContext.error(yylvalpp->loc, "EOF in macro", "preprocessor", GetStringOfAtom(&atomTable, atom));
|
parseContext.error(yylvalpp->loc, "EOF in macro", "preprocessor", GetAtomString(atom));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
parseContext.error(yylvalpp->loc, "Too many args in Macro", "preprocessor", GetStringOfAtom(&atomTable, atom));
|
parseContext.error(yylvalpp->loc, "Too many args in Macro", "preprocessor", GetAtomString(atom));
|
||||||
}
|
}
|
||||||
for (i = 0; i<in->mac->argc; i++) {
|
for (i = 0; i<in->mac->argc; i++) {
|
||||||
in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
|
in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
|
||||||
@ -1059,8 +1050,8 @@ int TPpContext::MacroExpand(int atom, TPpToken* yylvalpp, int expandUndef)
|
|||||||
#endif
|
#endif
|
||||||
/*retain the input source*/
|
/*retain the input source*/
|
||||||
in->base.prev = currentInput;
|
in->base.prev = currentInput;
|
||||||
sym->details.mac.busy = 1;
|
sym->mac.busy = 1;
|
||||||
RewindTokenStream(sym->details.mac.body);
|
RewindTokenStream(sym->mac.body);
|
||||||
currentInput = &in->base;
|
currentInput = &in->base;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -98,10 +98,6 @@ namespace {
|
|||||||
|
|
||||||
using namespace glslang;
|
using namespace glslang;
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////// String table: //////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
const struct {
|
const struct {
|
||||||
int val;
|
int val;
|
||||||
const char *str;
|
const char *str;
|
||||||
@ -129,579 +125,71 @@ const struct {
|
|||||||
{ CPP_INC_OP, "++" },
|
{ CPP_INC_OP, "++" },
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////////////// String table: //////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define INIT_STRING_TABLE_SIZE 16384
|
|
||||||
|
|
||||||
/*
|
|
||||||
* InitStringTable() - Initialize the string table.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int InitStringTable(TPpContext::StringTable *stable)
|
|
||||||
{
|
|
||||||
stable->strings = (char *) malloc(INIT_STRING_TABLE_SIZE);
|
|
||||||
if (!stable->strings)
|
|
||||||
return 0;
|
|
||||||
// Zero-th offset means "empty" so don't use it.
|
|
||||||
stable->nextFree = 1;
|
|
||||||
stable->size = INIT_STRING_TABLE_SIZE;
|
|
||||||
return 1;
|
|
||||||
} // InitStringTable
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FreeStringTable() - Free the string table.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void FreeStringTable(TPpContext::StringTable *stable)
|
|
||||||
{
|
|
||||||
if (stable->strings)
|
|
||||||
free(stable->strings);
|
|
||||||
stable->strings = NULL;
|
|
||||||
stable->nextFree = 0;
|
|
||||||
stable->size = 0;
|
|
||||||
} // FreeStringTable
|
|
||||||
|
|
||||||
/*
|
|
||||||
* HashString() - Hash a string with the base hash function.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int HashString(const char *s)
|
|
||||||
{
|
|
||||||
int hval = 0;
|
|
||||||
|
|
||||||
while (*s) {
|
|
||||||
hval = (hval*13507 + *s*197) ^ (hval >> 2);
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
return hval & 0x7fffffff;
|
|
||||||
} // HashString
|
|
||||||
|
|
||||||
/*
|
|
||||||
* HashString2() - Hash a string with the incrimenting hash function.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int HashString2(const char *s)
|
|
||||||
{
|
|
||||||
int hval = 0;
|
|
||||||
|
|
||||||
while (*s) {
|
|
||||||
hval = (hval*729 + *s*37) ^ (hval >> 1);
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
return hval;
|
|
||||||
} // HashString2
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AddString() - Add a string to a string table. Return it's offset.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int AddString(TPpContext::StringTable *stable, const char *s)
|
|
||||||
{
|
|
||||||
int len, loc;
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
len = (int) strlen(s);
|
|
||||||
if (stable->nextFree + len + 1 >= stable->size) {
|
|
||||||
assert(stable->size < 1000000);
|
|
||||||
str = (char *) malloc(stable->size*2);
|
|
||||||
memcpy(str, stable->strings, stable->size);
|
|
||||||
free(stable->strings);
|
|
||||||
stable->strings = str;
|
|
||||||
}
|
|
||||||
loc = stable->nextFree;
|
|
||||||
strcpy(&stable->strings[loc], s);
|
|
||||||
stable->nextFree += len + 1;
|
|
||||||
return loc;
|
|
||||||
} // AddString
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////// Hash table: ///////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define INIT_HASH_TABLE_SIZE 2047
|
|
||||||
|
|
||||||
/*
|
|
||||||
* InitHashTable() - Initialize the hash table.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int InitHashTable(TPpContext::HashTable *htable, int fsize)
|
|
||||||
{
|
|
||||||
int ii;
|
|
||||||
|
|
||||||
htable->entry = (TPpContext::HashEntry *) malloc(sizeof(TPpContext::HashEntry)*fsize);
|
|
||||||
if (! htable->entry)
|
|
||||||
return 0;
|
|
||||||
htable->size = fsize;
|
|
||||||
for (ii = 0; ii < fsize; ii++) {
|
|
||||||
htable->entry[ii].index = 0;
|
|
||||||
htable->entry[ii].value = 0;
|
|
||||||
}
|
|
||||||
htable->entries = 0;
|
|
||||||
for (ii = 0; ii <= TPpContext::hashTableMaxCollisions; ii++)
|
|
||||||
htable->counts[ii] = 0;
|
|
||||||
return 1;
|
|
||||||
} // InitHashTable
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FreeHashTable() - Free the hash table.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void FreeHashTable(TPpContext::HashTable *htable)
|
|
||||||
{
|
|
||||||
if (htable->entry)
|
|
||||||
free(htable->entry);
|
|
||||||
htable->entry = NULL;
|
|
||||||
htable->size = 0;
|
|
||||||
htable->entries = 0;
|
|
||||||
} // FreeHashTable
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Empty() - See if a hash table entry is empty.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int Empty(TPpContext::HashTable *htable, int hashloc)
|
|
||||||
{
|
|
||||||
assert(hashloc >= 0 && hashloc < htable->size);
|
|
||||||
if (htable->entry[hashloc].index == 0) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // Empty
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Match() - See if a hash table entry is matches a string.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int Match(TPpContext::HashTable *htable, TPpContext::StringTable *stable, const char *s, int hashloc)
|
|
||||||
{
|
|
||||||
int strloc;
|
|
||||||
|
|
||||||
strloc = htable->entry[hashloc].index;
|
|
||||||
if (!strcmp(s, &stable->strings[strloc])) {
|
|
||||||
return 1;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // Match
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/////////////////////////////////////////// Atom table: ///////////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
#define INIT_ATOM_TABLE_SIZE 1024
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GrowAtomTable() - Grow the atom table to at least "size" if it's smaller.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int GrowAtomTable(TPpContext::AtomTable *atable, int size)
|
|
||||||
{
|
|
||||||
int *newmap, *newrev;
|
|
||||||
|
|
||||||
if (atable->size < size) {
|
|
||||||
if (atable->amap) {
|
|
||||||
newmap = (int*)realloc(atable->amap, sizeof(int)*size);
|
|
||||||
newrev = (int*)realloc(atable->arev, sizeof(int)*size);
|
|
||||||
} else {
|
|
||||||
newmap = (int*)malloc(sizeof(int)*size);
|
|
||||||
newrev = (int*)malloc(sizeof(int)*size);
|
|
||||||
atable->size = 0;
|
|
||||||
}
|
|
||||||
if (!newmap || !newrev) {
|
|
||||||
/* failed to grow -- error */
|
|
||||||
if (newmap)
|
|
||||||
atable->amap = newmap;
|
|
||||||
if (newrev)
|
|
||||||
atable->amap = newrev;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
|
|
||||||
memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
|
|
||||||
atable->amap = newmap;
|
|
||||||
atable->arev = newrev;
|
|
||||||
atable->size = size;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} // GrowAtomTable
|
|
||||||
|
|
||||||
/*
|
|
||||||
* lReverse() - Reverse the bottom 20 bits of a 32 bit int.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int lReverse(int fval)
|
|
||||||
{
|
|
||||||
unsigned int in = fval;
|
|
||||||
int result = 0, cnt = 0;
|
|
||||||
|
|
||||||
while(in) {
|
|
||||||
result <<= 1;
|
|
||||||
result |= in&1;
|
|
||||||
in >>= 1;
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't use all 31 bits. One million atoms is plenty and sometimes the
|
|
||||||
// upper bits are used for other things.
|
|
||||||
|
|
||||||
if (cnt < 20)
|
|
||||||
result <<= 20 - cnt;
|
|
||||||
return result;
|
|
||||||
} // lReverse
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AllocateAtom() - Allocate a new atom. Associated with the "undefined" value of -1.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int AllocateAtom(TPpContext::AtomTable *atable)
|
|
||||||
{
|
|
||||||
if (atable->nextFree >= atable->size)
|
|
||||||
GrowAtomTable(atable, atable->nextFree*2);
|
|
||||||
atable->amap[atable->nextFree] = -1;
|
|
||||||
atable->arev[atable->nextFree] = lReverse(atable->nextFree);
|
|
||||||
atable->nextFree++;
|
|
||||||
return atable->nextFree - 1;
|
|
||||||
} // AllocateAtom
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SetAtomValue() - Allocate a new atom associated with "hashindex".
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void SetAtomValue(TPpContext::AtomTable *atable, int atomnumber, int hashindex)
|
|
||||||
{
|
|
||||||
atable->amap[atomnumber] = atable->htable.entry[hashindex].index;
|
|
||||||
atable->htable.entry[hashindex].value = atomnumber;
|
|
||||||
} // SetAtomValue
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FindHashLoc() - Find the hash location for this string. Return -1 it hash table is full.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int FindHashLoc(TPpContext::AtomTable *atable, const char *s)
|
|
||||||
{
|
|
||||||
int hashloc, hashdelta, count;
|
|
||||||
int FoundEmptySlot = 0;
|
|
||||||
#ifdef DUMP_TABLE
|
|
||||||
int collision[TPpContext::hashTableMaxCollisions + 1];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hashloc = HashString(s) % atable->htable.size;
|
|
||||||
if (!Empty(&atable->htable, hashloc)) {
|
|
||||||
if (Match(&atable->htable, &atable->stable, s, hashloc))
|
|
||||||
return hashloc;
|
|
||||||
#ifdef DUMP_TABLE
|
|
||||||
collision[0] = hashloc;
|
|
||||||
#endif
|
|
||||||
hashdelta = HashString2(s);
|
|
||||||
count = 0;
|
|
||||||
while (count < TPpContext::hashTableMaxCollisions) {
|
|
||||||
hashloc = ((hashloc + hashdelta) & 0x7fffffff) % atable->htable.size;
|
|
||||||
if (!Empty(&atable->htable, hashloc)) {
|
|
||||||
if (Match(&atable->htable, &atable->stable, s, hashloc)) {
|
|
||||||
return hashloc;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FoundEmptySlot = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
count++;
|
|
||||||
#ifdef DUMP_TABLE
|
|
||||||
collision[count] = hashloc;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! FoundEmptySlot) {
|
|
||||||
#ifdef DUMP_TABLE
|
|
||||||
{
|
|
||||||
int ii;
|
|
||||||
char str[200];
|
|
||||||
printf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
|
|
||||||
hashTableMaxCollisions);
|
|
||||||
printf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
|
|
||||||
for (ii = 0; ii <= hashTableMaxCollisions; ii++) {
|
|
||||||
printf(str, "*** Collides on try %d at hash entry %04x with \"%s\"",
|
|
||||||
ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
atable->htable.counts[count]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return hashloc;
|
|
||||||
} // FindHashLoc
|
|
||||||
|
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
/*
|
//
|
||||||
* IncreaseHashTableSize()
|
// Map a new or existing string to an atom, inventing a new atom if necessary.
|
||||||
*
|
//
|
||||||
*/
|
int TPpContext::LookUpAddString(const char *s)
|
||||||
int TPpContext::IncreaseHashTableSize(AtomTable *atable)
|
|
||||||
{
|
{
|
||||||
int ii, strloc, oldhashloc, value, size;
|
TAtomMap::const_iterator it = atomMap.find(s);
|
||||||
AtomTable oldtable;
|
if (it == atomMap.end())
|
||||||
char *s;
|
return AddAtomFixed(s, nextAtom++);
|
||||||
|
|
||||||
// Save the old atom table and create a new one:
|
|
||||||
|
|
||||||
oldtable = *atable;
|
|
||||||
size = oldtable.htable.size*2 + 1;
|
|
||||||
if (! InitAtomTable(atable, size))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Add all the existing values to the new atom table preserving their atom values:
|
|
||||||
|
|
||||||
for (ii = atable->nextFree; ii < oldtable.nextFree; ii++) {
|
|
||||||
strloc = oldtable.amap[ii];
|
|
||||||
s = &oldtable.stable.strings[strloc];
|
|
||||||
oldhashloc = FindHashLoc(&oldtable, s);
|
|
||||||
assert(oldhashloc >= 0);
|
|
||||||
value = oldtable.htable.entry[oldhashloc].value;
|
|
||||||
AddAtomFixed(atable, s, value);
|
|
||||||
}
|
|
||||||
FreeAtomTable(&oldtable);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
} // IncreaseHashTableSize
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LookUpAddStringHash() - Lookup a string in the hash table. If it's not there, add it and
|
|
||||||
* initialize the atom value in the hash table to 0. Return the hash table index.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int TPpContext::LookUpAddStringHash(AtomTable *atable, const char *s)
|
|
||||||
{
|
|
||||||
int hashloc, strloc;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
hashloc = FindHashLoc(atable, s);
|
|
||||||
if (hashloc >= 0)
|
|
||||||
break;
|
|
||||||
IncreaseHashTableSize(atable);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Empty(&atable->htable, hashloc)) {
|
|
||||||
atable->htable.entries++;
|
|
||||||
strloc = AddString(&atable->stable, s);
|
|
||||||
atable->htable.entry[hashloc].index = strloc;
|
|
||||||
atable->htable.entry[hashloc].value = 0;
|
|
||||||
}
|
|
||||||
return hashloc;
|
|
||||||
} // LookUpAddStringHash
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LookUpAddString() - Lookup a string in the hash table. If it's not there, add it and
|
|
||||||
* initialize the atom value in the hash table to the next atom number.
|
|
||||||
* Return the atom value of string.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int TPpContext::LookUpAddString(AtomTable *atable, const char *s)
|
|
||||||
{
|
|
||||||
int hashindex, atom;
|
|
||||||
|
|
||||||
hashindex = LookUpAddStringHash(atable, s);
|
|
||||||
atom = atable->htable.entry[hashindex].value;
|
|
||||||
if (atom == 0) {
|
|
||||||
atom = AllocateAtom(atable);
|
|
||||||
SetAtomValue(atable, atom, hashindex);
|
|
||||||
}
|
|
||||||
return atom;
|
|
||||||
} // LookUpAddString
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetAtomString()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
const char *TPpContext::GetAtomString(AtomTable *atable, int atom)
|
|
||||||
{
|
|
||||||
int soffset;
|
|
||||||
|
|
||||||
if (atom > 0 && atom < atable->nextFree) {
|
|
||||||
soffset = atable->amap[atom];
|
|
||||||
if (soffset > 0 && soffset < atable->stable.nextFree) {
|
|
||||||
return &atable->stable.strings[soffset];
|
|
||||||
} else {
|
|
||||||
return "<internal error: bad soffset>";
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (atom == 0) {
|
|
||||||
return "<null atom>";
|
|
||||||
} else {
|
|
||||||
if (atom == EOF) {
|
|
||||||
return "<EOF>";
|
|
||||||
} else {
|
|
||||||
return "<invalid atom>";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // GetAtomString
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetReversedAtom()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
int TPpContext::GetReversedAtom(TPpContext::AtomTable *atable, int atom)
|
|
||||||
{
|
|
||||||
if (atom > 0 && atom < atable->nextFree)
|
|
||||||
return atable->arev[atom];
|
|
||||||
else
|
else
|
||||||
return 0;
|
return it->second;
|
||||||
} // GetReversedAtom
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* AddAtom() - Add a string to the atom, hash and string tables if it isn't already there.
|
// Map an already created atom to its string.
|
||||||
* Return it's atom index.
|
//
|
||||||
*/
|
const char *TPpContext::GetAtomString(int atom)
|
||||||
|
|
||||||
int TPpContext::AddAtom(TPpContext::AtomTable *atable, const char *s)
|
|
||||||
{
|
{
|
||||||
int atom = LookUpAddString(atable, s);
|
if (atom == 0)
|
||||||
|
return "<null atom>";
|
||||||
|
if (atom < 0)
|
||||||
|
return "<EOF>";
|
||||||
|
if ((size_t)atom < stringMap.size())
|
||||||
|
return stringMap[atom]->c_str();
|
||||||
|
|
||||||
|
return "<invalid atom>";
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Add forced mapping of string to atom.
|
||||||
|
//
|
||||||
|
int TPpContext::AddAtomFixed(const char *s, int atom)
|
||||||
|
{
|
||||||
|
TAtomMap::const_iterator it = atomMap.insert(std::pair<TString, int>(s, atom)).first;
|
||||||
|
if (stringMap.size() < (size_t)atom + 1)
|
||||||
|
stringMap.resize(atom + 100);
|
||||||
|
stringMap[atom] = &it->first;
|
||||||
|
|
||||||
return atom;
|
return atom;
|
||||||
} // AddAtom
|
}
|
||||||
|
|
||||||
/*
|
//
|
||||||
* AddAtomFixed() - Add an atom to the hash and string tables if it isn't already there.
|
// Initialize the atom table.
|
||||||
* Assign it the atom value of "atom".
|
//
|
||||||
*/
|
void TPpContext::InitAtomTable()
|
||||||
|
|
||||||
int TPpContext::AddAtomFixed(AtomTable *atable, const char *s, int atom)
|
|
||||||
{
|
{
|
||||||
int hashindex, lsize;
|
|
||||||
|
|
||||||
hashindex = LookUpAddStringHash(atable, s);
|
|
||||||
if (atable->nextFree >= atable->size || atom >= atable->size) {
|
|
||||||
lsize = atable->size*2;
|
|
||||||
if (lsize <= atom)
|
|
||||||
lsize = atom + 1;
|
|
||||||
GrowAtomTable(atable, lsize);
|
|
||||||
}
|
|
||||||
atable->amap[atom] = atable->htable.entry[hashindex].index;
|
|
||||||
atable->htable.entry[hashindex].value = atom;
|
|
||||||
//if (atom >= atable->nextFree)
|
|
||||||
// atable->nextFree = atom + 1;
|
|
||||||
while (atom >= atable->nextFree) {
|
|
||||||
atable->arev[atable->nextFree] = lReverse(atable->nextFree);
|
|
||||||
atable->nextFree++;
|
|
||||||
}
|
|
||||||
return atom;
|
|
||||||
} // AddAtomFixed
|
|
||||||
|
|
||||||
/*
|
|
||||||
* InitAtomTable() - Initialize the atom table.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
int TPpContext::InitAtomTable(AtomTable *atable, int htsize)
|
|
||||||
{
|
|
||||||
int ii;
|
|
||||||
|
|
||||||
htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
|
|
||||||
if (! InitStringTable(&atable->stable))
|
|
||||||
return 0;
|
|
||||||
if (! InitHashTable(&atable->htable, htsize))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
atable->nextFree = 0;
|
|
||||||
atable->amap = NULL;
|
|
||||||
atable->size = 0;
|
|
||||||
atable->arev = 0;
|
|
||||||
GrowAtomTable(atable, INIT_ATOM_TABLE_SIZE);
|
|
||||||
if (!atable->amap)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Initialize lower part of atom table to "<undefined>" atom:
|
|
||||||
|
|
||||||
AddAtomFixed(atable, "<undefined>", 0);
|
|
||||||
for (ii = 0; ii < CPP_FIRST_USER_TOKEN_SY; ii++)
|
|
||||||
atable->amap[ii] = atable->amap[0];
|
|
||||||
|
|
||||||
// Add single character tokens to the atom table:
|
// Add single character tokens to the atom table:
|
||||||
|
const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#";
|
||||||
|
char t[2];
|
||||||
|
|
||||||
{
|
t[1] = '\0';
|
||||||
const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#";
|
while (*s) {
|
||||||
char t[2];
|
t[0] = *s;
|
||||||
|
AddAtomFixed(t, s[0]);
|
||||||
t[1] = '\0';
|
s++;
|
||||||
while (*s) {
|
|
||||||
t[0] = *s;
|
|
||||||
AddAtomFixed(atable, t, s[0]);
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add multiple character scanner tokens :
|
// Add multiple character scanner tokens :
|
||||||
|
for (int ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
|
||||||
|
AddAtomFixed(tokens[ii].str, tokens[ii].val);
|
||||||
|
|
||||||
for (ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
|
nextAtom = CPP_FIRST_USER_TOKEN_SY;
|
||||||
AddAtomFixed(atable, tokens[ii].str, tokens[ii].val);
|
}
|
||||||
|
|
||||||
AddAtom(atable, "<*** end fixed atoms ***>");
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
} // InitAtomTable
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
////////////////////////////////// Debug Printing Functions: //////////////////////////////////
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PrintAtomTable()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void TPpContext::PrintAtomTable(AtomTable *atable)
|
|
||||||
{
|
|
||||||
int ii;
|
|
||||||
char str[200];
|
|
||||||
|
|
||||||
for (ii = 0; ii < atable->nextFree; ii++) {
|
|
||||||
printf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
|
|
||||||
}
|
|
||||||
printf(str, "Hash table: size=%d, entries=%d, collisions=",
|
|
||||||
atable->htable.size, atable->htable.entries);
|
|
||||||
for (ii = 0; ii < hashTableMaxCollisions; ii++) {
|
|
||||||
printf(str, " %d", atable->htable.counts[ii]);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // PrintAtomTable
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* GetStringOfAtom()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
char* TPpContext::GetStringOfAtom(AtomTable *atable, int atom)
|
|
||||||
{
|
|
||||||
char* chr_str;
|
|
||||||
chr_str=&atable->stable.strings[atable->amap[atom]];
|
|
||||||
return chr_str;
|
|
||||||
} // GetStringOfAtom
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FreeAtomTable() - Free the atom table and associated memory
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void TPpContext::FreeAtomTable(AtomTable *atable)
|
|
||||||
{
|
|
||||||
FreeStringTable(&atable->stable);
|
|
||||||
FreeHashTable(&atable->htable);
|
|
||||||
if (atable->amap)
|
|
||||||
free(atable->amap);
|
|
||||||
if (atable->arev)
|
|
||||||
free(atable->arev);
|
|
||||||
atable->amap = NULL;
|
|
||||||
atable->arev = NULL;
|
|
||||||
atable->nextFree = 0;
|
|
||||||
atable->size = 0;
|
|
||||||
} // FreeAtomTable
|
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
@ -84,10 +84,9 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
TPpContext::TPpContext(TParseContext& pc) :
|
TPpContext::TPpContext(TParseContext& pc) :
|
||||||
preamble(0), strings(0), notAVersionToken(false), parseContext(pc),
|
preamble(0), strings(0), notAVersionToken(false), parseContext(pc)
|
||||||
ScopeList(0), CurrentScope(0), GlobalScope(0)
|
|
||||||
{
|
{
|
||||||
InitAtomTable(&atomTable, 0);
|
InitAtomTable();
|
||||||
InitScanner(this);
|
InitScanner(this);
|
||||||
|
|
||||||
ifdepth = 0;
|
ifdepth = 0;
|
||||||
@ -98,9 +97,8 @@ TPpContext::TPpContext(TParseContext& pc) :
|
|||||||
|
|
||||||
TPpContext::~TPpContext()
|
TPpContext::~TPpContext()
|
||||||
{
|
{
|
||||||
|
FinalCPP();
|
||||||
delete [] preamble;
|
delete [] preamble;
|
||||||
FreeAtomTable(&atomTable);
|
|
||||||
FreeScanner();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TPpContext::setPreamble(const char* p, size_t l)
|
void TPpContext::setPreamble(const char* p, size_t l)
|
||||||
|
@ -80,6 +80,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#include "../ParseHelper.h"
|
#include "../ParseHelper.h"
|
||||||
|
|
||||||
|
#include <hash_map>
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
class TPpToken {
|
class TPpToken {
|
||||||
@ -141,42 +143,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
// From PpAtom.cpp
|
// From Pp.cpp
|
||||||
//
|
//
|
||||||
struct StringTable {
|
|
||||||
char *strings;
|
|
||||||
int nextFree;
|
|
||||||
int size;
|
|
||||||
};
|
|
||||||
struct HashEntry {
|
|
||||||
int index; // String table offset of string representation
|
|
||||||
int value; // Atom (symbol) value
|
|
||||||
};
|
|
||||||
|
|
||||||
static const int hashTableMaxCollisions = 3;
|
|
||||||
|
|
||||||
struct HashTable {
|
|
||||||
HashEntry *entry;
|
|
||||||
int size;
|
|
||||||
int entries;
|
|
||||||
int counts[hashTableMaxCollisions + 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AtomTable {
|
|
||||||
StringTable stable; // String table.
|
|
||||||
HashTable htable; // Hashes string to atom number and token value. Multiple strings can
|
|
||||||
// have the same token value but each unique string is a unique atom.
|
|
||||||
int *amap; // Maps atom value to offset in string table. Atoms all map to unique
|
|
||||||
// strings except for some undefined values in the lower, fixed part
|
|
||||||
// of the atom table that map to "<undefined>". The lowest 256 atoms
|
|
||||||
// correspond to single character ASCII values except for alphanumeric
|
|
||||||
// characters and '_', which can be other tokens. Next come the
|
|
||||||
// language tokens with their atom values equal to the token value.
|
|
||||||
// Then come predefined atoms, followed by user specified identifiers.
|
|
||||||
int *arev; // Reversed atom for symbol table use.
|
|
||||||
int nextFree;
|
|
||||||
int size;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MacroSymbol {
|
struct MacroSymbol {
|
||||||
int argc;
|
int argc;
|
||||||
@ -186,19 +154,9 @@ public:
|
|||||||
unsigned undef:1;
|
unsigned undef:1;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum symbolkind {
|
|
||||||
MACRO_S
|
|
||||||
} symbolkind;
|
|
||||||
|
|
||||||
struct Symbol {
|
struct Symbol {
|
||||||
Symbol *left, *right;
|
int atom;
|
||||||
Symbol *next;
|
MacroSymbol mac;
|
||||||
int name; // Name atom
|
|
||||||
TSourceLoc loc;
|
|
||||||
symbolkind kind;
|
|
||||||
union {
|
|
||||||
MacroSymbol mac;
|
|
||||||
} details;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SymbolList {
|
struct SymbolList {
|
||||||
@ -206,18 +164,9 @@ public:
|
|||||||
Symbol *symb;
|
Symbol *symb;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Scope {
|
MemoryPool *pool;
|
||||||
Scope *next, *prev; // doubly-linked list of all scopes
|
typedef std::hash_map<int, Symbol*> TSymbol;
|
||||||
Scope *parent;
|
TSymbol symbols; // this has light use... just defined macros
|
||||||
Scope *funScope; // Points to base scope of enclosing function
|
|
||||||
MemoryPool *pool; // pool used for allocation in this scope
|
|
||||||
Symbol *symbols;
|
|
||||||
|
|
||||||
int level; // 0 = super globals, 1 = globals, etc.
|
|
||||||
|
|
||||||
// Only used at global scope (level 1):
|
|
||||||
SymbolList *programs; // List of programs for this compilation.
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
|
char* preamble; // string to parse, all before line 1 of string 0, it is 0 if no preamble
|
||||||
@ -277,11 +226,9 @@ protected:
|
|||||||
int compatibilityAtom;
|
int compatibilityAtom;
|
||||||
int esAtom;
|
int esAtom;
|
||||||
int extensionAtom;
|
int extensionAtom;
|
||||||
Scope *macros;
|
|
||||||
TSourceLoc ifloc; /* outermost #if */
|
TSourceLoc ifloc; /* outermost #if */
|
||||||
|
|
||||||
int InitCPP();
|
int InitCPP();
|
||||||
int FreeCPP();
|
|
||||||
int FinalCPP();
|
int FinalCPP();
|
||||||
int CPPdefine(TPpToken * yylvalpp);
|
int CPPdefine(TPpToken * yylvalpp);
|
||||||
int CPPundef(TPpToken * yylvalpp);
|
int CPPundef(TPpToken * yylvalpp);
|
||||||
@ -307,18 +254,9 @@ protected:
|
|||||||
//
|
//
|
||||||
// from PpSymbols.cpp
|
// from PpSymbols.cpp
|
||||||
//
|
//
|
||||||
Scope *ScopeList;
|
Symbol *NewSymbol(int name);
|
||||||
Scope *CurrentScope;
|
Symbol *AddSymbol(int atom);
|
||||||
Scope *GlobalScope;
|
Symbol *LookUpSymbol(int atom);
|
||||||
|
|
||||||
Scope *NewScopeInPool(MemoryPool *pool);
|
|
||||||
void PushScope(Scope *fScope);
|
|
||||||
Scope *PopScope(void);
|
|
||||||
Symbol *NewSymbol(TSourceLoc *loc, Scope *fScope, int name, symbolkind kind);
|
|
||||||
void lAddToTree(Symbol **fSymbols, Symbol *fSymb, AtomTable *atable);
|
|
||||||
Symbol *AddSymbol(TSourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
|
|
||||||
Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
|
|
||||||
Symbol *LookUpSymbol(Scope *fScope, int atom);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// From PpTokens.cpp
|
// From PpTokens.cpp
|
||||||
@ -356,7 +294,6 @@ protected:
|
|||||||
char *p;
|
char *p;
|
||||||
};
|
};
|
||||||
int InitScanner(TPpContext *cpp);
|
int InitScanner(TPpContext *cpp);
|
||||||
int FreeScanner(void);
|
|
||||||
static int str_getch(TPpContext*, StringInputSrc *in);
|
static int str_getch(TPpContext*, StringInputSrc *in);
|
||||||
static void str_ungetch(TPpContext*, StringInputSrc *in, int ch, TPpToken *type);
|
static void str_ungetch(TPpContext*, StringInputSrc *in, int ch, TPpToken *type);
|
||||||
int ScanFromString(char *s);
|
int ScanFromString(char *s);
|
||||||
@ -367,18 +304,15 @@ protected:
|
|||||||
//
|
//
|
||||||
// From PpAtom.cpp
|
// From PpAtom.cpp
|
||||||
//
|
//
|
||||||
AtomTable atomTable;
|
typedef std::hash_map<const TString, int> TAtomMap;
|
||||||
int InitAtomTable(AtomTable *atable, int htsize);
|
typedef TVector<const TString*> TStringMap;
|
||||||
void FreeAtomTable(AtomTable *atable);
|
TAtomMap atomMap;
|
||||||
int AddAtom(AtomTable *atable, const char *s);
|
TStringMap stringMap;
|
||||||
int AddAtomFixed(AtomTable *atable, const char *s, int atom);
|
int nextAtom;
|
||||||
void PrintAtomTable(AtomTable *atable);
|
void InitAtomTable();
|
||||||
int IncreaseHashTableSize(TPpContext::AtomTable *atable);
|
int AddAtomFixed(const char *s, int atom);
|
||||||
int LookUpAddStringHash(AtomTable *atable, const char *s);
|
int LookUpAddString(const char *s);
|
||||||
int LookUpAddString(AtomTable *atable, const char *s);
|
const char *GetAtomString(int atom);
|
||||||
const char *GetAtomString(AtomTable *atable, int atom);
|
|
||||||
int GetReversedAtom(AtomTable *atable, int atom);
|
|
||||||
char* GetStringOfAtom(AtomTable *atable, int atom);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// From PpMemory.cpp
|
// From PpMemory.cpp
|
||||||
|
@ -122,11 +122,6 @@ int TPpContext::InitScanner(TPpContext *cpp)
|
|||||||
return 1;
|
return 1;
|
||||||
} // InitScanner
|
} // InitScanner
|
||||||
|
|
||||||
int TPpContext::FreeScanner(void)
|
|
||||||
{
|
|
||||||
return (FreeCPP());
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* str_getch()
|
* str_getch()
|
||||||
* takes care of reading from multiple strings.
|
* takes care of reading from multiple strings.
|
||||||
@ -386,7 +381,7 @@ int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * yylvalpp)
|
|||||||
|
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
pp->currentInput->ungetch(pp, pp->currentInput, ch, yylvalpp);
|
||||||
yylvalpp->atom = pp->LookUpAddString(&pp->atomTable, tokenText);
|
yylvalpp->atom = pp->LookUpAddString(tokenText);
|
||||||
|
|
||||||
return CPP_IDENTIFIER;
|
return CPP_IDENTIFIER;
|
||||||
case '0':
|
case '0':
|
||||||
@ -769,7 +764,7 @@ int TPpContext::byte_scan(TPpContext* pp, InputSrc *in, TPpToken * yylvalpp)
|
|||||||
};
|
};
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
if (ch == '"') {
|
if (ch == '"') {
|
||||||
yylvalpp->atom = pp->LookUpAddString(&pp->atomTable, tokenText);
|
yylvalpp->atom = pp->LookUpAddString(tokenText);
|
||||||
return CPP_STRCONSTANT;
|
return CPP_STRCONSTANT;
|
||||||
} else {
|
} else {
|
||||||
pp->parseContext.error(yylvalpp->loc, "end of line in string", "string", "");
|
pp->parseContext.error(yylvalpp->loc, "end of line in string", "string", "");
|
||||||
@ -785,7 +780,7 @@ const char* TPpContext::tokenize(TPpToken* yylvalpp)
|
|||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
|
||||||
char* tokenString = 0;
|
const char* tokenString = 0;
|
||||||
token = currentInput->scan(this, currentInput, yylvalpp);
|
token = currentInput->scan(this, currentInput, yylvalpp);
|
||||||
yylvalpp->ppToken = token;
|
yylvalpp->ppToken = token;
|
||||||
if (check_EOF(token))
|
if (check_EOF(token))
|
||||||
@ -813,12 +808,12 @@ const char* TPpContext::tokenize(TPpToken* yylvalpp)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (token == CPP_IDENTIFIER)
|
if (token == CPP_IDENTIFIER)
|
||||||
tokenString = GetStringOfAtom(&atomTable, yylvalpp->atom);
|
tokenString = GetAtomString(yylvalpp->atom);
|
||||||
else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
|
else if (token == CPP_INTCONSTANT || token == CPP_UINTCONSTANT ||
|
||||||
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
|
token == CPP_FLOATCONSTANT || token == CPP_DOUBLECONSTANT)
|
||||||
tokenString = yylvalpp->name;
|
tokenString = yylvalpp->name;
|
||||||
else
|
else
|
||||||
tokenString = GetStringOfAtom(&atomTable, token);
|
tokenString = GetAtomString(token);
|
||||||
|
|
||||||
if (tokenString) {
|
if (tokenString) {
|
||||||
if (tokenString[0] != 0)
|
if (tokenString[0] != 0)
|
||||||
|
@ -90,237 +90,46 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
|
/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using namespace glslang;
|
|
||||||
|
|
||||||
void unlinkScope(void *_scope, void* scopeList)
|
|
||||||
{
|
|
||||||
TPpContext::Scope *scope = (TPpContext::Scope*)_scope;
|
|
||||||
|
|
||||||
if (scope->next)
|
|
||||||
scope->next->prev = scope->prev;
|
|
||||||
if (scope->prev)
|
|
||||||
scope->prev->next = scope->next;
|
|
||||||
else
|
|
||||||
*(TPpContext::Scope**)scopeList = scope->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end anonymous namespace
|
|
||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* NewScope()
|
* Allocate a new symbol node;
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
TPpContext::Scope* TPpContext::NewScopeInPool(MemoryPool *pool)
|
TPpContext::Symbol* TPpContext::NewSymbol(int atom)
|
||||||
{
|
|
||||||
Scope *lScope;
|
|
||||||
|
|
||||||
lScope = (Scope*)mem_Alloc(pool, sizeof(Scope));
|
|
||||||
lScope->pool = pool;
|
|
||||||
lScope->parent = NULL;
|
|
||||||
lScope->funScope = NULL;
|
|
||||||
lScope->symbols = NULL;
|
|
||||||
|
|
||||||
lScope->level = 0;
|
|
||||||
|
|
||||||
lScope->programs = NULL;
|
|
||||||
if ((lScope->next = ScopeList))
|
|
||||||
ScopeList->prev = lScope;
|
|
||||||
lScope->prev = 0;
|
|
||||||
ScopeList = lScope;
|
|
||||||
mem_AddCleanup(pool, unlinkScope, lScope, &ScopeList);
|
|
||||||
|
|
||||||
return lScope;
|
|
||||||
} // NewScope
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PushScope()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
void TPpContext::PushScope(Scope *fScope)
|
|
||||||
{
|
|
||||||
Scope *lScope;
|
|
||||||
|
|
||||||
if (CurrentScope) {
|
|
||||||
fScope->level = CurrentScope->level + 1;
|
|
||||||
if (fScope->level == 1) {
|
|
||||||
if (!GlobalScope) {
|
|
||||||
/* HACK - CTD -- if GlobalScope==NULL and level==1, we're
|
|
||||||
* defining a function in the superglobal scope. Things
|
|
||||||
* will break if we leave the level as 1, so we arbitrarily
|
|
||||||
* set it to 2 */
|
|
||||||
fScope->level = 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fScope->level >= 2) {
|
|
||||||
lScope = fScope;
|
|
||||||
while (lScope->level > 2)
|
|
||||||
lScope = lScope->next;
|
|
||||||
fScope->funScope = lScope;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fScope->level = 0;
|
|
||||||
}
|
|
||||||
fScope->parent = CurrentScope;
|
|
||||||
CurrentScope = fScope;
|
|
||||||
} // PushScope
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PopScope()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
TPpContext::Scope* TPpContext::PopScope(void)
|
|
||||||
{
|
|
||||||
Scope *lScope;
|
|
||||||
|
|
||||||
lScope = CurrentScope;
|
|
||||||
if (CurrentScope)
|
|
||||||
CurrentScope = CurrentScope->parent;
|
|
||||||
return lScope;
|
|
||||||
} // PopScope
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NewSymbol() - Allocate a new symbol node;
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
TPpContext::Symbol* TPpContext::NewSymbol(TSourceLoc *loc, Scope *fScope, int name, symbolkind kind)
|
|
||||||
{
|
{
|
||||||
Symbol *lSymb;
|
Symbol *lSymb;
|
||||||
char *pch;
|
char *pch;
|
||||||
int ii;
|
int ii;
|
||||||
|
|
||||||
lSymb = (Symbol *) mem_Alloc(fScope->pool, sizeof(Symbol));
|
lSymb = (Symbol *) mem_Alloc(pool, sizeof(Symbol));
|
||||||
lSymb->left = NULL;
|
lSymb->atom = atom;
|
||||||
lSymb->right = NULL;
|
|
||||||
lSymb->next = NULL;
|
|
||||||
lSymb->name = name;
|
|
||||||
lSymb->loc = *loc;
|
|
||||||
lSymb->kind = kind;
|
|
||||||
|
|
||||||
// Clear union area:
|
// Clear macro
|
||||||
|
pch = (char *) &lSymb->mac;
|
||||||
pch = (char *) &lSymb->details;
|
for (ii = 0; ii < sizeof(lSymb->mac); ii++)
|
||||||
for (ii = 0; ii < sizeof(lSymb->details); ii++)
|
|
||||||
*pch++ = 0;
|
*pch++ = 0;
|
||||||
|
|
||||||
return lSymb;
|
return lSymb;
|
||||||
} // NewSymbol
|
}
|
||||||
|
|
||||||
/*
|
TPpContext::Symbol* TPpContext::AddSymbol(int atom)
|
||||||
* lAddToTree() - Using a binary tree is not a good idea for basic atom values because they
|
|
||||||
* are generated in order. We'll fix this later (by reversing the bit pattern).
|
|
||||||
*/
|
|
||||||
|
|
||||||
void TPpContext::lAddToTree(Symbol **fSymbols, Symbol *fSymb, AtomTable *atable)
|
|
||||||
{
|
|
||||||
TPpContext::Symbol *lSymb;
|
|
||||||
int lrev, frev;
|
|
||||||
|
|
||||||
lSymb = *fSymbols;
|
|
||||||
if (lSymb) {
|
|
||||||
frev = GetReversedAtom(atable, fSymb->name);
|
|
||||||
while (lSymb) {
|
|
||||||
lrev = GetReversedAtom(atable, lSymb->name);
|
|
||||||
if (lrev == frev) {
|
|
||||||
printf("GetAtomString(atable, fSymb->name)");
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
if (lrev > frev) {
|
|
||||||
if (lSymb->left) {
|
|
||||||
lSymb = lSymb->left;
|
|
||||||
} else {
|
|
||||||
lSymb->left = fSymb;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (lSymb->right) {
|
|
||||||
lSymb = lSymb->right;
|
|
||||||
} else {
|
|
||||||
lSymb->right = fSymb;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
*fSymbols = fSymb;
|
|
||||||
}
|
|
||||||
} // lAddToTree
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* AddSymbol() - Add a variable, type, or function name to a scope.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
TPpContext::Symbol* TPpContext::AddSymbol(TSourceLoc *loc, Scope *fScope, int atom, symbolkind kind)
|
|
||||||
{
|
{
|
||||||
Symbol *lSymb;
|
Symbol *lSymb;
|
||||||
|
|
||||||
if (!fScope)
|
lSymb = NewSymbol(atom);
|
||||||
fScope = CurrentScope;
|
symbols[lSymb->atom] = lSymb;
|
||||||
lSymb = NewSymbol(loc, fScope, atom, kind);
|
|
||||||
lAddToTree(&fScope->symbols, lSymb, &atomTable);
|
|
||||||
return lSymb;
|
return lSymb;
|
||||||
} // AddSymbol
|
}
|
||||||
|
|
||||||
|
TPpContext::Symbol* TPpContext::LookUpSymbol(int atom)
|
||||||
/*********************************************************************************************/
|
|
||||||
/************************************ Symbol Semantic Functions ******************************/
|
|
||||||
/*********************************************************************************************/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LookUpLocalSymbol()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
TPpContext::Symbol* TPpContext::LookUpLocalSymbol(Scope *fScope, int atom)
|
|
||||||
{
|
{
|
||||||
Symbol *lSymb;
|
TSymbol::iterator it = symbols.find(atom);
|
||||||
int rname, ratom;
|
if (it == symbols.end())
|
||||||
|
return 0;
|
||||||
ratom = GetReversedAtom(&atomTable, atom);
|
else
|
||||||
if (!fScope)
|
return it->second;
|
||||||
fScope = CurrentScope;
|
}
|
||||||
lSymb = fScope->symbols;
|
|
||||||
while (lSymb) {
|
|
||||||
rname = GetReversedAtom(&atomTable, lSymb->name);
|
|
||||||
if (rname == ratom) {
|
|
||||||
return lSymb;
|
|
||||||
} else {
|
|
||||||
if (rname > ratom) {
|
|
||||||
lSymb = lSymb->left;
|
|
||||||
} else {
|
|
||||||
lSymb = lSymb->right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
} // LookUpLocalSymbol
|
|
||||||
|
|
||||||
/*
|
|
||||||
* LookUpSymbol()
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
TPpContext::Symbol* TPpContext::LookUpSymbol(Scope *fScope, int atom)
|
|
||||||
{
|
|
||||||
Symbol *lSymb;
|
|
||||||
|
|
||||||
if (!fScope)
|
|
||||||
fScope = CurrentScope;
|
|
||||||
while (fScope) {
|
|
||||||
lSymb = LookUpLocalSymbol(fScope, atom);
|
|
||||||
if (lSymb)
|
|
||||||
return lSymb;
|
|
||||||
fScope = fScope->parent;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
} // LookUpSymbol
|
|
||||||
|
|
||||||
} // end namespace glslang
|
} // end namespace glslang
|
||||||
|
@ -256,7 +256,7 @@ void TPpContext::RecordToken(TokenStream *pTok, int token, TPpToken * yylvalpp)
|
|||||||
case CPP_IDENTIFIER:
|
case CPP_IDENTIFIER:
|
||||||
case CPP_TYPEIDENTIFIER:
|
case CPP_TYPEIDENTIFIER:
|
||||||
case CPP_STRCONSTANT:
|
case CPP_STRCONSTANT:
|
||||||
s = GetAtomString(&atomTable, yylvalpp->atom);
|
s = GetAtomString(yylvalpp->atom);
|
||||||
while (*s)
|
while (*s)
|
||||||
lAddByte(pTok, (unsigned char) *s++);
|
lAddByte(pTok, (unsigned char) *s++);
|
||||||
lAddByte(pTok, 0);
|
lAddByte(pTok, 0);
|
||||||
@ -331,7 +331,7 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *yylvalpp)
|
|||||||
}
|
}
|
||||||
tokenText[len] = '\0';
|
tokenText[len] = '\0';
|
||||||
assert(ch == '\0');
|
assert(ch == '\0');
|
||||||
yylvalpp->atom = LookUpAddString(&atomTable, tokenText);
|
yylvalpp->atom = LookUpAddString(tokenText);
|
||||||
return CPP_IDENTIFIER;
|
return CPP_IDENTIFIER;
|
||||||
break;
|
break;
|
||||||
case CPP_STRCONSTANT:
|
case CPP_STRCONSTANT:
|
||||||
@ -344,7 +344,7 @@ int TPpContext::ReadToken(TokenStream *pTok, TPpToken *yylvalpp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
tokenText[len] = 0;
|
tokenText[len] = 0;
|
||||||
yylvalpp->atom = LookUpAddString(&atomTable, tokenText);
|
yylvalpp->atom = LookUpAddString(tokenText);
|
||||||
break;
|
break;
|
||||||
case CPP_FLOATCONSTANT:
|
case CPP_FLOATCONSTANT:
|
||||||
case CPP_DOUBLECONSTANT:
|
case CPP_DOUBLECONSTANT:
|
||||||
@ -465,10 +465,10 @@ void TPpContext::DumpTokenStream(FILE *fp, TokenStream *s, TPpToken * yylvalpp)
|
|||||||
switch (token) {
|
switch (token) {
|
||||||
case CPP_IDENTIFIER:
|
case CPP_IDENTIFIER:
|
||||||
case CPP_TYPEIDENTIFIER:
|
case CPP_TYPEIDENTIFIER:
|
||||||
printf("%s ", GetAtomString(&atomTable, yylvalpp->atom));
|
printf("%s ", GetAtomString(yylvalpp->atom));
|
||||||
break;
|
break;
|
||||||
case CPP_STRCONSTANT:
|
case CPP_STRCONSTANT:
|
||||||
printf("\"%s\"", GetAtomString(&atomTable, yylvalpp->atom));
|
printf("\"%s\"", GetAtomString(yylvalpp->atom));
|
||||||
break;
|
break;
|
||||||
case CPP_FLOATCONSTANT:
|
case CPP_FLOATCONSTANT:
|
||||||
case CPP_DOUBLECONSTANT:
|
case CPP_DOUBLECONSTANT:
|
||||||
@ -480,7 +480,7 @@ void TPpContext::DumpTokenStream(FILE *fp, TokenStream *s, TPpToken * yylvalpp)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (token >= 127)
|
if (token >= 127)
|
||||||
printf("%s ", GetAtomString(&atomTable, token));
|
printf("%s ", GetAtomString(token));
|
||||||
else
|
else
|
||||||
printf("%c", token);
|
printf("%c", token);
|
||||||
break;
|
break;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user