Initial import from TransGaming

git-svn-id: https://angleproject.googlecode.com/svn/trunk@2 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/Compiler/Preprocessor/atom.c b/Compiler/Preprocessor/atom.c
new file mode 100644
index 0000000..204fb0d
--- /dev/null
+++ b/Compiler/Preprocessor/atom.c
@@ -0,0 +1,740 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+//
+// atom.c
+//
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "slglobals.h"
+
+#undef malloc
+#undef realloc
+#undef free
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////// String table: //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+static const struct {
+    int val;
+    const char *str;
+} tokens[] = {
+    { CPP_AND_OP,         "&&" },
+    { CPP_AND_ASSIGN,     "&=" },
+    { CPP_SUB_ASSIGN,     "-=" },
+    { CPP_MOD_ASSIGN,     "%=" },
+    { CPP_ADD_ASSIGN,     "+=" },
+    { CPP_DIV_ASSIGN,     "/=" },
+    { CPP_MUL_ASSIGN,     "*=" },
+    { CPP_RIGHT_BRACKET,  ":>" },
+    { CPP_EQ_OP,          "==" },
+    { CPP_XOR_OP,         "^^" }, 
+    { CPP_XOR_ASSIGN,     "^=" }, 
+    { CPP_FLOATCONSTANT,  "<float-const>" },
+    { CPP_GE_OP,          ">=" },
+    { CPP_RIGHT_OP,       ">>" },
+    { CPP_RIGHT_ASSIGN,   ">>=" }, 
+    { CPP_IDENTIFIER,     "<ident>" },
+    { CPP_INTCONSTANT,    "<int-const>" },
+    { CPP_LE_OP,          "<=" },
+    { CPP_LEFT_OP,        "<<" },
+    { CPP_LEFT_ASSIGN,    "<<=" },
+    { CPP_LEFT_BRACKET,   "<:" },
+    { CPP_LEFT_BRACE,     "<%" }, 
+    { CPP_DEC_OP,         "--" },
+    { CPP_RIGHT_BRACE,    "%>" }, 
+    { CPP_NE_OP,          "!=" },
+    { CPP_OR_OP,          "||" },
+    { CPP_OR_ASSIGN,      "|=" }, 
+    { CPP_INC_OP,         "++" },
+    { CPP_STRCONSTANT,    "<string-const>" },
+    { CPP_TYPEIDENTIFIER, "<type-ident>" },
+};
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////// String table: //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+#define INIT_STRING_TABLE_SIZE 16384
+
+typedef struct StringTable_Rec {
+    char *strings;
+    int nextFree;
+    int size;
+} StringTable;
+
+/*
+ * InitStringTable() - Initialize the string table.
+ *
+ */
+
+static int InitStringTable(StringTable *stable)
+{
+    stable->strings = (char *) malloc(INIT_STRING_TABLE_SIZE);
+    if (!stable->strings)
+        return 0;
+    // Zero-th offset means "empty" so don't use it.
+    stable->nextFree = 1;
+    stable->size = INIT_STRING_TABLE_SIZE;
+    return 1;
+} // InitStringTable
+
+/*
+ * FreeStringTable() - Free the string table.
+ *
+ */
+
+static void FreeStringTable(StringTable *stable)
+{
+    if (stable->strings)
+        free(stable->strings);
+    stable->strings = NULL;
+    stable->nextFree = 0;
+    stable->size = 0;
+} // FreeStringTable
+
+/*
+ * HashString() - Hash a string with the base hash function.
+ *
+ */
+
+static int HashString(const char *s)
+{
+    int hval = 0;
+
+    while (*s) {
+        hval = (hval*13507 + *s*197) ^ (hval >> 2);
+        s++;
+    }
+    return hval & 0x7fffffff;
+} // HashString
+
+/*
+ * HashString2() - Hash a string with the incrimenting hash function.
+ *
+ */
+
+static int HashString2(const char *s)
+{
+    int hval = 0;
+
+    while (*s) {
+        hval = (hval*729 + *s*37) ^ (hval >> 1);
+        s++;
+    }
+    return hval;
+} // HashString2
+
+/*
+ * AddString() - Add a string to a string table.  Return it's offset.
+ *
+ */
+
+static int AddString(StringTable *stable, const char *s)
+{
+    int len, loc;
+    char *str;
+
+    len = (int) strlen(s);
+    if (stable->nextFree + len + 1 >= stable->size) {
+        assert(stable->size < 1000000);
+        str = (char *) malloc(stable->size*2);
+        memcpy(str, stable->strings, stable->size);
+        free(stable->strings);
+        stable->strings = str;
+    }
+    loc = stable->nextFree;
+    strcpy(&stable->strings[loc], s);
+    stable->nextFree += len + 1;
+    return loc;
+} // AddString
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////// Hash table: ///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+#define INIT_HASH_TABLE_SIZE 2047
+#define HASH_TABLE_MAX_COLLISIONS 3
+
+typedef struct HashEntry_Rec {
+    int index;      // String table offset of string representation
+    int value;      // Atom (symbol) value
+} HashEntry;
+
+typedef struct HashTable_Rec {
+    HashEntry *entry;
+    int size;
+    int entries;
+    int counts[HASH_TABLE_MAX_COLLISIONS + 1];
+} HashTable;
+
+/*
+ * InitHashTable() - Initialize the hash table.
+ *
+ */
+
+static int InitHashTable(HashTable *htable, int fsize)
+{
+    int ii;
+
+    htable->entry = (HashEntry *) malloc(sizeof(HashEntry)*fsize);
+    if (!htable->entry)
+        return 0;
+    htable->size = fsize;
+    for (ii = 0; ii < fsize; ii++) {
+        htable->entry[ii].index = 0;
+        htable->entry[ii].value = 0;
+    }
+    htable->entries = 0;
+    for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++)
+        htable->counts[ii] = 0;
+    return 1;
+} // InitHashTable
+
+/*
+ * FreeHashTable() - Free the hash table.
+ *
+ */
+
+static void FreeHashTable(HashTable *htable)
+{
+    if (htable->entry)
+        free(htable->entry);
+    htable->entry = NULL;
+    htable->size = 0;
+    htable->entries = 0;
+} // FreeHashTable
+
+/*
+ * Empty() - See if a hash table entry is empty.
+ *
+ */
+
+static int Empty(HashTable *htable, int hashloc)
+{
+    assert(hashloc >= 0 && hashloc < htable->size);
+    if (htable->entry[hashloc].index == 0) {
+        return 1;
+    } else {
+        return 0;
+    }
+} // Empty
+
+/*
+ * Match() - See if a hash table entry is matches a string.
+ *
+ */
+
+static int Match(HashTable *htable, StringTable *stable, const char *s, int hashloc)
+{
+    int strloc;
+
+    strloc = htable->entry[hashloc].index;
+    if (!strcmp(s, &stable->strings[strloc])) {
+        return 1;
+    } else {
+        return 0;
+    }
+} // Match
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////// Atom table: ///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+#define INIT_ATOM_TABLE_SIZE 1024
+
+
+struct AtomTable_Rec {
+    StringTable stable; // String table.
+    HashTable htable;   // Hashes string to atom number and token value.  Multiple strings can
+                        // have the same token value but each unique string is a unique atom.
+    int *amap;          // Maps atom value to offset in string table.  Atoms all map to unique
+                        // strings except for some undefined values in the lower, fixed part
+                        // of the atom table that map to "<undefined>".  The lowest 256 atoms
+                        // correspond to single character ASCII values except for alphanumeric
+                        // characters and '_', which can be other tokens.  Next come the
+                        // language tokens with their atom values equal to the token value.
+                        // Then come predefined atoms, followed by user specified identifiers.
+    int *arev;          // Reversed atom for symbol table use.
+    int nextFree;
+    int size;
+};
+
+static AtomTable latable = { { 0 } };
+AtomTable *atable = &latable;
+
+static int AddAtomFixed(AtomTable *atable, const char *s, int atom);
+
+/*
+ * GrowAtomTable() - Grow the atom table to at least "size" if it's smaller.
+ *
+ */
+
+static int GrowAtomTable(AtomTable *atable, int size)
+{
+    int *newmap, *newrev;
+
+    if (atable->size < size) {
+        if (atable->amap) {
+            newmap = realloc(atable->amap, sizeof(int)*size);
+            newrev = realloc(atable->arev, sizeof(int)*size);
+        } else {
+            newmap = malloc(sizeof(int)*size);
+            newrev = malloc(sizeof(int)*size);
+            atable->size = 0;
+        }
+        if (!newmap || !newrev) {
+            /* failed to grow -- error */
+            if (newmap)
+                atable->amap = newmap;
+            if (newrev)
+                atable->amap = newrev;
+            return -1;
+        }
+        memset(&newmap[atable->size], 0, (size - atable->size) * sizeof(int));
+        memset(&newrev[atable->size], 0, (size - atable->size) * sizeof(int));
+        atable->amap = newmap;
+        atable->arev = newrev;
+        atable->size = size;
+    }
+    return 0;
+} // GrowAtomTable
+
+/*
+ * lReverse() - Reverse the bottom 20 bits of a 32 bit int.
+ *
+ */
+
+static int lReverse(int fval)
+{
+    unsigned int in = fval;
+    int result = 0, cnt = 0;
+
+    while(in) {
+        result <<= 1;
+        result |= in&1;
+        in >>= 1;
+        cnt++;
+    }
+
+    // Don't use all 31 bits.  One million atoms is plenty and sometimes the
+    // upper bits are used for other things.
+
+    if (cnt < 20)
+        result <<= 20 - cnt;
+    return result;
+} // lReverse
+
+/*
+ * AllocateAtom() - Allocate a new atom.  Associated with the "undefined" value of -1.
+ *
+ */
+
+static int AllocateAtom(AtomTable *atable)
+{
+    if (atable->nextFree >= atable->size)
+        GrowAtomTable(atable, atable->nextFree*2);
+    atable->amap[atable->nextFree] = -1;
+    atable->arev[atable->nextFree] = lReverse(atable->nextFree);
+    atable->nextFree++;
+    return atable->nextFree - 1;
+} // AllocateAtom
+
+/*
+ * SetAtomValue() - Allocate a new atom associated with "hashindex".
+ *
+ */
+
+static void SetAtomValue(AtomTable *atable, int atomnumber, int hashindex)
+{
+    atable->amap[atomnumber] = atable->htable.entry[hashindex].index;
+    atable->htable.entry[hashindex].value = atomnumber;
+} // SetAtomValue
+
+/*
+ * FindHashLoc() - Find the hash location for this string.  Return -1 it hash table is full.
+ *
+ */
+
+static int FindHashLoc(AtomTable *atable, const char *s)
+{
+    int hashloc, hashdelta, count;
+    int FoundEmptySlot = 0;
+    int collision[HASH_TABLE_MAX_COLLISIONS + 1];
+
+    hashloc = HashString(s) % atable->htable.size;
+    if (!Empty(&atable->htable, hashloc)) {
+        if (Match(&atable->htable, &atable->stable, s, hashloc))
+            return hashloc;
+        collision[0] = hashloc;
+        hashdelta = HashString2(s);
+        count = 0;
+        while (count < HASH_TABLE_MAX_COLLISIONS) {
+            hashloc = ((hashloc + hashdelta) & 0x7fffffff) % atable->htable.size;
+            if (!Empty(&atable->htable, hashloc)) {
+                if (Match(&atable->htable, &atable->stable, s, hashloc)) {
+                    return hashloc;
+                }
+            } else {
+                FoundEmptySlot = 1;
+                break;
+            }
+            count++;
+            collision[count] = hashloc;
+        }
+
+        if (!FoundEmptySlot) {
+            if (cpp->options.DumpAtomTable) {
+                int ii;
+                char str[200];
+                sprintf(str, "*** Hash failed with more than %d collisions. Must increase hash table size. ***",
+                       HASH_TABLE_MAX_COLLISIONS);
+                CPPShInfoLogMsg(str);
+
+                sprintf(str, "*** New string \"%s\", hash=%04x, delta=%04x", s, collision[0], hashdelta);
+                CPPShInfoLogMsg(str);
+                for (ii = 0; ii <= HASH_TABLE_MAX_COLLISIONS; ii++) {
+                    sprintf(str, "*** Collides on try %d at hash entry %04x with \"%s\"",
+                           ii + 1, collision[ii], GetAtomString(atable, atable->htable.entry[collision[ii]].value));
+                    CPPShInfoLogMsg(str);
+                }
+            }
+            return -1;
+        } else {
+            atable->htable.counts[count]++;
+        }
+    }
+    return hashloc;
+} // FindHashLoc
+
+/*
+ * IncreaseHashTableSize()
+ *
+ */
+
+static int IncreaseHashTableSize(AtomTable *atable)
+{
+    int ii, strloc, oldhashloc, value, size;
+    AtomTable oldtable;
+    char *s;
+
+    // Save the old atom table and create a new one:
+
+    oldtable = *atable;
+    size = oldtable.htable.size*2 + 1;
+    if (!InitAtomTable(atable, size))
+        return 0;
+
+    // Add all the existing values to the new atom table preserving their atom values:
+
+    for (ii = atable->nextFree; ii < oldtable.nextFree; ii++) {
+        strloc = oldtable.amap[ii];
+        s = &oldtable.stable.strings[strloc];
+        oldhashloc = FindHashLoc(&oldtable, s);
+        assert(oldhashloc >= 0);
+        value = oldtable.htable.entry[oldhashloc].value;
+        AddAtomFixed(atable, s, value);
+    }
+    FreeAtomTable(&oldtable);
+    return 1;
+} // IncreaseHashTableSize
+
+/*
+ * LookUpAddStringHash() - Lookup a string in the hash table.  If it's not there, add it and
+ *        initialize the atom value in the hash table to 0.  Return the hash table index.
+ */
+
+static int LookUpAddStringHash(AtomTable *atable, const char *s)
+{
+    int hashloc, strloc;
+
+    while(1) {
+        hashloc = FindHashLoc(atable, s);
+        if (hashloc >= 0)
+            break;
+        IncreaseHashTableSize(atable);
+    }
+
+    if (Empty(&atable->htable, hashloc)) {
+        atable->htable.entries++;
+        strloc = AddString(&atable->stable, s);
+        atable->htable.entry[hashloc].index = strloc;
+        atable->htable.entry[hashloc].value = 0;
+    }
+    return hashloc;
+} // LookUpAddStringHash
+
+/*
+ * LookUpAddString() - Lookup a string in the hash table.  If it's not there, add it and
+ *        initialize the atom value in the hash table to the next atom number.
+ *        Return the atom value of string.
+ */
+
+int LookUpAddString(AtomTable *atable, const char *s)
+{
+    int hashindex, atom;
+
+    hashindex = LookUpAddStringHash(atable, s);
+    atom = atable->htable.entry[hashindex].value;
+    if (atom == 0) {
+        atom = AllocateAtom(atable);
+        SetAtomValue(atable, atom, hashindex);
+    }
+    return atom;
+} // LookUpAddString
+
+/*
+ * GetAtomString()
+ *
+ */
+
+const  char *GetAtomString(AtomTable *atable, int atom)
+{
+    int soffset;
+
+    if (atom > 0 && atom < atable->nextFree) {
+        soffset = atable->amap[atom];
+        if (soffset > 0 && soffset < atable->stable.nextFree) {
+            return &atable->stable.strings[soffset];
+        } else {
+            return "<internal error: bad soffset>";
+        }
+    } else {
+        if (atom == 0) {
+            return "<null atom>";
+        } else {
+            if (atom == EOF) {
+                return "<EOF>";
+            } else {
+                return "<invalid atom>";
+            }
+        }
+    }
+} // GetAtomString
+
+/*
+ * GetReversedAtom()
+ *
+ */
+
+int GetReversedAtom(AtomTable *atable, int atom)
+{
+    if (atom > 0 && atom < atable->nextFree) {
+        return atable->arev[atom];
+    } else {
+        return 0;
+    }
+} // GetReversedAtom
+
+/*
+ * AddAtom() - Add a string to the atom, hash and string tables if it isn't already there.
+ *         Return it's atom index.
+ */
+
+int AddAtom(AtomTable *atable, const char *s)
+{
+    int atom;
+
+    atom = LookUpAddString(atable, s);
+    return atom;
+} // AddAtom
+
+/*
+ * AddAtomFixed() - Add an atom to the hash and string tables if it isn't already there.
+ *         Assign it the atom value of "atom".
+ */
+
+static int AddAtomFixed(AtomTable *atable, const char *s, int atom)
+{
+    int hashindex, lsize;
+
+    hashindex = LookUpAddStringHash(atable, s);
+    if (atable->nextFree >= atable->size || atom >= atable->size) {
+        lsize = atable->size*2;
+        if (lsize <= atom)
+            lsize = atom + 1;
+        GrowAtomTable(atable, lsize);
+    }
+    atable->amap[atom] = atable->htable.entry[hashindex].index;
+    atable->htable.entry[hashindex].value = atom;
+    //if (atom >= atable->nextFree)
+    //    atable->nextFree = atom + 1;
+    while (atom >= atable->nextFree) {
+        atable->arev[atable->nextFree] = lReverse(atable->nextFree);
+        atable->nextFree++;
+    }
+    return atom;
+} // AddAtomFixed
+
+/*
+ * InitAtomTable() - Initialize the atom table.
+ *
+ */
+
+int InitAtomTable(AtomTable *atable, int htsize)
+{
+    int ii;
+
+    htsize = htsize <= 0 ? INIT_HASH_TABLE_SIZE : htsize;
+    if (!InitStringTable(&atable->stable))
+        return 0;
+    if (!InitHashTable(&atable->htable, htsize))
+        return 0;
+
+    atable->nextFree = 0;
+    atable->amap = NULL;
+    atable->size = 0;
+    GrowAtomTable(atable, INIT_ATOM_TABLE_SIZE);
+    if (!atable->amap)
+        return 0;
+
+    // Initialize lower part of atom table to "<undefined>" atom:
+
+    AddAtomFixed(atable, "<undefined>", 0);
+    for (ii = 0; ii < FIRST_USER_TOKEN_SY; ii++)
+        atable->amap[ii] = atable->amap[0];
+
+    // Add single character tokens to the atom table:
+
+    {
+		const char *s = "~!%^&*()-+=|,.<>/?;:[]{}#";
+        char t[2];
+
+        t[1] = '\0';
+        while (*s) {
+            t[0] = *s;
+            AddAtomFixed(atable, t, s[0]);
+            s++;
+        }
+    }
+
+    // Add multiple character scanner tokens :
+
+    for (ii = 0; ii < sizeof(tokens)/sizeof(tokens[0]); ii++)
+        AddAtomFixed(atable, tokens[ii].str, tokens[ii].val);
+
+    // Add error symbol if running in error mode:
+
+    if (cpp->options.ErrorMode)
+        AddAtomFixed(atable, "error", ERROR_SY);
+
+    AddAtom(atable, "<*** end fixed atoms ***>");
+
+    return 1;
+} // InitAtomTable
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////// Debug Printing Functions: //////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * PrintAtomTable()
+ *
+ */
+
+void PrintAtomTable(AtomTable *atable)
+{
+    int ii;
+    char str[200];
+
+    for (ii = 0; ii < atable->nextFree; ii++) {
+        sprintf(str, "%d: \"%s\"", ii, &atable->stable.strings[atable->amap[ii]]);
+        CPPDebugLogMsg(str);
+    }
+    sprintf(str, "Hash table: size=%d, entries=%d, collisions=",
+           atable->htable.size, atable->htable.entries);
+    CPPDebugLogMsg(str);
+    for (ii = 0; ii < HASH_TABLE_MAX_COLLISIONS; ii++) {
+        sprintf(str, " %d", atable->htable.counts[ii]);
+        CPPDebugLogMsg(str);
+    }
+
+} // PrintAtomTable
+
+
+/*
+ * GetStringOfAtom()
+ *
+ */
+
+char* GetStringOfAtom(AtomTable *atable, int atom)
+{
+	 char* chr_str;
+	 chr_str=&atable->stable.strings[atable->amap[atom]];
+	 return chr_str;
+} // GetStringOfAtom
+
+/*
+ * FreeAtomTable() - Free the atom table and associated memory
+ *
+ */
+
+void FreeAtomTable(AtomTable *atable)
+{
+    FreeStringTable(&atable->stable);
+    FreeHashTable(&atable->htable);
+    if (atable->amap)
+        free(atable->amap);
+    if (atable->arev)
+        free(atable->arev);
+    atable->amap = NULL;
+    atable->arev = NULL;
+    atable->nextFree = 0;
+    atable->size = 0;
+} // FreeAtomTable
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////// End of atom.c ///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/Compiler/Preprocessor/atom.h b/Compiler/Preprocessor/atom.h
new file mode 100644
index 0000000..9d42037
--- /dev/null
+++ b/Compiler/Preprocessor/atom.h
@@ -0,0 +1,68 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// atom.h
+//
+
+#if !defined(__ATOM_H)
+#define __ATOM_H 1
+
+typedef struct AtomTable_Rec AtomTable;
+
+extern AtomTable *atable;
+
+int InitAtomTable(AtomTable *atable, int htsize);
+void FreeAtomTable(AtomTable *atable);
+int AddAtom(AtomTable *atable, const char *s);
+void PrintAtomTable(AtomTable *atable);
+int LookUpAddString(AtomTable *atable, const char *s);
+const char *GetAtomString(AtomTable *atable, int atom);
+int GetReversedAtom(AtomTable *atable, int atom);
+char* GetStringOfAtom(AtomTable *atable, int atom);
+#endif // !defined(__ATOM_H)
diff --git a/Compiler/Preprocessor/compile.h b/Compiler/Preprocessor/compile.h
new file mode 100644
index 0000000..9e87afc
--- /dev/null
+++ b/Compiler/Preprocessor/compile.h
@@ -0,0 +1,104 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// compile.h
+//
+
+#if !defined(__COMPILE_H)
+#define __COMPILE_H 1
+
+int InitCPPStruct(void);
+
+typedef struct Options_Rec{
+    const char *profileString;
+    int ErrorMode;
+    int Quiet;
+	
+    // Debug The Compiler options:
+    int DumpAtomTable;
+} Options;
+
+struct CPPStruct_Rec {
+    // Public members
+    SourceLoc *pLastSourceLoc;  // Set at the start of each statement by the tree walkers
+    Options options;            // Compile options and parameters
+
+    // Private members
+    SourceLoc lastSourceLoc;
+
+    // Scanner data:
+
+    SourceLoc *tokenLoc;        // Source location of most recent token seen by the scanner
+    int mostRecentToken;        // Most recent token seen by the scanner
+    InputSrc *currentInput;
+    int previous_token;
+    int notAVersionToken;      // used to make sure that #version is the first token seen in the file, if present
+    
+	void *pC;                   // storing the parseContext of the compile object in cpp.  
+     
+    // Private members:
+    SourceLoc ltokenLoc;
+	int ifdepth;                //current #if-#else-#endif nesting in the cpp.c file (pre-processor)    
+    int elsedepth[64];          //Keep a track of #if depth..Max allowed is 64.   
+    int elsetracker;            //#if-#else and #endif constructs...Counter.
+    const char *ErrMsg;
+    int CompileError;           //Indicate compile error when #error, #else,#elif mismatch.
+
+    //
+    // Globals used to communicate between PaParseStrings() and yy_input()and 
+    // also across the files.(gen_glslang.cpp and scanner.c)
+    //
+    int    PaWhichStr;            // which string we're parsing
+    int*   PaStrLen;              // array of lengths of the PaArgv strings
+    int    PaArgc;                // count of strings in the array
+    char** PaArgv;                // our array of strings to parse    
+    unsigned int tokensBeforeEOF : 1;
+};
+
+#endif // !defined(__COMPILE_H)
diff --git a/Compiler/Preprocessor/cpp.c b/Compiler/Preprocessor/cpp.c
new file mode 100644
index 0000000..d852fd4
--- /dev/null
+++ b/Compiler/Preprocessor/cpp.c
@@ -0,0 +1,1009 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// cpp.c
+//
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "slglobals.h"
+
+static int CPPif(yystypepp * yylvalpp);
+
+/* Don't use memory.c's replacements, as we clean up properly here */
+#undef malloc
+#undef free
+
+static int bindAtom = 0;
+static int constAtom = 0;
+static int defaultAtom = 0;
+static int defineAtom = 0;
+static int definedAtom = 0;
+static int elseAtom = 0;
+static int elifAtom = 0;
+static int endifAtom = 0;
+static int ifAtom = 0;
+static int ifdefAtom = 0;
+static int ifndefAtom = 0;
+static int includeAtom = 0;
+static int lineAtom = 0;
+static int pragmaAtom = 0;
+static int texunitAtom = 0;
+static int undefAtom = 0;
+static int errorAtom = 0;
+static int __LINE__Atom = 0;
+static int __FILE__Atom = 0;
+static int __VERSION__Atom = 0;
+static int versionAtom = 0;
+static int extensionAtom = 0;
+
+static Scope *macros = 0;
+#define MAX_MACRO_ARGS  64
+#define MAX_IF_NESTING  64
+
+static SourceLoc ifloc; /* outermost #if */
+
+int InitCPP(void)
+{
+    char        buffer[64], *t;
+    const char  *f;
+    // Add various atoms needed by the CPP line scanner:
+    bindAtom = LookUpAddString(atable, "bind");
+    constAtom = LookUpAddString(atable, "const");
+    defaultAtom = LookUpAddString(atable, "default");
+    defineAtom = LookUpAddString(atable, "define");
+    definedAtom = LookUpAddString(atable, "defined");
+    elifAtom = LookUpAddString(atable, "elif");
+    elseAtom = LookUpAddString(atable, "else");
+    endifAtom = LookUpAddString(atable, "endif");
+    ifAtom = LookUpAddString(atable, "if");
+    ifdefAtom = LookUpAddString(atable, "ifdef");
+    ifndefAtom = LookUpAddString(atable, "ifndef");
+    includeAtom = LookUpAddString(atable, "include");
+    lineAtom = LookUpAddString(atable, "line");
+    pragmaAtom = LookUpAddString(atable, "pragma");
+    texunitAtom = LookUpAddString(atable, "texunit");
+    undefAtom = LookUpAddString(atable, "undef");
+	errorAtom = LookUpAddString(atable, "error");
+    __LINE__Atom = LookUpAddString(atable, "__LINE__");
+    __FILE__Atom = LookUpAddString(atable, "__FILE__");
+	__VERSION__Atom = LookUpAddString(atable, "__VERSION__");
+    versionAtom = LookUpAddString(atable, "version");
+    extensionAtom = LookUpAddString(atable, "extension");
+    macros = NewScopeInPool(mem_CreatePool(0, 0));
+    strcpy(buffer, "PROFILE_");
+    t = buffer + strlen(buffer);
+    f = cpp->options.profileString;
+    while ((isalnum(*f) || *f == '_') && t < buffer + sizeof(buffer) - 1)
+        *t++ = toupper(*f++);
+    *t = 0;
+	return 1;
+} // InitCPP
+
+int FreeCPP(void)
+{
+    if (macros)
+    {
+        mem_FreePool(macros->pool);
+        macros = 0;
+    }
+
+    return 1;
+}
+
+int FinalCPP(void)
+{
+	if (cpp->ifdepth)
+		CPPErrorToInfoLog("#if mismatch");
+    return 1;
+}
+
+static int CPPdefine(yystypepp * yylvalpp)
+{
+    int token, name, args[MAX_MACRO_ARGS], argc;
+    const char *message;
+    MacroSymbol mac;
+    Symbol *symb;
+    SourceLoc dummyLoc;
+    memset(&mac, 0, sizeof(mac));
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token != CPP_IDENTIFIER) {
+        CPPErrorToInfoLog("#define");
+        return token;
+    }
+    name = yylvalpp->sc_ident;
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token == '(' && !yylvalpp->sc_int) {
+        // gather arguments
+        argc = 0;
+        do {
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (argc == 0 && token == ')') break;
+            if (token != CPP_IDENTIFIER) {
+				CPPErrorToInfoLog("#define");
+                return token;
+            }
+            if (argc < MAX_MACRO_ARGS)
+                args[argc++] = yylvalpp->sc_ident;
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        } while (token == ',');
+        if (token != ')') {
+            CPPErrorToInfoLog("#define");
+            return token;
+        }
+        mac.argc = argc;
+        mac.args = mem_Alloc(macros->pool, argc * sizeof(int));
+        memcpy(mac.args, args, argc * sizeof(int));
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	}
+    mac.body = NewTokenStream(GetAtomString(atable, name), macros->pool);
+    while (token != '\n') {
+        while (token == '\\') {
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (token == '\n')
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            else
+                RecordToken(mac.body, '\\', yylvalpp);
+        }
+        RecordToken(mac.body, token, yylvalpp);
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    };
+
+    symb = LookUpSymbol(macros, name);
+    if (symb) {
+        if (!symb->details.mac.undef) {
+            // already defined -- need to make sure they are identical
+            if (symb->details.mac.argc != mac.argc) goto error;
+            for (argc=0; argc < mac.argc; argc++)
+                if (symb->details.mac.args[argc] != mac.args[argc])
+                    goto error;
+            RewindTokenStream(symb->details.mac.body);
+            RewindTokenStream(mac.body);
+            do {
+                int old_lval, old_token;
+                old_token = ReadToken(symb->details.mac.body, yylvalpp);
+                old_lval = yylvalpp->sc_int;
+                token = ReadToken(mac.body, yylvalpp);
+                if (token != old_token || yylvalpp->sc_int != old_lval) { 
+                error:
+                    StoreStr("Macro Redefined");
+                    StoreStr(GetStringOfAtom(atable,name));
+                    message=GetStrfromTStr();
+                    DecLineNumber();
+                    CPPShInfoLogMsg(message);
+                    IncLineNumber();
+                    ResetTString();
+                    break; }
+            } while (token > 0);
+        }
+        //FreeMacro(&symb->details.mac);
+    } else {
+        dummyLoc.file = 0;
+        dummyLoc.line = 0;
+        symb = AddSymbol(&dummyLoc, macros, name, MACRO_S);
+    }
+    symb->details.mac = mac;
+    return '\n';
+} // CPPdefine
+
+static int CPPundef(yystypepp * yylvalpp)
+{
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    Symbol *symb;
+	if(token == '\n'){
+		CPPErrorToInfoLog("#undef");
+	    return token;
+    }
+    if (token != CPP_IDENTIFIER)
+          goto error;
+    symb = LookUpSymbol(macros, yylvalpp->sc_ident);
+    if (symb) {
+        symb->details.mac.undef = 1;
+    }
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token != '\n') {
+    error:
+        CPPErrorToInfoLog("#undef");
+    }
+    return token;
+} // CPPundef
+
+/* CPPelse -- skip forward to appropriate spot.  This is actually used
+** to skip to and #endif after seeing an #else, AND to skip to a #else,
+** #elif, or #endif after a #if/#ifdef/#ifndef/#elif test was false
+*/
+
+static int CPPelse(int matchelse, yystypepp * yylvalpp)
+{
+    int atom,depth=0;
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	
+	while (token > 0) {
+        if (token != '#') {
+		    while (token != '\n')
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            continue;
+        }
+		if ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) != CPP_IDENTIFIER)
+			continue;
+        atom = yylvalpp->sc_ident;
+        if (atom == ifAtom || atom == ifdefAtom || atom == ifndefAtom){
+            depth++; cpp->ifdepth++; cpp->elsetracker++;
+		}
+		else if (atom == endifAtom) {
+            if(--depth<=0){
+		        cpp->elsedepth[cpp->elsetracker]=0;
+			    --cpp->elsetracker;
+                if (cpp->ifdepth) 
+                    --cpp->ifdepth;
+                break;
+            }             
+                --cpp->elsetracker;
+                --cpp->ifdepth;
+            }
+        else if (((int)(matchelse) != 0)&& depth==0) {
+			if (atom == elseAtom ) {
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                if (token != '\n') {
+                    CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
+                    while (token != '\n')
+                        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                } 
+				break;
+			} 
+			else if (atom == elifAtom) {
+                /* we decrement cpp->ifdepth here, because CPPif will increment
+                 * it and we really want to leave it alone */
+				if (cpp->ifdepth){
+					--cpp->ifdepth;
+				    --cpp->elsetracker;
+				}
+                return CPPif(yylvalpp);
+            }
+		}
+        else if((atom==elseAtom) && (!ChkCorrectElseNesting())){
+            CPPErrorToInfoLog("#else after a #else");
+            cpp->CompileError=1;
+        }
+	};
+    return token;
+}
+
+enum eval_prec {
+    MIN_PREC,
+    COND, LOGOR, LOGAND, OR, XOR, AND, EQUAL, RELATION, SHIFT, ADD, MUL, UNARY,
+    MAX_PREC
+};
+
+static int op_logor(int a, int b) { return a || b; }
+static int op_logand(int a, int b) { return a && b; }
+static int op_or(int a, int b) { return a | b; }
+static int op_xor(int a, int b) { return a ^ b; }
+static int op_and(int a, int b) { return a & b; }
+static int op_eq(int a, int b) { return a == b; }
+static int op_ne(int a, int b) { return a != b; }
+static int op_ge(int a, int b) { return a >= b; }
+static int op_le(int a, int b) { return a <= b; }
+static int op_gt(int a, int b) { return a > b; }
+static int op_lt(int a, int b) { return a < b; }
+static int op_shl(int a, int b) { return a << b; }
+static int op_shr(int a, int b) { return a >> b; }
+static int op_add(int a, int b) { return a + b; }
+static int op_sub(int a, int b) { return a - b; }
+static int op_mul(int a, int b) { return a * b; }
+static int op_div(int a, int b) { return a / b; }
+static int op_mod(int a, int b) { return a % b; }
+static int op_pos(int a) { return a; }
+static int op_neg(int a) { return -a; }
+static int op_cmpl(int a) { return ~a; }
+static int op_not(int a) { return !a; }
+
+struct {
+    int token, prec, (*op)(int, int);
+} binop[] = {
+    { CPP_OR_OP, LOGOR, op_logor },
+    { CPP_AND_OP, LOGAND, op_logand },
+    { '|', OR, op_or },
+    { '^', XOR, op_xor },
+    { '&', AND, op_and },
+    { CPP_EQ_OP, EQUAL, op_eq },
+    { CPP_NE_OP, EQUAL, op_ne },
+    { '>', RELATION, op_gt },
+    { CPP_GE_OP, RELATION, op_ge },
+    { '<', RELATION, op_lt },
+    { CPP_LE_OP, RELATION, op_le },
+    { CPP_LEFT_OP, SHIFT, op_shl },
+    { CPP_RIGHT_OP, SHIFT, op_shr },
+    { '+', ADD, op_add },
+    { '-', ADD, op_sub },
+    { '*', MUL, op_mul },
+    { '/', MUL, op_div },
+    { '%', MUL, op_mod },
+};
+
+struct {
+    int token, (*op)(int);
+} unop[] = {
+    { '+', op_pos },
+    { '-', op_neg },
+    { '~', op_cmpl },
+    { '!', op_not },
+};
+
+#define ALEN(A) (sizeof(A)/sizeof(A[0]))
+
+static int eval(int token, int prec, int *res, int *err, yystypepp * yylvalpp)
+{
+    int         i, val;
+    Symbol      *s;
+    if (token == CPP_IDENTIFIER) {
+        if (yylvalpp->sc_ident == definedAtom) {
+            int needclose = 0;
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (token == '(') {
+                needclose = 1;
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            }
+            if (token != CPP_IDENTIFIER)
+                goto error;
+            *res = (s = LookUpSymbol(macros, yylvalpp->sc_ident))
+                        ? !s->details.mac.undef : 0;
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            if (needclose) {
+                if (token != ')')
+                    goto error;
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            }
+		} else if (MacroExpand(yylvalpp->sc_ident, yylvalpp)) {
+			token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            return eval(token, prec, res, err, yylvalpp);
+        } else {
+            goto error;
+        }
+	} else if (token == CPP_INTCONSTANT) {
+        *res = yylvalpp->sc_int;
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    } else if (token == '(') {
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        token = eval(token, MIN_PREC, res, err, yylvalpp);
+        if (!*err) {
+            if (token != ')')
+                goto error;
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        }
+    } else {
+        for (i = ALEN(unop) - 1; i >= 0; i--) {
+            if (unop[i].token == token)
+                break;
+        }
+        if (i >= 0) {
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+            token = eval(token, UNARY, res, err, yylvalpp);
+            *res = unop[i].op(*res);
+        } else {
+            goto error;
+        }
+    }
+    while (!*err) {
+        if (token == ')' || token == '\n') break;
+        for (i = ALEN(binop) - 1; i >= 0; i--) {
+            if (binop[i].token == token)
+                break;
+        }
+        if (i < 0 || binop[i].prec <= prec)
+            break;
+        val = *res;
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        token = eval(token, binop[i].prec, res, err, yylvalpp);
+        *res = binop[i].op(val, *res);
+    }
+    return token;
+error:
+    CPPErrorToInfoLog("incorrect preprocessor directive");
+    *err = 1;
+    *res = 0;
+    return token;
+} // eval
+
+static int CPPif(yystypepp * yylvalpp) {
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    int res = 0, err = 0;
+	cpp->elsetracker++;
+    if (!cpp->ifdepth++)
+        ifloc = *cpp->tokenLoc;
+	if(cpp->ifdepth >MAX_IF_NESTING){
+        CPPErrorToInfoLog("max #if nesting depth exceeded");
+		return 0;
+	}
+	token = eval(token, MIN_PREC, &res, &err, yylvalpp);
+    if (token != '\n') {
+        CPPWarningToInfoLog("unexpected tokens following the preprocessor directive - expected a newline");
+        while (token != '\n')
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    } 
+    if (!res && !err) {
+        token = CPPelse(1, yylvalpp);
+    }
+
+    return token;
+} // CPPif
+
+static int CPPifdef(int defined, yystypepp * yylvalpp)
+{
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    int name = yylvalpp->sc_ident;
+	if(++cpp->ifdepth >MAX_IF_NESTING){
+	    CPPErrorToInfoLog("max #if nesting depth exceeded");
+		return 0;
+	}
+	cpp->elsetracker++;
+    if (token != CPP_IDENTIFIER) {
+            defined ? CPPErrorToInfoLog("ifdef"):CPPErrorToInfoLog("ifndef");
+    } else {
+        Symbol *s = LookUpSymbol(macros, name);
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        if (token != '\n') {
+            CPPWarningToInfoLog("unexpected tokens following #ifdef preprocessor directive - expected a newline");
+            while (token != '\n')
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        }
+        if (((s && !s->details.mac.undef) ? 1 : 0) != defined)
+            token = CPPelse(1, yylvalpp);
+    }
+    return token;
+} // CPPifdef
+
+static int CPPline(yystypepp * yylvalpp) 
+{
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	if(token=='\n'){
+		DecLineNumber();
+        CPPErrorToInfoLog("#line");
+        IncLineNumber();
+		return token;
+	}
+	else if (token == CPP_INTCONSTANT) {
+		yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
+		SetLineNumber(yylvalpp->sc_int);
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        
+		if (token == CPP_INTCONSTANT) {
+            yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
+			SetStringNumber(yylvalpp->sc_int);
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+			if(token!='\n')
+				CPPErrorToInfoLog("#line");
+        }
+		else if (token == '\n'){
+			return token;
+		}
+		else{
+            CPPErrorToInfoLog("#line");
+		}
+	}
+	else{
+          CPPErrorToInfoLog("#line");
+	}
+    return token;
+}
+
+static int CPPerror(yystypepp * yylvalpp) {
+
+	int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    const char *message;
+	
+    while (token != '\n') {
+		if (token == CPP_FLOATCONSTANT || token == CPP_INTCONSTANT){
+            StoreStr(yylvalpp->symbol_name);
+		}else if(token == CPP_IDENTIFIER || token == CPP_STRCONSTANT){
+			StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
+		}else {
+		    StoreStr(GetStringOfAtom(atable,token));
+		}
+		token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	}
+	DecLineNumber();
+	//store this msg into the shader's information log..set the Compile Error flag!!!!
+	message=GetStrfromTStr();
+    CPPShInfoLogMsg(message);
+    ResetTString();
+    cpp->CompileError=1;
+    IncLineNumber();
+    return '\n';
+}//CPPerror
+
+static int CPPpragma(yystypepp * yylvalpp)
+{
+	char SrcStrName[2];
+	char** allTokens;
+	int tokenCount = 0;
+	int maxTokenCount = 10;
+	const char* SrcStr;
+	int i;
+
+	int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	
+	if (token=='\n') {
+		DecLineNumber();
+        CPPErrorToInfoLog("#pragma");
+        IncLineNumber();
+	    return token;
+	}
+	
+	allTokens = (char**)malloc(sizeof(char*) * maxTokenCount);	
+
+	while (token != '\n') {
+		if (tokenCount >= maxTokenCount) {
+			maxTokenCount *= 2;
+			allTokens = (char**)realloc((char**)allTokens, sizeof(char*) * maxTokenCount);
+		}
+		switch (token) {
+		case CPP_IDENTIFIER:
+			SrcStr = GetAtomString(atable, yylvalpp->sc_ident);
+			allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
+			strcpy(allTokens[tokenCount++], SrcStr);
+			break;
+		case CPP_INTCONSTANT:
+			SrcStr = yylvalpp->symbol_name;
+			allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
+			strcpy(allTokens[tokenCount++], SrcStr);
+			break;
+		case CPP_FLOATCONSTANT:
+			SrcStr = yylvalpp->symbol_name;
+			allTokens[tokenCount] = (char*)malloc(strlen(SrcStr) + 1);
+			strcpy(allTokens[tokenCount++], SrcStr);
+			break;
+		case -1:
+            // EOF
+            CPPShInfoLogMsg("#pragma directive must end with a newline");			
+			return token;
+		default:
+			SrcStrName[0] = token;
+			SrcStrName[1] = '\0';
+			allTokens[tokenCount] = (char*)malloc(2);
+			strcpy(allTokens[tokenCount++], SrcStrName);
+		}
+		token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	}
+
+	cpp->currentInput->ungetch(cpp->currentInput, token, yylvalpp);
+	HandlePragma((const char**)allTokens, tokenCount);
+	token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	
+	for (i = 0; i < tokenCount; ++i) {
+		free (allTokens[i]);
+	}
+	free (allTokens);	
+
+	return token;    
+} // CPPpragma
+
+#define GL2_VERSION_NUMBER 110
+
+static int CPPversion(yystypepp * yylvalpp)
+{
+
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+
+    if (cpp->notAVersionToken == 1)
+        CPPShInfoLogMsg("#version must occur before any other statement in the program");
+
+    if(token=='\n'){
+		DecLineNumber();
+        CPPErrorToInfoLog("#version");
+        IncLineNumber();
+		return token;
+	}
+    if (token != CPP_INTCONSTANT)
+        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");
+
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    
+	if (token == '\n'){
+		return token;
+	}
+	else{
+        CPPErrorToInfoLog("#version");
+	}
+    return token;
+} // CPPversion
+
+static int CPPextension(yystypepp * yylvalpp)
+{
+
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    char extensionName[80];
+
+    if(token=='\n'){
+		DecLineNumber();
+        CPPShInfoLogMsg("extension name not specified");
+        IncLineNumber();
+		return token;
+	}
+
+    if (token != CPP_IDENTIFIER)
+        CPPErrorToInfoLog("#extension");
+    
+    strcpy(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
+	    
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token != ':') {
+        CPPShInfoLogMsg("':' missing after extension name");
+        return token;
+    }
+    
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    if (token != CPP_IDENTIFIER) {
+        CPPShInfoLogMsg("behavior for extension not specified");
+        return token;
+    }
+
+    updateExtensionBehavior(extensionName, GetAtomString(atable, yylvalpp->sc_ident));
+
+    token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	if (token == '\n'){
+		return token;
+	}
+	else{
+        CPPErrorToInfoLog("#extension");
+	}
+    return token;
+} // CPPextension
+
+int readCPPline(yystypepp * yylvalpp)
+{
+    int token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+    const char *message;
+    int isVersion = 0;
+
+    if (token == CPP_IDENTIFIER) {
+        if (yylvalpp->sc_ident == defineAtom) {
+             token = CPPdefine(yylvalpp);
+        } else if (yylvalpp->sc_ident == elseAtom) {
+			 if(ChkCorrectElseNesting()){
+                 if (!cpp->ifdepth ){
+                     CPPErrorToInfoLog("#else mismatch");
+                     cpp->CompileError=1;
+                 }
+                 token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                 if (token != '\n') {
+                     CPPWarningToInfoLog("unexpected tokens following #else preprocessor directive - expected a newline");
+                     while (token != '\n')
+                         token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                 }
+			     token = CPPelse(0, yylvalpp);
+             }else{
+                 CPPErrorToInfoLog("#else after a #else");
+                 cpp->ifdepth=0;
+                 cpp->notAVersionToken = 1;
+                 return 0;
+             }
+		} else if (yylvalpp->sc_ident == elifAtom) {
+            if (!cpp->ifdepth){
+                 CPPErrorToInfoLog("#elif mismatch");
+                 cpp->CompileError=1;
+            } 
+            // this token is really a dont care, but we still need to eat the tokens
+            token = cpp->currentInput->scan(cpp->currentInput, yylvalpp); 
+            while (token != '\n')
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+		    token = CPPelse(0, yylvalpp);
+        } else if (yylvalpp->sc_ident == endifAtom) {
+			 cpp->elsedepth[cpp->elsetracker]=0;
+		     --cpp->elsetracker;
+             if (!cpp->ifdepth){
+                 CPPErrorToInfoLog("#endif mismatch");
+                 cpp->CompileError=1;
+             }
+             else
+			  	 --cpp->ifdepth;
+	    } else if (yylvalpp->sc_ident == ifAtom) {
+             token = CPPif(yylvalpp);
+        } else if (yylvalpp->sc_ident == ifdefAtom) {
+             token = CPPifdef(1, yylvalpp);
+        } else if (yylvalpp->sc_ident == ifndefAtom) {
+             token = CPPifdef(0, yylvalpp);
+        } else if (yylvalpp->sc_ident == lineAtom) {
+             token = CPPline(yylvalpp);
+        } else if (yylvalpp->sc_ident == pragmaAtom) {
+             token = CPPpragma(yylvalpp);
+        } else if (yylvalpp->sc_ident == undefAtom) {
+             token = CPPundef(yylvalpp);
+        } else if (yylvalpp->sc_ident == errorAtom) {
+             token = CPPerror(yylvalpp);
+        } else if (yylvalpp->sc_ident == versionAtom) {
+            token = CPPversion(yylvalpp);
+            isVersion = 1;
+        } else if (yylvalpp->sc_ident == extensionAtom) {
+            token = CPPextension(yylvalpp);
+        } else {
+            StoreStr("Invalid Directive");
+            StoreStr(GetStringOfAtom(atable,yylvalpp->sc_ident));
+            message=GetStrfromTStr();
+            CPPShInfoLogMsg(message);
+            ResetTString();
+        }
+    }
+    while (token != '\n' && token != 0 && token != EOF) {
+		token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+	}
+        
+    cpp->notAVersionToken = !isVersion;
+
+    return token;
+} // readCPPline
+
+void FreeMacro(MacroSymbol *s) {
+    DeleteTokenStream(s->body);
+}
+
+static int eof_scan(InputSrc *in, yystypepp * yylvalpp) { return -1; }
+static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) { }
+
+static void PushEofSrc() {
+    InputSrc *in = malloc(sizeof(InputSrc));
+    memset(in, 0, sizeof(InputSrc));
+    in->scan = eof_scan;
+    in->getch = eof_scan;
+    in->ungetch = noop;
+    in->prev = cpp->currentInput;
+    cpp->currentInput = in;
+}
+
+static void PopEofSrc() {
+    if (cpp->currentInput->scan == eof_scan) {
+        InputSrc *in = cpp->currentInput;
+        cpp->currentInput = in->prev;
+        free(in);
+    }
+}
+
+static TokenStream *PrescanMacroArg(TokenStream *a, yystypepp * yylvalpp) {
+    int token;
+    TokenStream *n;
+    RewindTokenStream(a);
+    do {
+        token = ReadToken(a, yylvalpp);
+        if (token == CPP_IDENTIFIER && LookUpSymbol(macros, yylvalpp->sc_ident))
+            break;
+    } while (token > 0);
+    if (token <= 0) return a;
+    n = NewTokenStream("macro arg", 0);
+    PushEofSrc();
+    ReadFromTokenStream(a, 0, 0);
+    while ((token = cpp->currentInput->scan(cpp->currentInput, yylvalpp)) > 0) {
+        if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp->sc_ident, yylvalpp))
+            continue;
+        RecordToken(n, token, yylvalpp);
+    }
+    PopEofSrc();
+    DeleteTokenStream(a);
+    return n;
+} // PrescanMacroArg
+
+typedef struct MacroInputSrc {
+    InputSrc    base;
+    MacroSymbol *mac;
+    TokenStream **args;
+} MacroInputSrc;
+
+/* macro_scan ---
+** return the next token for a macro expanion, handling macro args 
+*/
+static int macro_scan(MacroInputSrc *in, yystypepp * yylvalpp) {
+    int i;
+    int token = ReadToken(in->mac->body, yylvalpp);
+    if (token == CPP_IDENTIFIER) {
+        for (i = in->mac->argc-1; i>=0; i--)
+            if (in->mac->args[i] == yylvalpp->sc_ident) break;
+        if (i >= 0) {
+            ReadFromTokenStream(in->args[i], yylvalpp->sc_ident, 0);
+            return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+        }
+    }
+    if (token > 0) return token;
+    in->mac->busy = 0;
+    cpp->currentInput = in->base.prev;
+    if (in->args) {
+        for (i=in->mac->argc-1; i>=0; i--)
+            DeleteTokenStream(in->args[i]);
+        free(in->args);
+    }
+    free(in);
+    return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+} // macro_scan
+
+/* MacroExpand
+** check an identifier (atom) to see if it a macro that should be expanded.
+** If it is, push an InputSrc that will produce the appropriate expansion
+** and return TRUE.  If not, return FALSE.
+*/
+
+int MacroExpand(int atom, yystypepp * yylvalpp)
+{
+    Symbol              *sym = LookUpSymbol(macros, atom);
+    MacroInputSrc       *in;
+    int i,j, token, depth=0;
+    const char *message;
+	if (atom == __LINE__Atom) {
+        yylvalpp->sc_int = GetLineNumber();
+        sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int);
+        UngetToken(CPP_INTCONSTANT, yylvalpp);
+        return 1;
+    }
+    if (atom == __FILE__Atom) {
+        yylvalpp->sc_int = GetStringNumber();
+        sprintf(yylvalpp->symbol_name,"%d",yylvalpp->sc_int);
+        UngetToken(CPP_INTCONSTANT, yylvalpp);
+        return 1;
+    }
+	if (atom == __VERSION__Atom) {
+        strcpy(yylvalpp->symbol_name,"100");
+        yylvalpp->sc_int = atoi(yylvalpp->symbol_name);
+        UngetToken(CPP_INTCONSTANT, yylvalpp);
+        return 1;
+    }
+    if (!sym || sym->details.mac.undef) return 0;
+    if (sym->details.mac.busy) return 0;        // no recursive expansions
+    in = malloc(sizeof(*in));
+    memset(in, 0, sizeof(*in));
+    in->base.scan = (void *)macro_scan;
+    in->base.line = cpp->currentInput->line;
+    in->base.name = cpp->currentInput->name;
+    in->mac = &sym->details.mac;
+    if (sym->details.mac.args) {
+        token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+		if (token != '(') {
+            UngetToken(token, yylvalpp);
+            yylvalpp->sc_ident = atom;
+            return 0;
+        }
+        in->args = malloc(in->mac->argc * sizeof(TokenStream *));
+        for (i=0; i<in->mac->argc; i++)
+            in->args[i] = NewTokenStream("macro arg", 0);
+		i=0;j=0;
+        do{
+            depth = 0;
+			while(1) {
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                if (token <= 0) {
+                    StoreStr("EOF in Macro ");
+                    StoreStr(GetStringOfAtom(atable,atom));
+                    message=GetStrfromTStr();
+                    CPPShInfoLogMsg(message);
+                    ResetTString();
+                    return 1;
+                }
+                if((in->mac->argc==0) && (token!=')')) break;
+                if (depth == 0 && (token == ',' || token == ')')) break;
+                if (token == '(') depth++;
+                if (token == ')') depth--;
+                RecordToken(in->args[i], token, yylvalpp);
+                j=1;
+			}
+            if (token == ')') {
+                if((in->mac->argc==1) &&j==0)
+                    break;
+                i++;
+                break;
+            }
+            i++;
+		}while(i < in->mac->argc);
+
+        if (i < in->mac->argc) {
+            StoreStr("Too few args in Macro ");
+            StoreStr(GetStringOfAtom(atable,atom));
+            message=GetStrfromTStr();
+            CPPShInfoLogMsg(message);
+            ResetTString();
+        } else if (token != ')') {
+            depth=0;
+			while (token >= 0 && (depth > 0 || token != ')')) {
+                if (token == ')') depth--;
+                token = cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+                if (token == '(') depth++;
+            }
+			
+            if (token <= 0) {
+                StoreStr("EOF in Macro ");
+                StoreStr(GetStringOfAtom(atable,atom));
+                message=GetStrfromTStr();
+                CPPShInfoLogMsg(message);
+                ResetTString();
+                return 1;
+            }
+            StoreStr("Too many args in Macro ");
+            StoreStr(GetStringOfAtom(atable,atom));
+            message=GetStrfromTStr();
+            CPPShInfoLogMsg(message);
+            ResetTString();
+		}
+		for (i=0; i<in->mac->argc; i++) {
+            in->args[i] = PrescanMacroArg(in->args[i], yylvalpp);
+        }
+    }
+#if 0
+    printf("  <%s:%d>found macro %s\n", GetAtomString(atable, loc.file),
+           loc.line, GetAtomString(atable, atom));
+    for (i=0; i<in->mac->argc; i++) {
+        printf("\targ %s = '", GetAtomString(atable, in->mac->args[i]));
+        DumpTokenStream(stdout, in->args[i]);
+        printf("'\n");
+    }
+#endif
+	/*retain the input source*/
+    in->base.prev = cpp->currentInput;
+    sym->details.mac.busy = 1;
+    RewindTokenStream(sym->details.mac.body);
+    cpp->currentInput = &in->base;
+    return 1;
+} // MacroExpand
+
+int ChkCorrectElseNesting(void)
+{
+    if(cpp->elsedepth[cpp->elsetracker]==0){
+	  cpp->elsedepth[cpp->elsetracker]=1;
+      return 1;          
+    }
+    return 0;
+}
+
+
diff --git a/Compiler/Preprocessor/cpp.h b/Compiler/Preprocessor/cpp.h
new file mode 100644
index 0000000..85abbb5
--- /dev/null
+++ b/Compiler/Preprocessor/cpp.h
@@ -0,0 +1,91 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// cpp.h
+//
+
+#if !defined(__CPP_H)
+#define __CPP_H 1
+
+#include "parser.h"
+#include "tokens.h"
+
+int InitCPP(void);
+int FinalCPP(void);
+int  readCPPline(yystypepp * yylvalpp);
+int MacroExpand(int atom, yystypepp * yylvalpp);
+int ChkCorrectElseNesting(void);
+
+typedef struct MacroSymbol {
+    int argc;
+    int *args;
+    TokenStream *body;
+    unsigned busy:1;
+    unsigned undef:1;
+} MacroSymbol;
+
+void FreeMacro(MacroSymbol *);
+int PredefineMacro(char *);
+
+void  CPPDebugLogMsg(const char *msg);      // Prints information into debug log
+void  CPPShInfoLogMsg(const char*);         // Store cpp Err Msg into Sh.Info.Log
+void  CPPWarningToInfoLog(const char *msg); // Prints warning messages into info log
+void  HandlePragma(const char**, int numTokens);  // #pragma directive container.
+void  ResetTString(void);                   // #error Message as TString.
+void  CPPErrorToInfoLog(char*);             // Stick all cpp errors into Sh.Info.log   .
+void  StoreStr(char*);                      // Store the TString in Parse Context.
+void  SetLineNumber(int);                   // Set line number.  
+void  SetStringNumber(int);                 // Set string number.    
+int   GetLineNumber(void);                  // Get the current String Number. 
+int   GetStringNumber(void);                // Get the current String Number. 
+const char* GetStrfromTStr(void);           // Convert TString to String.  
+void  updateExtensionBehavior(const char* extName, const char* behavior);
+int   FreeCPP(void);
+
+#endif // !(defined(__CPP_H)
diff --git a/Compiler/Preprocessor/cppstruct.c b/Compiler/Preprocessor/cppstruct.c
new file mode 100644
index 0000000..5144b6c
--- /dev/null
+++ b/Compiler/Preprocessor/cppstruct.c
@@ -0,0 +1,157 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// cppstruct.c
+//
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "slglobals.h"
+
+CPPStruct  *cpp      = NULL;
+static int  refCount = 0;
+
+int InitPreprocessor(void);
+int ResetPreprocessor(void);
+int FreeCPPStruct(void);
+int FinalizePreprocessor(void);
+
+/*
+ * InitCPPStruct() - Initilaize the CPP structure.
+ *
+ */
+
+int InitCPPStruct(void)
+{
+    int len;
+    char *p;
+
+    cpp = (CPPStruct *) malloc(sizeof(CPPStruct));
+    if (cpp == NULL)
+        return 0;
+
+    refCount++;
+
+    // Initialize public members:
+    cpp->pLastSourceLoc = &cpp->lastSourceLoc;
+    
+	p = (char *) &cpp->options;
+    len = sizeof(cpp->options);
+    while (--len >= 0)
+        p[len] = 0;
+     
+    ResetPreprocessor();
+    return 1;
+} // InitCPPStruct
+
+int ResetPreprocessor(void)
+{
+    // Initialize private members:
+
+    cpp->lastSourceLoc.file = 0;
+    cpp->lastSourceLoc.line = 0;
+	cpp->pC=0;
+    cpp->CompileError=0; 
+	cpp->ifdepth=0;
+    for(cpp->elsetracker=0; cpp->elsetracker<64; cpp->elsetracker++)
+		cpp->elsedepth[cpp->elsetracker]=0; 
+	cpp->elsetracker=0;
+    cpp->tokensBeforeEOF = 0;
+    return 1;
+}
+
+//Intializing the Preprocessor.
+
+int InitPreprocessor(void)
+{
+   #  define CPP_STUFF true
+        #  ifdef CPP_STUFF
+            FreeCPPStruct();
+            InitCPPStruct();
+            cpp->options.Quiet = 1;
+            cpp->options.profileString = "generic";
+            if (!InitAtomTable(atable, 0))
+                return 1;
+            if (!InitScanner(cpp))
+	            return 1;
+       #  endif
+  return 0; 
+}
+
+//FreeCPPStruct() - Free the CPP structure.
+
+int FreeCPPStruct(void)
+{
+    if (refCount)
+    {
+       free(cpp);
+       refCount--;
+    }
+    
+    return 1;
+}
+
+//Finalizing the Preprocessor.
+
+int FinalizePreprocessor(void)
+{
+   #  define CPP_STUFF true
+        #  ifdef CPP_STUFF
+            FreeAtomTable(atable);
+            FreeCPPStruct();
+            FreeScanner();
+       #  endif
+  return 0; 
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////// End of cppstruct.c //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Compiler/Preprocessor/memory.c b/Compiler/Preprocessor/memory.c
new file mode 100644
index 0000000..1a70231
--- /dev/null
+++ b/Compiler/Preprocessor/memory.c
@@ -0,0 +1,163 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __STDC99__
+#include <stdint.h>
+#elif defined (_WIN64)
+typedef unsigned __int64 uintptr_t;
+#else 
+typedef unsigned int uintptr_t;
+#endif
+
+#include "memory.h"
+
+// default alignment and chunksize, if called with 0 arguments
+#define CHUNKSIZE       (64*1024)
+#define ALIGN           8
+
+// we need to call the `real' malloc and free, not our replacements
+#undef malloc
+#undef free
+
+struct chunk {
+    struct chunk        *next;
+};
+
+struct cleanup {
+    struct cleanup      *next;
+    void                (*fn)(void *);
+    void                *arg;
+};
+
+struct MemoryPool_rec {
+    struct chunk        *next;
+    uintptr_t           free, end;
+    size_t              chunksize;
+    uintptr_t           alignmask;
+    struct cleanup      *cleanup;
+};
+
+MemoryPool *mem_CreatePool(size_t chunksize, unsigned int align)
+{
+    MemoryPool  *pool;
+
+    if (align == 0) align = ALIGN;
+    if (chunksize == 0) chunksize = CHUNKSIZE;
+    if (align & (align-1)) return 0;
+    if (chunksize < sizeof(MemoryPool)) return 0;
+    if (chunksize & (align-1)) return 0;
+    if (!(pool = malloc(chunksize))) return 0;
+    pool->next = 0;
+    pool->chunksize = chunksize;
+    pool->alignmask = (uintptr_t)(align)-1;  
+    pool->free = ((uintptr_t)(pool + 1) + pool->alignmask) & ~pool->alignmask;
+    pool->end = (uintptr_t)pool + chunksize;
+    pool->cleanup = 0;
+    return pool;
+}
+
+void mem_FreePool(MemoryPool *pool)
+{
+    struct cleanup      *cleanup;
+    struct chunk        *p, *next;
+
+    for (cleanup = pool->cleanup; cleanup; cleanup = cleanup->next) {
+        cleanup->fn(cleanup->arg);
+    }
+    for (p = (struct chunk *)pool; p; p = next) {
+        next = p->next;
+        free(p);
+    }
+}
+
+void *mem_Alloc(MemoryPool *pool, size_t size)
+{
+    struct chunk *ch;
+    void *rv = (void *)pool->free;
+    size = (size + pool->alignmask) & ~pool->alignmask;
+    if (size <= 0) size = pool->alignmask;
+    pool->free += size;
+    if (pool->free > pool->end || pool->free < (uintptr_t)rv) {
+        size_t minreq = (size + sizeof(struct chunk) + pool->alignmask)
+                      & ~pool->alignmask;
+        pool->free = (uintptr_t)rv;
+        if (minreq >= pool->chunksize) {
+            // request size is too big for the chunksize, so allocate it as
+            // a single chunk of the right size
+            ch = malloc(minreq);
+            if (!ch) return 0;
+        } else {
+            ch = malloc(pool->chunksize);
+            if (!ch) return 0;
+            pool->free = (uintptr_t)ch + minreq;
+            pool->end = (uintptr_t)ch + pool->chunksize;
+        }
+        ch->next = pool->next;
+        pool->next = ch;
+        rv = (void *)(((uintptr_t)(ch+1) + pool->alignmask) & ~pool->alignmask);
+    }
+    return rv;
+}
+
+int mem_AddCleanup(MemoryPool *pool, void (*fn)(void *), void *arg) {
+    struct cleanup *cleanup;
+
+    pool->free = (pool->free + sizeof(void *) - 1) & ~(sizeof(void *)-1);
+    cleanup = mem_Alloc(pool, sizeof(struct cleanup));
+    if (!cleanup) return -1;
+    cleanup->next = pool->cleanup;
+    cleanup->fn = fn;
+    cleanup->arg = arg;
+    pool->cleanup = cleanup;
+    return 0;
+}
diff --git a/Compiler/Preprocessor/memory.h b/Compiler/Preprocessor/memory.h
new file mode 100644
index 0000000..3da7989
--- /dev/null
+++ b/Compiler/Preprocessor/memory.h
@@ -0,0 +1,61 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+#ifndef __MEMORY_H
+#define __MEMORY_H
+
+typedef struct MemoryPool_rec MemoryPool;
+
+extern MemoryPool *mem_CreatePool(size_t chunksize, unsigned align);
+extern void mem_FreePool(MemoryPool *);
+extern void *mem_Alloc(MemoryPool *p, size_t size);
+extern void *mem_Realloc(MemoryPool *p, void *old, size_t oldsize, size_t newsize);
+extern int mem_AddCleanup(MemoryPool *p, void (*fn)(void *), void *arg);
+
+#endif /* __MEMORY_H */
diff --git a/Compiler/Preprocessor/parser.h b/Compiler/Preprocessor/parser.h
new file mode 100644
index 0000000..91a6200
--- /dev/null
+++ b/Compiler/Preprocessor/parser.h
@@ -0,0 +1,98 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+#ifndef BISON_PARSER_H
+# define BISON_PARSER_H
+
+#ifndef yystypepp
+typedef struct {
+    int    sc_int;
+    float  sc_fval;
+    int    sc_ident;
+	char   symbol_name[MAX_SYMBOL_NAME_LEN+1];
+} yystypepp;
+
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+# define	CPP_AND_OP	        257
+# define	CPP_SUB_ASSIGN	    259
+# define	CPP_MOD_ASSIGN	    260
+# define	CPP_ADD_ASSIGN	261
+# define	CPP_DIV_ASSIGN	262
+# define	CPP_MUL_ASSIGN	263
+# define	CPP_EQ_OP	        264
+# define    CPP_XOR_OP         265 
+# define	ERROR_SY	    266
+# define	CPP_FLOATCONSTANT	267
+# define	CPP_GE_OP	        268
+# define	CPP_RIGHT_OP        269
+# define	CPP_IDENTIFIER	    270
+# define	CPP_INTCONSTANT	    271
+# define	CPP_LE_OP	        272
+# define	CPP_LEFT_OP	        273
+# define	CPP_DEC_OP	274
+# define	CPP_NE_OP	        275
+# define	CPP_OR_OP	        276
+# define	CPP_INC_OP	    277
+# define	CPP_STRCONSTANT	    278
+# define	CPP_TYPEIDENTIFIER	279
+
+# define	FIRST_USER_TOKEN_SY	289
+
+# define	CPP_RIGHT_ASSIGN	    280
+# define	CPP_LEFT_ASSIGN	    281
+# define	CPP_AND_ASSIGN	282
+# define	CPP_OR_ASSIGN  	283
+# define	CPP_XOR_ASSIGN	284
+# define	CPP_LEFT_BRACKET	285
+# define	CPP_RIGHT_BRACKET	286
+# define	CPP_LEFT_BRACE	287
+# define	CPP_RIGHT_BRACE	288
+
+#endif /* not BISON_PARSER_H */
diff --git a/Compiler/Preprocessor/preprocess.h b/Compiler/Preprocessor/preprocess.h
new file mode 100644
index 0000000..323cd1e
--- /dev/null
+++ b/Compiler/Preprocessor/preprocess.h
@@ -0,0 +1,56 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+
+# include "slglobals.h"
+extern CPPStruct *cpp;
+int InitCPPStruct(void);
+int InitScanner(CPPStruct *cpp);
+int InitAtomTable(AtomTable *atable, int htsize);
+int ScanFromString(char *s);
+char* GetStringOfAtom(AtomTable *atable, int atom);
diff --git a/Compiler/Preprocessor/scanner.c b/Compiler/Preprocessor/scanner.c
new file mode 100644
index 0000000..fcdf751
--- /dev/null
+++ b/Compiler/Preprocessor/scanner.c
@@ -0,0 +1,766 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// scanner.c
+//
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if 0
+    #include <ieeefp.h>
+    #else
+    #define isinff(x) (((*(int *)&(x) & 0x7f800000L)==0x7f800000L) && \
+                       ((*(int *)&(x) & 0x007fffffL)==0000000000L))
+#endif
+
+#include "slglobals.h"
+
+
+typedef struct StringInputSrc {
+    InputSrc base;
+    char *p;
+} StringInputSrc;
+
+static int eof_scan(InputSrc *is, yystypepp * yylvalpp)
+{
+    return EOF;
+} // eof_scan
+
+static void noop(InputSrc *in, int ch, yystypepp * yylvalpp) {}
+
+static InputSrc eof_inputsrc = { 0, &eof_scan, &eof_scan, &noop };
+
+static int byte_scan(InputSrc *, yystypepp * yylvalpp);
+
+#define EOL_SY '\n'
+
+#if defined(_WIN32)
+    #define DBG_BREAKPOINT() __asm int 3
+    #elif defined(_M_AMD64)
+    #define DBG_BREAKPOINT() assert(!"Dbg_Breakpoint");
+    #else
+    #define DBG_BREAKPOINT()
+    #endif
+
+    #if defined(_WIN32) && !defined(_M_AMD64)
+    __int64 RDTSC ( void ) {
+
+        __int64 v;
+    
+        __asm __emit 0x0f
+        __asm __emit 0x31
+        __asm mov dword ptr v, eax
+        __asm mov dword ptr v+4, edx
+    
+        return v;
+    }
+#endif
+
+
+int InitScanner(CPPStruct *cpp)
+{
+    // Add various atoms needed by the CPP line scanner:
+    if (!InitCPP())
+        return 0;
+
+    cpp->mostRecentToken = 0;
+    cpp->tokenLoc = &cpp->ltokenLoc;
+
+    cpp->ltokenLoc.file = 0;
+    cpp->ltokenLoc.line = 0;
+
+    cpp->currentInput = &eof_inputsrc;
+    cpp->previous_token = '\n';
+    cpp->notAVersionToken = 0;
+
+    return 1;
+} // InitScanner
+
+int FreeScanner(void)
+{
+    return (FreeCPP());
+}
+
+/*
+ * str_getch()
+ * takes care of reading from multiple strings.
+ * returns the next-char from the input stream.
+ * returns EOF when the complete shader is parsed.
+ */
+static int str_getch(StringInputSrc *in)
+{
+	for(;;){
+	   if (*in->p){
+	      if (*in->p == '\n') {
+             in->base.line++;
+             IncLineNumber();
+          }
+          return *in->p++;
+	   }
+	   if(++(cpp->PaWhichStr) < cpp->PaArgc){
+		  free(in);
+		  SetStringNumber(cpp->PaWhichStr);
+    	  SetLineNumber(1);
+		  ScanFromString(cpp->PaArgv[cpp->PaWhichStr]);
+		  in=(StringInputSrc*)cpp->currentInput;
+	      continue;             
+	   }
+	   else{
+	      cpp->currentInput = in->base.prev;
+	      cpp->PaWhichStr=0;
+          free(in);
+          return EOF;
+       }  
+	}
+} // str_getch
+
+static void str_ungetch(StringInputSrc *in, int ch, yystypepp *type) {
+    if (in->p[-1] == ch)in->p--;
+	else {
+		*(in->p)='\0'; //this would take care of shifting to the previous string.
+	    cpp->PaWhichStr--;
+	}  
+	if (ch == '\n') {
+        in->base.line--;
+        DecLineNumber();
+    }
+} // str_ungetch
+
+int ScanFromString(char *s)
+{
+    
+	StringInputSrc *in = malloc(sizeof(StringInputSrc));
+    memset(in, 0, sizeof(StringInputSrc));
+	in->p = s;
+    in->base.line = 1;
+    in->base.scan = byte_scan;
+    in->base.getch = (int (*)(InputSrc *, yystypepp *))str_getch;
+    in->base.ungetch = (void (*)(InputSrc *, int, yystypepp *))str_ungetch;
+    in->base.prev = cpp->currentInput;
+    cpp->currentInput = &in->base;
+
+    return 1;
+} // ScanFromString;
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// 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
+ *         has seen at least one digit, followed by either a decimal '.' or the
+ *         letter 'e'.
+ */
+
+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;
+    exp = 0;
+	
+    str_len=len;
+    if (ch == '.') {
+		str[len++]=ch;
+        HasDecimal = 1;
+        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+        while (ch >= '0' && ch <= '9') {
+            if (len < MAX_SYMBOL_NAME_LEN) {
+                declen++;
+                if (len > 0 || ch != '0') {
+                    str[len] = ch;
+                    len++;str_len++;
+                }
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            } else {
+                CPPErrorToInfoLog("ERROR___FP_CONST_TOO_LONG");
+                len = 1,str_len=1;
+            }
+        }
+    }
+
+    // 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;
+            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;
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            }
+        } else {
+            CPPErrorToInfoLog("ERROR___ERROR_IN_EXPONENT");
+        }
+        exp *= ExpSign;
+    }
+      
+    if (len == 0) {
+        lval = 0.0f;
+		strcpy(str,"0.0");
+    } else {
+        str[len]='\0';      
+        lval = lBuildFloatValue(str, str_len, exp - declen);
+    }
+    // Suffix:
+    
+    yylvalpp->sc_fval = lval;
+    strcpy(yylvalpp->symbol_name,str);
+    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);            
+    return CPP_FLOATCONSTANT;
+} // lFloatConst
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////// Normal Scanner //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+    
+static int byte_scan(InputSrc *in, yystypepp * yylvalpp)
+{
+    char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
+    char string_val[MAX_STRING_LEN + 1];
+    int AlreadyComplained;
+    int len, ch, ii, ival = 0;
+
+    for (;;) {
+        yylvalpp->sc_int = 0;
+        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+		
+        while (ch == ' ' || ch == '\t' || ch == '\r') {
+            yylvalpp->sc_int = 1;
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+        }
+		
+        cpp->ltokenLoc.file = cpp->currentInput->name;
+        cpp->ltokenLoc.line = cpp->currentInput->line;
+        len = 0;
+        switch (ch) {
+        default:
+			return ch; // Single character token
+        case EOF:
+            return -1;
+		case 'A': case 'B': case 'C': case 'D': case 'E':
+        case 'F': case 'G': case 'H': case 'I': case 'J':
+        case 'K': case 'L': case 'M': case 'N': case 'O':
+        case 'P': case 'Q': case 'R': case 'S': case 'T':
+        case 'U': case 'V': case 'W': case 'X': case 'Y':
+        case 'Z': case '_':
+        case 'a': case 'b': case 'c': case 'd': case 'e':
+        case 'f': case 'g': case 'h': case 'i': case 'j':
+        case 'k': case 'l': case 'm': case 'n': case 'o':
+        case 'p': case 'q': case 'r': case 's': case 't':
+        case 'u': case 'v': case 'w': case 'x': case 'y':
+        case 'z':            
+            do {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    symbol_name[len] = ch;
+                    len++;
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);					
+                } else {
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                }
+            } while ((ch >= 'a' && ch <= 'z') ||
+                     (ch >= 'A' && ch <= 'Z') ||
+                     (ch >= '0' && ch <= '9') ||
+                     ch == '_');
+            if (len >= MAX_SYMBOL_NAME_LEN)
+                len = MAX_SYMBOL_NAME_LEN - 1;
+            symbol_name[len] = '\0';
+            cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+            yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
+            return CPP_IDENTIFIER;
+            break;
+        case '0':
+            yylvalpp->symbol_name[len++] = ch;
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == 'x' || ch == 'X') {
+				yylvalpp->symbol_name[len++] = ch;
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                if ((ch >= '0' && ch <= '9') ||
+                    (ch >= 'A' && ch <= 'F') ||
+                    (ch >= 'a' && ch <= 'f'))
+                {
+                    AlreadyComplained = 0;
+                    ival = 0;
+                    do {
+						yylvalpp->symbol_name[len++] = ch;
+                        if (ival <= 0x0fffffff) {
+                            if (ch >= '0' && ch <= '9') {
+                                ii = ch - '0';
+                            } else if (ch >= 'A' && ch <= 'F') {
+                                ii = ch - 'A' + 10;
+                            } else {
+                                ii = ch - 'a' + 10;
+                            }
+                            ival = (ival << 4) | ii;
+                        } else {
+                            if (!AlreadyComplained)
+                                CPPErrorToInfoLog("ERROR___HEX_CONST_OVERFLOW");
+                            AlreadyComplained = 1;
+                        }
+                        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    } while ((ch >= '0' && ch <= '9') ||
+                             (ch >= 'A' && ch <= 'F') ||
+                             (ch >= 'a' && ch <= 'f'));
+                } else {
+                    CPPErrorToInfoLog("ERROR___ERROR_IN_HEX_CONSTANT");
+                }
+                yylvalpp->symbol_name[len] = '\0';
+				cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+				yylvalpp->sc_int = ival;
+                return CPP_INTCONSTANT;
+            } else if (ch >= '0' && ch <= '7') { // octal integer constants
+                AlreadyComplained = 0;
+                ival = 0;
+                do {
+                    yylvalpp->symbol_name[len++] = ch;
+                    if (ival <= 0x1fffffff) {
+                        ii = ch - '0';
+                        ival = (ival << 3) | ii;
+                    } else {
+                        if (!AlreadyComplained)
+                           CPPErrorToInfoLog("ERROR___OCT_CONST_OVERFLOW");
+                        AlreadyComplained = 1;
+                    }
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                } while (ch >= '0' && ch <= '7');
+                if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') 
+                     return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
+                yylvalpp->symbol_name[len] = '\0';
+				cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+				yylvalpp->sc_int = ival;
+                return CPP_INTCONSTANT;
+            } else {
+				cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+				ch = '0';
+            }
+            // Fall through...
+        case '1': case '2': case '3': case '4':
+        case '5': case '6': case '7': case '8': case '9':
+            do {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    if (len > 0 || ch != '0') {
+                        yylvalpp->symbol_name[len] = ch;
+                   len++;
+                    }
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                }
+            } while (ch >= '0' && ch <= '9');
+            if (ch == '.' || ch == 'e' || ch == 'f' || ch == 'h' || ch == 'x'|| ch == 'E') {
+                return lFloatConst(yylvalpp->symbol_name, len, ch, yylvalpp);
+            } else {
+                yylvalpp->symbol_name[len] = '\0';
+				cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                ival = 0;
+                AlreadyComplained = 0;
+                for (ii = 0; ii < len; ii++) {
+                    ch = yylvalpp->symbol_name[ii] - '0';
+                    if ((ival > 214748364) || (ival == 214748364 && ch >= 8)) {
+                        if (!AlreadyComplained)
+                           CPPErrorToInfoLog("ERROR___INTEGER_CONST_OVERFLOW");
+                        AlreadyComplained = 1;
+                    }
+                    ival = ival*10 + ch;
+                }
+                yylvalpp->sc_int = ival;
+                if(ival==0)
+                   strcpy(yylvalpp->symbol_name,"0");
+                return CPP_INTCONSTANT;
+            }
+            break;
+        case '-':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '-') {
+                return CPP_DEC_OP;
+            } else if (ch == '=') {
+                return CPP_SUB_ASSIGN;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '-';
+            }
+        case '+':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '+') {
+                return CPP_INC_OP;
+            } else if (ch == '=') {
+                return CPP_ADD_ASSIGN;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '+';
+            }
+        case '*':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '=') {
+                return CPP_MUL_ASSIGN;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '*';
+            }
+        case '%':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '=') {
+                return CPP_MOD_ASSIGN;
+            } else if (ch == '>'){
+                return CPP_RIGHT_BRACE;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '%';
+            }
+        case ':':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '>') {
+                return CPP_RIGHT_BRACKET;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return ':';
+            }
+        case '^':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '^') {
+                return CPP_XOR_OP;
+            } else {
+                if (ch == '=')
+                    return CPP_XOR_ASSIGN;
+                else{
+                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                  return '^';
+                }
+            }
+        
+        case '=':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '=') {
+                return CPP_EQ_OP;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '=';
+            }
+        case '!':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '=') {
+                return CPP_NE_OP;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '!';
+            }
+        case '|':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '|') {
+                return CPP_OR_OP;
+            } else {
+                if (ch == '=')
+                    return CPP_OR_ASSIGN;
+                else{
+                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                  return '|';
+                }
+            }
+        case '&':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '&') {
+                return CPP_AND_OP;
+            } else {
+                if (ch == '=')
+                    return CPP_AND_ASSIGN;
+                else{
+                  cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                  return '&';
+                }
+            }
+        case '<':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '<') {
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                if(ch == '=')
+                    return CPP_LEFT_ASSIGN;
+                else{
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                    return CPP_LEFT_OP;
+                }
+            } else {
+                if (ch == '=') {
+                    return CPP_LE_OP;
+                } else {
+                    if (ch == '%')
+                        return CPP_LEFT_BRACE;
+                    else if (ch == ':')
+                        return CPP_LEFT_BRACKET;
+                    else{
+                        cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                        return '<';
+                    }
+                }
+            }
+        case '>':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '>') {
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                if(ch == '=')
+                    return CPP_RIGHT_ASSIGN;
+                else{
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                    return CPP_RIGHT_OP;
+                }
+            } else {
+                if (ch == '=') {
+                    return CPP_GE_OP;
+                } else {
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                    return '>';
+                }
+            }
+        case '.':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch >= '0' && ch <= '9') {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return lFloatConst(yylvalpp->symbol_name, 0, '.', yylvalpp);
+            } else {
+                if (ch == '.') {
+                    return -1; // Special EOF hack
+                } else {
+                    cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                    return '.';
+                }
+            }
+        case '/':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            if (ch == '/') {
+                do {
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                } while (ch != '\n' && ch != EOF);
+                if (ch == EOF)
+                    return -1;
+                return '\n';
+            } else if (ch == '*') {
+                int nlcount = 0;
+                ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                do {
+                    while (ch != '*') {
+                        if (ch == '\n') nlcount++;
+                        if (ch == EOF) {
+                            CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
+                            return -1;
+                        }
+                        ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    }
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    if (ch == EOF) {
+                        CPPErrorToInfoLog("ERROR___EOF_IN_COMMENT");
+                        return -1;
+                    }
+                } while (ch != '/');
+                if (nlcount) {
+                    return '\n';
+                }
+                // Go try it again...
+            } else if (ch == '=') {
+                return CPP_DIV_ASSIGN;
+            } else {
+                cpp->currentInput->ungetch(cpp->currentInput, ch, yylvalpp);
+                return '/';
+            }
+            break;
+        case '"':
+            ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+            while (ch != '"' && ch != '\n' && ch != EOF) {
+                if (ch == '\\') {
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                    if (ch == '\n' || ch == EOF) {
+                        break;
+                    }
+                }
+                if (len < MAX_STRING_LEN) {
+                    string_val[len] = ch;
+                    len++;
+                    ch = cpp->currentInput->getch(cpp->currentInput, yylvalpp);
+                }
+            };
+            string_val[len] = '\0';
+            if (ch == '"') {
+                yylvalpp->sc_ident = LookUpAddString(atable, string_val);
+                return CPP_STRCONSTANT;
+            } else {
+                CPPErrorToInfoLog("ERROR___CPP_EOL_IN_STRING");
+                return ERROR_SY;
+            }
+        }
+    }
+} // byte_scan
+
+int yylex_CPP(char* buf, int maxSize)
+{    
+	yystypepp yylvalpp;
+    int token = '\n';   
+
+    for(;;) {
+
+        char* tokenString = 0;
+        token = cpp->currentInput->scan(cpp->currentInput, &yylvalpp);
+		if(check_EOF(token))
+		    return 0;
+        if (token == '#') {
+            if (cpp->previous_token == '\n'|| cpp->previous_token == 0) {
+			    token = readCPPline(&yylvalpp);
+                if(check_EOF(token))
+                    return 0;
+			    continue;
+            } else {
+                CPPErrorToInfoLog("preprocessor command must not be preceded by any other statement in that line");
+                return 0;
+            }
+        }
+        cpp->previous_token = token;
+        // expand macros
+        if (token == CPP_IDENTIFIER && MacroExpand(yylvalpp.sc_ident, &yylvalpp)) {
+            cpp->notAVersionToken = 1;
+            continue;
+        }
+        
+        if (token == '\n')
+            continue;
+          
+        if (token == CPP_IDENTIFIER) {                
+            cpp->notAVersionToken = 1;
+            tokenString = GetStringOfAtom(atable,yylvalpp.sc_ident);
+        } else if (token == CPP_FLOATCONSTANT||token == CPP_INTCONSTANT){             
+            cpp->notAVersionToken = 1;            
+            tokenString = yylvalpp.symbol_name;
+		} else {            
+            cpp->notAVersionToken = 1;            
+            tokenString = GetStringOfAtom(atable,token);
+	    }
+
+        if (tokenString) {
+            if ((signed)strlen(tokenString) >= maxSize) {
+                cpp->tokensBeforeEOF = 1;
+                return maxSize;               
+            } else  if (strlen(tokenString) > 0) {
+			    strcpy(buf, tokenString);
+                cpp->tokensBeforeEOF = 1;
+                return (int)strlen(tokenString);
+            }  
+
+            return 0;
+        }
+    }
+
+    return 0;
+} // yylex
+
+//Checks if the token just read is EOF or not.
+int check_EOF(int token)
+{
+   if(token==-1){
+       if(cpp->ifdepth >0){
+		CPPErrorToInfoLog("#endif missing!! Compilation stopped");
+        cpp->CompileError=1;
+       }
+      return 1;
+   }
+   return 0;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////// End of scanner.c //////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/Compiler/Preprocessor/scanner.h b/Compiler/Preprocessor/scanner.h
new file mode 100644
index 0000000..288a090
--- /dev/null
+++ b/Compiler/Preprocessor/scanner.h
@@ -0,0 +1,90 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// scanner.h
+//
+
+#if !defined(__SCANNER_H)
+#define __SCANNER_H 1
+
+#define MAX_SYMBOL_NAME_LEN 128
+#define MAX_STRING_LEN 512
+
+#include "parser.h"
+
+// Not really atom table stuff but needed first...
+
+typedef struct SourceLoc_Rec {
+    unsigned short file, line;
+} SourceLoc;
+
+int yyparse (void);
+
+int yylex_CPP(char* buf, int maxSize);
+
+typedef struct InputSrc {
+    struct InputSrc	*prev;
+    int			(*scan)(struct InputSrc *, yystypepp *);
+    int			(*getch)(struct InputSrc *, yystypepp *);
+    void		(*ungetch)(struct InputSrc *, int, yystypepp *);
+    int			name;  /* atom */
+    int			line;
+} InputSrc;
+
+int InitScanner(CPPStruct *cpp);   // Intialise the cpp scanner. 
+int ScanFromString(char *);      // Start scanning the input from the string mentioned.
+int check_EOF(int);              // check if we hit a EOF abruptly 
+void CPPErrorToInfoLog(char *);   // sticking the msg,line into the Shader's.Info.log
+void SetLineNumber(int);
+void SetStringNumber(int);
+void IncLineNumber(void);
+void DecLineNumber(void);
+int FreeScanner(void);                 // Free the cpp scanner
+#endif // !(defined(__SCANNER_H)
+
diff --git a/Compiler/Preprocessor/slglobals.h b/Compiler/Preprocessor/slglobals.h
new file mode 100644
index 0000000..852502f
--- /dev/null
+++ b/Compiler/Preprocessor/slglobals.h
@@ -0,0 +1,87 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// slglobals.h
+//
+
+#if !defined(__SLGLOBALS_H)
+#define __SLGLOBALS_H 1
+
+typedef struct CPPStruct_Rec CPPStruct;
+
+extern CPPStruct *cpp;
+
+#undef  CPPC_DEBUG_THE_COMPILER
+#if defined(_DEBUG)
+#define CPPC_DEBUG_THE_COMPILER 1
+#endif
+
+#undef  CPPC_ENABLE_TOOLS
+#define CPPC_ENABLE_TOOLS 1
+
+#include "memory.h"
+#include "atom.h"
+#include "scanner.h"
+#include "cpp.h"
+#include "tokens.h"
+#include "symbols.h"
+#include "compile.h"
+#if !defined(NO_PARSER)
+#include "parser.h"
+#endif
+
+#if !defined(NULL)
+#define NULL 0
+#endif
+
+#endif // !(defined(__SLGLOBALS_H)
+
+
+    
+
diff --git a/Compiler/Preprocessor/symbols.c b/Compiler/Preprocessor/symbols.c
new file mode 100644
index 0000000..d97bae0
--- /dev/null
+++ b/Compiler/Preprocessor/symbols.c
@@ -0,0 +1,290 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// symbols.c
+//
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "slglobals.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////// Symbol Table Variables: ///////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+Scope *ScopeList = NULL;
+Scope *CurrentScope = NULL;
+Scope *GlobalScope = NULL;
+
+static void unlinkScope(void *_scope) {
+    Scope *scope = _scope;
+
+    if (scope->next)
+        scope->next->prev = scope->prev;
+    if (scope->prev)
+        scope->prev->next = scope->next;
+    else
+        ScopeList = scope->next;
+}
+
+/*
+ * NewScope()
+ *
+ */
+Scope *NewScopeInPool(MemoryPool *pool)
+{
+    Scope *lScope;
+
+    lScope = mem_Alloc(pool, sizeof(Scope));
+    lScope->pool = pool;
+    lScope->parent = NULL;
+    lScope->funScope = NULL;
+    lScope->symbols = NULL;
+    
+    lScope->level = 0;
+
+    lScope->programs = NULL;
+    if ((lScope->next = ScopeList))
+        ScopeList->prev = lScope;
+    lScope->prev = 0;
+    ScopeList = lScope;
+    mem_AddCleanup(pool, unlinkScope, lScope);
+    return lScope;
+} // NewScope
+
+/*
+ * PushScope()
+ *
+ */
+
+void PushScope(Scope *fScope)
+{
+    Scope *lScope;
+
+    if (CurrentScope) {
+        fScope->level = CurrentScope->level + 1;
+        if (fScope->level == 1) {
+            if (!GlobalScope) {
+                /* HACK - CTD -- if GlobalScope==NULL and level==1, we're
+                 * defining a function in the superglobal scope.  Things
+                 * will break if we leave the level as 1, so we arbitrarily
+                 * set it to 2 */
+                fScope->level = 2;
+            }
+        }
+        if (fScope->level >= 2) {
+            lScope = fScope;
+            while (lScope->level > 2)
+                lScope = lScope->next;
+            fScope->funScope = lScope;
+        }
+    } else {
+        fScope->level = 0;
+    }
+    fScope->parent = CurrentScope;
+    CurrentScope = fScope;
+} // PushScope
+
+/*
+ * PopScope()
+ *
+ */
+
+Scope *PopScope(void)
+{
+    Scope *lScope;
+
+    lScope = CurrentScope;
+    if (CurrentScope)
+        CurrentScope = CurrentScope->parent;
+    return lScope;
+} // PopScope
+
+/*
+ * NewSymbol() - Allocate a new symbol node;
+ *
+ */
+
+Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind)
+{
+    Symbol *lSymb;
+    char *pch;
+    int ii;
+
+    lSymb = (Symbol *) mem_Alloc(fScope->pool, sizeof(Symbol));
+    lSymb->left = NULL;
+    lSymb->right = NULL;
+    lSymb->next = NULL;
+    lSymb->name = name;
+    lSymb->loc = *loc;
+    lSymb->kind = kind;
+    
+    // Clear union area:
+
+    pch = (char *) &lSymb->details;
+    for (ii = 0; ii < sizeof(lSymb->details); ii++)
+        *pch++ = 0;
+    return lSymb;
+} // NewSymbol
+
+/*
+ * lAddToTree() - Using a binary tree is not a good idea for basic atom values because they
+ *         are generated in order.  We'll fix this later (by reversing the bit pattern).
+ */
+
+static void lAddToTree(Symbol **fSymbols, Symbol *fSymb)
+{
+    Symbol *lSymb;
+    int lrev, frev;
+
+    lSymb = *fSymbols;
+    if (lSymb) {
+        frev = GetReversedAtom(atable, fSymb->name);
+        while (lSymb) {
+            lrev = GetReversedAtom(atable, lSymb->name);
+            if (lrev == frev) {
+                CPPErrorToInfoLog("GetAtomString(atable, fSymb->name)");
+                break;
+            } else {
+                if (lrev > frev) {
+                    if (lSymb->left) {
+                        lSymb = lSymb->left;
+                    } else {
+                        lSymb->left = fSymb;
+                        break;
+                    }
+                } else {
+                    if (lSymb->right) {
+                        lSymb = lSymb->right;
+                    } else {
+                        lSymb->right = fSymb;
+                        break;
+                    }
+                }
+            }
+        }
+    } else {
+        *fSymbols = fSymb;
+    }
+} // lAddToTree
+
+
+/*
+ * AddSymbol() - Add a variable, type, or function name to a scope.
+ *
+ */
+
+Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind)
+{
+    Symbol *lSymb;
+
+    if (!fScope)
+        fScope = CurrentScope;
+    lSymb = NewSymbol(loc, fScope, atom, kind);
+    lAddToTree(&fScope->symbols, lSymb);
+    return lSymb;
+} // AddSymbol
+
+
+/*********************************************************************************************/
+/************************************ Symbol Semantic Functions ******************************/
+/*********************************************************************************************/
+
+/*
+ * LookUpLocalSymbol()
+ *
+ */
+
+Symbol *LookUpLocalSymbol(Scope *fScope, int atom)
+{
+    Symbol *lSymb;
+    int rname, ratom;
+
+    ratom = GetReversedAtom(atable, atom);
+    if (!fScope)
+        fScope = CurrentScope;
+    lSymb = fScope->symbols;
+    while (lSymb) {
+        rname = GetReversedAtom(atable, lSymb->name);
+        if (rname == ratom) {
+            return lSymb;
+        } else {
+            if (rname > ratom) {
+                lSymb = lSymb->left;
+            } else {
+                lSymb = lSymb->right;
+            }
+        }
+    }
+    return NULL;
+} // LookUpLocalSymbol
+
+/*
+ * LookUpSymbol()
+ *
+ */
+
+Symbol *LookUpSymbol(Scope *fScope, int atom)
+{
+    Symbol *lSymb;
+
+    if (!fScope)
+        fScope = CurrentScope;
+    while (fScope) {
+        lSymb = LookUpLocalSymbol(fScope, atom);
+        if (lSymb)
+            return lSymb;
+        fScope = fScope->parent;
+    }
+    return NULL;
+} // LookUpSymbol
+
diff --git a/Compiler/Preprocessor/symbols.h b/Compiler/Preprocessor/symbols.h
new file mode 100644
index 0000000..a94adbf
--- /dev/null
+++ b/Compiler/Preprocessor/symbols.h
@@ -0,0 +1,117 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// symbols.h
+//
+
+#if !defined(__SYMBOLS_H)
+#define __SYMBOLS_H 1
+
+#include "memory.h"
+
+typedef enum symbolkind {
+   MACRO_S
+} symbolkind;
+
+// Typedefs for things defined here in "symbols.h":
+
+typedef struct Scope_Rec Scope;
+typedef struct Symbol_Rec Symbol;
+
+typedef struct SymbolList_Rec {
+    struct SymbolList_Rec *next;
+    Symbol *symb;
+} SymbolList;
+
+struct Scope_Rec {
+    Scope *next, *prev;     // doubly-linked list of all scopes
+    Scope *parent;
+    Scope *funScope;        // Points to base scope of enclosing function
+    MemoryPool *pool;       // pool used for allocation in this scope
+    Symbol *symbols;
+    
+	int level;              // 0 = super globals, 1 = globals, etc.
+
+    // Only used at global scope (level 1):
+    SymbolList *programs;   // List of programs for this compilation.
+};
+
+
+// Symbol table is a simple binary tree.
+
+#include "cpp.h"        // to get MacroSymbol def
+
+struct Symbol_Rec {
+    Symbol *left, *right;
+    Symbol *next;
+    int name;       // Name atom
+    SourceLoc loc;
+    symbolkind kind;
+    union {
+        MacroSymbol mac;
+    } details;
+};
+
+extern Scope *CurrentScope;
+extern Scope *GlobalScope;
+extern Scope *ScopeList;
+
+Scope *NewScopeInPool(MemoryPool *);
+#define NewScope()      NewScopeInPool(CurrentScope->pool)
+void PushScope(Scope *fScope);
+Scope *PopScope(void);
+Symbol *NewSymbol(SourceLoc *loc, Scope *fScope, int name, symbolkind kind);
+Symbol *AddSymbol(SourceLoc *loc, Scope *fScope, int atom, symbolkind kind);
+Symbol *LookUpLocalSymbol(Scope *fScope, int atom);
+Symbol *LookUpSymbol(Scope *fScope, int atom);
+void CPPErrorToInfoLog(char *);
+
+
+#endif // !defined(__SYMBOLS_H)
+
diff --git a/Compiler/Preprocessor/tokens.c b/Compiler/Preprocessor/tokens.c
new file mode 100644
index 0000000..b508f03
--- /dev/null
+++ b/Compiler/Preprocessor/tokens.c
@@ -0,0 +1,444 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// tokens.c
+//
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "slglobals.h"
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+//////////////////////// Preprocessor and Token Recorder and Playback: ////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
+/*
+ * idstr()
+ * Copy a string to a malloc'ed block and convert it into something suitable
+ * for an ID
+ *
+ */
+
+static char *idstr(const char *fstr, MemoryPool *pool)
+{
+    size_t len;
+    char *str, *t;
+    const char *f;
+
+    len = strlen(fstr);
+    if (!pool)
+        str = (char *) malloc(len + 1);
+    else
+        str = (char *) mem_Alloc(pool, len + 1);
+    
+    for (f=fstr, t=str; *f; f++) {
+        if (isalnum(*f)) *t++ = *f;
+        else if (*f == '.' || *f == '/') *t++ = '_';
+    }
+    *t = 0;
+    return str;
+} // idstr
+
+
+/*
+ * lNewBlock()
+ *
+ */
+
+static TokenBlock *lNewBlock(TokenStream *fTok, MemoryPool *pool)
+{
+    TokenBlock *lBlock;
+
+    if (!pool)
+        lBlock = (TokenBlock *) malloc(sizeof(TokenBlock) + 256);
+    else
+        lBlock = (TokenBlock *) mem_Alloc(pool, sizeof(TokenBlock) + 256);
+    lBlock->count = 0;
+    lBlock->current = 0;
+    lBlock->data = (unsigned char *) lBlock + sizeof(TokenBlock);
+    lBlock->max = 256;
+    lBlock->next = NULL;
+    if (fTok->head) {
+        fTok->current->next = lBlock;
+    } else {
+        fTok->head = lBlock;
+    }
+    fTok->current = lBlock;
+    return lBlock;
+} // lNewBlock
+
+/*
+ * lAddByte()
+ *
+ */
+
+static void lAddByte(TokenStream *fTok, unsigned char fVal)
+{
+    TokenBlock *lBlock;
+    lBlock = fTok->current;
+    if (lBlock->count >= lBlock->max)
+        lBlock = lNewBlock(fTok, 0);
+    lBlock->data[lBlock->count++] = fVal;
+} // lAddByte
+
+
+
+/*
+ * lReadByte() - Get the next byte from a stream.
+ *
+ */
+
+static int lReadByte(TokenStream *pTok)
+{
+    TokenBlock *lBlock;
+    int lval = -1;
+
+    lBlock = pTok->current;
+    if (lBlock) {
+        if (lBlock->current >= lBlock->count) {
+            lBlock = lBlock->next;
+            if (lBlock)
+                lBlock->current = 0;
+            pTok->current = lBlock;
+        }
+        if (lBlock)
+            lval = lBlock->data[lBlock->current++];
+    }
+    return lval;
+} // lReadByte
+
+/////////////////////////////////////// Global Functions://////////////////////////////////////
+
+/*
+ * NewTokenStream()
+ *
+ */
+
+TokenStream *NewTokenStream(const char *name, MemoryPool *pool)
+{
+    TokenStream *pTok;
+
+    if (!pool)
+        pTok = (TokenStream *) malloc(sizeof(TokenStream));
+    else
+        pTok = (TokenStream*)mem_Alloc(pool, sizeof(TokenStream));
+    pTok->next = NULL;
+    pTok->name = idstr(name, pool);
+    pTok->head = NULL;
+    pTok->current = NULL;
+    lNewBlock(pTok, pool);
+    return pTok;
+} // NewTokenStream
+
+/*
+ * DeleteTokenStream()
+ *
+ */
+
+void DeleteTokenStream(TokenStream *pTok)
+{
+    TokenBlock *pBlock, *nBlock;
+
+    if (pTok) {
+        pBlock = pTok->head;
+        while (pBlock) {
+            nBlock = pBlock->next;
+            free(pBlock);
+            pBlock = nBlock;
+        }
+        if (pTok->name)
+            free(pTok->name);
+        free(pTok);
+    }
+} // DeleteTokenStream
+
+/*
+ * RecordToken() - Add a token to the end of a list for later playback or printout.
+ *
+ */
+
+void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp)
+{
+    const char *s;
+    unsigned char *str=NULL;
+
+    if (token > 256)
+        lAddByte(pTok, (unsigned char)((token & 0x7f) + 0x80));
+    else
+        lAddByte(pTok, (unsigned char)(token & 0x7f));
+    switch (token) {
+    case CPP_IDENTIFIER:
+    case CPP_TYPEIDENTIFIER:
+    case CPP_STRCONSTANT:
+        s = GetAtomString(atable, yylvalpp->sc_ident);
+        while (*s)
+            lAddByte(pTok, (unsigned char) *s++);
+        lAddByte(pTok, 0);
+        break;
+    case CPP_FLOATCONSTANT:
+    case CPP_INTCONSTANT:
+         str=yylvalpp->symbol_name;
+         while (*str){
+            lAddByte(pTok,(unsigned char) *str);
+            *str++;
+         }
+         lAddByte(pTok, 0);
+         break;
+    case '(':
+        lAddByte(pTok, (unsigned char)(yylvalpp->sc_int ? 1 : 0));
+    default:
+        break;
+    }
+} // RecordToken
+
+/*
+ * RewindTokenStream() - Reset a token stream in preperation for reading.
+ *
+ */
+
+void RewindTokenStream(TokenStream *pTok)
+{
+    if (pTok->head) {
+        pTok->current = pTok->head;
+        pTok->current->current = 0;
+    }
+} // RewindTokenStream
+
+/*
+ * ReadToken() - Read the next token from a stream.
+ *
+ */
+
+int ReadToken(TokenStream *pTok, yystypepp * yylvalpp)
+{
+    char symbol_name[MAX_SYMBOL_NAME_LEN + 1];
+    char string_val[MAX_STRING_LEN + 1];
+    int ltoken, len;
+    char ch;
+
+    ltoken = lReadByte(pTok);
+    if (ltoken >= 0) {
+        if (ltoken > 127)
+            ltoken += 128;
+        switch (ltoken) {
+        case CPP_IDENTIFIER:
+        case CPP_TYPEIDENTIFIER:
+            len = 0;
+            ch = lReadByte(pTok);
+            while ((ch >= 'a' && ch <= 'z') ||
+                     (ch >= 'A' && ch <= 'Z') ||
+                     (ch >= '0' && ch <= '9') ||
+                     ch == '_')
+            {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    symbol_name[len] = ch;
+                    len++;
+                    ch = lReadByte(pTok);
+                }
+            }
+            symbol_name[len] = '\0';
+            assert(ch == '\0');
+            yylvalpp->sc_ident = LookUpAddString(atable, symbol_name);
+            return CPP_IDENTIFIER;
+            break;
+        case CPP_STRCONSTANT:
+            len = 0;
+            while ((ch = lReadByte(pTok)) != 0)
+                if (len < MAX_STRING_LEN)
+                    string_val[len++] = ch;
+            string_val[len] = 0;
+            yylvalpp->sc_ident = LookUpAddString(atable, string_val);
+            break;
+        case CPP_FLOATCONSTANT:
+            len = 0;
+            ch = lReadByte(pTok);
+            while ((ch >= '0' && ch <= '9')||(ch=='e'||ch=='E'||ch=='.')||(ch=='+'||ch=='-'))
+            {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    symbol_name[len] = ch;
+                    len++;
+                    ch = lReadByte(pTok);
+                }
+            }
+            symbol_name[len] = '\0';
+            assert(ch == '\0');
+            strcpy(yylvalpp->symbol_name,symbol_name);
+            yylvalpp->sc_fval=(float)atof(yylvalpp->symbol_name);
+            break;
+        case CPP_INTCONSTANT:
+            len = 0;
+            ch = lReadByte(pTok);
+            while ((ch >= '0' && ch <= '9'))
+            {
+                if (len < MAX_SYMBOL_NAME_LEN) {
+                    symbol_name[len] = ch;
+                    len++;
+                    ch = lReadByte(pTok);
+                }
+            }
+            symbol_name[len] = '\0';
+            assert(ch == '\0');
+            strcpy(yylvalpp->symbol_name,symbol_name);
+            yylvalpp->sc_int=atoi(yylvalpp->symbol_name);
+            break;
+        case '(':
+            yylvalpp->sc_int = lReadByte(pTok);
+            break;
+        }
+        return ltoken;
+    }
+    return EOF_SY;
+} // ReadToken
+
+typedef struct TokenInputSrc {
+    InputSrc            base;
+    TokenStream         *tokens;
+    int                 (*final)(CPPStruct *);
+} TokenInputSrc;
+
+static int scan_token(TokenInputSrc *in, yystypepp * yylvalpp)
+{
+    int token = ReadToken(in->tokens, yylvalpp);
+    int (*final)(CPPStruct *);
+    cpp->tokenLoc->file = cpp->currentInput->name;
+    cpp->tokenLoc->line = cpp->currentInput->line;
+    if (token == '\n') {
+        in->base.line++;
+        return token;
+    }
+    if (token > 0) return token;
+    cpp->currentInput = in->base.prev;
+    final = in->final;
+    free(in);
+    if (final && !final(cpp)) return -1;
+    return cpp->currentInput->scan(cpp->currentInput, yylvalpp);
+}
+
+int ReadFromTokenStream(TokenStream *ts, int name, int (*final)(CPPStruct *))
+{
+    TokenInputSrc *in = malloc(sizeof(TokenInputSrc));
+    memset(in, 0, sizeof(TokenInputSrc));
+    in->base.name = name;
+    in->base.prev = cpp->currentInput;
+    in->base.scan = (int (*)(InputSrc *, yystypepp *))scan_token;
+    in->base.line = 1;
+    in->tokens = ts;
+    in->final = final;
+    RewindTokenStream(ts);
+    cpp->currentInput = &in->base;
+    return 1;
+}
+
+typedef struct UngotToken {
+    InputSrc    base;
+    int         token;
+    yystypepp     lval;
+} UngotToken;
+
+static int reget_token(UngotToken *t, yystypepp * yylvalpp)
+{
+    int token = t->token;
+    *yylvalpp = t->lval;
+    cpp->currentInput = t->base.prev;
+    free(t);
+    return token;
+}
+
+void UngetToken(int token, yystypepp * yylvalpp) {
+    UngotToken *t = malloc(sizeof(UngotToken));
+    memset(t, 0, sizeof(UngotToken));
+    t->token = token;
+    t->lval = *yylvalpp;
+    t->base.scan = (void *)reget_token;
+    t->base.prev = cpp->currentInput;
+    t->base.name = cpp->currentInput->name;
+    t->base.line = cpp->currentInput->line;
+    cpp->currentInput = &t->base;
+}
+
+
+void DumpTokenStream(FILE *fp, TokenStream *s, yystypepp * yylvalpp) {
+    int token;
+    char str[100];
+
+    if (fp == 0) fp = stdout;
+    RewindTokenStream(s);
+    while ((token = ReadToken(s, yylvalpp)) > 0) {
+        switch (token) {
+        case CPP_IDENTIFIER:
+        case CPP_TYPEIDENTIFIER:
+            sprintf(str, "%s ", GetAtomString(atable, yylvalpp->sc_ident));
+            break;
+        case CPP_STRCONSTANT:
+            sprintf(str, "\"%s\"", GetAtomString(atable, yylvalpp->sc_ident));
+            break;
+        case CPP_FLOATCONSTANT:
+            //printf("%g9.6 ", yylvalpp->sc_fval);
+            break;
+        case CPP_INTCONSTANT:
+            //printf("%d ", yylvalpp->sc_int);
+            break;
+        default:
+            if (token >= 127)
+                sprintf(str, "%s ", GetAtomString(atable, token));
+            else
+                sprintf(str, "%c", token);
+            break;
+        }
+        CPPDebugLogMsg(str);
+    }
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////// End of tokens.c ///////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Compiler/Preprocessor/tokens.h b/Compiler/Preprocessor/tokens.h
new file mode 100644
index 0000000..19938d7
--- /dev/null
+++ b/Compiler/Preprocessor/tokens.h
@@ -0,0 +1,94 @@
+//
+// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+/****************************************************************************\
+Copyright (c) 2002, NVIDIA Corporation.
+
+NVIDIA Corporation("NVIDIA") supplies this software to you in
+consideration of your agreement to the following terms, and your use,
+installation, modification or redistribution of this NVIDIA software
+constitutes acceptance of these terms.  If you do not agree with these
+terms, please do not use, install, modify or redistribute this NVIDIA
+software.
+
+In consideration of your agreement to abide by the following terms, and
+subject to these terms, NVIDIA grants you a personal, non-exclusive
+license, under NVIDIA's copyrights in this original NVIDIA software (the
+"NVIDIA Software"), to use, reproduce, modify and redistribute the
+NVIDIA Software, with or without modifications, in source and/or binary
+forms; provided that if you redistribute the NVIDIA Software, you must
+retain the copyright notice of NVIDIA, this notice and the following
+text and disclaimers in all such redistributions of the NVIDIA Software.
+Neither the name, trademarks, service marks nor logos of NVIDIA
+Corporation may be used to endorse or promote products derived from the
+NVIDIA Software without specific prior written permission from NVIDIA.
+Except as expressly stated in this notice, no other rights or licenses
+express or implied, are granted by NVIDIA herein, including but not
+limited to any patent rights that may be infringed by your derivative
+works or by other works in which the NVIDIA Software may be
+incorporated. No hardware is licensed hereunder. 
+
+THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT
+WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED,
+INCLUDING WITHOUT LIMITATION, WARRANTIES OR CONDITIONS OF TITLE,
+NON-INFRINGEMENT, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
+ITS USE AND OPERATION EITHER ALONE OR IN COMBINATION WITH OTHER
+PRODUCTS.
+
+IN NO EVENT SHALL NVIDIA BE LIABLE FOR ANY SPECIAL, INDIRECT,
+INCIDENTAL, EXEMPLARY, CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, LOST PROFITS; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) OR ARISING IN ANY WAY
+OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE
+NVIDIA SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT,
+TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF
+NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+\****************************************************************************/
+//
+// tokens.h
+//
+
+#if !defined(__TOKENS_H)
+#define __TOKENS_H 1
+
+#include "parser.h"
+
+#define EOF_SY (-1)
+
+typedef struct TokenBlock_Rec TokenBlock;
+
+typedef struct TokenStream_Rec {
+    struct TokenStream_Rec *next;
+    char *name;
+    TokenBlock *head;
+    TokenBlock *current;
+} TokenStream;
+
+struct TokenBlock_Rec {
+    TokenBlock *next;
+    int current;
+    int count;
+    int max;
+    unsigned char *data;
+};
+
+extern TokenStream stdlib_cpp_stream;
+
+
+TokenStream *NewTokenStream(const char *name, MemoryPool *pool);
+void DeleteTokenStream(TokenStream *pTok); 
+void RecordToken(TokenStream *pTok, int token, yystypepp * yylvalpp);
+void RewindTokenStream(TokenStream *pTok);
+int ReadToken(TokenStream *pTok, yystypepp * yylvalpp);
+int ReadFromTokenStream(TokenStream *pTok, int name, int (*final)(CPPStruct *));
+void UngetToken(int, yystypepp * yylvalpp);
+
+#if defined(CPPC_ENABLE_TOOLS)
+
+void DumpTokenStream(FILE *, TokenStream *, yystypepp * yylvalpp);
+
+#endif // defined(CPPC_ENABLE_TOOLS)
+
+#endif // !defined(__TOKENS_H)