Preparation for macro expansion.
Review URL: http://codereview.appspot.com/4919045

git-svn-id: https://angleproject.googlecode.com/svn/trunk@741 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/preprocessor/new/Context.cpp b/src/compiler/preprocessor/new/Context.cpp
index 70a1b7d..4cb8476 100644
--- a/src/compiler/preprocessor/new/Context.cpp
+++ b/src/compiler/preprocessor/new/Context.cpp
@@ -6,16 +6,108 @@
 
 #include "Context.h"
 
+#include <algorithm>
+#include <sstream>
+
+#include "compiler/debug.h"
+#include "stl_utils.h"
+#include "token_type.h"
+
 namespace pp
 {
 
-Context::Context(int count, const char* const string[], const int length[],
-                 TokenVector* output)
-    : input(count, string, length),
-      output(output),
-      lexer(NULL)
+Context::Context()
+    : mLexer(NULL),
+      mInput(NULL),
+      mOutput(NULL)
 {
 }
 
+Context::~Context()
+{
+    destroyLexer();
+}
+
+bool Context::init()
+{
+    return initLexer();
+
+    // TODO(alokp): Define built-in macros here so that we do not need to
+    // define them everytime in process().
+}
+
+bool Context::process(int count,
+                      const char* const string[],
+                      const int length[],
+                      TokenVector* output)
+{
+    ASSERT((count >=0) && (string != NULL) && (output != NULL));
+
+    // Setup.
+    mInput = new Input(count, string, length);
+    mOutput = output;
+    defineBuiltInMacro("GL_ES", 1);
+
+    // Parse.
+    bool success = parse();
+
+    // Cleanup.
+    reset();
+    return success;
+}
+
+bool Context::defineMacro(pp::Token::Location location,
+                          pp::Macro::Type type,
+                          std::string* identifier,
+                          pp::Macro::ParameterVector* parameters,
+                          pp::TokenVector* replacements)
+{
+    // TODO(alokp): Check for reserved macro names and duplicate macros.
+    mMacros[*identifier] = new Macro(type, identifier, parameters, replacements);
+    return true;
+}
+
+bool Context::undefineMacro(const std::string* identifier)
+{
+    MacroSet::iterator iter = mMacros.find(*identifier);
+    if (iter == mMacros.end())
+    {
+        // TODO(alokp): Report error.
+        return false;
+    }
+    mMacros.erase(iter);
+    return true;
+}
+
+bool Context::isMacroDefined(const std::string* identifier)
+{
+    return mMacros.find(*identifier) != mMacros.end();
+}
+
+// Reset to initialized state.
+void Context::reset()
+{
+    std::for_each(mMacros.begin(), mMacros.end(), DeleteSecond());
+    mMacros.clear();
+
+    delete mInput;
+    mInput = NULL;
+
+    mOutput = NULL;
+}
+
+void Context::defineBuiltInMacro(const std::string& identifier, int value)
+{
+    std::ostringstream stream;
+    stream << value;
+    Token* token = new Token(0, INT_CONSTANT, new std::string(stream.str()));
+    TokenVector* replacements = new pp::TokenVector(1, token);
+
+    mMacros[identifier] = new Macro(Macro::kTypeObj,
+                                    new std::string(identifier),
+                                    NULL,
+                                    replacements);
+}
+
 }  // namespace pp
 
diff --git a/src/compiler/preprocessor/new/Context.h b/src/compiler/preprocessor/new/Context.h
index d54ee10..799e3f9 100644
--- a/src/compiler/preprocessor/new/Context.h
+++ b/src/compiler/preprocessor/new/Context.h
@@ -7,6 +7,9 @@
 #ifndef COMPILER_PREPROCESSOR_CONTEXT_H_
 #define COMPILER_PREPROCESSOR_CONTEXT_H_
 
+#include <map>
+
+#include "common/angleutils.h"
 #include "Input.h"
 #include "Macro.h"
 #include "Token.h"
@@ -14,16 +17,42 @@
 namespace pp
 {
 
-struct Context
+class Context
 {
-    Context(int count, const char* const string[], const int length[],
-            TokenVector* output);
+  public:
+    Context();
+    ~Context();
 
-    Input input;
-    TokenVector* output;
+    bool init();
+    bool process(int count, const char* const string[], const int length[],
+                 TokenVector* output);
 
-    void* lexer;  // Lexer handle.
-    MacroSet macros;  // Defined macros.
+    void* lexer() { return mLexer; }
+    int readInput(char* buf, int maxSize);
+    TokenVector* output() { return mOutput; }
+
+    bool defineMacro(pp::Token::Location location,
+                     pp::Macro::Type type,
+                     std::string* identifier,
+                     pp::Macro::ParameterVector* parameters,
+                     pp::TokenVector* replacements);
+    bool undefineMacro(const std::string* identifier);
+    bool isMacroDefined(const std::string* identifier);
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Context);
+    typedef std::map<std::string, Macro*> MacroSet;
+
+    void reset();
+    bool initLexer();
+    void destroyLexer();
+    void defineBuiltInMacro(const std::string& identifier, int value);
+    bool parse();
+
+    void* mLexer;  // Lexer handle.
+    Input* mInput;
+    TokenVector* mOutput;
+    MacroSet mMacros;  // Defined macros.
 };
 
 }  // namespace pp
diff --git a/src/compiler/preprocessor/new/Macro.cpp b/src/compiler/preprocessor/new/Macro.cpp
new file mode 100644
index 0000000..b8ff745
--- /dev/null
+++ b/src/compiler/preprocessor/new/Macro.cpp
@@ -0,0 +1,45 @@
+//
+// Copyright (c) 2011 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.
+//
+
+#include "Macro.h"
+
+#include <algorithm>
+
+#include "stl_utils.h"
+
+namespace pp
+{
+
+Macro::Macro(Type type,
+             std::string* identifier,
+             ParameterVector* parameters,
+             TokenVector* replacements)
+    : mType(type),
+      mIdentifier(identifier),
+      mParameters(parameters),
+      mReplacements(replacements)
+{
+}
+
+Macro::~Macro()
+{
+    delete mIdentifier;
+
+    if (mParameters)
+    {
+        std::for_each(mParameters->begin(), mParameters->end(), Delete());
+        delete mParameters;
+    }
+
+    if (mReplacements)
+    {
+        std::for_each(mReplacements->begin(), mReplacements->end(), Delete());
+        delete mReplacements;
+    }
+}
+
+}  // namespace pp
+
diff --git a/src/compiler/preprocessor/new/Macro.h b/src/compiler/preprocessor/new/Macro.h
index bb5e64a..71dad06 100644
--- a/src/compiler/preprocessor/new/Macro.h
+++ b/src/compiler/preprocessor/new/Macro.h
@@ -7,27 +7,45 @@
 #ifndef COMPILER_PREPROCESSOR_MACRO_H_
 #define COMPILER_PREPROCESSOR_MACRO_H_
 
-#include <map>
 #include <string>
+#include <vector>
 
+#include "common/angleutils.h"
 #include "Token.h"
 
 namespace pp
 {
 
-struct Macro
+class Macro
 {
+  public:
     enum Type
     {
         kTypeObj,
         kTypeFunc
     };
-    Type type;
-    std::string identifier;
-    TokenVector parameters;
-    TokenVector replacements;
+    typedef std::vector<std::string*> ParameterVector;
+
+    // Takes ownership of pointer parameters.
+    Macro(Type type,
+          std::string* identifier,
+          ParameterVector* parameters,
+          TokenVector* replacements);
+    ~Macro();
+
+    Type type() const { return mType; }
+    const std::string* identifier() const { return mIdentifier; }
+    const ParameterVector* parameters() const { return mParameters; }
+    const TokenVector* replacements() const { return mReplacements; }
+
+  private:
+    DISALLOW_COPY_AND_ASSIGN(Macro);
+
+    Type mType;
+    std::string* mIdentifier;
+    ParameterVector* mParameters;
+    TokenVector* mReplacements;
 };
-typedef std::map<std::string, Macro> MacroSet;
 
 }  // namespace pp
 #endif COMPILER_PREPROCESSOR_MACRO_H_
diff --git a/src/compiler/preprocessor/new/Preprocessor.cpp b/src/compiler/preprocessor/new/Preprocessor.cpp
index 3dc246c..ef49e57 100644
--- a/src/compiler/preprocessor/new/Preprocessor.cpp
+++ b/src/compiler/preprocessor/new/Preprocessor.cpp
@@ -6,12 +6,30 @@
 
 #include "Preprocessor.h"
 
+#include <algorithm>
+
 #include "compiler/debug.h"
 #include "Context.h"
+#include "stl_utils.h"
 
 namespace pp
 {
 
+Preprocessor::Preprocessor() : mContext(NULL)
+{
+}
+
+Preprocessor::~Preprocessor()
+{
+    delete mContext;
+}
+
+bool Preprocessor::init()
+{
+    mContext = new Context;
+    return mContext->init();
+}
+
 bool Preprocessor::process(int count,
                            const char* const string[],
                            const int length[])
@@ -20,22 +38,14 @@
     if ((count < 0) || (string == NULL))
         return false;
 
-    clearResults();
-    Context context(count, string, length, &mTokens);
-    if (!initLexer(&context))
-        return false;
+    reset();
 
-    bool success = parse(&context);
-
-    destroyLexer(&context);
-    return success;
+    return mContext->process(count, string, length, &mTokens);
 }
 
-void Preprocessor::clearResults()
+void Preprocessor::reset()
 {
-    for (TokenVector::iterator i = mTokens.begin(); i != mTokens.end(); ++i)
-        delete (*i);
-
+    std::for_each(mTokens.begin(), mTokens.end(), Delete());
     mTokens.clear();
 }
 
diff --git a/src/compiler/preprocessor/new/Preprocessor.h b/src/compiler/preprocessor/new/Preprocessor.h
index f8e4c8e..885bb70 100644
--- a/src/compiler/preprocessor/new/Preprocessor.h
+++ b/src/compiler/preprocessor/new/Preprocessor.h
@@ -13,27 +13,27 @@
 namespace pp
 {
 
-struct Context;
+class Context;
 
 class Preprocessor
 {
   public:
-    Preprocessor() { }
+    Preprocessor();
+    ~Preprocessor();
+
+    bool init();
 
     bool process(int count, const char* const string[], const int length[]);
-
     TokenIterator begin() const { return mTokens.begin(); }
     TokenIterator end() const { return mTokens.end(); }
 
   private:
     DISALLOW_COPY_AND_ASSIGN(Preprocessor);
 
-    static bool initLexer(Context* context);
-    static void destroyLexer(Context* context);
-    static bool parse(Context* context);
+    // Reset to initialized state.
+    void reset();
 
-    void clearResults();
-
+    Context* mContext;
     TokenVector mTokens;  // Output.
 };
 
diff --git a/src/compiler/preprocessor/new/Token.h b/src/compiler/preprocessor/new/Token.h
index 9047352..4f5a12b 100644
--- a/src/compiler/preprocessor/new/Token.h
+++ b/src/compiler/preprocessor/new/Token.h
@@ -10,6 +10,8 @@
 #include <string>
 #include <vector>
 
+#include "common/angleutils.h"
+
 namespace pp
 {
 
@@ -29,6 +31,8 @@
     const std::string* value() const { return mValue; }
 
   private:
+    DISALLOW_COPY_AND_ASSIGN(Token);
+
     Location mLocation;
     int mType;
     std::string* mValue;
diff --git a/src/compiler/preprocessor/new/pp.l b/src/compiler/preprocessor/new/pp.l
index 514a79c..3669ef8 100644
--- a/src/compiler/preprocessor/new/pp.l
+++ b/src/compiler/preprocessor/new/pp.l
@@ -26,7 +26,6 @@
 #include "compiler/debug.h"
 #include "Context.h"
 #include "pp_tab.h"
-#include "Preprocessor.h"
 
 #define YY_USER_ACTION                        \
     do {                                      \
@@ -36,9 +35,7 @@
     } while(0);
 
 #define YY_INPUT(buf, result, maxSize) \
-    result = readInput(yyextra, buf, maxSize);
-
-static int readInput(pp::Context* context, char* buf, int maxSize);
+    result = yyextra->readInput(buf, maxSize);
 %}
 
 %option noyywrap nounput never-interactive
@@ -110,24 +107,23 @@
 
 %%
 
-int readInput(pp::Context* context, char* buf, int maxSize)
-{
-    yyscan_t lexer = context->lexer;
-    ASSERT(lexer);
+namespace pp {
 
+int Context::readInput(char* buf, int maxSize)
+{
     int nread = YY_NULL;
-    while (!context->input.eof() &&
-           (context->input.error() == pp::Input::kErrorNone) &&
+    while (!mInput->eof() &&
+           (mInput->error() == pp::Input::kErrorNone) &&
            (nread == YY_NULL))
     {
         int line = 0, file = 0;
-        pp::Token::decodeLocation(yyget_lineno(lexer), &line, &file);
-        file = context->input.stringIndex();
-        yyset_lineno(pp::Token::encodeLocation(line, file), lexer);
+        pp::Token::decodeLocation(yyget_lineno(mLexer), &line, &file);
+        file = mInput->stringIndex();
+        yyset_lineno(pp::Token::encodeLocation(line, file), mLexer);
 
-        nread = context->input.read(buf, maxSize);
+        nread = mInput->read(buf, maxSize);
 
-        if (context->input.error() == pp::Input::kErrorUnexpectedEOF)
+        if (mInput->error() == pp::Input::kErrorUnexpectedEOF)
         {
             // TODO(alokp): Report error.
         }
@@ -135,27 +131,23 @@
     return nread;
 }
 
-namespace pp {
-
-bool Preprocessor::initLexer(Context* context)
+bool Context::initLexer()
 {
-    ASSERT(context->lexer == NULL);
+    ASSERT(mLexer == NULL);
 
-    yyscan_t lexer = 0;
-    if (yylex_init_extra(context, &lexer))
+    if (yylex_init_extra(this, &mLexer))
         return false;
 
-    context->lexer = lexer;
-    yyrestart(0, lexer);
+    yyrestart(0, mLexer);
     return true;
 }
 
-void Preprocessor::destroyLexer(Context* context)
+void Context::destroyLexer()
 {
-    ASSERT(context->lexer);
+    ASSERT(mLexer);
 
-    yylex_destroy(context->lexer);
-    context->lexer = 0;
+    yylex_destroy(mLexer);
+    mLexer = NULL;
 }
 
 }  // namespace pp
diff --git a/src/compiler/preprocessor/new/pp.y b/src/compiler/preprocessor/new/pp.y
index df92b84..9a69739 100644
--- a/src/compiler/preprocessor/new/pp.y
+++ b/src/compiler/preprocessor/new/pp.y
@@ -23,9 +23,8 @@
 // This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
 
 #include "Context.h"
-#include "Preprocessor.h"
 
-#define YYLEX_PARAM context->lexer
+#define YYLEX_PARAM context->lexer()
 #define YYDEBUG 1
 %}
 
@@ -48,14 +47,6 @@
                     pp::Context* context,
                     const char* reason);
 
-static void defineMacro(pp::Context* context,
-                        YYLTYPE* llocp,
-                        pp::Macro::Type type,
-                        const std::string* identifier,
-                        std::vector<std::string*>* parameters,
-                        pp::TokenVector* replacements);
-static void undefineMacro(pp::Context* context, const std::string* identifier);
-static bool isMacroDefined(pp::Context* context, const std::string* identifier);
 static void pushConditionalBlock(pp::Context* context, bool condition);
 static void popConditionalBlock(pp::Context* context);
 %}
@@ -79,7 +70,7 @@
 line
     : text_line {
         // TODO(alokp): Expand macros.
-        pp::TokenVector* out = context->output;
+        pp::TokenVector* out = context->output();
         out->insert(out->end(), $1->begin(), $1->end());
         delete $1;
     }
@@ -94,22 +85,22 @@
 control_line
     : HASH '\n'
     | HASH_DEFINE_OBJ IDENTIFIER replacement_token_list '\n' {
-        defineMacro(context, & @2, pp::Macro::kTypeObj, $2, NULL, $3);
+        context->defineMacro(@2.first_line, pp::Macro::kTypeObj, $2, NULL, $3);
     }
     | HASH_DEFINE_FUNC IDENTIFIER '(' parameter_list ')' replacement_token_list '\n' {
-        defineMacro(context, & @2, pp::Macro::kTypeFunc, $2, $4, $6);
+        context->defineMacro(@2.first_line, pp::Macro::kTypeFunc, $2, $4, $6);
     }
     | HASH_UNDEF IDENTIFIER '\n' {
-        undefineMacro(context, $2);
+        context->undefineMacro($2);
     }
     | HASH_IF conditional_token_list '\n' {
         pushConditionalBlock(context, $2 ? true : false);
     }
     | HASH_IFDEF IDENTIFIER '\n' {
-        pushConditionalBlock(context, isMacroDefined(context, $2));
+        pushConditionalBlock(context, context->isMacroDefined($2));
     }
     | HASH_IFNDEF IDENTIFIER '\n' {
-        pushConditionalBlock(context, !isMacroDefined(context, $2));
+        pushConditionalBlock(context, !context->isMacroDefined($2));
     }
     | HASH_ELIF conditional_token_list '\n' {
     }
@@ -223,24 +214,6 @@
 {
 }
 
-void defineMacro(pp::Context* context,
-                 YYLTYPE* llocp,
-                 pp::Macro::Type type,
-                 const std::string* identifier,
-                 std::vector<std::string*>* parameters,
-                 pp::TokenVector* replacements)
-{
-}
-
-void undefineMacro(pp::Context* context, const std::string* identifier)
-{
-}
-
-bool isMacroDefined(pp::Context* context, const std::string* identifier)
-{
-    return false;
-}
-
 void pushConditionalBlock(pp::Context* context, bool condition)
 {
 }
@@ -250,10 +223,10 @@
 }
 
 namespace pp {
-bool Preprocessor::parse(Context* context)
+bool Context::parse()
 {
     yydebug = 1;
-    return yyparse(context) == 0 ? true : false;
+    return yyparse(this) == 0 ? true : false;
 }
 }  // namespace pp
 
diff --git a/src/compiler/preprocessor/new/pp_lex.cpp b/src/compiler/preprocessor/new/pp_lex.cpp
index b62dfe0..d410e3e 100644
--- a/src/compiler/preprocessor/new/pp_lex.cpp
+++ b/src/compiler/preprocessor/new/pp_lex.cpp
@@ -571,7 +571,6 @@
 #include "compiler/debug.h"
 #include "Context.h"
 #include "pp_tab.h"
-#include "Preprocessor.h"
 
 #define YY_USER_ACTION                        \
     do {                                      \
@@ -581,9 +580,7 @@
     } while(0);
 
 #define YY_INPUT(buf, result, maxSize) \
-    result = readInput(yyextra, buf, maxSize);
-
-static int readInput(pp::Context* context, char* buf, int maxSize);
+    result = yyextra->readInput(buf, maxSize);
 
 #define INITIAL 0
 
@@ -2224,24 +2221,23 @@
 
 #define YYTABLES_NAME "yytables"
 
-int readInput(pp::Context* context, char* buf, int maxSize)
-{
-    yyscan_t lexer = context->lexer;
-    ASSERT(lexer);
+namespace pp {
 
+int Context::readInput(char* buf, int maxSize)
+{
     int nread = YY_NULL;
-    while (!context->input.eof() &&
-           (context->input.error() == pp::Input::kErrorNone) &&
+    while (!mInput->eof() &&
+           (mInput->error() == pp::Input::kErrorNone) &&
            (nread == YY_NULL))
     {
         int line = 0, file = 0;
-        pp::Token::decodeLocation(ppget_lineno(lexer), &line, &file);
-        file = context->input.stringIndex();
-        ppset_lineno(pp::Token::encodeLocation(line, file),lexer);
+        pp::Token::decodeLocation(ppget_lineno(mLexer), &line, &file);
+        file = mInput->stringIndex();
+        ppset_lineno(pp::Token::encodeLocation(line, file),mLexer);
 
-        nread = context->input.read(buf, maxSize);
+        nread = mInput->read(buf, maxSize);
 
-        if (context->input.error() == pp::Input::kErrorUnexpectedEOF)
+        if (mInput->error() == pp::Input::kErrorUnexpectedEOF)
         {
             // TODO(alokp): Report error.
         }
@@ -2249,27 +2245,23 @@
     return nread;
 }
 
-namespace pp {
-
-bool Preprocessor::initLexer(Context* context)
+bool Context::initLexer()
 {
-    ASSERT(context->lexer == NULL);
+    ASSERT(mLexer == NULL);
 
-    yyscan_t lexer = 0;
-    if (pplex_init_extra(context,&lexer))
+    if (pplex_init_extra(this,&mLexer))
         return false;
 
-    context->lexer = lexer;
-    pprestart(0,lexer);
+    pprestart(0,mLexer);
     return true;
 }
 
-void Preprocessor::destroyLexer(Context* context)
+void Context::destroyLexer()
 {
-    ASSERT(context->lexer);
+    ASSERT(mLexer);
 
-    pplex_destroy(context->lexer);
-    context->lexer = 0;
+    pplex_destroy(mLexer);
+    mLexer = NULL;
 }
 
 }  // namespace pp
diff --git a/src/compiler/preprocessor/new/pp_tab.cpp b/src/compiler/preprocessor/new/pp_tab.cpp
index 4ef4658..86c882d 100644
--- a/src/compiler/preprocessor/new/pp_tab.cpp
+++ b/src/compiler/preprocessor/new/pp_tab.cpp
@@ -133,9 +133,8 @@
 // This file is auto-generated by generate_glslang_parser.sh. DO NOT EDIT!
 
 #include "Context.h"
-#include "Preprocessor.h"
 
-#define YYLEX_PARAM context->lexer
+#define YYLEX_PARAM context->lexer()
 #define YYDEBUG 1
 
 
@@ -197,14 +196,6 @@
                     pp::Context* context,
                     const char* reason);
 
-static void defineMacro(pp::Context* context,
-                        YYLTYPE* llocp,
-                        pp::Macro::Type type,
-                        const std::string* identifier,
-                        std::vector<std::string*>* parameters,
-                        pp::TokenVector* replacements);
-static void undefineMacro(pp::Context* context, const std::string* identifier);
-static bool isMacroDefined(pp::Context* context, const std::string* identifier);
 static void pushConditionalBlock(pp::Context* context, bool condition);
 static void popConditionalBlock(pp::Context* context);
 
@@ -517,13 +508,13 @@
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
-       0,    74,    74,    76,    80,    86,    90,    91,    95,    96,
-      99,   102,   105,   108,   111,   114,   116,   118,   121,   122,
-     123,   124,   125,   129,   130,   134,   138,   145,   147,   149,
-     153,   154,   158,   165,   169,   176,   179,   182,   185,   188,
-     194,   195,   196,   197,   198,   199,   200,   201,   202,   203,
-     204,   205,   206,   207,   208,   209,   210,   211,   212,   213,
-     214,   215,   216,   217
+       0,    65,    65,    67,    71,    77,    81,    82,    86,    87,
+      90,    93,    96,    99,   102,   105,   107,   109,   112,   113,
+     114,   115,   116,   120,   121,   125,   129,   136,   138,   140,
+     144,   145,   149,   156,   160,   167,   170,   173,   176,   179,
+     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,
+     195,   196,   197,   198,   199,   200,   201,   202,   203,   204,
+     205,   206,   207,   208
 };
 #endif
 
@@ -1552,7 +1543,7 @@
 
     {
         // TODO(alokp): Expand macros.
-        pp::TokenVector* out = context->output;
+        pp::TokenVector* out = context->output();
         out->insert(out->end(), (yyvsp[(1) - (1)].tlist)->begin(), (yyvsp[(1) - (1)].tlist)->end());
         delete (yyvsp[(1) - (1)].tlist);
     ;}
@@ -1571,21 +1562,21 @@
   case 9:
 
     {
-        defineMacro(context, & (yylsp[(2) - (4)]), pp::Macro::kTypeObj, (yyvsp[(2) - (4)].sval), NULL, (yyvsp[(3) - (4)].tlist));
+        context->defineMacro((yylsp[(2) - (4)]).first_line, pp::Macro::kTypeObj, (yyvsp[(2) - (4)].sval), NULL, (yyvsp[(3) - (4)].tlist));
     ;}
     break;
 
   case 10:
 
     {
-        defineMacro(context, & (yylsp[(2) - (7)]), pp::Macro::kTypeFunc, (yyvsp[(2) - (7)].sval), (yyvsp[(4) - (7)].slist), (yyvsp[(6) - (7)].tlist));
+        context->defineMacro((yylsp[(2) - (7)]).first_line, pp::Macro::kTypeFunc, (yyvsp[(2) - (7)].sval), (yyvsp[(4) - (7)].slist), (yyvsp[(6) - (7)].tlist));
     ;}
     break;
 
   case 11:
 
     {
-        undefineMacro(context, (yyvsp[(2) - (3)].sval));
+        context->undefineMacro((yyvsp[(2) - (3)].sval));
     ;}
     break;
 
@@ -1599,14 +1590,14 @@
   case 13:
 
     {
-        pushConditionalBlock(context, isMacroDefined(context, (yyvsp[(2) - (3)].sval)));
+        pushConditionalBlock(context, context->isMacroDefined((yyvsp[(2) - (3)].sval)));
     ;}
     break;
 
   case 14:
 
     {
-        pushConditionalBlock(context, !isMacroDefined(context, (yyvsp[(2) - (3)].sval)));
+        pushConditionalBlock(context, !context->isMacroDefined((yyvsp[(2) - (3)].sval)));
     ;}
     break;
 
@@ -2083,24 +2074,6 @@
 {
 }
 
-void defineMacro(pp::Context* context,
-                 YYLTYPE* llocp,
-                 pp::Macro::Type type,
-                 const std::string* identifier,
-                 std::vector<std::string*>* parameters,
-                 pp::TokenVector* replacements)
-{
-}
-
-void undefineMacro(pp::Context* context, const std::string* identifier)
-{
-}
-
-bool isMacroDefined(pp::Context* context, const std::string* identifier)
-{
-    return false;
-}
-
 void pushConditionalBlock(pp::Context* context, bool condition)
 {
 }
@@ -2110,10 +2083,10 @@
 }
 
 namespace pp {
-bool Preprocessor::parse(Context* context)
+bool Context::parse()
 {
     yydebug = 1;
-    return yyparse(context) == 0 ? true : false;
+    return yyparse(this) == 0 ? true : false;
 }
 }  // namespace pp
 
diff --git a/src/compiler/preprocessor/new/stl_utils.h b/src/compiler/preprocessor/new/stl_utils.h
new file mode 100644
index 0000000..0d1ce50
--- /dev/null
+++ b/src/compiler/preprocessor/new/stl_utils.h
@@ -0,0 +1,29 @@
+//
+// Copyright (c) 2011 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.
+//
+
+// stl_utils.h: Common STL utilities.
+
+#ifndef COMMON_STLUTILS_H_
+#define COMMON_STLUTILS_H_
+
+namespace pp
+{
+
+struct Delete
+{
+    template<class T>
+    void operator() (T x) { delete x; }
+};
+
+struct DeleteSecond
+{
+    template<class A, class B>
+    void operator() (std::pair<A, B>& x) { delete x.second; }
+};
+
+} // namespace pp
+#endif // COMMON_STLUTILS_H_
+