Commit 5d3e2e35 by John Kessenich

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
parent e95ecc54
......@@ -41,6 +41,7 @@
enum TBasicType {
EbtVoid,
EbtFloat,
EbtDouble,
EbtInt,
EbtBool,
EbtGuardSamplerBegin, // non type: see implementation of IsSampler()
......
......@@ -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)
......@@ -91,6 +102,11 @@ public:
return true;
break;
case EbtDouble:
if (constant.dConst == dConst)
return true;
break;
case EbtBool:
if (constant.bConst == bConst)
return true;
......@@ -135,6 +151,11 @@ public:
return true;
return false;
case EbtDouble:
if (dConst > constant.dConst)
return true;
return false;
default:
assert(false && "Default missing");
return false;
......@@ -157,6 +178,11 @@ public:
return true;
return false;
case EbtDouble:
if (dConst < constant.dConst)
return true;
return false;
default:
assert(false && "Default missing");
return false;
......@@ -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;
......
......@@ -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;
......
......@@ -187,6 +187,7 @@ enum TOperator {
EOpConstructInt,
EOpConstructBool,
EOpConstructFloat,
EOpConstructDouble,
EOpConstructVec2,
EOpConstructVec3,
EOpConstructVec4,
......
......@@ -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;
}
......
......@@ -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;
......
/*
//
//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;
}
......@@ -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
......
......@@ -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;
......
......@@ -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)
......@@ -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
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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';
......
......@@ -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
......
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