diff --git a/glslang/Include/BaseTypes.h b/glslang/Include/BaseTypes.h
index da273031613c07f0658b9efcef94593d0d155a67..1283c0c290b22f429b713b6d9e8c8a4a9121dab8 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 311679653559bb98c060ccb6dee4b90c2dc5dff3..700ce06029a02f0aa02d09e80c872e6b5cccdcc6 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 3db8d3a63a2095e58473b61f825c684ddf46c161..e9bfa443fa008f43a9753d1b8fe342ad88465ee0 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 f0c2cbd3f809cc60b4d0d9ca4b4a852d2075e3ea..f9571c982f8c04cfce9ebe5cfff7bc83fcfeea6e 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 6dc3ca8a32e4168ee4beaa64a6490f780174b98a..03871edab1c3f35e3e13e594c8bd9d753c1201a3 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 aabb5beb945f67c1ff2a604ce6c5c35dafc1dd40..60f31b2b85a71a82e106c3afc0240b52d4db2e28 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 66e3e689167a7b7ecaaec5680127016cee0b0bd1..771d22c35c791aa384a4cdeda7998bb1d6f74022 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 4a43d10dda1cf36112179c80e054fd85e015a1d8..e1f9fd6c97944cd27f158c9ec1caaab98bf7e641 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 14fe3147b15543b34e544541d3ffcc9b8e1afc22..b5df82487199e137e63dc75f25fce1c7bc1b1ddd 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 08a928089d4c91fa997c1d9e759d1288fc7e78d2..140a2159171de9042c0bdc23755800715f6356e3 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 1281edd1a6b6dbe4093d5c92f64fa465d9bf097d..72837050ab0a25694b645503459633e958d2e8ee 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 b1b15fa0b897dd0b5558df4431ead5dfe2c424f9..c924dc2402b2dfd42c764829e5d121b6e0f8006e 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 1b428447004f3f0d433d1fbb37e890907b65dc07..98a9afb4cf77b83dc269c0eb43942a04ba8a46bf 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 90ebcf08cd15ca83bd27965dd949c5b3df93eb32..1f6f9251b13657d754339ab29c56c684f95acade 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 ebe27c308054fc31548695b298326571f3bec6d1..88c63773a35eaf4f85c29a2bb9676303542ca02e 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