Merge pull request #648 from steve-lunarg/type-identifiers
HLSL: allow type keywords as identifiers, and add half type
This commit is contained in:
@@ -85,21 +85,36 @@ bool HlslGrammar::acceptIdentifier(HlslToken& idToken)
|
||||
return true;
|
||||
}
|
||||
|
||||
// Even though "sample" is a keyword (for interpolation modifiers), it IS still accepted as
|
||||
// an identifier. This appears to be a solitary exception: other interp modifier keywords such
|
||||
// as "linear" or "centroid" NOT valid identifiers. This code special cases "sample",
|
||||
// so e.g, "int sample;" is accepted.
|
||||
if (peekTokenClass(EHTokSample)) {
|
||||
token.string = NewPoolTString("sample");
|
||||
token.tokenClass = EHTokIdentifier;
|
||||
token.symbol = nullptr;
|
||||
|
||||
idToken = token;
|
||||
advanceToken();
|
||||
return true;
|
||||
// Even though "sample", "bool", "float", etc keywords (for types, interpolation modifiers),
|
||||
// they ARE still accepted as identifiers. This is not a dense space: e.g, "void" is not a
|
||||
// valid identifier, nor is "linear". This code special cases the known instances of this, so
|
||||
// e.g, "int sample;" or "float float;" is accepted. Other cases can be added here if needed.
|
||||
|
||||
TString* idString = nullptr;
|
||||
switch (peek()) {
|
||||
case EHTokSample: idString = NewPoolTString("sample"); break;
|
||||
case EHTokHalf: idString = NewPoolTString("half"); break;
|
||||
case EHTokBool: idString = NewPoolTString("bool"); break;
|
||||
case EHTokFloat: idString = NewPoolTString("float"); break;
|
||||
case EHTokDouble: idString = NewPoolTString("double"); break;
|
||||
case EHTokInt: idString = NewPoolTString("int"); break;
|
||||
case EHTokUint: idString = NewPoolTString("uint"); break;
|
||||
case EHTokMin16float: idString = NewPoolTString("min16float"); break;
|
||||
case EHTokMin10float: idString = NewPoolTString("min10float"); break;
|
||||
case EHTokMin16int: idString = NewPoolTString("min16int"); break;
|
||||
case EHTokMin12int: idString = NewPoolTString("min12int"); break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
token.string = idString;
|
||||
token.tokenClass = EHTokIdentifier;
|
||||
token.symbol = nullptr;
|
||||
idToken = token;
|
||||
|
||||
advanceToken();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// compilationUnit
|
||||
@@ -418,7 +433,15 @@ bool HlslGrammar::acceptDeclaration(TIntermNode*& node)
|
||||
|
||||
// SEMICOLON
|
||||
if (! acceptTokenClass(EHTokSemicolon)) {
|
||||
expected(";");
|
||||
// This may have been a false detection of what appeared to be a declaration, but
|
||||
// was actually an assignment such as "float = 4", where "float" is an identifier.
|
||||
// We put the token back to let further parsing happen for cases where that may
|
||||
// happen. This errors on the side of caution, and mostly triggers the error.
|
||||
|
||||
if (peek() == EHTokAssign || peek() == EHTokLeftBracket || peek() == EHTokDot || peek() == EHTokComma)
|
||||
recedeToken();
|
||||
else
|
||||
expected(";");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1086,6 +1109,7 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
// changes, e.g, to use native halfs.
|
||||
static const TBasicType min16float_bt = EbtFloat;
|
||||
static const TBasicType min10float_bt = EbtFloat;
|
||||
static const TBasicType half_bt = EbtFloat;
|
||||
static const TBasicType min16int_bt = EbtInt;
|
||||
static const TBasicType min12int_bt = EbtInt;
|
||||
static const TBasicType min16uint_bt = EbtUint;
|
||||
@@ -1255,6 +1279,23 @@ bool HlslGrammar::acceptType(TType& type)
|
||||
new(&type) TType(EbtBool, EvqTemporary, 4);
|
||||
break;
|
||||
|
||||
case EHTokHalf:
|
||||
new(&type) TType(half_bt, EvqTemporary, EpqMedium);
|
||||
break;
|
||||
case EHTokHalf1:
|
||||
new(&type) TType(half_bt, EvqTemporary, EpqMedium);
|
||||
type.makeVector();
|
||||
break;
|
||||
case EHTokHalf2:
|
||||
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 2);
|
||||
break;
|
||||
case EHTokHalf3:
|
||||
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 3);
|
||||
break;
|
||||
case EHTokHalf4:
|
||||
new(&type) TType(half_bt, EvqTemporary, EpqMedium, 4);
|
||||
break;
|
||||
|
||||
case EHTokMin16float:
|
||||
new(&type) TType(min16float_bt, EvqTemporary, EpqMedium);
|
||||
break;
|
||||
@@ -1683,6 +1724,7 @@ bool HlslGrammar::acceptStruct(TType& type)
|
||||
bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
|
||||
{
|
||||
typeList = new TTypeList();
|
||||
HlslToken idToken;
|
||||
|
||||
do {
|
||||
// success on seeing the RIGHT_BRACE coming up
|
||||
@@ -1700,8 +1742,7 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
|
||||
|
||||
// struct_declarator COMMA struct_declarator ...
|
||||
do {
|
||||
// peek IDENTIFIER
|
||||
if (! peekTokenClass(EHTokIdentifier)) {
|
||||
if (! acceptIdentifier(idToken)) {
|
||||
expected("member name");
|
||||
return false;
|
||||
}
|
||||
@@ -1709,12 +1750,9 @@ bool HlslGrammar::acceptStructDeclarationList(TTypeList*& typeList)
|
||||
// add it to the list of members
|
||||
TTypeLoc member = { new TType(EbtVoid), token.loc };
|
||||
member.type->shallowCopy(memberType);
|
||||
member.type->setFieldName(*token.string);
|
||||
member.type->setFieldName(*idToken.string);
|
||||
typeList->push_back(member);
|
||||
|
||||
// accept IDENTIFIER
|
||||
advanceToken();
|
||||
|
||||
// array_specifier
|
||||
TArraySizes* arraySizes = nullptr;
|
||||
acceptArraySpecifier(arraySizes);
|
||||
@@ -2378,7 +2416,9 @@ bool HlslGrammar::acceptConstructor(TIntermTyped*& node)
|
||||
// arguments
|
||||
TIntermTyped* arguments = nullptr;
|
||||
if (! acceptArguments(constructorFunction, arguments)) {
|
||||
expected("constructor arguments");
|
||||
// It's possible this is a type keyword used as an identifier. Put the token back
|
||||
// for later use.
|
||||
recedeToken();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user