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[])
//
// .frag* = fragment programs
// .vert* = vertex programs
// .pack* = pack programs
// .unpa* = unpack pragrams
//
static EShLanguage FindLanguage(char *name)
{
......@@ -228,8 +226,6 @@ static EShLanguage FindLanguage(char *name)
if (ext = strrchr(name, '.')) {
if (strncmp(ext, ".frag", 4) == 0) return EShLangFragment;
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;
......
......@@ -77,10 +77,6 @@ enum TQualifier {
EvqVaryingOut, // vertex shaders only read/write
EvqUniform, // Readonly, vertex and fragment
// pack/unpack input and output
EvqInput,
EvqOutput,
// parameters
EvqIn,
EvqOut,
......@@ -113,16 +109,14 @@ __inline const char* getQualifierString(TQualifier q)
case EvqTemporary: return "Temporary"; break;
case EvqGlobal: return "Global"; break;
case EvqConst: return "const"; break;
case EvqConstReadOnly: return "const"; break;
case EvqConstReadOnly: return "const (read only)"; break;
case EvqAttribute: return "attribute"; break;
case EvqVaryingIn: return "varying"; break;
case EvqVaryingOut: return "varying"; break;
case EvqVaryingIn: return "varying in"; break;
case EvqVaryingOut: return "varying out"; break;
case EvqUniform: return "uniform"; break;
case EvqIn: return "in"; break;
case EvqOut: return "out"; break;
case EvqInOut: return "inout"; break;
case EvqInput: return "input"; break;
case EvqOutput: return "output"; break;
case EvqPosition: return "Position"; break;
case EvqPointSize: return "PointSize"; break;
case EvqClipVertex: return "ClipVertex"; break;
......
......@@ -118,6 +118,8 @@ enum TOperator {
EOpVectorSwizzle,
EOpMethod,
//
// Built-in functions potentially mapped to operators
//
......@@ -169,16 +171,6 @@ enum TOperator {
EOpAny,
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
//
......@@ -242,6 +234,7 @@ class TIntermBinary;
class TIntermConstantUnion;
class TIntermSelection;
class TIntermTyped;
class TIntermMethod;
class TIntermSymbol;
class TInfoSink;
......@@ -261,6 +254,7 @@ public:
virtual TIntermAggregate* getAsAggregate() { return 0; }
virtual TIntermBinary* getAsBinaryNode() { return 0; }
virtual TIntermSelection* getAsSelectionNode() { return 0; }
virtual TIntermMethod* getAsMethodNode() { return 0; }
virtual TIntermSymbol* getAsSymbolNode() { return 0; }
virtual ~TIntermNode() { }
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.
//
class TIntermSymbol : public TIntermTyped {
......
......@@ -918,18 +918,6 @@ void IdentifyBuiltIns(EShLanguage language, TSymbolTable& symbolTable)
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");
}
}
......
......@@ -51,6 +51,12 @@
//
// 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)
{
if (it->visitSymbol)
......
......@@ -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,
// 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
}
//
// 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
// an l-value that can be operated on this way.
//
......@@ -311,7 +335,6 @@ bool TParseContext::lValueErrorCheck(int line, char* op, TIntermTyped* node)
case EvqAttribute: message = "can't modify an attribute"; break;
case EvqUniform: message = "can't modify a uniform"; 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 EvqFragCoord: message = "can't modify gl_FragCoord"; break;
default:
......@@ -596,6 +619,24 @@ bool TParseContext::samplerErrorCheck(int line, const TPublicType& pType, const
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)
{
if ((pType.qualifier == EvqVaryingIn || pType.qualifier == EvqVaryingOut || pType.qualifier == EvqAttribute) &&
......@@ -885,23 +926,26 @@ bool TParseContext::nonInitErrorCheck(int line, TString& identifier, TPublicType
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), "");
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)
......
......@@ -67,16 +67,18 @@ struct TParseContext {
TParseContext(TSymbolTable& symt, TIntermediate& interm, EShLanguage L, TInfoSink& is) :
intermediate(interm), symbolTable(symt), infoSink(is), language(L), treeRoot(0),
recoveredFromError(false), numErrors(0), lexAfterType(false), loopNestingLevel(0),
switchNestingLevel(0),
inTypeParen(false), contextPragma(true, false) { }
TIntermediate& intermediate; // to hold and build a parse tree
TSymbolTable& symbolTable; // symbol table that goes with the language currently being parsed
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
bool recoveredFromError; // true if a parse error has occurred, but we continue to parse
int numErrors;
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 switchNestingLevel; // 0 if outside all switch statements
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
bool functionReturnsValue; // true if a non-void function has a return
......@@ -93,6 +95,7 @@ struct TParseContext {
void assignError(int line, const char* op, TString left, TString right);
void unaryOpError(int line, char* op, TString operand);
void binaryOpError(int line, char* op, TString left, TString right);
void variableErrorCheck(TIntermTyped*& nodePtr);
bool lValueErrorCheck(int line, char* op, TIntermTyped*);
bool constErrorCheck(TIntermTyped* node);
bool integerErrorCheck(TIntermTyped* node, char* token);
......@@ -107,12 +110,13 @@ struct TParseContext {
bool boolErrorCheck(int, const TIntermTyped*);
bool boolErrorCheck(int, const TPublicType&);
bool samplerErrorCheck(int line, const TPublicType& pType, const char* reason);
bool globalQualifierFixAndErrorCheck(int line, TQualifier&);
bool structQualifierErrorCheck(int line, const TPublicType& pType);
bool parameterSamplerErrorCheck(int line, TQualifier qualifier, const TType& type);
bool containsSampler(TType& type);
bool nonInitConstErrorCheck(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*);
const TFunction* findFunction(int line, TFunction* pfnCall, bool *builtIn = 0);
bool executeInitializer(TSourceLoc line, TString& identifier, TPublicType& pType,
......
......@@ -53,6 +53,10 @@ L [a-zA-Z_]
H [a-fA-F0-9]
E [Ee][+-]?{D}+
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
%{
......@@ -92,36 +96,85 @@ TSourceLoc yylineno;
<*>"//"[^\n]*"\n" { /* ?? carriage and/or line-feed? */ };
"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); }
"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); }
"layout" { pyylval->lex.line = yylineno; return(LAYOUT); }
"break" { pyylval->lex.line = yylineno; return(BREAK); }
"continue" { pyylval->lex.line = yylineno; return(CONTINUE); }
"do" { pyylval->lex.line = yylineno; return(DO); }
"for" { pyylval->lex.line = yylineno; return(FOR); }
"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); }
"else" { pyylval->lex.line = yylineno; return(ELSE); }
"in" { pyylval->lex.line = yylineno; return(IN_QUAL); }
"out" { pyylval->lex.line = yylineno; return(OUT_QUAL); }
"inout" { pyylval->lex.line = yylineno; return(INOUT_QUAL); }
"float" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(FLOAT_TYPE); }
"int" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(INT_TYPE); }
"void" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(VOID_TYPE); }
"bool" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(BOOL_TYPE); }
"in" { pyylval->lex.line = yylineno; return(IN); }
"out" { pyylval->lex.line = yylineno; return(OUT); }
"inout" { pyylval->lex.line = yylineno; return(INOUT); }
"centroid" { pyylval->lex.line = yylineno; return(CENTROID); }
"noperspective" { pyylval->lex.line = yylineno; return(NOPERSPECTIVE); }
"flat" { pyylval->lex.line = yylineno; return(FLAT); }
"smooth" { pyylval->lex.line = yylineno; return(SMOOTH); }
"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); }
"false" { pyylval->lex.line = yylineno; pyylval->lex.b = false; return(BOOLCONSTANT); }
"discard" { pyylval->lex.line = yylineno; return(DISCARD); }
"return" { pyylval->lex.line = yylineno; return(RETURN); }
"mat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX2); }
"mat3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX3); }
"mat4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MATRIX4); }
"subroutine" { pyylval->lex.line = yylineno; return(SUBROUTINE); }
"mat2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return(MAT2); }
"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); }
"vec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); }
......@@ -129,6 +182,9 @@ TSourceLoc yylineno;
"ivec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC2); }
"ivec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (IVEC3); }
"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); }
"bvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC3); }
"bvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (BVEC4); }
......@@ -140,8 +196,71 @@ TSourceLoc yylineno;
"sampler1DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1DSHADOW; }
"sampler2DShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DSHADOW; }
"sampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERRECTARB; /* ARB_texture_rectangle */ }
"sampler2DRectShadow" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERRECTSHADOWARB; /* ARB_texture_rectangle */ }
"sampler2DRect" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2DRECT; }
"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); }
......@@ -156,12 +275,9 @@ TSourceLoc yylineno;
"packed" { PaReservedWord(); return 0; }
"goto" { PaReservedWord(); return 0; }
"switch" { PaReservedWord(); return 0; }
"default" { PaReservedWord(); return 0; }
"inline" { PaReservedWord(); return 0; }
"noinline" { PaReservedWord(); return 0; }
"volatile" { PaReservedWord(); return 0; }
"public" { PaReservedWord(); return 0; }
"static" { PaReservedWord(); return 0; }
"extern" { PaReservedWord(); return 0; }
......@@ -170,7 +286,6 @@ TSourceLoc yylineno;
"long" { PaReservedWord(); return 0; }
"short" { PaReservedWord(); return 0; }
"double" { PaReservedWord(); return 0; }
"half" { PaReservedWord(); return 0; }
"fixed" { PaReservedWord(); return 0; }
"unsigned" { PaReservedWord(); return 0; }
......@@ -207,6 +322,11 @@ TSourceLoc yylineno;
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); }
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}+"."{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
extern void yyerror(char*);
#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) { \
if (parseContext.language != EShLangVertex) { \
parseContext.error(L, " supported in vertex shaders only ", S, "", ""); \
......@@ -87,32 +79,11 @@ Jutta Degener, 1995
#define FRAG_ONLY(S, L) { \
if (parseContext.language != EShLangFragment) { \
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.error(L, " supported in fragment shaders only ", S, "", "");\
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 {
struct {
......@@ -153,16 +124,52 @@ Jutta Degener, 1995
%pure_parser /* Just in case is called from multiple threads */
%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> LEFT_OP RIGHT_OP
%token <lex> INC_OP DEC_OP LE_OP GE_OP EQ_OP NE_OP
......@@ -174,6 +181,9 @@ Jutta Degener, 1995
%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> INVARIANT PRECISE
%token <lex> HIGH_PRECISION MEDIUM_PRECISION LOW_PRECISION PRECISION
%type <interm> assignment_operator unary_operator
%type <interm.intermTypedNode> variable_identifier primary_expression postfix_expression
%type <interm.intermTypedNode> expression integer_expression assignment_expression
......@@ -182,12 +192,13 @@ Jutta Degener, 1995
%type <interm.intermTypedNode> conditional_expression constant_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> 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> statement simple_statement
%type <interm.intermAggregate> statement_list compound_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> for_init_statement compound_statement_no_new_scope
%type <interm.nodePair> selection_rest_statement for_rest_statement
......@@ -195,17 +206,20 @@ Jutta Degener, 1995
%type <interm> single_declaration init_declarator_list
%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> single_type_qualifier
%type <interm.type> type_specifier_nonarray
%type <interm.type> struct_specifier
%type <interm.typeLine> struct_declarator
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list
%type <interm.function> function_header function_declarator function_identifier
%type <interm.function> function_header_with_parameters function_call_header
%type <interm.typeList> struct_declarator_list struct_declaration struct_declaration_list type_name_list
%type <interm.function> function_header function_declarator
%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_or_method
%type <interm> function_call_or_method function_identifier function_call_header
%start translation_unit
%%
......@@ -216,11 +230,7 @@ variable_identifier
const TSymbol* symbol = $1.symbol;
const TVariable* variable;
if (symbol == 0) {
parseContext.error($1.line, "undeclared identifier", $1.string->c_str(), "");
parseContext.recover();
TType type(EbtFloat);
TVariable* fakeVariable = new TVariable($1.string, type);
parseContext.symbolTable.insert(*fakeVariable);
TVariable* fakeVariable = new TVariable($1.string, TType(EbtVoid));
variable = fakeVariable;
} else {
// This identifier can only be a variable type symbol
......@@ -250,14 +260,11 @@ primary_expression
$$ = $1;
}
| INTCONSTANT {
//
// INT_TYPE is only 16-bit plus sign bit for vertex/fragment shaders,
// check for overflow for constants
//
if (abs($1.i) >= (1 << 16)) {
parseContext.error($1.line, " integer constant overflow", "", "");
parseContext.recover();
constUnion *unionArray = new constUnion[1];
unionArray->setIConst($1.i);
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
}
| UINTCONSTANT {
constUnion *unionArray = new constUnion[1];
unionArray->setIConst($1.i);
$$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtInt, EvqConst), $1.line);
......@@ -267,6 +274,11 @@ primary_expression
unionArray->setFConst($1.f);
$$ = 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 {
constUnion *unionArray = new constUnion[1];
unionArray->setBConst($1.b);
......@@ -282,6 +294,7 @@ postfix_expression
$$ = $1;
}
| postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET {
parseContext.variableErrorCheck($1);
if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) {
if ($1->getAsSymbolNode())
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
$$ = $1;
}
| postfix_expression DOT FIELD_SELECTION {
parseContext.variableErrorCheck($1);
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();
$$ = $1;
} else {
$$ = parseContext.intermediate.addMethod($1, TType(EbtInt), $3.string, $2.line);
}
if ($1->isVector()) {
} else {
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;
if (! parseContext.parseVectorFields(*$3.string, $1->getNominalSize(), fields, $3.line)) {
fields.num = 1;
......@@ -467,6 +496,7 @@ postfix_expression
// don't delete $3.string, it's from the pool
}
| postfix_expression INC_OP {
parseContext.variableErrorCheck($1);
if (parseContext.lValueErrorCheck($2.line, "++", $1))
parseContext.recover();
$$ = parseContext.intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, parseContext.symbolTable);
......@@ -477,6 +507,7 @@ postfix_expression
}
}
| postfix_expression DEC_OP {
parseContext.variableErrorCheck($1);
if (parseContext.lValueErrorCheck($2.line, "--", $1))
parseContext.recover();
$$ = parseContext.intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, parseContext.symbolTable);
......@@ -500,8 +531,8 @@ function_call
: function_call_or_method {
TFunction* fnCall = $1.function;
TOperator op = fnCall->getBuiltInOp();
if (op == EOpArrayLength) {
// TODO: check for no arguments to .length()
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.recover();
......@@ -602,29 +633,11 @@ function_call
}
;
// TODO: can we eliminate function_call_or_method and function_call_generic?
function_call_or_method
: function_call_generic {
$$ = $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
......@@ -639,21 +652,19 @@ function_call_generic
;
function_call_header_no_parameters
: function_call_header VOID_TYPE {
$$.function = $1;
$$.intermNode = 0;
: function_call_header VOID {
$$ = $1;
}
| function_call_header {
$$.function = $1;
$$.intermNode = 0;
$$ = $1;
}
;
function_call_header_with_parameters
: function_call_header assignment_expression {
TParameter param = { 0, new TType($2->getType()) };
$1->addParameter(param);
$$.function = $1;
$1.function->addParameter(param);
$$.function = $1.function;
$$.intermNode = $2;
}
| function_call_header_with_parameters COMMA assignment_expression {
......@@ -677,6 +688,9 @@ function_identifier
//
// Constructor
//
$$.function = 0;
$$.intermNode = 0;
if ($1.array) {
if (parseContext.extensionErrorCheck($1.line, "GL_3DL_array_objects")) {
parseContext.recover();
......@@ -688,7 +702,7 @@ function_identifier
TString tempString = "";
TType type($1);
TFunction *function = new TFunction(&tempString, type, EOpConstructStruct);
$$ = function;
$$.function = function;
} else {
TOperator op = EOpNull;
switch ($1.type) {
......@@ -711,17 +725,17 @@ function_identifier
case EbtInt:
switch($1.size) {
case 1: op = EOpConstructInt; break;
case 2: FRAG_VERT_ONLY("ivec2", $1.line); op = EOpConstructIVec2; break;
case 3: FRAG_VERT_ONLY("ivec3", $1.line); op = EOpConstructIVec3; break;
case 4: FRAG_VERT_ONLY("ivec4", $1.line); op = EOpConstructIVec4; break;
case 2: op = EOpConstructIVec2; break;
case 3: op = EOpConstructIVec3; break;
case 4: op = EOpConstructIVec4; break;
}
break;
case EbtBool:
switch($1.size) {
case 1: op = EOpConstructBool; break;
case 2: FRAG_VERT_ONLY("bvec2", $1.line); op = EOpConstructBVec2; break;
case 3: FRAG_VERT_ONLY("bvec3", $1.line); op = EOpConstructBVec3; break;
case 4: FRAG_VERT_ONLY("bvec4", $1.line); op = EOpConstructBVec4; break;
case 2: op = EOpConstructBVec2; break;
case 3: op = EOpConstructBVec3; break;
case 4: op = EOpConstructBVec4; break;
}
break;
}
......@@ -734,27 +748,48 @@ function_identifier
TString tempString = "";
TType type($1);
TFunction *function = new TFunction(&tempString, type, op);
$$ = function;
$$.function = function;
}
}
| IDENTIFIER {
if (parseContext.reservedErrorCheck($1.line, *$1.string))
| postfix_expression {
//
// 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();
TType type(EbtVoid);
TFunction *function = new TFunction($1.string, type);
$$ = function;
}
| FIELD_SELECTION {
if (parseContext.reservedErrorCheck($1.line, *$1.string))
} else {
TIntermSymbol* symbol = $1->getAsSymbolNode();
if (symbol) {
if (parseContext.reservedErrorCheck(symbol->getLine(), symbol->getSymbol()))
parseContext.recover();
TType type(EbtVoid);
TFunction *function = new TFunction($1.string, type);
$$ = function;
TFunction *function = new TFunction(&symbol->getSymbol(), TType(EbtVoid));
$$.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
: postfix_expression {
parseContext.variableErrorCheck($1);
$$ = $1;
}
| INC_OP unary_expression {
......@@ -802,15 +837,13 @@ unary_operator
: PLUS { $$.line = $1.line; $$.op = EOpNull; }
| DASH { $$.line = $1.line; $$.op = EOpNegative; }
| BANG { $$.line = $1.line; $$.op = EOpLogicalNot; }
| TILDE { PACK_UNPACK_ONLY("~", $1.line);
$$.line = $1.line; $$.op = EOpBitwiseNot; }
| TILDE { $$.line = $1.line; $$.op = EOpBitwiseNot; }
;
// Grammar Note: No '*' or '&' unary ops. Pointers are not supported.
multiplicative_expression
: unary_expression { $$ = $1; }
| multiplicative_expression STAR unary_expression {
FRAG_VERT_ONLY("*", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) {
parseContext.binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString());
......@@ -819,7 +852,6 @@ multiplicative_expression
}
}
| multiplicative_expression SLASH unary_expression {
FRAG_VERT_ONLY("/", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) {
parseContext.binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString());
......@@ -828,7 +860,6 @@ multiplicative_expression
}
}
| multiplicative_expression PERCENT unary_expression {
PACK_UNPACK_ONLY("%", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpMod, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) {
parseContext.binaryOpError($2.line, "%", $1->getCompleteString(), $3->getCompleteString());
......@@ -861,7 +892,6 @@ additive_expression
shift_expression
: additive_expression { $$ = $1; }
| shift_expression LEFT_OP additive_expression {
PACK_UNPACK_ONLY("<<", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpLeftShift, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) {
parseContext.binaryOpError($2.line, "<<", $1->getCompleteString(), $3->getCompleteString());
......@@ -870,7 +900,6 @@ shift_expression
}
}
| shift_expression RIGHT_OP additive_expression {
PACK_UNPACK_ONLY(">>", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpRightShift, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) {
parseContext.binaryOpError($2.line, ">>", $1->getCompleteString(), $3->getCompleteString());
......@@ -953,7 +982,6 @@ equality_expression
and_expression
: equality_expression { $$ = $1; }
| and_expression AMPERSAND equality_expression {
PACK_UNPACK_ONLY("&", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpAnd, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) {
parseContext.binaryOpError($2.line, "&", $1->getCompleteString(), $3->getCompleteString());
......@@ -966,7 +994,6 @@ and_expression
exclusive_or_expression
: and_expression { $$ = $1; }
| exclusive_or_expression CARET and_expression {
PACK_UNPACK_ONLY("^", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpExclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) {
parseContext.binaryOpError($2.line, "^", $1->getCompleteString(), $3->getCompleteString());
......@@ -979,7 +1006,6 @@ exclusive_or_expression
inclusive_or_expression
: exclusive_or_expression { $$ = $1; }
| inclusive_or_expression VERTICAL_BAR exclusive_or_expression {
PACK_UNPACK_ONLY("|", $2.line);
$$ = parseContext.intermediate.addBinaryMath(EOpInclusiveOr, $1, $3, $2.line, parseContext.symbolTable);
if ($$ == 0) {
parseContext.binaryOpError($2.line, "|", $1->getCompleteString(), $3->getCompleteString());
......@@ -1066,16 +1092,16 @@ assignment_expression
assignment_operator
: EQUAL { $$.line = $1.line; $$.op = EOpAssign; }
| MUL_ASSIGN { FRAG_VERT_ONLY("*=", $1.line); $$.line = $1.line; $$.op = EOpMulAssign; }
| DIV_ASSIGN { FRAG_VERT_ONLY("/=", $1.line); $$.line = $1.line; $$.op = EOpDivAssign; }
| MOD_ASSIGN { PACK_UNPACK_ONLY("%=", $1.line); $$.line = $1.line; $$.op = EOpModAssign; }
| MUL_ASSIGN { $$.line = $1.line; $$.op = EOpMulAssign; }
| DIV_ASSIGN { $$.line = $1.line; $$.op = EOpDivAssign; }
| MOD_ASSIGN { $$.line = $1.line; $$.op = EOpModAssign; }
| ADD_ASSIGN { $$.line = $1.line; $$.op = EOpAddAssign; }
| SUB_ASSIGN { $$.line = $1.line; $$.op = EOpSubAssign; }
| LEFT_ASSIGN { PACK_UNPACK_ONLY("<<=", $1.line); $$.line = $1.line; $$.op = EOpLeftShiftAssign; }
| RIGHT_ASSIGN { PACK_UNPACK_ONLY("<<=", $1.line); $$.line = $1.line; $$.op = EOpRightShiftAssign; }
| AND_ASSIGN { PACK_UNPACK_ONLY("&=", $1.line); $$.line = $1.line; $$.op = EOpAndAssign; }
| XOR_ASSIGN { PACK_UNPACK_ONLY("^=", $1.line); $$.line = $1.line; $$.op = EOpExclusiveOrAssign; }
| OR_ASSIGN { PACK_UNPACK_ONLY("|=", $1.line); $$.line = $1.line; $$.op = EOpInclusiveOrAssign; }
| LEFT_ASSIGN { $$.line = $1.line; $$.op = EOpLeftShiftAssign; }
| RIGHT_ASSIGN { $$.line = $1.line; $$.op = EOpRightShiftAssign; }
| AND_ASSIGN { $$.line = $1.line; $$.op = EOpAndAssign; }
| XOR_ASSIGN { $$.line = $1.line; $$.op = EOpExclusiveOrAssign; }
| OR_ASSIGN { $$.line = $1.line; $$.op = EOpInclusiveOrAssign; }
;
expression
......@@ -1101,12 +1127,55 @@ constant_expression
;
declaration
: function_prototype SEMICOLON { $$ = 0; }
: function_prototype SEMICOLON {
$$ = 0;
// TODO: subroutines: make the identifier a user type for this signature
}
| init_declarator_list SEMICOLON {
if ($1.intermAggregate)
$1.intermAggregate->setOperator(EOpSequence);
$$ = $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
......@@ -1228,8 +1297,7 @@ parameter_declarator
parseContext.recover();
$1.setArray(true, size);
TType* type = new TType($1);
TParameter param = { $2.string, type };
TParameter param = { $2.string, new TType($1)};
$$.line = $2.line;
$$.param = param;
}
......@@ -1237,54 +1305,42 @@ parameter_declarator
parameter_declaration
//
// The only parameter qualifier a parameter can have are
// IN_QUAL, OUT_QUAL, INOUT_QUAL, or CONST.
// With name
//
: type_qualifier parameter_declarator {
$$ = $2;
//
// Type + name
//
: type_qualifier parameter_qualifier parameter_declarator {
$$ = $3;
if (parseContext.paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier, *$2.param.type))
parseContext.recover();
if (parseContext.paramErrorCheck($1.line, $1.qualifier, $$.param.type))
parseContext.recover();
}
| parameter_qualifier parameter_declarator {
$$ = $2;
if (parseContext.parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
| parameter_declarator {
$$ = $1;
if (parseContext.parameterSamplerErrorCheck($1.line, EvqIn, *$1.param.type))
parseContext.recover();
if (parseContext.paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type))
parseContext.recover();
}
//
// Only type
// Without name
//
| type_qualifier parameter_qualifier parameter_type_specifier {
$$ = $3;
if (parseContext.paramErrorCheck($3.line, $1.qualifier, $2, $$.param.type))
parseContext.recover();
}
| parameter_qualifier parameter_type_specifier {
| type_qualifier parameter_type_specifier {
$$ = $2;
if (parseContext.parameterSamplerErrorCheck($2.line, $1, *$2.param.type))
if (parseContext.parameterSamplerErrorCheck($2.line, $1.qualifier, *$2.param.type))
parseContext.recover();
if (parseContext.paramErrorCheck($2.line, EvqTemporary, $1, $$.param.type))
if (parseContext.paramErrorCheck($1.line, $1.qualifier, $$.param.type))
parseContext.recover();
}
;
| parameter_type_specifier {
$$ = $1;
parameter_qualifier
: /* empty */ {
$$ = EvqIn;
}
| IN_QUAL {
$$ = EvqIn;
}
| OUT_QUAL {
$$ = EvqOut;
}
| INOUT_QUAL {
$$ = EvqInOut;
if (parseContext.parameterSamplerErrorCheck($1.line, $1.qualifier, *$1.param.type))
parseContext.recover();
if (parseContext.paramErrorCheck($1.line, EvqTemporary, $$.param.type))
parseContext.recover();
}
;
......@@ -1447,6 +1503,10 @@ single_declaration
}
| fully_specified_type IDENTIFIER {
$$.intermAggregate = 0;
if (parseContext.globalQualifierFixAndErrorCheck($1.line, $1.qualifier))
parseContext.recover();
$$.type = $1;
if (parseContext.structQualifierErrorCheck($2.line, $$.type))
......@@ -1595,75 +1655,8 @@ single_declaration
}
}
//
// Place holder for the pack/unpack languages.
//
// | buffer_specifier {
// $$.intermAggregate = 0;
// }
;
// 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
: type_specifier {
$$ = $1;
......@@ -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
: 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);
}
| ATTRIBUTE {
......@@ -1718,17 +1796,104 @@ type_qualifier
else
$$.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 {
if (parseContext.globalErrorCheck($1.line, parseContext.symbolTable.atGlobalLevel(), "uniform"))
parseContext.recover();
$$.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_nonarray {
$$ = $1;
}
| type_specifier_nonarray LEFT_BRACKET RIGHT_BRACKET {
$$ = $1;
}
| type_specifier_nonarray LEFT_BRACKET constant_expression RIGHT_BRACKET {
$$ = $1;
......@@ -1744,27 +1909,32 @@ type_specifier
;
type_specifier_nonarray
: VOID_TYPE {
: VOID {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.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;
// TODO: implement EbtDouble, check all float types
$$.setBasic(EbtFloat, qual, $1.line);
}
| INT_TYPE {
| INT {
// TODO: implement EbtUint, check all int types
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.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;
$$.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 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
......@@ -1780,6 +1950,12 @@ type_specifier_nonarray
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4);
}
| DVEC2 {
}
| DVEC3 {
}
| DVEC4 {
}
| BVEC2 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtBool, qual, $1.line);
......@@ -1810,76 +1986,514 @@ type_specifier_nonarray
$$.setBasic(EbtInt, qual, $1.line);
$$.setAggregate(4);
}
| MATRIX2 {
FRAG_VERT_ONLY("mat2", $1.line);
| UVEC2 {
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;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(2, true);
}
| MATRIX3 {
FRAG_VERT_ONLY("mat3", $1.line);
| MAT3 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(3, true);
}
| MATRIX4 {
FRAG_VERT_ONLY("mat4", $1.line);
| MAT4 {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtFloat, qual, $1.line);
$$.setAggregate(4, true);
}
| SAMPLER1D {
FRAG_VERT_ONLY("sampler1D", $1.line);
| MAT2X2 {
// TODO: implement this type
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 {
FRAG_VERT_ONLY("sampler2D", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2D, qual, $1.line);
}
| SAMPLER3D {
FRAG_VERT_ONLY("sampler3D", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler3D, qual, $1.line);
}
| SAMPLERCUBE {
FRAG_VERT_ONLY("samplerCube", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerCube, qual, $1.line);
}
| SAMPLER1DSHADOW {
FRAG_VERT_ONLY("sampler1DShadow", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler1DShadow, qual, $1.line);
}
| SAMPLER2DSHADOW {
FRAG_VERT_ONLY("sampler2DShadow", $1.line);
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $1.line);
}
| SAMPLERRECTARB {
// ARB_texture_rectangle
FRAG_VERT_ONLY("samplerRectARB", $1.line);
| SAMPLERCUBESHADOW {
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSampler2DShadow, qual, $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"))
parseContext.recover();
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.setBasic(EbtSamplerRect, qual, $1.line);
}
| SAMPLERRECTSHADOWARB {
// ARB_texture_rectangle
FRAG_VERT_ONLY("samplerRectShadowARB", $1.line);
| SAMPLER2DRECTSHADOW {
if (parseContext.extensionErrorCheck($1.line, "GL_ARB_texture_rectangle"))
parseContext.recover();
TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
$$.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 {
FRAG_VERT_ONLY("struct", $1.line);
$$ = $1;
$$.qualifier = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary;
}
......@@ -1895,6 +2509,15 @@ type_specifier_nonarray
}
;
precision_qualifier
: HIGH_PRECISION {
}
| MEDIUM_PRECISION {
}
| LOW_PRECISION {
}
;
struct_specifier
: STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE {
TType* structure = new TType($4, *$2.string);
......@@ -1955,6 +2578,29 @@ struct_declaration
(*$$)[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
......@@ -1973,6 +2619,12 @@ struct_declarator
$$.line = $1.line;
$$.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 {
$$.type = new TType(EbtVoid);
$$.line = $1.line;
......@@ -1986,7 +2638,25 @@ struct_declarator
;
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
......@@ -1998,12 +2668,14 @@ statement
| 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
: declaration_statement { $$ = $1; }
| expression_statement { $$ = $1; }
| selection_statement { $$ = $1; }
| switch_statement { $$ = $1; }
| case_label { $$ = $1; }
| iteration_statement { $$ = $1; }
| jump_statement { $$ = $1; }
;
......@@ -2067,8 +2739,6 @@ selection_rest_statement
}
;
// Grammar Note: No 'switch'. Switch statements not supported.
condition
// In 1996 c++ draft, conditions can include single declarations
: expression {
......@@ -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
: WHILE LEFT_PAREN { parseContext.symbolTable.push(); ++parseContext.loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
parseContext.symbolTable.pop();
......@@ -2155,8 +2849,8 @@ jump_statement
$$ = parseContext.intermediate.addBranch(EOpContinue, $1.line);
}
| BREAK SEMICOLON {
if (parseContext.loopNestingLevel <= 0) {
parseContext.error($1.line, "break statement only allowed in loops", "", "");
if (parseContext.loopNestingLevel + parseContext.switchNestingLevel <= 0) {
parseContext.error($1.line, "break statement only allowed in switch and loops", "", "");
parseContext.recover();
}
$$ = parseContext.intermediate.addBranch(EOpBreak, $1.line);
......
......@@ -306,16 +306,6 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
case EOpRefract: out.debug << "refract"; 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");
}
......
......@@ -65,6 +65,7 @@ public:
TIntermNode* addSelection(TIntermTyped* cond, TIntermNodePair code, TSourceLoc);
TIntermTyped* addSelection(TIntermTyped* cond, TIntermTyped* trueBlock, TIntermTyped* falseBlock, TSourceLoc);
TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc);
TIntermTyped* addMethod(TIntermTyped*, TType&, const TString*, TSourceLoc);
TIntermConstantUnion* addConstantUnion(constUnion*, const TType&, TSourceLoc);
TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
bool parseConstTree(TSourceLoc, TIntermNode*, constUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);
......
......@@ -72,8 +72,6 @@ SH_IMPORT_EXPORT int __fastcall ShFinalize();
typedef enum {
EShLangVertex,
EShLangFragment,
EShLangPack,
EShLangUnpack,
EShLangCount,
} EShLanguage;
......@@ -82,8 +80,6 @@ typedef enum {
//
typedef enum {
EShExVertexFragment,
EShExPackFragment,
EShExUnpackFragment,
EShExFragment
} 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