Hash :
b401a92b
Author :
Date :
2012-10-26T18:58:24
Move the new preprocessor out of the 'new' directory. TRAC #21966 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@1326 736b8ea6-26fd-11df-bfd4-992fa37f6226
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
//
// 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 "Preprocessor.h"
#include <cassert>
#include <sstream>
#include "Diagnostics.h"
#include "DirectiveParser.h"
#include "Macro.h"
#include "MacroExpander.h"
#include "Token.h"
#include "Tokenizer.h"
namespace pp
{
struct PreprocessorImpl
{
Diagnostics* diagnostics;
MacroSet macroSet;
Tokenizer tokenizer;
DirectiveParser directiveParser;
MacroExpander macroExpander;
PreprocessorImpl(Diagnostics* diag,
DirectiveHandler* directiveHandler) :
diagnostics(diag),
tokenizer(diag),
directiveParser(&tokenizer, ¯oSet, diag, directiveHandler),
macroExpander(&directiveParser, ¯oSet, diag)
{
}
};
Preprocessor::Preprocessor(Diagnostics* diagnostics,
DirectiveHandler* directiveHandler)
{
mImpl = new PreprocessorImpl(diagnostics, directiveHandler);
}
Preprocessor::~Preprocessor()
{
delete mImpl;
}
bool Preprocessor::init(int count,
const char* const string[],
const int length[])
{
static const int kGLSLVersion = 100;
// Add standard pre-defined macros.
predefineMacro("__LINE__", 0);
predefineMacro("__FILE__", 0);
predefineMacro("__VERSION__", kGLSLVersion);
predefineMacro("GL_ES", 1);
return mImpl->tokenizer.init(count, string, length);
}
void Preprocessor::predefineMacro(const char* name, int value)
{
std::ostringstream stream;
stream << value;
Token token;
token.type = Token::CONST_INT;
token.text = stream.str();
Macro macro;
macro.predefined = true;
macro.type = Macro::kTypeObj;
macro.name = name;
macro.replacements.push_back(token);
mImpl->macroSet[name] = macro;
}
void Preprocessor::lex(Token* token)
{
bool validToken = false;
while (!validToken)
{
mImpl->macroExpander.lex(token);
switch (token->type)
{
// We should not be returning internal preprocessing tokens.
// Convert preprocessing tokens to compiler tokens or report
// diagnostics.
case Token::PP_HASH:
assert(false);
break;
case Token::CONST_INT:
{
int val = 0;
if (!token->iValue(&val))
{
// Do not mark the token as invalid.
// Just emit the diagnostic and reset value to 0.
mImpl->diagnostics->report(Diagnostics::INTEGER_OVERFLOW,
token->location, token->text);
token->text.assign("0");
}
validToken = true;
break;
}
case Token::CONST_FLOAT:
{
float val = 0;
if (!token->fValue(&val))
{
// Do not mark the token as invalid.
// Just emit the diagnostic and reset value to 0.0.
mImpl->diagnostics->report(Diagnostics::FLOAT_OVERFLOW,
token->location, token->text);
token->text.assign("0.0");
}
validToken = true;
break;
}
case Token::PP_NUMBER:
mImpl->diagnostics->report(Diagnostics::INVALID_NUMBER,
token->location, token->text);
break;
case Token::PP_OTHER:
mImpl->diagnostics->report(Diagnostics::INVALID_CHARACTER,
token->location, token->text);
break;
default:
validToken = true;
break;
}
}
}
} // namespace pp