From 5d3e2e35b6c86b1a4f7968e8f1408b6063d0443a Mon Sep 17 00:00:00 2001 From: John Kessenich <cepheus@frii.com> Date: Wed, 12 Dec 2012 22:42:30 +0000 Subject: [PATCH] Support suffixes for floats and doubles (none were supported in 110). Add preprocessor support for parsing doubles. Add double support to the flex stage. Put in some of the basic double supported needed in the front end. Add generic support for version numbers in the preprocessor, and the core, compatibility, and es profiles. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@19949 e7fa87d3-cd2b-0410-9028-fcbf551c1848 --- glslang/Include/BaseTypes.h | 1 + glslang/Include/ConstantUnion.h | 30 + glslang/Include/Types.h | 1 + glslang/Include/intermediate.h | 1 + glslang/MachineIndependent/Intermediate.cpp | 7 +- glslang/MachineIndependent/SymbolTable.cpp | 1 + glslang/MachineIndependent/glslang.l | 1394 +++++++++-------- glslang/MachineIndependent/glslang.y | 7 +- glslang/MachineIndependent/intermOut.cpp | 9 + .../MachineIndependent/preprocessor/compile.h | 4 + glslang/MachineIndependent/preprocessor/cpp.c | 28 +- .../preprocessor/cppstruct.c | 2 + .../MachineIndependent/preprocessor/parser.h | 1 + .../MachineIndependent/preprocessor/scanner.c | 124 +- .../preprocessor/slglobals.h | 2 + 15 files changed, 842 insertions(+), 770 deletions(-) diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h index da2730316..1283c0c29 100644 --- a/glslang/Include/BaseTypes.h +++ b/glslang/Include/BaseTypes.h @@ -41,6 +41,7 @@ enum TBasicType { EbtVoid, EbtFloat, + EbtDouble, EbtInt, EbtBool, EbtGuardSamplerBegin, // non type: see implementation of IsSampler() diff --git a/glslang/Include/ConstantUnion.h b/glslang/Include/ConstantUnion.h index 311679653..700ce0602 100644 --- a/glslang/Include/ConstantUnion.h +++ b/glslang/Include/ConstantUnion.h @@ -42,13 +42,16 @@ public: POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) void setIConst(int i) {iConst = i; type = EbtInt; } void setFConst(float f) {fConst = f; type = EbtFloat; } + void setDConst(double d) {dConst = d; type = EbtDouble; } void setBConst(bool b) {bConst = b; type = EbtBool; } int getIConst() { return iConst; } float getFConst() { return fConst; } + double getDConst() { return dConst; } bool getBConst() { return bConst; } int getIConst() const { return iConst; } float getFConst() const { return fConst; } + double getDConst() const { return dConst; } bool getBConst() const { return bConst; } bool operator==(const int i) const @@ -67,6 +70,14 @@ public: return false; } + bool operator==(const double d) const + { + if (d == dConst) + return true; + + return false; + } + bool operator==(const bool b) const { if (b == bConst) @@ -90,6 +101,11 @@ public: if (constant.fConst == fConst) return true; + break; + case EbtDouble: + if (constant.dConst == dConst) + return true; + break; case EbtBool: if (constant.bConst == bConst) @@ -134,6 +150,11 @@ public: if (fConst > constant.fConst) return true; + return false; + case EbtDouble: + if (dConst > constant.dConst) + return true; + return false; default: assert(false && "Default missing"); @@ -156,6 +177,11 @@ public: if (fConst < constant.fConst) return true; + return false; + case EbtDouble: + if (dConst < constant.dConst) + return true; + return false; default: assert(false && "Default missing"); @@ -172,6 +198,7 @@ public: switch (type) { case EbtInt: returnValue.setIConst(iConst + constant.iConst); break; case EbtFloat: returnValue.setFConst(fConst + constant.fConst); break; + case EbtDouble: returnValue.setDConst(dConst + constant.dConst); break; default: assert(false && "Default missing"); } @@ -185,6 +212,7 @@ public: switch (type) { case EbtInt: returnValue.setIConst(iConst - constant.iConst); break; case EbtFloat: returnValue.setFConst(fConst - constant.fConst); break; + case EbtDouble: returnValue.setDConst(dConst - constant.dConst); break; default: assert(false && "Default missing"); } @@ -198,6 +226,7 @@ public: switch (type) { case EbtInt: returnValue.setIConst(iConst * constant.iConst); break; case EbtFloat: returnValue.setFConst(fConst * constant.fConst); break; + case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; default: assert(false && "Default missing"); } @@ -307,6 +336,7 @@ private: int iConst; // used for ivec, scalar ints bool bConst; // used for bvec, scalar bools float fConst; // used for vec, mat, scalar floats + double dConst; // used for dvec, dmat, scalar doubles } ; TBasicType type; diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index 3db8d3a63..e9bfa443f 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -235,6 +235,7 @@ public: switch (t) { case EbtVoid: return "void"; break; case EbtFloat: return "float"; break; + case EbtDouble: return "double"; break; case EbtInt: return "int"; break; case EbtBool: return "bool"; break; case EbtSampler1D: return "sampler1D"; break; diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index f0c2cbd3f..f9571c982 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -187,6 +187,7 @@ enum TOperator { EOpConstructInt, EOpConstructBool, EOpConstructFloat, + EOpConstructDouble, EOpConstructVec2, EOpConstructVec3, EOpConstructVec4, diff --git a/glslang/MachineIndependent/Intermediate.cpp b/glslang/MachineIndependent/Intermediate.cpp index 6dc3ca8a3..03871edab 100644 --- a/glslang/MachineIndependent/Intermediate.cpp +++ b/glslang/MachineIndependent/Intermediate.cpp @@ -243,9 +243,10 @@ TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, // TBasicType newType = EbtVoid; switch (op) { - case EOpConstructInt: newType = EbtInt; break; - case EOpConstructBool: newType = EbtBool; break; - case EOpConstructFloat: newType = EbtFloat; break; + case EOpConstructInt: newType = EbtInt; break; + case EOpConstructBool: newType = EbtBool; break; + case EOpConstructFloat: newType = EbtFloat; break; + case EOpConstructDouble: newType = EbtDouble; break; default: break; } diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index aabb5beb9..60f31b2b8 100644 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -55,6 +55,7 @@ void TType::buildMangledName(TString& mangledName) switch (type) { case EbtFloat: mangledName += 'f'; break; + case EbtDouble: mangledName += 'd'; break; case EbtInt: mangledName += 'i'; break; case EbtBool: mangledName += 'b'; break; case EbtSampler1D: mangledName += "s1"; break; diff --git a/glslang/MachineIndependent/glslang.l b/glslang/MachineIndependent/glslang.l index 66e3e6891..771d22c35 100644 --- a/glslang/MachineIndependent/glslang.l +++ b/glslang/MachineIndependent/glslang.l @@ -1,159 +1,161 @@ -/* -// -//Copyright (C) 2002-2005 3Dlabs Inc. Ltd. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions -//are met: -// -// Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following -// disclaimer in the documentation and/or other materials provided -// with the distribution. -// -// Neither the name of 3Dlabs Inc. Ltd. nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS -//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE -//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, -//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN -//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -*/ -/* Based on -ANSI C grammar, Lex specification - -In 1985, Jeff Lee published this Lex specification together with a Yacc -grammar for the April 30, 1985 ANSI C draft. Tom Stockfisch reposted -both to net.sources in 1987; that original, as mentioned in the answer -to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net, -file usenet/net.sources/ansi.c.grammar.Z. - -I intend to keep this version as close to the current C Standard grammar -as possible; please let me know if you discover discrepancies. - -Jutta Degener, 1995 -*/ - -D [0-9] -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 -%{ -#include <stdio.h> -#include <stdlib.h> -#include "ParseHelper.h" -#include "glslang_tab.cpp.h" - -/* windows only pragma */ -#ifdef _MSC_VER -#pragma warning(disable : 4102) -#endif - -int yy_input(char* buf, int max_size); -TSourceLoc yylineno; - -#ifdef _WIN32 - extern int yyparse(TParseContext&); - #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext) -#else - extern int yyparse(void*); - #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal) - #define parseContext (*((TParseContext*)(parseContextLocal))) -#endif - -#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size)) - -%} - -%option noyywrap -%option never-interactive -%option outfile="gen_glslang.cpp" -%x FIELDS - - -%% -<*>"//"[^\n]*"\n" { /* ?? carriage and/or line-feed? */ }; - -"attribute" { pyylval->lex.line = yylineno; return(ATTRIBUTE); } -"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); } -"buffer" { pyylval->lex.line = yylineno; return(BUFFER); } -"shared" { pyylval->lex.line = yylineno; return(SHARED); } -"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); } -"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); } -"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); } +/* +// +//Copyright (C) 2002-2005 3Dlabs Inc. Ltd. +//All rights reserved. +// +//Redistribution and use in source and binary forms, with or without +//modification, are permitted provided that the following conditions +//are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// +// Neither the name of 3Dlabs Inc. Ltd. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +//POSSIBILITY OF SUCH DAMAGE. +// +*/ +/* Based on +ANSI C grammar, Lex specification + +In 1985, Jeff Lee published this Lex specification together with a Yacc +grammar for the April 30, 1985 ANSI C draft. Tom Stockfisch reposted +both to net.sources in 1987; that original, as mentioned in the answer +to question 17.25 of the comp.lang.c FAQ, can be ftp'ed from ftp.uu.net, +file usenet/net.sources/ansi.c.grammar.Z. + +I intend to keep this version as close to the current C Standard grammar +as possible; please let me know if you discover discrepancies. + +Jutta Degener, 1995 +*/ + +D [0-9] +L [a-zA-Z_] +H [a-fA-F0-9] +E [Ee][+-]?{D}+ +O [0-7] +U [uU] +F [fF] +LF [lL][fF] + +/* TODO: double literals, which will likely require pre-processor rework */ +/* TODO: unsigned int literals, which will likely require pre-processor rework */ + +%option nounput +%{ +#include <stdio.h> +#include <stdlib.h> +#include "ParseHelper.h" +#include "glslang_tab.cpp.h" + +/* windows only pragma */ +#ifdef _MSC_VER +#pragma warning(disable : 4102) +#endif + +int yy_input(char* buf, int max_size); +TSourceLoc yylineno; + +#ifdef _WIN32 + extern int yyparse(TParseContext&); + #define YY_DECL int yylex(YYSTYPE* pyylval, TParseContext& parseContext) +#else + extern int yyparse(void*); + #define YY_DECL int yylex(YYSTYPE* pyylval, void* parseContextLocal) + #define parseContext (*((TParseContext*)(parseContextLocal))) +#endif + +#define YY_INPUT(buf,result,max_size) (result = yy_input(buf, max_size)) + +%} + +%option noyywrap +%option never-interactive +%option outfile="gen_glslang.cpp" +%x FIELDS + + +%% +<*>"//"[^\n]*"\n" { /* ?? carriage and/or line-feed? */ }; + +"attribute" { pyylval->lex.line = yylineno; return(ATTRIBUTE); } +"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); } +"buffer" { pyylval->lex.line = yylineno; return(BUFFER); } +"shared" { pyylval->lex.line = yylineno; return(SHARED); } +"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); } +"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); } +"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); } @@ -177,52 +179,52 @@ TSourceLoc yylineno; "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); } -"vec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); } -"dvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (DVEC2); } -"dvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (DVEC3); } -"dvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (DVEC4); } -"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); } - -"sampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1D; } -"sampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; } -"sampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER3D; } -"samplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; } -"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 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; } + +"vec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC2); } +"vec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC3); } +"vec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (VEC4); } +"dvec2" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (DVEC2); } +"dvec3" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (DVEC3); } +"dvec4" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return (DVEC4); } +"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); } + +"sampler1D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER1D; } +"sampler2D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER2D; } +"sampler3D" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLER3D; } +"samplerCube" { pyylval->lex.line = yylineno; parseContext.lexAfterType = true; return SAMPLERCUBE; } +"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 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); } @@ -266,494 +268,500 @@ TSourceLoc yylineno; "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); } - -"asm" { PaReservedWord(); return 0; } - -"class" { PaReservedWord(); return 0; } -"union" { PaReservedWord(); return 0; } -"enum" { PaReservedWord(); return 0; } -"typedef" { PaReservedWord(); return 0; } -"template" { PaReservedWord(); return 0; } -"this" { PaReservedWord(); return 0; } -"packed" { PaReservedWord(); return 0; } - -"goto" { PaReservedWord(); return 0; } - -"inline" { PaReservedWord(); return 0; } -"noinline" { PaReservedWord(); return 0; } -"public" { PaReservedWord(); return 0; } -"static" { PaReservedWord(); return 0; } -"extern" { PaReservedWord(); return 0; } -"external" { PaReservedWord(); return 0; } -"interface" { PaReservedWord(); return 0; } - -"long" { PaReservedWord(); return 0; } -"short" { PaReservedWord(); return 0; } -"half" { PaReservedWord(); return 0; } -"fixed" { PaReservedWord(); return 0; } -"unsigned" { PaReservedWord(); return 0; } - -"input" { PaReservedWord(); return 0; } -"output" { PaReservedWord(); return 0; } - -"hvec2" { PaReservedWord(); return 0; } -"hvec3" { PaReservedWord(); return 0; } -"hvec4" { PaReservedWord(); return 0; } -"fvec2" { PaReservedWord(); return 0; } -"fvec3" { PaReservedWord(); return 0; } -"fvec4" { PaReservedWord(); return 0; } - -"sampler3DRect" { PaReservedWord(); return 0; } - -"sizeof" { PaReservedWord(); return 0; } -"cast" { PaReservedWord(); return 0; } - -"namespace" { PaReservedWord(); return 0; } -"using" { PaReservedWord(); return 0; } - -{L}({L}|{D})* { - pyylval->lex.line = yylineno; - pyylval->lex.string = NewPoolTString(yytext); - return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol); -} - -0[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } -0{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } -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); } - -"/*" { int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; } - -"+=" { pyylval->lex.line = yylineno; return(ADD_ASSIGN); } -"-=" { pyylval->lex.line = yylineno; return(SUB_ASSIGN); } -"*=" { pyylval->lex.line = yylineno; return(MUL_ASSIGN); } -"/=" { pyylval->lex.line = yylineno; return(DIV_ASSIGN); } -"%=" { pyylval->lex.line = yylineno; return(MOD_ASSIGN); } -"<<=" { pyylval->lex.line = yylineno; return(LEFT_ASSIGN); } -">>=" { pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); } -"&=" { pyylval->lex.line = yylineno; return(AND_ASSIGN); } -"^=" { pyylval->lex.line = yylineno; return(XOR_ASSIGN); } -"|=" { pyylval->lex.line = yylineno; return(OR_ASSIGN); } - -"++" { pyylval->lex.line = yylineno; return(INC_OP); } -"--" { pyylval->lex.line = yylineno; return(DEC_OP); } -"&&" { pyylval->lex.line = yylineno; return(AND_OP); } -"||" { pyylval->lex.line = yylineno; return(OR_OP); } -"^^" { pyylval->lex.line = yylineno; return(XOR_OP); } -"<=" { pyylval->lex.line = yylineno; return(LE_OP); } -">=" { pyylval->lex.line = yylineno; return(GE_OP); } -"==" { pyylval->lex.line = yylineno; return(EQ_OP); } -"!=" { pyylval->lex.line = yylineno; return(NE_OP); } -"<<" { pyylval->lex.line = yylineno; return(LEFT_OP); } -">>" { pyylval->lex.line = yylineno; return(RIGHT_OP); } -";" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); } -("{"|"<%") { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); } -("}"|"%>") { pyylval->lex.line = yylineno; return(RIGHT_BRACE); } -"," { pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); } -":" { pyylval->lex.line = yylineno; return(COLON); } -"=" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); } -"(" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); } -")" { pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); } -("["|"<:") { pyylval->lex.line = yylineno; return(LEFT_BRACKET); } -("]"|":>") { pyylval->lex.line = yylineno; return(RIGHT_BRACKET); } -"." { BEGIN(FIELDS); return(DOT); } -"!" { pyylval->lex.line = yylineno; return(BANG); } -"-" { pyylval->lex.line = yylineno; return(DASH); } -"~" { pyylval->lex.line = yylineno; return(TILDE); } -"+" { pyylval->lex.line = yylineno; return(PLUS); } -"*" { pyylval->lex.line = yylineno; return(STAR); } -"/" { pyylval->lex.line = yylineno; return(SLASH); } -"%" { pyylval->lex.line = yylineno; return(PERCENT); } -"<" { pyylval->lex.line = yylineno; return(LEFT_ANGLE); } -">" { pyylval->lex.line = yylineno; return(RIGHT_ANGLE); } -"|" { pyylval->lex.line = yylineno; return(VERTICAL_BAR); } -"^" { pyylval->lex.line = yylineno; return(CARET); } -"&" { pyylval->lex.line = yylineno; return(AMPERSAND); } -"?" { pyylval->lex.line = yylineno; return(QUESTION); } - -<FIELDS>{L}({L}|{D})* { -BEGIN(INITIAL); - pyylval->lex.line = yylineno; - pyylval->lex.string = NewPoolTString(yytext); - return FIELD_SELECTION; } -<FIELDS>[ \t\v\f\r] {} - -[ \t\v\n\f\r] { } -<*><<EOF>> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();} -<*>. { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n"; - return 0; } - -%% - - -//Including Pre-processor. -extern "C" { - #include "./preprocessor/preprocess.h" -} - -// -// The YY_INPUT macro just calls this. Maybe this could be just put into -// the macro directly. -// - -int yy_input(char* buf, int max_size) -{ - char *char_token =NULL; - int len; - - if ((len = yylex_CPP(buf, max_size)) == 0) - return 0; - if (len >= max_size) - YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); - - buf[len] = ' '; - return len+1; -} - - -// -// Parse an array of strings using yyparse. We set up globals used by -// yywrap. -// -// Returns 0 for success, as per yyparse(). -// -int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal) -{ - int argv0len; - - ScanFromString(argv[0]); - - //Storing the Current Compiler Parse context into the cpp structure. - cpp->pC = (void*)&parseContextLocal; - - if (!argv || argc == 0) - return 1; - - for (int i = 0; i < argc; ++i) { - if (!argv[i]) { - parseContextLocal.error(0, "Null shader source string", "", ""); - parseContextLocal.recover(); - return 1; - } - } - - if (!strLen) { - argv0len = (int) strlen(argv[0]); - strLen = &argv0len; - } - yyrestart(0); - (&parseContextLocal)->AfterEOF = false; - cpp->PaWhichStr = 0; - cpp->PaArgv = argv; - cpp->PaArgc = argc; - cpp->PaStrLen = strLen; - cpp->notAVersionToken = 0; - yylineno = 1; - - if (*cpp->PaStrLen >= 0) { - int ret; - #ifdef _WIN32 - ret = yyparse(parseContextLocal); - #else - ret = yyparse((void*)(&parseContextLocal)); - #endif - if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0) - return 1; - else - return 0; - } - else - return 0; -} - -void yyerror(char *s) -{ - if (((TParseContext *)cpp->pC)->AfterEOF) { - if (cpp->tokensBeforeEOF == 1) { - GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, ""); - GlobalParseContext->recover(); - } - } else { - GlobalParseContext->error(yylineno, "syntax error", yytext, s, ""); - GlobalParseContext->recover(); - } -} - -void PaReservedWord() -{ - GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", ""); - GlobalParseContext->recover(); -} - -int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol) -{ - symbol = parseContextLocal.symbolTable.find(id); - if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) { - TVariable* variable = static_cast<TVariable*>(symbol); - if (variable->isUserType()) { - parseContextLocal.lexAfterType = true; - return TYPE_NAME; - } - } - - return IDENTIFIER; -} - -int PaParseComment(int &lineno, TParseContext& parseContextLocal) -{ - int transitionFlag = 0; - int nextChar; - - while (transitionFlag != 2) { - nextChar = yyinput(); - if (nextChar == '\n') - lineno++; - switch (nextChar) { - case '*' : - transitionFlag = 1; - break; - case '/' : /* if star is the previous character, then it is the end of comment */ - if (transitionFlag == 1) { - return 1 ; - } - break; - case EOF : - /* Raise error message here */ - parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", ""); - GlobalParseContext->recover(); - return YY_NULL; - default : /* Any other character will be a part of the comment */ - transitionFlag = 0; - } - } - return 1; -} - -extern "C" { - -void CPPDebugLogMsg(const char *msg) -{ - ((TParseContext *)cpp->pC)->infoSink.debug.message(EPrefixNone, msg); -} - -void CPPWarningToInfoLog(const char *msg) -{ - ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg, yylineno); -} - -void CPPShInfoLogMsg(const char *msg) -{ - ((TParseContext *)cpp->pC)->error(yylineno,"", "",msg,""); - GlobalParseContext->recover(); -} - -void CPPErrorToInfoLog(char *msg) -{ - ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,""); - GlobalParseContext->recover(); -} - -void SetLineNumber(int line) -{ - yylineno &= ~SourceLocLineMask; - yylineno |= line; -} - -void SetStringNumber(int string) -{ - yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask); -} - -int GetStringNumber(void) -{ - return yylineno >> 16; -} - -int GetLineNumber(void) -{ - return yylineno & SourceLocLineMask; -} - -void IncLineNumber(void) -{ - if ((yylineno & SourceLocLineMask) <= SourceLocLineMask) - ++yylineno; -} - -void DecLineNumber(void) -{ - if ((yylineno & SourceLocLineMask) > 0) - --yylineno; -} - -void HandlePragma(const char **tokens, int numTokens) -{ - if (!strcmp(tokens[0], "optimize")) { - if (numTokens != 4) { - CPPShInfoLogMsg("optimize pragma syntax is incorrect"); - return; - } - - if (strcmp(tokens[1], "(")) { - CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword"); - return; - } - - if (!strcmp(tokens[2], "on")) - ((TParseContext *)cpp->pC)->contextPragma.optimize = true; - else if (!strcmp(tokens[2], "off")) - ((TParseContext *)cpp->pC)->contextPragma.optimize = false; - else { - CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); - return; - } - - if (strcmp(tokens[3], ")")) { - CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma"); - return; - } - } else if (!strcmp(tokens[0], "debug")) { - if (numTokens != 4) { - CPPShInfoLogMsg("debug pragma syntax is incorrect"); - return; - } - - if (strcmp(tokens[1], "(")) { - CPPShInfoLogMsg("\"(\" expected after 'debug' keyword"); - return; - } - - if (!strcmp(tokens[2], "on")) - ((TParseContext *)cpp->pC)->contextPragma.debug = true; - else if (!strcmp(tokens[2], "off")) - ((TParseContext *)cpp->pC)->contextPragma.debug = false; - else { - CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma"); - return; - } - - if (strcmp(tokens[3], ")")) { - CPPShInfoLogMsg("\")\" expected to end 'debug' pragma"); - return; - } - } else { - -#ifdef PRAGMA_TABLE - // - // implementation specific pragma - // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma - // For now, just ignore the pragma that the implementation cannot recognize - // An Example of one such implementation for a pragma that has a syntax like - // #pragma pragmaname(pragmavalue) - // This implementation stores the current pragmavalue against the pragma name in pragmaTable. - // - if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) { - TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; - TPragmaTable::iterator iter; - iter = pragmaTable.find(TString(tokens[0])); - if (iter != pragmaTable.end()) { - iter->second = tokens[2]; - } else { - pragmaTable[tokens[0]] = tokens[2]; - } - } else if (numTokens >= 2) { - TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; - TPragmaTable::iterator iter; - iter = pragmaTable.find(TString(tokens[0])); - if (iter != pragmaTable.end()) { - iter->second = tokens[1]; - } else { - pragmaTable[tokens[0]] = tokens[1]; - } - } -#endif // PRAGMA_TABLE - } -} - -void StoreStr(char *string) -{ - TString strSrc; - strSrc = TString(string); - - ((TParseContext *)cpp->pC)->HashErrMsg = ((TParseContext *)cpp->pC)->HashErrMsg + " " + strSrc; -} - -const char* GetStrfromTStr(void) -{ - cpp->ErrMsg = (((TParseContext *)cpp->pC)->HashErrMsg).c_str(); - return cpp->ErrMsg; -} - -void ResetTString(void) -{ - ((TParseContext *)cpp->pC)->HashErrMsg = ""; -} - -TBehavior GetBehavior(const char* behavior) -{ - if (!strcmp("require", behavior)) - return EBhRequire; - else if (!strcmp("enable", behavior)) - return EBhEnable; - else if (!strcmp("disable", behavior)) - return EBhDisable; - else if (!strcmp("warn", behavior)) - return EBhWarn; - else { - CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str()); - return EBhDisable; - } -} - -void updateExtensionBehavior(const char* extName, const char* behavior) -{ - TBehavior behaviorVal = GetBehavior(behavior); - TMap<TString, TBehavior>:: iterator iter; - TString msg; - - // special cased for all extension - if (!strcmp(extName, "all")) { - if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) { - CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior"); - return; - } else { - for (iter = ((TParseContext *)cpp->pC)->extensionBehavior.begin(); iter != ((TParseContext *)cpp->pC)->extensionBehavior.end(); ++iter) - iter->second = behaviorVal; - } - } else { - iter = ((TParseContext *)cpp->pC)->extensionBehavior.find(TString(extName)); - if (iter == ((TParseContext *)cpp->pC)->extensionBehavior.end()) { - switch (behaviorVal) { - case EBhRequire: - CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str()); - break; - case EBhEnable: - case EBhWarn: - case EBhDisable: - msg = TString("extension '") + extName + "' is not supported"; - ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); - break; - } - return; - } else - iter->second = behaviorVal; - } -} - -} // extern "C" - -void setInitialState() -{ - yy_start = 1; -} + +"struct" { pyylval->lex.line = yylineno; return(STRUCT); } + +"asm" { PaReservedWord(); return 0; } + +"class" { PaReservedWord(); return 0; } +"union" { PaReservedWord(); return 0; } +"enum" { PaReservedWord(); return 0; } +"typedef" { PaReservedWord(); return 0; } +"template" { PaReservedWord(); return 0; } +"this" { PaReservedWord(); return 0; } +"packed" { PaReservedWord(); return 0; } + +"goto" { PaReservedWord(); return 0; } + +"inline" { PaReservedWord(); return 0; } +"noinline" { PaReservedWord(); return 0; } +"public" { PaReservedWord(); return 0; } +"static" { PaReservedWord(); return 0; } +"extern" { PaReservedWord(); return 0; } +"external" { PaReservedWord(); return 0; } +"interface" { PaReservedWord(); return 0; } + +"long" { PaReservedWord(); return 0; } +"short" { PaReservedWord(); return 0; } +"half" { PaReservedWord(); return 0; } +"fixed" { PaReservedWord(); return 0; } +"unsigned" { PaReservedWord(); return 0; } + +"input" { PaReservedWord(); return 0; } +"output" { PaReservedWord(); return 0; } + +"hvec2" { PaReservedWord(); return 0; } +"hvec3" { PaReservedWord(); return 0; } +"hvec4" { PaReservedWord(); return 0; } +"fvec2" { PaReservedWord(); return 0; } +"fvec3" { PaReservedWord(); return 0; } +"fvec4" { PaReservedWord(); return 0; } + +"sampler3DRect" { PaReservedWord(); return 0; } + +"sizeof" { PaReservedWord(); return 0; } +"cast" { PaReservedWord(); return 0; } + +"namespace" { PaReservedWord(); return 0; } +"using" { PaReservedWord(); return 0; } + +{L}({L}|{D})* { + pyylval->lex.line = yylineno; + pyylval->lex.string = NewPoolTString(yytext); + return PaIdentOrType(*pyylval->lex.string, parseContext, pyylval->lex.symbol); +} + +0[xX]{H}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } +0{O}+ { pyylval->lex.line = yylineno; pyylval->lex.i = strtol(yytext, 0, 0); return(INTCONSTANT); } +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}+{F} { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); } +{D}+{E}{F}? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); } +{D}+"."{D}*({E})?{F}? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); } +"."{D}+({E})?{F}? { pyylval->lex.line = yylineno; pyylval->lex.f = static_cast<float>(atof(yytext)); return(FLOATCONSTANT); } + +{D}+{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return(DOUBLECONSTANT); } +{D}+{E}{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return(DOUBLECONSTANT); } +{D}+"."{D}*({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return(DOUBLECONSTANT); } +"."{D}+({E})?{LF} { pyylval->lex.line = yylineno; pyylval->lex.d = atof(yytext); return(DOUBLECONSTANT); } + +"/*" { int ret = PaParseComment(pyylval->lex.line, parseContext); if (!ret) return ret; } + +"+=" { pyylval->lex.line = yylineno; return(ADD_ASSIGN); } +"-=" { pyylval->lex.line = yylineno; return(SUB_ASSIGN); } +"*=" { pyylval->lex.line = yylineno; return(MUL_ASSIGN); } +"/=" { pyylval->lex.line = yylineno; return(DIV_ASSIGN); } +"%=" { pyylval->lex.line = yylineno; return(MOD_ASSIGN); } +"<<=" { pyylval->lex.line = yylineno; return(LEFT_ASSIGN); } +">>=" { pyylval->lex.line = yylineno; return(RIGHT_ASSIGN); } +"&=" { pyylval->lex.line = yylineno; return(AND_ASSIGN); } +"^=" { pyylval->lex.line = yylineno; return(XOR_ASSIGN); } +"|=" { pyylval->lex.line = yylineno; return(OR_ASSIGN); } + +"++" { pyylval->lex.line = yylineno; return(INC_OP); } +"--" { pyylval->lex.line = yylineno; return(DEC_OP); } +"&&" { pyylval->lex.line = yylineno; return(AND_OP); } +"||" { pyylval->lex.line = yylineno; return(OR_OP); } +"^^" { pyylval->lex.line = yylineno; return(XOR_OP); } +"<=" { pyylval->lex.line = yylineno; return(LE_OP); } +">=" { pyylval->lex.line = yylineno; return(GE_OP); } +"==" { pyylval->lex.line = yylineno; return(EQ_OP); } +"!=" { pyylval->lex.line = yylineno; return(NE_OP); } +"<<" { pyylval->lex.line = yylineno; return(LEFT_OP); } +">>" { pyylval->lex.line = yylineno; return(RIGHT_OP); } +";" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(SEMICOLON); } +("{"|"<%") { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(LEFT_BRACE); } +("}"|"%>") { pyylval->lex.line = yylineno; return(RIGHT_BRACE); } +"," { pyylval->lex.line = yylineno; if (parseContext.inTypeParen) parseContext.lexAfterType = false; return(COMMA); } +":" { pyylval->lex.line = yylineno; return(COLON); } +"=" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; return(EQUAL); } +"(" { pyylval->lex.line = yylineno; parseContext.lexAfterType = false; parseContext.inTypeParen = true; return(LEFT_PAREN); } +")" { pyylval->lex.line = yylineno; parseContext.inTypeParen = false; return(RIGHT_PAREN); } +("["|"<:") { pyylval->lex.line = yylineno; return(LEFT_BRACKET); } +("]"|":>") { pyylval->lex.line = yylineno; return(RIGHT_BRACKET); } +"." { BEGIN(FIELDS); return(DOT); } +"!" { pyylval->lex.line = yylineno; return(BANG); } +"-" { pyylval->lex.line = yylineno; return(DASH); } +"~" { pyylval->lex.line = yylineno; return(TILDE); } +"+" { pyylval->lex.line = yylineno; return(PLUS); } +"*" { pyylval->lex.line = yylineno; return(STAR); } +"/" { pyylval->lex.line = yylineno; return(SLASH); } +"%" { pyylval->lex.line = yylineno; return(PERCENT); } +"<" { pyylval->lex.line = yylineno; return(LEFT_ANGLE); } +">" { pyylval->lex.line = yylineno; return(RIGHT_ANGLE); } +"|" { pyylval->lex.line = yylineno; return(VERTICAL_BAR); } +"^" { pyylval->lex.line = yylineno; return(CARET); } +"&" { pyylval->lex.line = yylineno; return(AMPERSAND); } +"?" { pyylval->lex.line = yylineno; return(QUESTION); } + +<FIELDS>{L}({L}|{D})* { +BEGIN(INITIAL); + pyylval->lex.line = yylineno; + pyylval->lex.string = NewPoolTString(yytext); + return FIELD_SELECTION; } +<FIELDS>[ \t\v\f\r] {} + +[ \t\v\n\f\r] { } +<*><<EOF>> { (&parseContext)->AfterEOF = true; yy_delete_buffer(YY_CURRENT_BUFFER); yyterminate();} +<*>. { parseContext.infoSink.info << "FLEX: Unknown char " << yytext << "\n"; + return 0; } + +%% + + +//Including Pre-processor. +extern "C" { + #include "./preprocessor/preprocess.h" +} + +// +// The YY_INPUT macro just calls this. Maybe this could be just put into +// the macro directly. +// + +int yy_input(char* buf, int max_size) +{ + char *char_token =NULL; + int len; + + if ((len = yylex_CPP(buf, max_size)) == 0) + return 0; + if (len >= max_size) + YY_FATAL_ERROR( "input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); + + buf[len] = ' '; + return len+1; +} + + +// +// Parse an array of strings using yyparse. We set up globals used by +// yywrap. +// +// Returns 0 for success, as per yyparse(). +// +int PaParseStrings(char* argv[], int strLen[], int argc, TParseContext& parseContextLocal) +{ + int argv0len; + + ScanFromString(argv[0]); + + //Storing the Current Compiler Parse context into the cpp structure. + cpp->pC = (void*)&parseContextLocal; + + if (!argv || argc == 0) + return 1; + + for (int i = 0; i < argc; ++i) { + if (!argv[i]) { + parseContextLocal.error(0, "Null shader source string", "", ""); + parseContextLocal.recover(); + return 1; + } + } + + if (!strLen) { + argv0len = (int) strlen(argv[0]); + strLen = &argv0len; + } + yyrestart(0); + (&parseContextLocal)->AfterEOF = false; + cpp->PaWhichStr = 0; + cpp->PaArgv = argv; + cpp->PaArgc = argc; + cpp->PaStrLen = strLen; + cpp->notAVersionToken = 0; + yylineno = 1; + + if (*cpp->PaStrLen >= 0) { + int ret; + #ifdef _WIN32 + ret = yyparse(parseContextLocal); + #else + ret = yyparse((void*)(&parseContextLocal)); + #endif + if (cpp->CompileError == 1 || parseContextLocal.recoveredFromError || parseContextLocal.numErrors > 0) + return 1; + else + return 0; + } + else + return 0; +} + +void yyerror(char *s) +{ + if (((TParseContext *)cpp->pC)->AfterEOF) { + if (cpp->tokensBeforeEOF == 1) { + GlobalParseContext->error(yylineno, "syntax error", "pre-mature EOF", s, ""); + GlobalParseContext->recover(); + } + } else { + GlobalParseContext->error(yylineno, "syntax error", yytext, s, ""); + GlobalParseContext->recover(); + } +} + +void PaReservedWord() +{ + GlobalParseContext->error(yylineno, "Reserved word.", yytext, "", ""); + GlobalParseContext->recover(); +} + +int PaIdentOrType(TString& id, TParseContext& parseContextLocal, TSymbol*& symbol) +{ + symbol = parseContextLocal.symbolTable.find(id); + if (parseContextLocal.lexAfterType == false && symbol && symbol->isVariable()) { + TVariable* variable = static_cast<TVariable*>(symbol); + if (variable->isUserType()) { + parseContextLocal.lexAfterType = true; + return TYPE_NAME; + } + } + + return IDENTIFIER; +} + +int PaParseComment(int &lineno, TParseContext& parseContextLocal) +{ + int transitionFlag = 0; + int nextChar; + + while (transitionFlag != 2) { + nextChar = yyinput(); + if (nextChar == '\n') + lineno++; + switch (nextChar) { + case '*' : + transitionFlag = 1; + break; + case '/' : /* if star is the previous character, then it is the end of comment */ + if (transitionFlag == 1) { + return 1 ; + } + break; + case EOF : + /* Raise error message here */ + parseContextLocal.error(yylineno, "End of shader found before end of comment.", "", "", ""); + GlobalParseContext->recover(); + return YY_NULL; + default : /* Any other character will be a part of the comment */ + transitionFlag = 0; + } + } + return 1; +} + +extern "C" { + +void CPPDebugLogMsg(const char *msg) +{ + ((TParseContext *)cpp->pC)->infoSink.debug.message(EPrefixNone, msg); +} + +void CPPWarningToInfoLog(const char *msg) +{ + ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg, yylineno); +} + +void CPPShInfoLogMsg(const char *msg) +{ + ((TParseContext *)cpp->pC)->error(yylineno,"", "",msg,""); + GlobalParseContext->recover(); +} + +void CPPErrorToInfoLog(char *msg) +{ + ((TParseContext *)cpp->pC)->error(yylineno,"syntax error", "",msg,""); + GlobalParseContext->recover(); +} + +void SetLineNumber(int line) +{ + yylineno &= ~SourceLocLineMask; + yylineno |= line; +} + +void SetStringNumber(int string) +{ + yylineno = (string << SourceLocStringShift) | (yylineno & SourceLocLineMask); +} + +int GetStringNumber(void) +{ + return yylineno >> 16; +} + +int GetLineNumber(void) +{ + return yylineno & SourceLocLineMask; +} + +void IncLineNumber(void) +{ + if ((yylineno & SourceLocLineMask) <= SourceLocLineMask) + ++yylineno; +} + +void DecLineNumber(void) +{ + if ((yylineno & SourceLocLineMask) > 0) + --yylineno; +} + +void HandlePragma(const char **tokens, int numTokens) +{ + if (!strcmp(tokens[0], "optimize")) { + if (numTokens != 4) { + CPPShInfoLogMsg("optimize pragma syntax is incorrect"); + return; + } + + if (strcmp(tokens[1], "(")) { + CPPShInfoLogMsg("\"(\" expected after 'optimize' keyword"); + return; + } + + if (!strcmp(tokens[2], "on")) + ((TParseContext *)cpp->pC)->contextPragma.optimize = true; + else if (!strcmp(tokens[2], "off")) + ((TParseContext *)cpp->pC)->contextPragma.optimize = false; + else { + CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'optimize' pragma"); + return; + } + + if (strcmp(tokens[3], ")")) { + CPPShInfoLogMsg("\")\" expected to end 'optimize' pragma"); + return; + } + } else if (!strcmp(tokens[0], "debug")) { + if (numTokens != 4) { + CPPShInfoLogMsg("debug pragma syntax is incorrect"); + return; + } + + if (strcmp(tokens[1], "(")) { + CPPShInfoLogMsg("\"(\" expected after 'debug' keyword"); + return; + } + + if (!strcmp(tokens[2], "on")) + ((TParseContext *)cpp->pC)->contextPragma.debug = true; + else if (!strcmp(tokens[2], "off")) + ((TParseContext *)cpp->pC)->contextPragma.debug = false; + else { + CPPShInfoLogMsg("\"on\" or \"off\" expected after '(' for 'debug' pragma"); + return; + } + + if (strcmp(tokens[3], ")")) { + CPPShInfoLogMsg("\")\" expected to end 'debug' pragma"); + return; + } + } else { + +#ifdef PRAGMA_TABLE + // + // implementation specific pragma + // use ((TParseContext *)cpp->pC)->contextPragma.pragmaTable to store the information about pragma + // For now, just ignore the pragma that the implementation cannot recognize + // An Example of one such implementation for a pragma that has a syntax like + // #pragma pragmaname(pragmavalue) + // This implementation stores the current pragmavalue against the pragma name in pragmaTable. + // + if (numTokens == 4 && !strcmp(tokens[1], "(") && !strcmp(tokens[3], ")")) { + TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; + TPragmaTable::iterator iter; + iter = pragmaTable.find(TString(tokens[0])); + if (iter != pragmaTable.end()) { + iter->second = tokens[2]; + } else { + pragmaTable[tokens[0]] = tokens[2]; + } + } else if (numTokens >= 2) { + TPragmaTable& pragmaTable = ((TParseContext *)cpp->pC)->contextPragma.pragmaTable; + TPragmaTable::iterator iter; + iter = pragmaTable.find(TString(tokens[0])); + if (iter != pragmaTable.end()) { + iter->second = tokens[1]; + } else { + pragmaTable[tokens[0]] = tokens[1]; + } + } +#endif // PRAGMA_TABLE + } +} + +void StoreStr(char *string) +{ + TString strSrc; + strSrc = TString(string); + + ((TParseContext *)cpp->pC)->HashErrMsg = ((TParseContext *)cpp->pC)->HashErrMsg + " " + strSrc; +} + +const char* GetStrfromTStr(void) +{ + cpp->ErrMsg = (((TParseContext *)cpp->pC)->HashErrMsg).c_str(); + return cpp->ErrMsg; +} + +void ResetTString(void) +{ + ((TParseContext *)cpp->pC)->HashErrMsg = ""; +} + +TBehavior GetBehavior(const char* behavior) +{ + if (!strcmp("require", behavior)) + return EBhRequire; + else if (!strcmp("enable", behavior)) + return EBhEnable; + else if (!strcmp("disable", behavior)) + return EBhDisable; + else if (!strcmp("warn", behavior)) + return EBhWarn; + else { + CPPShInfoLogMsg((TString("behavior '") + behavior + "' is not supported").c_str()); + return EBhDisable; + } +} + +void updateExtensionBehavior(const char* extName, const char* behavior) +{ + TBehavior behaviorVal = GetBehavior(behavior); + TMap<TString, TBehavior>:: iterator iter; + TString msg; + + // special cased for all extension + if (!strcmp(extName, "all")) { + if (behaviorVal == EBhRequire || behaviorVal == EBhEnable) { + CPPShInfoLogMsg("extension 'all' cannot have 'require' or 'enable' behavior"); + return; + } else { + for (iter = ((TParseContext *)cpp->pC)->extensionBehavior.begin(); iter != ((TParseContext *)cpp->pC)->extensionBehavior.end(); ++iter) + iter->second = behaviorVal; + } + } else { + iter = ((TParseContext *)cpp->pC)->extensionBehavior.find(TString(extName)); + if (iter == ((TParseContext *)cpp->pC)->extensionBehavior.end()) { + switch (behaviorVal) { + case EBhRequire: + CPPShInfoLogMsg((TString("extension '") + extName + "' is not supported").c_str()); + break; + case EBhEnable: + case EBhWarn: + case EBhDisable: + msg = TString("extension '") + extName + "' is not supported"; + ((TParseContext *)cpp->pC)->infoSink.info.message(EPrefixWarning, msg.c_str(), yylineno); + break; + } + return; + } else + iter->second = behaviorVal; + } +} + +} // extern "C" + +void setInitialState() +{ + yy_start = 1; +} diff --git a/glslang/MachineIndependent/glslang.y b/glslang/MachineIndependent/glslang.y index 4a43d10dd..e1f9fd6c9 100644 --- a/glslang/MachineIndependent/glslang.y +++ b/glslang/MachineIndependent/glslang.y @@ -93,6 +93,7 @@ Jutta Degener, 1995 float f; int i; bool b; + double d; }; TSymbol* symbol; } lex; @@ -278,8 +279,8 @@ primary_expression } | DOUBLECONSTANT { constUnion *unionArray = new constUnion[1]; - unionArray->setFConst($1.f); - $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtFloat, EvqConst), $1.line); + unionArray->setDConst($1.d); + $$ = parseContext.intermediate.addConstantUnion(unionArray, TType(EbtDouble, EvqConst), $1.line); } | BOOLCONSTANT { constUnion *unionArray = new constUnion[1]; @@ -1825,7 +1826,7 @@ type_specifier_nonarray | DOUBLE { TQualifier qual = parseContext.symbolTable.atGlobalLevel() ? EvqGlobal : EvqTemporary; // TODO: implement EbtDouble, check all float types - $$.setBasic(EbtFloat, qual, $1.line); + $$.setBasic(EbtDouble, qual, $1.line); } | INT { // TODO: implement EbtUint, check all int types diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index 14fe3147b..b5df82487 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -380,6 +380,15 @@ void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it) out.debug << buf << "\n"; } break; + case EbtDouble: + { + const int maxSize = 300; + char buf[maxSize]; + sprintf_s(buf, maxSize, "%f (%s)", node->getUnionArrayPointer()[i].getDConst(), "const double"); + + out.debug << buf << "\n"; + } + break; case EbtInt: { const int maxSize = 300; diff --git a/glslang/MachineIndependent/preprocessor/compile.h b/glslang/MachineIndependent/preprocessor/compile.h index 08a928089..140a21591 100644 --- a/glslang/MachineIndependent/preprocessor/compile.h +++ b/glslang/MachineIndependent/preprocessor/compile.h @@ -127,6 +127,10 @@ struct CPPStruct_Rec { int PaArgc; // count of strings in the array char** PaArgv; // our array of strings to parse unsigned int tokensBeforeEOF : 1; + + // Declared version of the shader + int version; + int profileAtom; }; #endif // !defined(__COMPILE_H) diff --git a/glslang/MachineIndependent/preprocessor/cpp.c b/glslang/MachineIndependent/preprocessor/cpp.c index 1281edd1a..72837050a 100644 --- a/glslang/MachineIndependent/preprocessor/cpp.c +++ b/glslang/MachineIndependent/preprocessor/cpp.c @@ -115,6 +115,9 @@ static int __LINE__Atom = 0; static int __FILE__Atom = 0; static int __VERSION__Atom = 0; static int versionAtom = 0; +static int coreAtom = 0; +static int compatibilityAtom = 0; +static int esAtom = 0; static int extensionAtom = 0; static Scope *macros = 0; @@ -149,6 +152,9 @@ int InitCPP(void) __FILE__Atom = LookUpAddString(atable, "__FILE__"); __VERSION__Atom = LookUpAddString(atable, "__VERSION__"); versionAtom = LookUpAddString(atable, "version"); + coreAtom = LookUpAddString(atable, "core"); + compatibilityAtom = LookUpAddString(atable, "compatibility"); + esAtom = LookUpAddString(atable, "es"); extensionAtom = LookUpAddString(atable, "extension"); macros = NewScopeInPool(mem_CreatePool(0, 0)); strcpy(buffer, "PROFILE_"); @@ -660,8 +666,6 @@ static int CPPpragma(yystypepp * yylvalpp) return token; } // CPPpragma -#define GL2_VERSION_NUMBER 110 - static int CPPversion(yystypepp * yylvalpp) { @@ -680,10 +684,8 @@ static int CPPversion(yystypepp * yylvalpp) CPPErrorToInfoLog("#version"); yylvalpp->sc_int=atoi(yylvalpp->symbol_name); - //SetVersionNumber(yylvalpp->sc_int); - - if (yylvalpp->sc_int != GL2_VERSION_NUMBER) - CPPShInfoLogMsg("Version number not supported by GL2"); + + cpp->version = yylvalpp->sc_int; token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); @@ -691,8 +693,20 @@ static int CPPversion(yystypepp * yylvalpp) return token; } else{ - CPPErrorToInfoLog("#version"); + cpp->profileAtom = yylvalpp->sc_ident; + if (cpp->profileAtom != coreAtom && + cpp->profileAtom != compatibilityAtom && + cpp->profileAtom != esAtom) + CPPErrorToInfoLog("#version profile name"); + + token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); + + if (token == '\n') + return token; + else + CPPErrorToInfoLog("#version"); } + return token; } // CPPversion diff --git a/glslang/MachineIndependent/preprocessor/cppstruct.c b/glslang/MachineIndependent/preprocessor/cppstruct.c index b1b15fa0b..c924dc240 100644 --- a/glslang/MachineIndependent/preprocessor/cppstruct.c +++ b/glslang/MachineIndependent/preprocessor/cppstruct.c @@ -132,6 +132,8 @@ int ResetPreprocessor(void) cpp->elsedepth[cpp->elsetracker]=0; cpp->elsetracker=0; cpp->tokensBeforeEOF = 0; + cpp->version = 110; + cpp->profileAtom = 0; return 1; } diff --git a/glslang/MachineIndependent/preprocessor/parser.h b/glslang/MachineIndependent/preprocessor/parser.h index 1b4284470..98a9afb4c 100644 --- a/glslang/MachineIndependent/preprocessor/parser.h +++ b/glslang/MachineIndependent/preprocessor/parser.h @@ -82,6 +82,7 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. typedef struct { int sc_int; float sc_fval; + double sc_dval; int sc_ident; char symbol_name[MAX_SYMBOL_NAME_LEN+1]; } yystypepp; diff --git a/glslang/MachineIndependent/preprocessor/scanner.c b/glslang/MachineIndependent/preprocessor/scanner.c index 90ebcf08c..1f6f9251b 100644 --- a/glslang/MachineIndependent/preprocessor/scanner.c +++ b/glslang/MachineIndependent/preprocessor/scanner.c @@ -225,47 +225,9 @@ int ScanFromString(char *s) /////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////// Floating point constants: ///////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////// -/* - * lBuildFloatValue() - Quick and dirty conversion to floating point. Since all - * we need is single precision this should be quite precise. - */ - -static float lBuildFloatValue(const char *str, int len, int exp) -{ - double val, expval, ten; - int ii, llen, absexp; - float rv; - - val = 0.0; - llen = len; - for (ii = 0; ii < len; ii++) - val = val*10.0 + (str[ii] - '0'); - if (exp != 0) { - absexp = exp > 0 ? exp : -exp; - expval = 1.0f; - ten = 10.0; - while (absexp) { - if (absexp & 1) - expval *= ten; - ten *= ten; - absexp >>= 1; - } - if (exp >= 0) { - val *= expval; - } else { - val /= expval; - } - } - rv = (float)val; - if (isinff(rv)) { - CPPErrorToInfoLog(" ERROR___FP_CONST_OVERFLOW"); - } - return rv; -} // lBuildFloatValue - /* - * lFloatConst() - Scan a floating point constant. Assumes that the scanner + * lFloatConst() - Scan a single- or double-precision floating point constant. Assumes that the scanner * has seen at least one digit, followed by either a decimal '.' or the * letter 'e'. */ @@ -274,7 +236,6 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) { int HasDecimal, declen, exp, ExpSign; int str_len; - float lval; HasDecimal = 0; declen = 0; @@ -303,41 +264,76 @@ static int lFloatConst(char *str, int len, int ch, yystypepp * yylvalpp) // Exponent: if (ch == 'e' || ch == 'E') { - ExpSign = 1; - str[len++]=ch; - ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); - if (ch == '+') { - str[len++]=ch; - ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); - } else if (ch == '-') { - ExpSign = -1; - str[len++]=ch; + if (len >= MAX_SYMBOL_NAME_LEN) { + CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + len = 1,str_len=1; + } else { + ExpSign = 1; + str[len++]=ch; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); - } - if (ch >= '0' && ch <= '9') { - while (ch >= '0' && ch <= '9') { - exp = exp*10 + ch - '0'; - str[len++]=ch; + if (ch == '+') { + str[len++]=ch; + ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); + } else if (ch == '-') { + ExpSign = -1; + str[len++]=ch; ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } - } else { - CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT"); + if (ch >= '0' && ch <= '9') { + while (ch >= '0' && ch <= '9') { + if (len < MAX_SYMBOL_NAME_LEN) { + exp = exp*10 + ch - '0'; + str[len++]=ch; + ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); + } else { + CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + len = 1,str_len=1; + } + } + } else { + CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT"); + } + exp *= ExpSign; } - exp *= ExpSign; } if (len == 0) { - lval = 0.0f; + yylvalpp->sc_fval = 0.0f; + yylvalpp->sc_dval = 0.0; strcpy(str,"0.0"); } else { + if (ch == 'l' || ch == 'L') { + int ch2 = cpp->currentInput->getch(cpp->currentInput, yylvalpp); + if (ch2 != 'f' && ch2 != 'F') { + cpp->currentInput->ungetch(cpp->currentInput, ch2, yylvalpp); + cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); + } else { + if (len < MAX_SYMBOL_NAME_LEN-1) { + str[len++] = ch; + str[len++] = ch2; + } else { + CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + len = 1,str_len=1; + } + } + } else if (ch == 'f' || ch == 'F') { + if (len < MAX_SYMBOL_NAME_LEN) + str[len++] = ch; + else { + CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG"); + len = 1,str_len=1; + } + } else + cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); + str[len]='\0'; - lval = lBuildFloatValue(str, str_len, exp - declen); + + yylvalpp->sc_dval = strtod(str, 0); + yylvalpp->sc_fval = (float)yylvalpp->sc_dval; } // Suffix: - - yylvalpp->sc_fval = lval; strcpy(yylvalpp->symbol_name,str); - cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); + return CPP_FLOATCONSTANT; } // lFloatConst @@ -454,7 +450,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) } ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } while (ch >= '0' && ch <= '7'); - if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') + if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp); yylvalpp->symbol_name[len] = '\0'; cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp); @@ -476,7 +472,7 @@ static int byte_scan(InputSrc *in, yystypepp * yylvalpp) ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp); } } while (ch >= '0' && ch <= '9'); - if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') { + if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E' || ch == 'F' || ch == 'l' || ch == 'L') { return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp); } else { yylvalpp->symbol_name[len] = '\0'; diff --git a/glslang/MachineIndependent/preprocessor/slglobals.h b/glslang/MachineIndependent/preprocessor/slglobals.h index ebe27c308..88c63773a 100644 --- a/glslang/MachineIndependent/preprocessor/slglobals.h +++ b/glslang/MachineIndependent/preprocessor/slglobals.h @@ -83,6 +83,8 @@ NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. typedef struct CPPStruct_Rec CPPStruct; +// Multi-threading note: The existence of this global makes +// this preprocessing single-threaded only. extern CPPStruct *cpp; #undef CPPC_DEBUG_THE_COMPILER -- GitLab