Commit e320a185 by John Kessenich

Remove the pack/unpack languages and bring grammar up from 1.1 to 4.2 and fix…

Remove the pack/unpack languages and bring grammar up from 1.1 to 4.2 and fix the affected 1.1 productions and semantics to still work correctly for 1.1 shaders. For 4.2, largely, it is only the grammar that is working. Productions and semantics are mostly missing. Lexical analysis is mostly done, but not in the preprocessor, which still can't handle uint and double literals. The grammar and token names are reorganized to match the specification, to allow easier comparison between the specification and the working grammar. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@19946 e7fa87d3-cd2b-0410-9028-fcbf551c1848
parent 200b2734
...@@ -212,8 +212,6 @@ int C_DECL main(int argc, char* argv[]) ...@@ -212,8 +212,6 @@ int C_DECL main(int argc, char* argv[])
// //
// .frag* = fragment programs // .frag* = fragment programs
// .vert* = vertex programs // .vert* = vertex programs
// .pack* = pack programs
// .unpa* = unpack pragrams
// //
static EShLanguage FindLanguage(char *name) static EShLanguage FindLanguage(char *name)
{ {
...@@ -228,8 +226,6 @@ static EShLanguage FindLanguage(char *name) ...@@ -228,8 +226,6 @@ static EShLanguage FindLanguage(char *name)
if (ext = strrchr(name, '.')) { if (ext = strrchr(name, '.')) {
if (strncmp(ext, ".frag", 4) == 0) return EShLangFragment; if (strncmp(ext, ".frag", 4) == 0) return EShLangFragment;
if (strncmp(ext, ".vert", 4) == 0) return EShLangVertex; if (strncmp(ext, ".vert", 4) == 0) return EShLangVertex;
if (strncmp(ext, ".pack", 4) == 0) return EShLangPack;
if (strncmp(ext, ".unpa", 4) == 0) return EShLangUnpack;
} }
return EShLangFragment; return EShLangFragment;
......
...@@ -77,10 +77,6 @@ enum TQualifier { ...@@ -77,10 +77,6 @@ enum TQualifier {
EvqVaryingOut, // vertex shaders only read/write EvqVaryingOut, // vertex shaders only read/write
EvqUniform, // Readonly, vertex and fragment EvqUniform, // Readonly, vertex and fragment
// pack/unpack input and output
EvqInput,
EvqOutput,
// parameters // parameters
EvqIn, EvqIn,
EvqOut, EvqOut,
...@@ -113,16 +109,14 @@ __inline const char* getQualifierString(TQualifier q) ...@@ -113,16 +109,14 @@ __inline const char* getQualifierString(TQualifier q)
case EvqTemporary: return "Temporary"; break; case EvqTemporary: return "Temporary"; break;
case EvqGlobal: return "Global"; break; case EvqGlobal: return "Global"; break;
case EvqConst: return "const"; break; case EvqConst: return "const"; break;
case EvqConstReadOnly: return "const"; break; case EvqConstReadOnly: return "const (read only)"; break;
case EvqAttribute: return "attribute"; break; case EvqAttribute: return "attribute"; break;
case EvqVaryingIn: return "varying"; break; case EvqVaryingIn: return "varying in"; break;
case EvqVaryingOut: return "varying"; break; case EvqVaryingOut: return "varying out"; break;
case EvqUniform: return "uniform"; break; case EvqUniform: return "uniform"; break;
case EvqIn: return "in"; break; case EvqIn: return "in"; break;
case EvqOut: return "out"; break; case EvqOut: return "out"; break;
case EvqInOut: return "inout"; break; case EvqInOut: return "inout"; break;
case EvqInput: return "input"; break;
case EvqOutput: return "output"; break;
case EvqPosition: return "Position"; break; case EvqPosition: return "Position"; break;
case EvqPointSize: return "PointSize"; break; case EvqPointSize: return "PointSize"; break;
case EvqClipVertex: return "ClipVertex"; break; case EvqClipVertex: return "ClipVertex"; break;
......
...@@ -118,6 +118,8 @@ enum TOperator { ...@@ -118,6 +118,8 @@ enum TOperator {
EOpVectorSwizzle, EOpVectorSwizzle,
EOpMethod,
// //
// Built-in functions potentially mapped to operators // Built-in functions potentially mapped to operators
// //
...@@ -169,16 +171,6 @@ enum TOperator { ...@@ -169,16 +171,6 @@ enum TOperator {
EOpAny, EOpAny,
EOpAll, EOpAll,
EOpItof, // pack/unpack only
EOpFtoi, // pack/unpack only
EOpSkipPixels, // pack/unpack only
EOpReadInput, // unpack only
EOpWritePixel, // unpack only
EOpBitmapLsb, // unpack only
EOpBitmapMsb, // unpack only
EOpWriteOutput, // pack only
EOpReadPixel, // pack only
// //
// Branch // Branch
// //
...@@ -242,6 +234,7 @@ class TIntermBinary; ...@@ -242,6 +234,7 @@ class TIntermBinary;
class TIntermConstantUnion; class TIntermConstantUnion;
class TIntermSelection; class TIntermSelection;
class TIntermTyped; class TIntermTyped;
class TIntermMethod;
class TIntermSymbol; class TIntermSymbol;
class TInfoSink; class TInfoSink;
...@@ -261,6 +254,7 @@ public: ...@@ -261,6 +254,7 @@ public:
virtual TIntermAggregate* getAsAggregate() { return 0; } virtual TIntermAggregate* getAsAggregate() { return 0; }
virtual TIntermBinary* getAsBinaryNode() { return 0; } virtual TIntermBinary* getAsBinaryNode() { return 0; }
virtual TIntermSelection* getAsSelectionNode() { return 0; } virtual TIntermSelection* getAsSelectionNode() { return 0; }
virtual TIntermMethod* getAsMethodNode() { return 0; }
virtual TIntermSymbol* getAsSymbolNode() { return 0; } virtual TIntermSymbol* getAsSymbolNode() { return 0; }
virtual ~TIntermNode() { } virtual ~TIntermNode() { }
protected: protected:
...@@ -343,6 +337,23 @@ protected: ...@@ -343,6 +337,23 @@ protected:
}; };
// //
// Represent method names before seeing their calling signature
// or resolving them to operations. Just an expression as the base object
// and a textural name.
//
class TIntermMethod : public TIntermTyped {
public:
TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
virtual TIntermMethod* getAsMethodNode() { return this; }
virtual const TString& getMethodName() const { return method; }
virtual TIntermTyped* getObject() const { return object; }
virtual void traverse(TIntermTraverser*);
protected:
TIntermTyped* object;
TString method;
};
//
// Nodes that correspond to symbols or constants in the source code. // Nodes that correspond to symbols or constants in the source code.
// //
class TIntermSymbol : public TIntermTyped { class TIntermSymbol : public TIntermTyped {
......
...@@ -918,18 +918,6 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable) ...@@ -918,18 +918,6 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable)
break; break;
case EShLangPack:
case EShLangUnpack:
symbolTable.relateToOperator("itof", EOpItof);
symbolTable.relateToOperator("ftoi", EOpFtoi);
symbolTable.relateToOperator("skipPixels", EOpSkipPixels);
symbolTable.relateToOperator("readInput", EOpReadInput);
symbolTable.relateToOperator("writePixel", EOpWritePixel);
symbolTable.relateToOperator("bitmapLSB", EOpBitmapLsb);
symbolTable.relateToOperator("bitmapMSB", EOpBitmapMsb);
symbolTable.relateToOperator("writeOutput", EOpWriteOutput);
symbolTable.relateToOperator("readPixel", EOpReadPixel);
break;
default: assert(false && "Language not supported"); default: assert(false && "Language not supported");
} }
} }
......
...@@ -51,6 +51,12 @@ ...@@ -51,6 +51,12 @@
// //
// Traversal functions for terminals are straighforward.... // Traversal functions for terminals are straighforward....
// //
void TIntermMethod::traverse(TIntermTraverser* it)
{
// TODO: current tree should always resolve all methods as constants
// 4.3 will leave some length methods as methods
}
void TIntermSymbol::traverse(TIntermTraverser* it) void TIntermSymbol::traverse(TIntermTraverser* it)
{ {
if (it->visitSymbol) if (it->visitSymbol)
......
...@@ -554,6 +554,14 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T ...@@ -554,6 +554,14 @@ TIntermTyped* TIntermediate::addComma(TIntermTyped* left, TIntermTyped* right, T
} }
} }
TIntermTyped* TIntermediate::addMethod(TIntermTyped* object, TType& type, const TString* name, TSourceLoc line)
{
TIntermMethod* method = new TIntermMethod(object, type, *name);
method->setLine(line);
return method;
}
// //
// For "?:" test nodes. There are three children; a condition, // For "?:" test nodes. There are three children; a condition,
// a true path, and a false path. The two paths are specified // a true path, and a false path. The two paths are specified
......
...@@ -252,6 +252,30 @@ void TParseContext::binaryOpError(int line, char* op, TString left, TString righ ...@@ -252,6 +252,30 @@ void TParseContext::binaryOpError(int line, char* op, TString left, TString righ
} }
// //
// A basic type of EbtVoid is a key that the name string was seen in the source, but
// it was not found as a variable in the symbol table. If so, give the error
// message and insert a dummy variable in the symbol table to prevent future errors.
//
void TParseContext::variableErrorCheck(TIntermTyped*& nodePtr)
{
TIntermSymbol* symbol = nodePtr->getAsSymbolNode();
if (symbol && symbol->getType().getBasicType() == EbtVoid) {
error(symbol->getLine(), "undeclared identifier", symbol->getSymbol().c_str(), "");
recover();
// Add to symbol table to prevent future error messages on the same name
TVariable* fakeVariable = new TVariable(&symbol->getSymbol(), TType(EbtFloat));
symbolTable.insert(*fakeVariable);
// substitute a symbol node for this new variable
nodePtr = intermediate.addSymbol(fakeVariable->getUniqueId(),
fakeVariable->getName(),
fakeVariable->getType(), symbol->getLine());
}
}
//
// Both test and if necessary, spit out an error, to see if the node is really // Both test and if necessary, spit out an error, to see if the node is really
// an l-value that can be operated on this way. // an l-value that can be operated on this way.
// //
...@@ -311,7 +335,6 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node) ...@@ -311,7 +335,6 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node)
case EvqAttribute: message = "can't modify an attribute"; break; case EvqAttribute: message = "can't modify an attribute"; break;
case EvqUniform: message = "can't modify a uniform"; break; case EvqUniform: message = "can't modify a uniform"; break;
case EvqVaryingIn: message = "can't modify a varying"; break; case EvqVaryingIn: message = "can't modify a varying"; break;
case EvqInput: message = "can't modify an input"; break;
case EvqFace: message = "can't modify gl_FrontFace"; break; case EvqFace: message = "can't modify gl_FrontFace"; break;
case EvqFragCoord: message = "can't modify gl_FragCoord"; break; case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
default: default:
...@@ -596,6 +619,24 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const ...@@ -596,6 +619,24 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
return false; return false;
} }
bool TParseContext::globalQualifierFixAndErrorCheck(int line, TQualifier& qualifier)
{
switch (qualifier) {
case EvqIn:
qualifier = EvqVaryingIn;
return false;
case EvqOut:
qualifier = EvqVaryingOut;
return false;
case EvqInOut:
qualifier = EvqVaryingIn;
error(line, "cannot use both 'in' and 'out' at global scope", "", "");
return true;
}
return false;
}
bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType) bool TParseContext::structQualifierErrorCheck(int line, const TPublicType& pType)
{ {
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) && if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
...@@ -885,23 +926,26 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType ...@@ -885,23 +926,26 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
return false; return false;
} }
bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type) bool TParseContext::paramErrorCheck(int line, TQualifier qualifier, TType* type)
{ {
if (qualifier != EvqConst && qualifier != EvqTemporary) { switch (qualifier) {
case EvqConst:
case EvqConstReadOnly:
type->changeQualifier(EvqConstReadOnly);
return false;
case EvqIn:
case EvqOut:
case EvqInOut:
type->changeQualifier(qualifier);
return false;
case EvqTemporary:
type->changeQualifier(EvqIn);
return false;
default:
type->changeQualifier(EvqIn);
error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), ""); error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier), "");
return true; return true;
} }
if (qualifier == EvqConst && paramQualifier != EvqIn) {
error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
return true;
}
if (qualifier == EvqConst)
type->changeQualifier(EvqConstReadOnly);
else
type->changeQualifier(paramQualifier);
return false;
} }
bool TParseContext::extensionErrorCheck(int line, const char* extension) bool TParseContext::extensionErrorCheck(int line, const char* extension)
......
...@@ -67,16 +67,18 @@ struct TParseContext { ...@@ -67,16 +67,18 @@ struct TParseContext {
TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) : TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) :
intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0), intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0), recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
switchNestingLevel(0),
inTypeParen(false), contextPragma(true, false) { } inTypeParen(false), contextPragma(true, false) { }
TIntermediate& intermediate; // to hold and build a parse tree TIntermediate& intermediate; // to hold and build a parse tree
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
TInfoSink& infoSink; TInfoSink& infoSink;
EShLanguage language; // vertex or fragment language (future: pack or unpack) EShLanguage language; // vertex or fragment language
TIntermNode* treeRoot; // root of parse tree being created TIntermNode* treeRoot; // root of parse tree being created
bool recoveredFromError; // true if a parse error has occurred, but we continue to parse bool recoveredFromError; // true if a parse error has occurred, but we continue to parse
int numErrors; int numErrors;
bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier bool lexAfterType; // true if we've recognized a type, so can only be looking for an identifier
int loopNestingLevel; // 0 if outside all loops int loopNestingLevel; // 0 if outside all loops
int switchNestingLevel; // 0 if outside all switch statements
bool inTypeParen; // true if in parentheses, looking only for an identifier bool inTypeParen; // true if in parentheses, looking only for an identifier
const TType* currentFunctionType; // the return type of the function that's currently being parsed const TType* currentFunctionType; // the return type of the function that's currently being parsed
bool functionReturnsValue; // true if a non-void function has a return bool functionReturnsValue; // true if a non-void function has a return
...@@ -93,6 +95,7 @@ struct TParseContext { ...@@ -93,6 +95,7 @@ struct TParseContext {
void assignError(int line, const char* op, TString left, TString right); void assignError(int line, const char* op, TString left, TString right);
void unaryOpError(int line, char* op, TString operand); void unaryOpError(int line, char* op, TString operand);
void binaryOpError(int line, char* op, TString left, TString right); void binaryOpError(int line, char* op, TString left, TString right);
void variableErrorCheck(TIntermTyped*& nodePtr);
bool lValueErrorCheck(int line, char* op, TIntermTyped*); bool lValueErrorCheck(int line, char* op, TIntermTyped*);
bool constErrorCheck(TIntermTyped* node); bool constErrorCheck(TIntermTyped* node);
bool integerErrorCheck(TIntermTyped* node, char* token); bool integerErrorCheck(TIntermTyped* node, char* token);
...@@ -107,12 +110,13 @@ struct TParseContext { ...@@ -107,12 +110,13 @@ struct TParseContext {
bool boolErrorCheck(int, const TIntermTyped*); bool boolErrorCheck(int, const TIntermTyped*);
bool boolErrorCheck(int, const TPublicType&); bool boolErrorCheck(int, const TPublicType&);
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason); bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
bool structQualifierErrorCheck(int line, const TPublicType& pType); bool structQualifierErrorCheck(int line, const TPublicType& pType);
bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type); bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
bool containsSampler(TType& type); bool containsSampler(TType& type);
bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type); bool nonInitConstErrorCheck(int line, TString& identifier, TPublicType& type);
bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type); bool nonInitErrorCheck(int line, TString& identifier, TPublicType& type);
bool paramErrorCheck(int line, TQualifier qualifier, TQualifier paramQualifier, TType* type); bool paramErrorCheck(int line, TQualifier qualifier, TType* type);
bool extensionErrorCheck(int line, const char*); bool extensionErrorCheck(int line, const char*);
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0); const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType, bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
......
...@@ -53,6 +53,10 @@ L [a-zA-Z_] ...@@ -53,6 +53,10 @@ L [a-zA-Z_]
H [a-fA-F0-9] H [a-fA-F0-9]
E [Ee][+-]?{D}+ E [Ee][+-]?{D}+
O [0-7] O [0-7]
U [uU]
/* TODO: double literals, which will likely require pre-processor rework */
/* TODO: unsigned int literals, which will likely require pre-processor rework */
%option nounput %option nounput
%{ %{
...@@ -92,36 +96,85 @@ TSourceLoc yylineno; ...@@ -92,36 +96,85 @@ TSourceLoc yylineno;
<*>"//"[^\n]*"\n" { /* ?? carriage and/or line-feed? */ }; <*>"//"[^\n]*"\n" { /* ?? carriage and/or line-feed? */ };
"attribute" { pyylval->lex.line = yylineno; return(ATTRIBUTE); } "attribute" { pyylval->lex.line = yylineno; return(ATTRIBUTE); }
"const" { pyylval->lex.line = yylineno; return(CONST_QUAL); } "const" { pyylval->lex.line = yylineno; return(CONST); }
"patch" { pyylval->lex.line = yylineno; return(PATCH); }
"sample" { pyylval->lex.line = yylineno; return(SAMPLE); }
"uniform" { pyylval->lex.line = yylineno; return(UNIFORM); } "uniform" { pyylval->lex.line = yylineno; return(UNIFORM); }
"coherent" { pyylval->lex.line = yylineno; return(COHERENT); }
"volatile" { pyylval->lex.line = yylineno; return(VOLATILE); }
"restrict" { pyylval->lex.line = yylineno; return(RESTRICT); }
"readonly" { pyylval->lex.line = yylineno; return(READONLY); }
"writeonly" { pyylval->lex.line = yylineno; return(WRITEONLY); }
"varying" { pyylval->lex.line = yylineno; return(VARYING); } "varying" { pyylval->lex.line = yylineno; return(VARYING); }
"layout" { pyylval->lex.line = yylineno; return(LAYOUT); }
"break" { pyylval->lex.line = yylineno; return(BREAK); } "break" { pyylval->lex.line = yylineno; return(BREAK); }
"continue" { pyylval->lex.line = yylineno; return(CONTINUE); } "continue" { pyylval->lex.line = yylineno; return(CONTINUE); }
"do" { pyylval->lex.line = yylineno; return(DO); } "do" { pyylval->lex.line = yylineno; return(DO); }
"for" { pyylval->lex.line = yylineno; return(FOR); } "for" { pyylval->lex.line = yylineno; return(FOR); }
"while" { pyylval->lex.line = yylineno; return(WHILE); } "while" { pyylval->lex.line = yylineno; return(WHILE); }
"switch" { pyylval->lex.line = yylineno; return(SWITCH); }
"case" { pyylval->lex.line = yylineno; return(CASE); }
"default" { pyylval->lex.line = yylineno; return(DEFAULT); }
"if" { pyylval->lex.line = yylineno; return(IF); } "if" { pyylval->lex.line = yylineno; return(IF); }
"else" { pyylval->lex.line = yylineno; return(ELSE); } "else" { pyylval->lex.line = yylineno; return(ELSE); }
"in" { pyylval->lex.line = yylineno; return(IN_QUAL); } "in" { pyylval->lex.line = yylineno; return(IN); }
"out" { pyylval->lex.line = yylineno; return(OUT_QUAL); } "out" { pyylval->lex.line = yylineno; return(OUT); }
"inout" { pyylval->lex.line = yylineno; return(INOUT_QUAL); } "inout" { pyylval->lex.line = yylineno; return(INOUT); }
"centroid" { pyylval->lex.line = yylineno; return(CENTROID); }
"float" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); } "noperspective" { pyylval->lex.line = yylineno; return(NOPERSPECTIVE); }
"int" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); } "flat" { pyylval->lex.line = yylineno; return(FLAT); }
"void" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); } "smooth" { pyylval->lex.line = yylineno; return(SMOOTH); }
"bool" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
"precise" { pyylval->lex.line = yylineno; return(PRECISE); }
"invariant" { pyylval->lex.line = yylineno; return(INVARIANT); }
"precision" { pyylval->lex.line = yylineno; return(PRECISION); }
"highp" { pyylval->lex.line = yylineno; return(HIGH_PRECISION); }
"mediump" { pyylval->lex.line = yylineno; return(MEDIUM_PRECISION); }
"lowp" { pyylval->lex.line = yylineno; return(LOW_PRECISION); }
"float" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT); }
"double" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DOUBLE); }
"int" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT); }
"uint" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UINT); }
"void" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID); }
"bool" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL); }
"true" { pyylval->lex.line = yylineno; pyylval->lex.b = true; return(BOOLCONSTANT); } "true" { pyylval->lex.line = yylineno; pyylval->lex.b = true; return(BOOLCONSTANT); }
"false" { pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); } "false" { pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
"discard" { pyylval->lex.line = yylineno; return(DISCARD); } "discard" { pyylval->lex.line = yylineno; return(DISCARD); }
"return" { pyylval->lex.line = yylineno; return(RETURN); } "return" { pyylval->lex.line = yylineno; return(RETURN); }
"subroutine" { pyylval->lex.line = yylineno; return(SUBROUTINE); }
"mat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
"mat3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); } "mat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT2); }
"mat4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); } "mat3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT3); }
"mat4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT4); }
"mat2x2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT2X2); }
"mat2x3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT2X3); }
"mat2x4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT2X4); }
"mat3x2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT3X2); }
"mat3x3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT3X3); }
"mat3x4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT3X4); }
"mat4x2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT4X2); }
"mat4x3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT4X3); }
"mat4x4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT4X4); }
"dmat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT2); }
"dmat3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT3); }
"dmat4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT4); }
"dmat2x2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT2X2); }
"dmat2x3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT2X3); }
"dmat2x4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT2X4); }
"dmat3x2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT3X2); }
"dmat3x3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT3X3); }
"dmat3x4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT3X4); }
"dmat4x2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT4X2); }
"dmat4x3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT4X3); }
"dmat4x4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(DMAT4X4); }
"atomic_uint" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(ATOMIC_UINT); }
"vec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); } "vec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); }
"vec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); } "vec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
...@@ -129,6 +182,9 @@ TSourceLoc yylineno; ...@@ -129,6 +182,9 @@ TSourceLoc yylineno;
"ivec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); } "ivec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
"ivec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); } "ivec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
"ivec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); } "ivec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC4); }
"uvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (UVEC2); }
"uvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (UVEC3); }
"uvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (UVEC4); }
"bvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); } "bvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC2); }
"bvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); } "bvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
"bvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); } "bvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
...@@ -140,8 +196,71 @@ TSourceLoc yylineno; ...@@ -140,8 +196,71 @@ TSourceLoc yylineno;
"sampler1DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DSHADOW; } "sampler1DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DSHADOW; }
"sampler2DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DSHADOW; } "sampler2DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DSHADOW; }
"sampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERRECTARB; /* ARB_texture_rectangle */ } "sampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DRECT; }
"sampler2DRectShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERRECTSHADOWARB; /* ARB_texture_rectangle */ } "isampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER2DRECT; }
"usampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER2DRECT; }
"sampler2DRectShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DRECTSHADOW; }
"samplerCubeShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBESHADOW; }
"sampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DARRAY; }
"sampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DARRAY; }
"sampler1DArrayShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DARRAYSHADOW; }
"sampler2DArrayShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DARRAYSHADOW; }
"isampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER1D; }
"isampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER2D; }
"isampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER3D; }
"isamplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLERCUBE; }
"isampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER1DARRAY; }
"isampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return ISAMPLER2DARRAY; }
"usampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER1D; }
"usampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER2D; }
"usampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER3D; }
"usamplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLERCUBE; }
"usampler1DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER1DARRAY; }
"usampler2DArray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return USAMPLER2DARRAY; }
"samplerBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(SAMPLERBUFFER); }
"isamplerBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(ISAMPLERBUFFER); }
"usamplerBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(USAMPLERBUFFER); }
"sampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(SAMPLER2DMS); }
"isampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(ISAMPLER2DMS); }
"usampler2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(USAMPLER2DMS); }
"sampler2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(SAMPLER2DMSARRAY); }
"isampler2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(ISAMPLER2DMSARRAY); }
"usampler2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(USAMPLER2DMSARRAY); }
"image1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE1D); }
"iimage1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE1D); }
"uimage1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE1D); }
"image2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2D); }
"iimage2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2D); }
"uimage2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2D); }
"image3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE3D); }
"iimage3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE3D); }
"uimage3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE3D); }
"image2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DRECT); }
"iimage2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DRECT); }
"uimage2Drect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DRECT); }
"imageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGECUBE); }
"iimageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGECUBE); }
"uimageCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGECUBE); }
"imageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGEBUFFER); }
"iimageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGEBUFFER); }
"uimageBuffer" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGEBUFFER); }
"image1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE1DARRAY); }
"iimage1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE1DARRAY); }
"uimage1Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE1DARRAY); }
"image2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DARRAY); }
"iimage2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DARRAY); }
"uimage2Darray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DARRAY); }
"imageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGECUBEARRAY); }
"iimageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGECUBEARRAY); }
"uimageCubearray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGECUBEARRAY); }
"image2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DMS); }
"iimage2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DMS); }
"uimage2DMS" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DMS); }
"image2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IMAGE2DMSARRAY); }
"iimage2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(IIMAGE2DMSARRAY); }
"uimage2DMSarray" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(UIMAGE2DMSARRAY); }
"struct" { pyylval->lex.line = yylineno; return(STRUCT); } "struct" { pyylval->lex.line = yylineno; return(STRUCT); }
...@@ -156,12 +275,9 @@ TSourceLoc yylineno; ...@@ -156,12 +275,9 @@ TSourceLoc yylineno;
"packed" { PaReservedWord(); return 0; } "packed" { PaReservedWord(); return 0; }
"goto" { PaReservedWord(); return 0; } "goto" { PaReservedWord(); return 0; }
"switch" { PaReservedWord(); return 0; }
"default" { PaReservedWord(); return 0; }
"inline" { PaReservedWord(); return 0; } "inline" { PaReservedWord(); return 0; }
"noinline" { PaReservedWord(); return 0; } "noinline" { PaReservedWord(); return 0; }
"volatile" { PaReservedWord(); return 0; }
"public" { PaReservedWord(); return 0; } "public" { PaReservedWord(); return 0; }
"static" { PaReservedWord(); return 0; } "static" { PaReservedWord(); return 0; }
"extern" { PaReservedWord(); return 0; } "extern" { PaReservedWord(); return 0; }
...@@ -170,7 +286,6 @@ TSourceLoc yylineno; ...@@ -170,7 +286,6 @@ TSourceLoc yylineno;
"long" { PaReservedWord(); return 0; } "long" { PaReservedWord(); return 0; }
"short" { PaReservedWord(); return 0; } "short" { PaReservedWord(); return 0; }
"double" { PaReservedWord(); return 0; }
"half" { PaReservedWord(); return 0; } "half" { PaReservedWord(); return 0; }
"fixed" { PaReservedWord(); return 0; } "fixed" { PaReservedWord(); return 0; }
"unsigned" { PaReservedWord(); return 0; } "unsigned" { PaReservedWord(); return 0; }
...@@ -207,6 +322,11 @@ TSourceLoc yylineno; ...@@ -207,6 +322,11 @@ TSourceLoc yylineno;
0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;} 0{D}+ { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
{D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } {D}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); }
0[xX]{H}+{U} { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(UINTCONSTANT); }
0{O}+{U} { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(UINTCONSTANT); }
0{D}+{U} { pyylval->lex.line = yylineno; parseContext.error(yylineno, "Invalid Octal number.", yytext, "", ""); parseContext.recover(); return 0;}
{D}+{U} { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(UINTCONSTANT); }
{D}+{E} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); } {D}+{E} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
{D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); } {D}+"."{D}*({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
"."{D}+({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); } "."{D}+({E})? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); }
......
...@@ -70,14 +70,6 @@ Jutta Degener, 1995 ...@@ -70,14 +70,6 @@ Jutta Degener, 1995
extern void yyerror(char*); extern void yyerror(char*);
#endif #endif
#define FRAG_VERT_ONLY(S, L) { \
if (parseContext.language != EShLangFragment && \
parseContext.language != EShLangVertex) { \
parseContext.error(L, " supported in vertex/fragment shaders only ", S, "", ""); \
parseContext.recover(); \
} \
}
#define VERTEX_ONLY(S, L) { \ #define VERTEX_ONLY(S, L) { \
if (parseContext.language != EShLangVertex) { \ if (parseContext.language != EShLangVertex) { \
parseContext.error(L, " supported in vertex shaders only ", S, "", ""); \ parseContext.error(L, " supported in vertex shaders only ", S, "", ""); \
...@@ -87,32 +79,11 @@ Jutta Degener, 1995 ...@@ -87,32 +79,11 @@ Jutta Degener, 1995
#define FRAG_ONLY(S, L) { \ #define FRAG_ONLY(S, L) { \
if (parseContext.language != EShLangFragment) { \ if (parseContext.language != EShLangFragment) { \
parseContext.error(L, " supported in fragment shaders only ", S, "", ""); \ parseContext.error(L, " supported in fragment shaders only ", S, "", "");\
parseContext.recover(); \
} \
}
#define PACK_ONLY(S, L) { \
if (parseContext.language != EShLangPack) { \
parseContext.error(L, " supported in pack shaders only ", S, "", ""); \
parseContext.recover(); \ parseContext.recover(); \
} \ } \
} }
#define UNPACK_ONLY(S, L) { \
if (parseContext.language != EShLangUnpack) { \
parseContext.error(L, " supported in unpack shaders only ", S, "", ""); \
parseContext.recover(); \
} \
}
#define PACK_UNPACK_ONLY(S, L) { \
if (parseContext.language != EShLangUnpack && \
parseContext.language != EShLangPack) { \
parseContext.error(L, " supported in pack/unpack shaders only ", S, "", ""); \
parseContext.recover(); \
} \
}
%} %}
%union { %union {
struct { struct {
...@@ -153,16 +124,52 @@ Jutta Degener, 1995 ...@@ -153,16 +124,52 @@ Jutta Degener, 1995
%pure_parser /* Just in case is called from multiple threads */ %pure_parser /* Just in case is called from multiple threads */
%expect 1 /* One shift reduce conflict because of if | else */ %expect 1 /* One shift reduce conflict because of if | else */
%token <lex> ATTRIBUTE CONST_QUAL BOOL_TYPE FLOAT_TYPE INT_TYPE
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 VEC2 VEC3 VEC4
%token <lex> MATRIX2 MATRIX3 MATRIX4 IN_QUAL OUT_QUAL INOUT_QUAL UNIFORM VARYING
%token <lex> STRUCT VOID_TYPE WHILE
%token <lex> SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
%token <lex> SAMPLERRECTARB SAMPLERRECTSHADOWARB // ARB_texture_rectangle %token <lex> ATTRIBUTE VARYING
%token <lex> CONST BOOL FLOAT DOUBLE INT UINT
%token <lex> BREAK CONTINUE DO ELSE FOR IF DISCARD RETURN SWITCH CASE DEFAULT SUBROUTINE
%token <lex> BVEC2 BVEC3 BVEC4 IVEC2 IVEC3 IVEC4 UVEC2 UVEC3 UVEC4 VEC2 VEC3 VEC4
%token <lex> MAT2 MAT3 MAT4 CENTROID IN OUT INOUT
%token <lex> UNIFORM PATCH SAMPLE
%token <lex> COHERENT VOLATILE RESTRICT READONLY WRITEONLY
%token <lex> DVEC2 DVEC3 DVEC4 DMAT2 DMAT3 DMAT4
%token <lex> NOPERSPECTIVE FLAT SMOOTH LAYOUT
%token <lex> MAT2X2 MAT2X3 MAT2X4
%token <lex> MAT3X2 MAT3X3 MAT3X4
%token <lex> MAT4X2 MAT4X3 MAT4X4
%token <lex> DMAT2X2 DMAT2X3 DMAT2X4
%token <lex> DMAT3X2 DMAT3X3 DMAT3X4
%token <lex> DMAT4X2 DMAT4X3 DMAT4X4
%token <lex> ATOMIC_UINT
%token <lex> IDENTIFIER TYPE_NAME FLOATCONSTANT INTCONSTANT BOOLCONSTANT %token <lex> SAMPLER1D SAMPLER2D SAMPLER3D SAMPLERCUBE SAMPLER1DSHADOW SAMPLER2DSHADOW
%token <lex> SAMPLERCUBESHADOW SAMPLER1DARRAY SAMPLER2DARRAY SAMPLER1DARRAYSHADOW
%token <lex> SAMPLER2DARRAYSHADOW ISAMPLER1D ISAMPLER2D ISAMPLER3D ISAMPLERCUBE
%token <lex> ISAMPLER1DARRAY ISAMPLER2DARRAY USAMPLER1D USAMPLER2D USAMPLER3D
%token <lex> USAMPLERCUBE USAMPLER1DARRAY USAMPLER2DARRAY
%token <lex> SAMPLER2DRECT SAMPLER2DRECTSHADOW ISAMPLER2DRECT USAMPLER2DRECT
%token <lex> SAMPLERBUFFER ISAMPLERBUFFER USAMPLERBUFFER
%token <lex> SAMPLERCUBEARRAY SAMPLERCUBEARRAYSHADOW
%token <lex> ISAMPLERCUBEARRAY USAMPLERCUBEARRAY
%token <lex> SAMPLER2DMS ISAMPLER2DMS USAMPLER2DMS
%token <lex> SAMPLER2DMSARRAY ISAMPLER2DMSARRAY USAMPLER2DMSARRAY
%token <lex> IMAGE1D IIMAGE1D UIMAGE1D IMAGE2D IIMAGE2D
%token <lex> UIMAGE2D IMAGE3D IIMAGE3D UIMAGE3D
%token <lex> IMAGE2DRECT IIMAGE2DRECT UIMAGE2DRECT
%token <lex> IMAGECUBE IIMAGECUBE UIMAGECUBE
%token <lex> IMAGEBUFFER IIMAGEBUFFER UIMAGEBUFFER
%token <lex> IMAGE1DARRAY IIMAGE1DARRAY UIMAGE1DARRAY
%token <lex> IMAGE2DARRAY IIMAGE2DARRAY UIMAGE2DARRAY
%token <lex> IMAGECUBEARRAY IIMAGECUBEARRAY UIMAGECUBEARRAY
%token <lex> IMAGE2DMS IIMAGE2DMS UIMAGE2DMS
%token <lex> IMAGE2DMSARRAY IIMAGE2DMSARRAY UIMAGE2DMSARRAY
%token <lex> STRUCT VOID WHILE
%token <lex> IDENTIFIER TYPE_NAME
%token <lex> FLOATCONSTANT DOUBLECONSTANT INTCONSTANT UINTCONSTANT BOOLCONSTANT
%token <lex> FIELD_SELECTION %token <lex> FIELD_SELECTION
%token <lex> LEFT_OP RIGHT_OP %token <lex> LEFT_OP RIGHT_OP
%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP %token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
...@@ -174,6 +181,9 @@ Jutta Degener, 1995 ...@@ -174,6 +181,9 @@ Jutta Degener, 1995
%token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT %token <lex> COMMA COLON EQUAL SEMICOLON BANG DASH TILDE PLUS STAR SLASH PERCENT
%token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION %token <lex> LEFT_ANGLE RIGHT_ANGLE VERTICAL_BAR CARET AMPERSAND QUESTION
%token <lex> INVARIANT PRECISE
%token <lex> HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
%type <interm> assignment_operator unary_operator %type <interm> assignment_operator unary_operator
%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression %type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
%type <interm.intermTypedNode> expression integer_expression assignment_expression %type <interm.intermTypedNode> expression integer_expression assignment_expression
...@@ -182,12 +192,13 @@ Jutta Degener, 1995 ...@@ -182,12 +192,13 @@ Jutta Degener, 1995
%type <interm.intermTypedNode> conditional_expression constant_expression %type <interm.intermTypedNode> conditional_expression constant_expression
%type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression %type <interm.intermTypedNode> logical_or_expression logical_xor_expression logical_and_expression
%type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression %type <interm.intermTypedNode> shift_expression and_expression exclusive_or_expression inclusive_or_expression
%type <interm.intermTypedNode> function_call initializer condition conditionopt %type <interm.intermTypedNode> function_call initializer initializer_list condition conditionopt
%type <interm.intermNode> translation_unit function_definition %type <interm.intermNode> translation_unit function_definition
%type <interm.intermNode> statement simple_statement %type <interm.intermNode> statement simple_statement
%type <interm.intermAggregate> statement_list compound_statement %type <interm.intermAggregate> statement_list compound_statement
%type <interm.intermNode> declaration_statement selection_statement expression_statement %type <interm.intermNode> declaration_statement selection_statement expression_statement
%type <interm.intermNode> switch_statement case_label switch_statement_list
%type <interm.intermNode> declaration external_declaration %type <interm.intermNode> declaration external_declaration
%type <interm.intermNode> for_init_statement compound_statement_no_new_scope %type <interm.intermNode> for_init_statement compound_statement_no_new_scope
%type <interm.nodePair> selection_rest_statement for_rest_statement %type <interm.nodePair> selection_rest_statement for_rest_statement
...@@ -195,17 +206,20 @@ Jutta Degener, 1995 ...@@ -195,17 +206,20 @@ Jutta Degener, 1995
%type <interm> single_declaration init_declarator_list %type <interm> single_declaration init_declarator_list
%type <interm> parameter_declaration parameter_declarator parameter_type_specifier %type <interm> parameter_declaration parameter_declarator parameter_type_specifier
%type <interm.qualifier> parameter_qualifier
%type <interm.type> precise_qualifier invariant_qualifier interpolation_qualifier storage_qualifier precision_qualifier
%type <interm.type> layout_qualifier layout_qualifier_id_list
%type <interm.type> type_qualifier fully_specified_type type_specifier %type <interm.type> type_qualifier fully_specified_type type_specifier
%type <interm.type> single_type_qualifier
%type <interm.type> type_specifier_nonarray %type <interm.type> type_specifier_nonarray
%type <interm.type> struct_specifier %type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator %type <interm.typeLine> struct_declarator
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list %type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list type_name_list
%type <interm.function> function_header function_declarator function_identifier %type <interm.function> function_header function_declarator
%type <interm.function> function_header_with_parameters function_call_header %type <interm.function> function_header_with_parameters
%type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype %type <interm> function_call_header_with_parameters function_call_header_no_parameters function_call_generic function_prototype
%type <interm> function_call_or_method %type <interm> function_call_or_method function_identifier function_call_header
%start translation_unit %start translation_unit
%% %%
...@@ -216,11 +230,7 @@ variable_identifier ...@@ -216,11 +230,7 @@ variable_identifier
const TSymbol* symbol = $1.symbol; const TSymbol* symbol = $1.symbol;
const TVariable* variable; const TVariable* variable;
if (symbol == 0) { if (symbol == 0) {
parseContext.error($1.line, "undeclared identifier", $1.string->c_str(), ""); TVariable* fakeVariable = new TVariable($1.string, TType(EbtVoid));
parseContext.recover();
TType type(EbtFloat);
TVariable* fakeVariable = new TVariable($1.string, type);
parseContext.symbolTable.insert(*fakeVariable);
variable = fakeVariable; variable = fakeVariable;
} else { } else {
// This identifier can only be a variable type symbol // This identifier can only be a variable type symbol
...@@ -250,14 +260,11 @@ primary_expression ...@@ -250,14 +260,11 @@ primary_expression
$$ = $1; $$ = $1;
} }
| INTCONSTANT { | INTCONSTANT {
// constUnion *unionArray = new constUnion[1];
// INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders, unionArray->setIConst($1.i);
// check for overflow for constants $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
//
if (abs($1.i) >= (1 << 16)) {
parseContext.error($1.line, " integer constant overflow", "", "");
parseContext.recover();
} }
| UINTCONSTANT {
constUnion *unionArray = new constUnion[1]; constUnion *unionArray = new constUnion[1];
unionArray->setIConst($1.i); unionArray->setIConst($1.i);
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
...@@ -267,6 +274,11 @@ primary_expression ...@@ -267,6 +274,11 @@ primary_expression
unionArray->setFConst($1.f); unionArray->setFConst($1.f);
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line); $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);
} }
| DOUBLECONSTANT {
constUnion *unionArray = new constUnion[1];
unionArray->setFConst($1.f);
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line);
}
| BOOLCONSTANT { | BOOLCONSTANT {
constUnion *unionArray = new constUnion[1]; constUnion *unionArray = new constUnion[1];
unionArray->setBConst($1.b); unionArray->setBConst($1.b);
...@@ -282,6 +294,7 @@ postfix_expression ...@@ -282,6 +294,7 @@ postfix_expression
$$ = $1; $$ = $1;
} }
| postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
parseContext.variableErrorCheck($1);
if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
if ($1->getAsSymbolNode()) if ($1->getAsSymbolNode())
parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), ""); parseContext.error($2.line, " left of '[' is not of type array, matrix, or vector ", $1->getAsSymbolNode()->getSymbol().c_str(), "");
...@@ -358,12 +371,28 @@ postfix_expression ...@@ -358,12 +371,28 @@ postfix_expression
$$ = $1; $$ = $1;
} }
| postfix_expression DOT FIELD_SELECTION { | postfix_expression DOT FIELD_SELECTION {
parseContext.variableErrorCheck($1);
if ($1->isArray()) { if ($1->isArray()) {
parseContext.error($3.line, "cannot apply dot operator to an array", ".", ""); //
// It can only be a method (e.g., length), which can't be resolved until
// we later see the function calling syntax. Save away the name for now.
//
// TODO: if next token is not "(", then this is an error
if (*$3.string == "length") {
if (parseContext.extensionErrorCheck($3.line, "GL_3DL_array_objects")) {
parseContext.recover(); parseContext.recover();
$$ = $1;
} else {
$$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line);
} }
} else {
if ($1->isVector()) { parseContext.error($3.line, "only the length method is supported for array", $3.string->c_str(), "");
parseContext.recover();
$$ = $1;
}
} else if ($1->isVector()) {
TVectorFields fields; TVectorFields fields;
if (! parseContext.parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) { if (! parseContext.parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
fields.num = 1; fields.num = 1;
...@@ -467,6 +496,7 @@ postfix_expression ...@@ -467,6 +496,7 @@ postfix_expression
// don't delete $3.string, it's from the pool // don't delete $3.string, it's from the pool
} }
| postfix_expression INC_OP { | postfix_expression INC_OP {
parseContext.variableErrorCheck($1);
if (parseContext.lValueErrorCheck($2.line, "++", $1)) if (parseContext.lValueErrorCheck($2.line, "++", $1))
parseContext.recover(); parseContext.recover();
$$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, parseContext.symbolTable);
...@@ -477,6 +507,7 @@ postfix_expression ...@@ -477,6 +507,7 @@ postfix_expression
} }
} }
| postfix_expression DEC_OP { | postfix_expression DEC_OP {
parseContext.variableErrorCheck($1);
if (parseContext.lValueErrorCheck($2.line, "--", $1)) if (parseContext.lValueErrorCheck($2.line, "--", $1))
parseContext.recover(); parseContext.recover();
$$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, parseContext.symbolTable);
...@@ -500,8 +531,8 @@ function_call ...@@ -500,8 +531,8 @@ function_call
: function_call_or_method { : function_call_or_method {
TFunction* fnCall = $1.function; TFunction* fnCall = $1.function;
TOperator op = fnCall->getBuiltInOp(); TOperator op = fnCall->getBuiltInOp();
if (op == EOpArrayLength) { if (op == EOpArrayLength) {
// TODO: check for no arguments to .length()
if ($1.intermNode->getAsTyped() == 0 || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) { if ($1.intermNode->getAsTyped() == 0 || $1.intermNode->getAsTyped()->getType().getArraySize() == 0) {
parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method"); parseContext.error($1.line, "", fnCall->getName().c_str(), "array must be declared with a size before using this method");
parseContext.recover(); parseContext.recover();
...@@ -602,29 +633,11 @@ function_call ...@@ -602,29 +633,11 @@ function_call
} }
; ;
// TODO: can we eliminate function_call_or_method and function_call_generic?
function_call_or_method function_call_or_method
: function_call_generic { : function_call_generic {
$$ = $1; $$ = $1;
} }
| postfix_expression DOT function_call_generic {
if ($1->isArray() && $3.function->getName() == "length") {
//
// implement array.length()
//
if (parseContext.extensionErrorCheck($3.line, "GL_3DL_array_objects")) {
parseContext.recover();
$$ = $3;
} else {
$$ = $3;
$$.intermNode = $1;
$$.function->relateToOperator(EOpArrayLength);
}
} else {
parseContext.error($3.line, "methods are not supported", "", "");
parseContext.recover();
$$ = $3;
}
}
; ;
function_call_generic function_call_generic
...@@ -639,21 +652,19 @@ function_call_generic ...@@ -639,21 +652,19 @@ function_call_generic
; ;
function_call_header_no_parameters function_call_header_no_parameters
: function_call_header VOID_TYPE { : function_call_header VOID {
$$.function = $1; $$ = $1;
$$.intermNode = 0;
} }
| function_call_header { | function_call_header {
$$.function = $1; $$ = $1;
$$.intermNode = 0;
} }
; ;
function_call_header_with_parameters function_call_header_with_parameters
: function_call_header assignment_expression { : function_call_header assignment_expression {
TParameter param = { 0, new TType($2->getType()) }; TParameter param = { 0, new TType($2->getType()) };
$1->addParameter(param); $1.function->addParameter(param);
$$.function = $1; $$.function = $1.function;
$$.intermNode = $2; $$.intermNode = $2;
} }
| function_call_header_with_parameters COMMA assignment_expression { | function_call_header_with_parameters COMMA assignment_expression {
...@@ -677,6 +688,9 @@ function_identifier ...@@ -677,6 +688,9 @@ function_identifier
// //
// Constructor // Constructor
// //
$$.function = 0;
$$.intermNode = 0;
if ($1.array) { if ($1.array) {
if (parseContext.extensionErrorCheck($1.line, "GL_3DL_array_objects")) { if (parseContext.extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
parseContext.recover(); parseContext.recover();
...@@ -688,7 +702,7 @@ function_identifier ...@@ -688,7 +702,7 @@ function_identifier
TString tempString = ""; TString tempString = "";
TType type($1); TType type($1);
TFunction *function = new TFunction(&tempString, type, EOpConstructStruct); TFunction *function = new TFunction(&tempString, type, EOpConstructStruct);
$$ = function; $$.function = function;
} else { } else {
TOperator op = EOpNull; TOperator op = EOpNull;
switch ($1.type) { switch ($1.type) {
...@@ -711,17 +725,17 @@ function_identifier ...@@ -711,17 +725,17 @@ function_identifier
case EbtInt: case EbtInt:
switch($1.size) { switch($1.size) {
case 1: op = EOpConstructInt; break; case 1: op = EOpConstructInt; break;
case 2: FRAG_VERT_ONLY("ivec2", $1.line); op = EOpConstructIVec2; break; case 2: op = EOpConstructIVec2; break;
case 3: FRAG_VERT_ONLY("ivec3", $1.line); op = EOpConstructIVec3; break; case 3: op = EOpConstructIVec3; break;
case 4: FRAG_VERT_ONLY("ivec4", $1.line); op = EOpConstructIVec4; break; case 4: op = EOpConstructIVec4; break;
} }
break; break;
case EbtBool: case EbtBool:
switch($1.size) { switch($1.size) {
case 1: op = EOpConstructBool; break; case 1: op = EOpConstructBool; break;
case 2: FRAG_VERT_ONLY("bvec2", $1.line); op = EOpConstructBVec2; break; case 2: op = EOpConstructBVec2; break;
case 3: FRAG_VERT_ONLY("bvec3", $1.line); op = EOpConstructBVec3; break; case 3: op = EOpConstructBVec3; break;
case 4: FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break; case 4: op = EOpConstructBVec4; break;
} }
break; break;
} }
...@@ -734,27 +748,48 @@ function_identifier ...@@ -734,27 +748,48 @@ function_identifier
TString tempString = ""; TString tempString = "";
TType type($1); TType type($1);
TFunction *function = new TFunction(&tempString, type, op); TFunction *function = new TFunction(&tempString, type, op);
$$ = function; $$.function = function;
} }
} }
| IDENTIFIER { | postfix_expression {
if (parseContext.reservedErrorCheck($1.line, *$1.string)) //
// Should be a method or subroutine call, but we don't have arguments yet.
//
$$.function = 0;
$$.intermNode = 0;
TIntermMethod* method = $1->getAsMethodNode();
if (method) {
if (method->getObject()->isArray()) {
$$.function = new TFunction(&method->getMethodName(), TType(EbtInt), EOpArrayLength);
$$.intermNode = method->getObject();
} else {
parseContext.error(method->getLine(), "only arrays have methods", "", "");
parseContext.recover(); parseContext.recover();
TType type(EbtVoid);
TFunction *function = new TFunction($1.string, type);
$$ = function;
} }
| FIELD_SELECTION { } else {
if (parseContext.reservedErrorCheck($1.line, *$1.string)) TIntermSymbol* symbol = $1->getAsSymbolNode();
if (symbol) {
if (parseContext.reservedErrorCheck(symbol->getLine(), symbol->getSymbol()))
parseContext.recover(); parseContext.recover();
TType type(EbtVoid); TFunction *function = new TFunction(&symbol->getSymbol(), TType(EbtVoid));
TFunction *function = new TFunction($1.string, type); $$.function = function;
$$ = function; } else {
parseContext.error($1->getLine(), "function call, method or subroutine call expected", "", "");
parseContext.recover();
}
}
if ($$.function == 0) {
// error recover
$$.function = new TFunction(&TString(""), TType(EbtVoid), EOpNull);
}
} }
; ;
unary_expression unary_expression
: postfix_expression { : postfix_expression {
parseContext.variableErrorCheck($1);
$$ = $1; $$ = $1;
} }
| INC_OP unary_expression { | INC_OP unary_expression {
...@@ -802,15 +837,13 @@ unary_operator ...@@ -802,15 +837,13 @@ unary_operator
: PLUS { $$.line = $1.line; $$.op = EOpNull; } : PLUS { $$.line = $1.line; $$.op = EOpNull; }
| DASH { $$.line = $1.line; $$.op = EOpNegative; } | DASH { $$.line = $1.line; $$.op = EOpNegative; }
| BANG { $$.line = $1.line; $$.op = EOpLogicalNot; } | BANG { $$.line = $1.line; $$.op = EOpLogicalNot; }
| TILDE { PACK_UNPACK_ONLY("~", $1.line); | TILDE { $$.line = $1.line; $$.op = EOpBitwiseNot; }
$$.line = $1.line; $$.op = EOpBitwiseNot; }
; ;
// Grammar Note: No '*' or '&' unary ops. Pointers are not supported. // Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
multiplicative_expression multiplicative_expression
: unary_expression { $$ = $1; } : unary_expression { $$ = $1; }
| multiplicative_expression STAR unary_expression { | multiplicative_expression STAR unary_expression {
FRAG_VERT_ONLY("*", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
...@@ -819,7 +852,6 @@ multiplicative_expression ...@@ -819,7 +852,6 @@ multiplicative_expression
} }
} }
| multiplicative_expression SLASH unary_expression { | multiplicative_expression SLASH unary_expression {
FRAG_VERT_ONLY("/", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
...@@ -828,7 +860,6 @@ multiplicative_expression ...@@ -828,7 +860,6 @@ multiplicative_expression
} }
} }
| multiplicative_expression PERCENT unary_expression { | multiplicative_expression PERCENT unary_expression {
PACK_UNPACK_ONLY("%", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.line, "%", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.line, "%", $1->getCompleteString(), $3->getCompleteString());
...@@ -861,7 +892,6 @@ additive_expression ...@@ -861,7 +892,6 @@ additive_expression
shift_expression shift_expression
: additive_expression { $$ = $1; } : additive_expression { $$ = $1; }
| shift_expression LEFT_OP additive_expression { | shift_expression LEFT_OP additive_expression {
PACK_UNPACK_ONLY("<<", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString());
...@@ -870,7 +900,6 @@ shift_expression ...@@ -870,7 +900,6 @@ shift_expression
} }
} }
| shift_expression RIGHT_OP additive_expression { | shift_expression RIGHT_OP additive_expression {
PACK_UNPACK_ONLY(">>", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString());
...@@ -953,7 +982,6 @@ equality_expression ...@@ -953,7 +982,6 @@ equality_expression
and_expression and_expression
: equality_expression { $$ = $1; } : equality_expression { $$ = $1; }
| and_expression AMPERSAND equality_expression { | and_expression AMPERSAND equality_expression {
PACK_UNPACK_ONLY("&", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString());
...@@ -966,7 +994,6 @@ and_expression ...@@ -966,7 +994,6 @@ and_expression
exclusive_or_expression exclusive_or_expression
: and_expression { $$ = $1; } : and_expression { $$ = $1; }
| exclusive_or_expression CARET and_expression { | exclusive_or_expression CARET and_expression {
PACK_UNPACK_ONLY("^", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString());
...@@ -979,7 +1006,6 @@ exclusive_or_expression ...@@ -979,7 +1006,6 @@ exclusive_or_expression
inclusive_or_expression inclusive_or_expression
: exclusive_or_expression { $$ = $1; } : exclusive_or_expression { $$ = $1; }
| inclusive_or_expression VERTICAL_BAR exclusive_or_expression { | inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
PACK_UNPACK_ONLY("|", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line, parseContext.symbolTable); $$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) { if ($$ == 0) {
parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString()); parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString());
...@@ -1066,16 +1092,16 @@ assignment_expression ...@@ -1066,16 +1092,16 @@ assignment_expression
assignment_operator assignment_operator
: EQUAL { $$.line = $1.line; $$.op = EOpAssign; } : EQUAL { $$.line = $1.line; $$.op = EOpAssign; }
| MUL_ASSIGN { FRAG_VERT_ONLY("*=", $1.line); $$.line = $1.line; $$.op = EOpMulAssign; } | MUL_ASSIGN { $$.line = $1.line; $$.op = EOpMulAssign; }
| DIV_ASSIGN { FRAG_VERT_ONLY("/=", $1.line); $$.line = $1.line; $$.op = EOpDivAssign; } | DIV_ASSIGN { $$.line = $1.line; $$.op = EOpDivAssign; }
| MOD_ASSIGN { PACK_UNPACK_ONLY("%=", $1.line); $$.line = $1.line; $$.op = EOpModAssign; } | MOD_ASSIGN { $$.line = $1.line; $$.op = EOpModAssign; }
| ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; } | ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; }
| SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; } | SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; }
| LEFT_ASSIGN { PACK_UNPACK_ONLY("<<=", $1.line); $$.line = $1.line; $$.op = EOpLeftShiftAssign; } | LEFT_ASSIGN { $$.line = $1.line; $$.op = EOpLeftShiftAssign; }
| RIGHT_ASSIGN { PACK_UNPACK_ONLY("<<=", $1.line); $$.line = $1.line; $$.op = EOpRightShiftAssign; } | RIGHT_ASSIGN { $$.line = $1.line; $$.op = EOpRightShiftAssign; }
| AND_ASSIGN { PACK_UNPACK_ONLY("&=", $1.line); $$.line = $1.line; $$.op = EOpAndAssign; } | AND_ASSIGN { $$.line = $1.line; $$.op = EOpAndAssign; }
| XOR_ASSIGN { PACK_UNPACK_ONLY("^=", $1.line); $$.line = $1.line; $$.op = EOpExclusiveOrAssign; } | XOR_ASSIGN { $$.line = $1.line; $$.op = EOpExclusiveOrAssign; }
| OR_ASSIGN { PACK_UNPACK_ONLY("|=", $1.line); $$.line = $1.line; $$.op = EOpInclusiveOrAssign; } | OR_ASSIGN { $$.line = $1.line; $$.op = EOpInclusiveOrAssign; }
; ;
expression expression
...@@ -1101,12 +1127,55 @@ constant_expression ...@@ -1101,12 +1127,55 @@ constant_expression
; ;
declaration declaration
: function_prototype SEMICOLON { $$ = 0; } : function_prototype SEMICOLON {
$$ = 0;
// TODO: subroutines: make the identifier a user type for this signature
}
| init_declarator_list SEMICOLON { | init_declarator_list SEMICOLON {
if ($1.intermAggregate) if ($1.intermAggregate)
$1.intermAggregate->setOperator(EOpSequence); $1.intermAggregate->setOperator(EOpSequence);
$$ = $1.intermAggregate; $$ = $1.intermAggregate;
} }
| PRECISION precision_qualifier type_specifier SEMICOLON {
$$ = 0;
}
| type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE SEMICOLON {
// block
$$ = 0;
}
| type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER SEMICOLON {
// block
$$ = 0;
}
| type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET RIGHT_BRACKET SEMICOLON {
// block
$$ = 0;
}
| type_qualifier IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET SEMICOLON {
// block
$$ = 0;
}
| type_qualifier SEMICOLON {
// setting defaults
$$ = 0;
}
| type_qualifier IDENTIFIER SEMICOLON {
// precise foo;
// invariant foo;
$$ = 0;
}
| type_qualifier IDENTIFIER identifier_list SEMICOLON {
// precise foo, bar;
// invariant foo, bar;
$$ = 0;
}
;
identifier_list
: COMMA IDENTIFIER {
}
| identifier_list COMMA IDENTIFIER {
}
; ;
function_prototype function_prototype
...@@ -1228,8 +1297,7 @@ parameter_declarator ...@@ -1228,8 +1297,7 @@ parameter_declarator
parseContext.recover(); parseContext.recover();
$1.setArray(true, size); $1.setArray(true, size);
TType* type = new TType($1); TParameter param = { $2.string, new TType($1)};
TParameter param = { $2.string, type };
$$.line = $2.line; $$.line = $2.line;
$$.param = param; $$.param = param;
} }
...@@ -1237,54 +1305,42 @@ parameter_declarator ...@@ -1237,54 +1305,42 @@ parameter_declarator
parameter_declaration parameter_declaration
// //
// The only parameter qualifier a parameter can have are // With name
// IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
// //
: type_qualifier parameter_declarator {
$$ = $2;
// if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier, *$2.param.type))
// Type + name parseContext.recover();
// if (parseContext.paramErrorCheck($1.line, $1.qualifier, $$.param.type))
: type_qualifier parameter_qualifier parameter_declarator {
$$ = $3;
if (parseContext.paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
parseContext.recover(); parseContext.recover();
} }
| parameter_qualifier parameter_declarator { | parameter_declarator {
$$ = $2; $$ = $1;
if (parseContext.parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
if (parseContext.parameterSamplerErrorCheck($1.line, EvqIn, *$1.param.type))
parseContext.recover(); parseContext.recover();
if (parseContext.paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type)) if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type))
parseContext.recover(); parseContext.recover();
} }
// //
// Only type // Without name
// //
| type_qualifier parameter_qualifier parameter_type_specifier { | type_qualifier parameter_type_specifier {
$$ = $3;
if (parseContext.paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
parseContext.recover();
}
| parameter_qualifier parameter_type_specifier {
$$ = $2; $$ = $2;
if (parseContext.parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier, *$2.param.type))
parseContext.recover(); parseContext.recover();
if (parseContext.paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type)) if (parseContext.paramErrorCheck($1.line, $1.qualifier, $$.param.type))
parseContext.recover(); parseContext.recover();
} }
; | parameter_type_specifier {
$$ = $1;
parameter_qualifier if (parseContext.parameterSamplerErrorCheck($1.line, $1.qualifier, *$1.param.type))
: /* empty */ { parseContext.recover();
$$ = EvqIn; if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type))
} parseContext.recover();
| IN_QUAL {
$$ = EvqIn;
}
| OUT_QUAL {
$$ = EvqOut;
}
| INOUT_QUAL {
$$ = EvqInOut;
} }
; ;
...@@ -1447,6 +1503,10 @@ single_declaration ...@@ -1447,6 +1503,10 @@ single_declaration
} }
| fully_specified_type IDENTIFIER { | fully_specified_type IDENTIFIER {
$$.intermAggregate = 0; $$.intermAggregate = 0;
if (parseContext.globalQualifierFixAndErrorCheck($1.line, $1.qualifier))
parseContext.recover();
$$.type = $1; $$.type = $1;
if (parseContext.structQualifierErrorCheck($2.line, $$.type)) if (parseContext.structQualifierErrorCheck($2.line, $$.type))
...@@ -1595,75 +1655,8 @@ single_declaration ...@@ -1595,75 +1655,8 @@ single_declaration
} }
} }
//
// Place holder for the pack/unpack languages.
//
// | buffer_specifier {
// $$.intermAggregate = 0;
// }
;
// Grammar Note: No 'enum', or 'typedef'. // Grammar Note: No 'enum', or 'typedef'.
//
// Place holder for the pack/unpack languages.
//
//%type <interm> buffer_declaration
//%type <interm.type> buffer_specifier input_or_output buffer_declaration_list
//buffer_specifier
// : input_or_output LEFT_BRACE buffer_declaration_list RIGHT_BRACE {
// }
// ;
//
//input_or_output
// : INPUT {
// if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "input"))
// parseContext.recover();
// UNPACK_ONLY("input", $1.line);
// $$.qualifier = EvqInput;
// }
// | OUTPUT {
// if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "output"))
// parseContext.recover();
// PACK_ONLY("output", $1.line);
// $$.qualifier = EvqOutput;
// }
// ;
//
// Place holder for the pack/unpack languages.
//
//buffer_declaration_list
// : buffer_declaration {
// }
// | buffer_declaration_list buffer_declaration {
// }
// ;
//
// Input/output semantics:
// float must be 16 or 32 bits
// float alignment restrictions?
// check for only one input and only one output
// sum of bitfields has to be multiple of 32
//
//
// Place holder for the pack/unpack languages.
//
//buffer_declaration
// : type_specifier IDENTIFIER COLON constant_expression SEMICOLON {
// if (parseContext.reservedErrorCheck($2.line, *$2.string, parseContext))
// parseContext.recover();
// $$.variable = new TVariable($2.string, $1);
// if (! parseContext.symbolTable.insert(*$$.variable)) {
// parseContext.error($2.line, "redefinition", $$.variable->getName().c_str(), "");
// parseContext.recover();
// // don't have to delete $$.variable, the pool pop will take care of it
// }
// }
// ;
fully_specified_type fully_specified_type
: type_specifier { : type_specifier {
$$ = $1; $$ = $1;
...@@ -1700,8 +1693,93 @@ fully_specified_type ...@@ -1700,8 +1693,93 @@ fully_specified_type
} }
; ;
invariant_qualifier
: INVARIANT {
}
;
interpolation_qualifier
: SMOOTH {
}
| FLAT {
}
| NOPERSPECTIVE {
}
;
layout_qualifier
: LAYOUT LEFT_PAREN layout_qualifier_id_list RIGHT_PAREN {
}
;
layout_qualifier_id_list
: layout_qualifier_id {
}
| layout_qualifier_id_list COMMA layout_qualifier_id {
}
layout_qualifier_id
: IDENTIFIER {
}
| IDENTIFIER EQUAL INTCONSTANT {
}
;
precise_qualifier
: PRECISE {
}
;
type_qualifier type_qualifier
: CONST_QUAL { : single_type_qualifier {
$$ = $1;
}
| type_qualifier single_type_qualifier {
$$ = $1;
// TODO: merge qualifiers in $1 and $2 and check for duplication
if ($$.type == EbtVoid) {
$$.type = $2.type;
}
if ($$.qualifier == EvqTemporary) {
$$.qualifier = $2.qualifier;
} else if ($$.qualifier == EvqIn && $2.qualifier == EvqOut ||
$$.qualifier == EvqOut && $2.qualifier == EvqIn) {
$$.qualifier = EvqInOut;
} else if ($$.qualifier == EvqIn && $2.qualifier == EvqConst ||
$$.qualifier == EvqConst && $2.qualifier == EvqIn) {
$$.qualifier = EvqConstReadOnly;
}
}
;
single_type_qualifier
: storage_qualifier {
$$ = $1;
}
| layout_qualifier {
$$ = $1;
}
| precision_qualifier {
$$ = $1;
}
| interpolation_qualifier {
// allow inheritance of storage qualifier from block declaration
$$ = $1;
}
| invariant_qualifier {
// allow inheritance of storage qualifier from block declaration
$$ = $1;
}
| precise_qualifier {
// allow inheritance of storage qualifier from block declaration
$$ = $1;
}
;
storage_qualifier
: CONST {
$$.setBasic(EbtVoid, EvqConst, $1.line); $$.setBasic(EbtVoid, EvqConst, $1.line);
} }
| ATTRIBUTE { | ATTRIBUTE {
...@@ -1718,17 +1796,104 @@ type_qualifier ...@@ -1718,17 +1796,104 @@ type_qualifier
else else
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line); $$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
} }
| INOUT {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqInOut, $1.line);
}
| IN {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "in"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqIn, $1.line);
}
| OUT {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "out"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqOut, $1.line);
}
| CENTROID {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "centroid"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqVaryingIn, $1.line);
}
| PATCH {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "patch"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
| SAMPLE {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "sample"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
| UNIFORM { | UNIFORM {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform")) if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
parseContext.recover(); parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line); $$.setBasic(EbtVoid, EvqUniform, $1.line);
} }
| COHERENT {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "coherent"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
| VOLATILE {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "volatile"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
| RESTRICT {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "restrict"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
| READONLY {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "readonly"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
| WRITEONLY {
// TODO: implement this qualifier
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "writeonly"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
| SUBROUTINE {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
}
| SUBROUTINE LEFT_PAREN type_name_list RIGHT_PAREN {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "subroutine"))
parseContext.recover();
$$.setBasic(EbtVoid, EvqUniform, $1.line);
// TODO: subroutine semantics
// 1) make sure each identifier is a type declared earlier with SUBROUTINE
// 2) save all of the identifiers for future comparison with the declared function
}
;
type_name_list
: TYPE_NAME {
// TODO: add subroutine type to list
}
| type_name_list COMMA TYPE_NAME {
// TODO: add subroutine type to list
}
; ;
type_specifier type_specifier
: type_specifier_nonarray { : type_specifier_nonarray {
$$ = $1; $$ = $1;
} }
| type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET {
$$ = $1;
}
| type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET { | type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$ = $1; $$ = $1;
...@@ -1744,27 +1909,32 @@ type_specifier ...@@ -1744,27 +1909,32 @@ type_specifier
; ;
type_specifier_nonarray type_specifier_nonarray
: VOID_TYPE { : VOID {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtVoid, qual, $1.line); $$.setBasic(EbtVoid, qual, $1.line);
} }
| FLOAT_TYPE { | FLOAT {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
}
| DOUBLE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
// TODO: implement EbtDouble, check all float types
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
} }
| INT_TYPE { | INT {
// TODO: implement EbtUint, check all int types
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line); $$.setBasic(EbtInt, qual, $1.line);
} }
| BOOL_TYPE { | UINT {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
}
| BOOL {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line); $$.setBasic(EbtBool, qual, $1.line);
} }
// | UNSIGNED INT_TYPE {
// PACK_UNPACK_ONLY("unsigned", $1.line);
// TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
// $$.setBasic(EbtInt, qual, $1.line);
// }
| VEC2 { | VEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
...@@ -1780,6 +1950,12 @@ type_specifier_nonarray ...@@ -1780,6 +1950,12 @@ type_specifier_nonarray
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4); $$.setAggregate(4);
} }
| DVEC2 {
}
| DVEC3 {
}
| DVEC4 {
}
| BVEC2 { | BVEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line); $$.setBasic(EbtBool, qual, $1.line);
...@@ -1810,76 +1986,514 @@ type_specifier_nonarray ...@@ -1810,76 +1986,514 @@ type_specifier_nonarray
$$.setBasic(EbtInt, qual, $1.line); $$.setBasic(EbtInt, qual, $1.line);
$$.setAggregate(4); $$.setAggregate(4);
} }
| MATRIX2 { | UVEC2 {
FRAG_VERT_ONLY("mat2", $1.line); TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.setAggregate(2);
}
| UVEC3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.setAggregate(3);
}
| UVEC4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
$$.setAggregate(4);
}
| MAT2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(2, true); $$.setAggregate(2, true);
} }
| MATRIX3 { | MAT3 {
FRAG_VERT_ONLY("mat3", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(3, true); $$.setAggregate(3, true);
} }
| MATRIX4 { | MAT4 {
FRAG_VERT_ONLY("mat4", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true); $$.setAggregate(4, true);
} }
| SAMPLER1D { | MAT2X2 {
FRAG_VERT_ONLY("sampler1D", $1.line); // TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler1D, qual, $1.line); $$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| MAT2X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| MAT2X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| MAT3X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| MAT3X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| MAT3X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| MAT4X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| MAT4X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| MAT4X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT2X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT2X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT2X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT3X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT3X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT3X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT4X2 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT4X3 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| DMAT4X4 {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| ATOMIC_UINT {
// TODO: add type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtInt, qual, $1.line);
}
| SAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler1D, qual, $1.line);
} }
| SAMPLER2D { | SAMPLER2D {
FRAG_VERT_ONLY("sampler2D", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line); $$.setBasic(EbtSampler2D, qual, $1.line);
} }
| SAMPLER3D { | SAMPLER3D {
FRAG_VERT_ONLY("sampler3D", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler3D, qual, $1.line); $$.setBasic(EbtSampler3D, qual, $1.line);
} }
| SAMPLERCUBE { | SAMPLERCUBE {
FRAG_VERT_ONLY("samplerCube", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerCube, qual, $1.line); $$.setBasic(EbtSamplerCube, qual, $1.line);
} }
| SAMPLER1DSHADOW { | SAMPLER1DSHADOW {
FRAG_VERT_ONLY("sampler1DShadow", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler1DShadow, qual, $1.line); $$.setBasic(EbtSampler1DShadow, qual, $1.line);
} }
| SAMPLER2DSHADOW { | SAMPLER2DSHADOW {
FRAG_VERT_ONLY("sampler2DShadow", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line); $$.setBasic(EbtSampler2DShadow, qual, $1.line);
} }
| SAMPLERRECTARB { | SAMPLERCUBESHADOW {
// ARB_texture_rectangle TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
FRAG_VERT_ONLY("samplerRectARB", $1.line); }
| SAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| SAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| SAMPLER1DARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| SAMPLER2DARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| SAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| SAMPLERCUBEARRAYSHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| ISAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| ISAMPLER2D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| ISAMPLER3D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| ISAMPLERCUBE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| ISAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| ISAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| ISAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| USAMPLER1D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| USAMPLER2D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| USAMPLER3D {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| USAMPLERCUBE {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| USAMPLER1DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| USAMPLER2DARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| USAMPLERCUBEARRAY {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| SAMPLER2DRECT {
if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle")) if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle"))
parseContext.recover(); parseContext.recover();
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRect, qual, $1.line); $$.setBasic(EbtSamplerRect, qual, $1.line);
} }
| SAMPLERRECTSHADOWARB { | SAMPLER2DRECTSHADOW {
// ARB_texture_rectangle
FRAG_VERT_ONLY("samplerRectShadowARB", $1.line);
if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle")) if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle"))
parseContext.recover(); parseContext.recover();
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRectShadow, qual, $1.line); $$.setBasic(EbtSamplerRectShadow, qual, $1.line);
} }
| ISAMPLER2DRECT {
if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle"))
parseContext.recover();
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRect, qual, $1.line);
}
| USAMPLER2DRECT {
if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle"))
parseContext.recover();
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRect, qual, $1.line);
}
| SAMPLERBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| ISAMPLERBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| USAMPLERBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| SAMPLER2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| ISAMPLER2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| USAMPLER2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| SAMPLER2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| ISAMPLER2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| USAMPLER2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGE1D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGE1D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGE1D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGE2D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGE2D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGE2D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGE3D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGE3D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGE3D {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGE2DRECT {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGE2DRECT {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGE2DRECT {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGECUBE {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGECUBE {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGECUBE {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGEBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGEBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGEBUFFER {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGE1DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGE1DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGE1DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGE2DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGE2DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGE2DARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGECUBEARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGECUBEARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGECUBEARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGE2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGE2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGE2DMS {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IMAGE2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| IIMAGE2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| UIMAGE2DMSARRAY {
// TODO: implement this type
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| struct_specifier { | struct_specifier {
FRAG_VERT_ONLY("struct", $1.line);
$$ = $1; $$ = $1;
$$.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; $$.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
} }
...@@ -1895,6 +2509,15 @@ type_specifier_nonarray ...@@ -1895,6 +2509,15 @@ type_specifier_nonarray
} }
; ;
precision_qualifier
: HIGH_PRECISION {
}
| MEDIUM_PRECISION {
}
| LOW_PRECISION {
}
;
struct_specifier struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE { : STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($4, *$2.string); TType* structure = new TType($4, *$2.string);
...@@ -1955,6 +2578,29 @@ struct_declaration ...@@ -1955,6 +2578,29 @@ struct_declaration
(*$$)[i].type->setTypeName($1.userDef->getTypeName()); (*$$)[i].type->setTypeName($1.userDef->getTypeName());
} }
} }
| type_qualifier type_specifier struct_declarator_list SEMICOLON {
$$ = $3;
if (parseContext.voidErrorCheck($2.line, (*$3)[0].type->getFieldName(), $2)) {
parseContext.recover();
}
for (unsigned int i = 0; i < $$->size(); ++i) {
//
// Careful not to replace already know aspects of type, like array-ness
//
(*$$)[i].type->setType($2.type, $2.size, $2.matrix, $2.userDef);
// don't allow arrays of arrays
if ((*$$)[i].type->isArray()) {
if (parseContext.arrayTypeErrorCheck($2.line, $2))
parseContext.recover();
}
if ($2.array)
(*$$)[i].type->setArraySize($2.arraySize);
if ($2.userDef)
(*$$)[i].type->setTypeName($2.userDef->getTypeName());
}
}
; ;
struct_declarator_list struct_declarator_list
...@@ -1973,6 +2619,12 @@ struct_declarator ...@@ -1973,6 +2619,12 @@ struct_declarator
$$.line = $1.line; $$.line = $1.line;
$$.type->setFieldName(*$1.string); $$.type->setFieldName(*$1.string);
} }
| IDENTIFIER LEFT_BRACKET RIGHT_BRACKET {
// allow non-sized arrays in blocks
$$.type = new TType(EbtVoid);
$$.line = $1.line;
$$.type->setFieldName(*$1.string);
}
| IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET { | IDENTIFIER LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$.type = new TType(EbtVoid); $$.type = new TType(EbtVoid);
$$.line = $1.line; $$.line = $1.line;
...@@ -1986,7 +2638,25 @@ struct_declarator ...@@ -1986,7 +2638,25 @@ struct_declarator
; ;
initializer initializer
: assignment_expression { $$ = $1; } : assignment_expression {
$$ = $1;
}
| LEFT_BRACE initializer_list RIGHT_BRACE {
$$ = $2;
}
| LEFT_BRACE initializer_list COMMA RIGHT_BRACE {
$$ = $2;
}
;
initializer_list
: initializer {
$$ = $1;
}
| initializer_list COMMA initializer {
// TODO: implement the list
$$ = $3;
}
; ;
declaration_statement declaration_statement
...@@ -1998,12 +2668,14 @@ statement ...@@ -1998,12 +2668,14 @@ statement
| simple_statement { $$ = $1; } | simple_statement { $$ = $1; }
; ;
// Grammar Note: No labeled statements; 'goto' is not supported. // Grammar Note: labeled statements for switch statements only; 'goto' is not supported.
simple_statement simple_statement
: declaration_statement { $$ = $1; } : declaration_statement { $$ = $1; }
| expression_statement { $$ = $1; } | expression_statement { $$ = $1; }
| selection_statement { $$ = $1; } | selection_statement { $$ = $1; }
| switch_statement { $$ = $1; }
| case_label { $$ = $1; }
| iteration_statement { $$ = $1; } | iteration_statement { $$ = $1; }
| jump_statement { $$ = $1; } | jump_statement { $$ = $1; }
; ;
...@@ -2067,8 +2739,6 @@ selection_rest_statement ...@@ -2067,8 +2739,6 @@ selection_rest_statement
} }
; ;
// Grammar Note: No 'switch'. Switch statements not supported.
condition condition
// In 1996 c++ draft, conditions can include single declarations // In 1996 c++ draft, conditions can include single declarations
: expression { : expression {
...@@ -2092,6 +2762,30 @@ condition ...@@ -2092,6 +2762,30 @@ condition
} }
; ;
switch_statement
: SWITCH LEFT_PAREN expression RIGHT_PAREN { ++parseContext.switchNestingLevel; } LEFT_BRACE switch_statement_list RIGHT_BRACE {
$$ = 0;
--parseContext.switchNestingLevel;
}
;
switch_statement_list
: /* nothing */ {
}
| statement_list {
$$ = $1;
}
;
case_label
: CASE expression COLON {
$$ = 0;
}
| DEFAULT COLON {
$$ = 0;
}
;
iteration_statement iteration_statement
: WHILE LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope { : WHILE LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop(); parseContext.symbolTable.pop();
...@@ -2155,8 +2849,8 @@ jump_statement ...@@ -2155,8 +2849,8 @@ jump_statement
$$ = parseContext.intermediate.addBranch(EOpContinue, $1.line); $$ = parseContext.intermediate.addBranch(EOpContinue, $1.line);
} }
| BREAK SEMICOLON { | BREAK SEMICOLON {
if (parseContext.loopNestingLevel <= 0) { if (parseContext.loopNestingLevel + parseContext.switchNestingLevel <= 0) {
parseContext.error($1.line, "break statement only allowed in loops", "", ""); parseContext.error($1.line, "break statement only allowed in switch and loops", "", "");
parseContext.recover(); parseContext.recover();
} }
$$ = parseContext.intermediate.addBranch(EOpBreak, $1.line); $$ = parseContext.intermediate.addBranch(EOpBreak, $1.line);
......
...@@ -306,16 +306,6 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers ...@@ -306,16 +306,6 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
case EOpRefract: out.debug << "refract"; break; case EOpRefract: out.debug << "refract"; break;
case EOpMul: out.debug << "component-wise multiply"; break; case EOpMul: out.debug << "component-wise multiply"; break;
case EOpItof: out.debug << "itof"; break;
case EOpFtoi: out.debug << "ftoi"; break;
case EOpSkipPixels: out.debug << "skipPixels"; break;
case EOpReadInput: out.debug << "readInput"; break;
case EOpWritePixel: out.debug << "writePixel"; break;
case EOpBitmapLsb: out.debug << "bitmapLSB"; break;
case EOpBitmapMsb: out.debug << "bitmapMSB"; break;
case EOpWriteOutput: out.debug << "writeOutput"; break;
case EOpReadPixel: out.debug << "readPixel"; break;
default: out.debug.message(EPrefixError, "Bad aggregation op"); default: out.debug.message(EPrefixError, "Bad aggregation op");
} }
......
...@@ -65,6 +65,7 @@ public: ...@@ -65,6 +65,7 @@ public:
TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc); TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc); TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addMethod(TIntermTyped*, TType&, const TString*, TSourceLoc);
TIntermConstantUnion* addConstantUnion(constUnion*, const TType&, TSourceLoc); TIntermConstantUnion* addConstantUnion(constUnion*, const TType&, TSourceLoc);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ; TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
bool parseConstTree(TSourceLoc, TIntermNode*, constUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false); bool parseConstTree(TSourceLoc, TIntermNode*, constUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);
......
...@@ -72,8 +72,6 @@ SH_IMPORT_EXPORT int __fastcall ShFinalize(); ...@@ -72,8 +72,6 @@ SH_IMPORT_EXPORT int __fastcall ShFinalize();
typedef enum { typedef enum {
EShLangVertex, EShLangVertex,
EShLangFragment, EShLangFragment,
EShLangPack,
EShLangUnpack,
EShLangCount, EShLangCount,
} EShLanguage; } EShLanguage;
...@@ -82,8 +80,6 @@ typedef enum { ...@@ -82,8 +80,6 @@ typedef enum {
// //
typedef enum { typedef enum {
EShExVertexFragment, EShExVertexFragment,
EShExPackFragment,
EShExUnpackFragment,
EShExFragment EShExFragment
} EShExecutable; } EShExecutable;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment