Update to June 11 2013 code drop. This should fix the hang bug we've been seeing.
diff --git a/src/GLES2/compiler/AnalyzeCallDepth.cpp b/src/GLES2/compiler/AnalyzeCallDepth.cpp new file mode 100644 index 0000000..de256a5 --- /dev/null +++ b/src/GLES2/compiler/AnalyzeCallDepth.cpp
@@ -0,0 +1,191 @@ +// +// Copyright (c) 2002-2013 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 "compiler/AnalyzeCallDepth.h" + +AnalyzeCallDepth::FunctionNode::FunctionNode(TIntermAggregate *node) : node(node) +{ + visit = PreVisit; + callDepth = 0; +} + +const TString &AnalyzeCallDepth::FunctionNode::getName() const +{ + return node->getName(); +} + +void AnalyzeCallDepth::FunctionNode::addCallee(AnalyzeCallDepth::FunctionNode *callee) +{ + for(size_t i = 0; i < callees.size(); i++) + { + if(callees[i] == callee) + { + return; + } + } + + callees.push_back(callee); +} + +unsigned int AnalyzeCallDepth::FunctionNode::analyzeCallDepth(AnalyzeCallDepth *analyzeCallDepth) +{ + ASSERT(visit == PreVisit); + ASSERT(analyzeCallDepth); + + callDepth = 0; + visit = InVisit; + + for(size_t i = 0; i < callees.size(); i++) + { + switch(callees[i]->visit) + { + case InVisit: + // Cycle detected (recursion) + return UINT_MAX; + case PostVisit: + callDepth = std::max(callDepth, 1 + callees[i]->getLastDepth()); + break; + case PreVisit: + callDepth = std::max(callDepth, 1 + callees[i]->analyzeCallDepth(analyzeCallDepth)); + break; + default: + UNREACHABLE(); + break; + } + } + + visit = PostVisit; + return callDepth; +} + +unsigned int AnalyzeCallDepth::FunctionNode::getLastDepth() const +{ + return callDepth; +} + +void AnalyzeCallDepth::FunctionNode::removeIfUnreachable() +{ + if(visit == PreVisit) + { + node->setOp(EOpPrototype); + node->getSequence().resize(1); // Remove function body + } +} + +AnalyzeCallDepth::AnalyzeCallDepth(TIntermNode *root) + : TIntermTraverser(true, false, true, false), + currentFunction(0) +{ + root->traverse(this); +} + +AnalyzeCallDepth::~AnalyzeCallDepth() +{ + for(size_t i = 0; i < functions.size(); i++) + { + delete functions[i]; + } +} + +bool AnalyzeCallDepth::visitAggregate(Visit visit, TIntermAggregate *node) +{ + switch(node->getOp()) + { + case EOpFunction: // Function definition + { + if(visit == PreVisit) + { + currentFunction = findFunctionByName(node->getName()); + + if(!currentFunction) + { + currentFunction = new FunctionNode(node); + functions.push_back(currentFunction); + } + } + else if(visit == PostVisit) + { + currentFunction = 0; + } + } + break; + case EOpFunctionCall: + { + if(!node->isUserDefined()) + { + return false; + } + + if(visit == PreVisit) + { + FunctionNode *function = findFunctionByName(node->getName()); + + if(!function) + { + function = new FunctionNode(node); + functions.push_back(function); + } + + if(currentFunction) + { + currentFunction->addCallee(function); + } + else + { + globalFunctionCalls.insert(function); + } + } + } + break; + default: + break; + } + + return true; +} + +unsigned int AnalyzeCallDepth::analyzeCallDepth() +{ + FunctionNode *main = findFunctionByName("main("); + + if(!main) + { + return 0; + } + + unsigned int depth = 1 + main->analyzeCallDepth(this); + + for(FunctionSet::iterator globalCall = globalFunctionCalls.begin(); globalCall != globalFunctionCalls.end(); globalCall++) + { + unsigned int globalDepth = 1 + (*globalCall)->analyzeCallDepth(this); + + if(globalDepth > depth) + { + depth = globalDepth; + } + } + + for(size_t i = 0; i < functions.size(); i++) + { + functions[i]->removeIfUnreachable(); + } + + return depth; +} + +AnalyzeCallDepth::FunctionNode *AnalyzeCallDepth::findFunctionByName(const TString &name) +{ + for(size_t i = 0; i < functions.size(); i++) + { + if(functions[i]->getName() == name) + { + return functions[i]; + } + } + + return 0; +} +
diff --git a/src/GLES2/compiler/AnalyzeCallDepth.h b/src/GLES2/compiler/AnalyzeCallDepth.h new file mode 100644 index 0000000..7da46fe --- /dev/null +++ b/src/GLES2/compiler/AnalyzeCallDepth.h
@@ -0,0 +1,55 @@ +// +// Copyright (c) 2002-2013 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. +// + +#ifndef COMPILER_ANALYZE_CALL_DEPTH_H_ +#define COMPILER_ANALYZE_CALL_DEPTH_H_ + +#include "compiler/intermediate.h" + +#include <set> +#include <limits.h> + +// Traverses intermediate tree to analyze call depth or detect function recursion +class AnalyzeCallDepth : public TIntermTraverser +{ +public: + AnalyzeCallDepth(TIntermNode *root); + ~AnalyzeCallDepth(); + + virtual bool visitAggregate(Visit, TIntermAggregate*); + + unsigned int analyzeCallDepth(); + +private: + class FunctionNode + { + public: + FunctionNode(TIntermAggregate *node); + + const TString &getName() const; + void addCallee(FunctionNode *callee); + unsigned int analyzeCallDepth(AnalyzeCallDepth *analyzeCallDepth); + unsigned int getLastDepth() const; + + void removeIfUnreachable(); + + private: + TIntermAggregate *const node; + TVector<FunctionNode*> callees; + + Visit visit; + unsigned int callDepth; + }; + + FunctionNode *findFunctionByName(const TString &name); + + std::vector<FunctionNode*> functions; + typedef std::set<FunctionNode*> FunctionSet; + FunctionSet globalFunctionCalls; + FunctionNode *currentFunction; +}; + +#endif // COMPILER_ANALYZE_CALL_DEPTH_H_
diff --git a/src/GLES2/compiler/BaseTypes.h b/src/GLES2/compiler/BaseTypes.h index 3334436..c1ae09c 100644 --- a/src/GLES2/compiler/BaseTypes.h +++ b/src/GLES2/compiler/BaseTypes.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -16,7 +16,7 @@ EbpUndefined, EbpLow, EbpMedium, - EbpHigh, + EbpHigh }; inline const char* getPrecisionString(TPrecision p) @@ -45,7 +45,7 @@ EbtGuardSamplerEnd, // non type: see implementation of IsSampler() EbtStruct, EbtAddress, // should be deprecated?? - EbtInvariant, // used as a type when qualifying a previously declared variable as being invariant + EbtInvariant // used as a type when qualifying a previously declared variable as being invariant }; inline const char* getBasicString(TBasicType t) @@ -110,7 +110,7 @@ EvqFragData, // end of list - EvqLast, + EvqLast }; //
diff --git a/src/GLES2/compiler/Compiler.cpp b/src/GLES2/compiler/Compiler.cpp index 59e8ffe..7a50274 100644 --- a/src/GLES2/compiler/Compiler.cpp +++ b/src/GLES2/compiler/Compiler.cpp
@@ -1,61 +1,18 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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 "compiler/DetectRecursion.h" +#include "compiler/AnalyzeCallDepth.h" #include "compiler/Initialize.h" #include "compiler/InitializeParseContext.h" #include "compiler/ParseHelper.h" #include "compiler/ShHandle.h" #include "compiler/ValidateLimitations.h" -namespace { -bool InitializeSymbolTable( - const TBuiltInStrings& builtInStrings, - ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources, - TInfoSink& infoSink, TSymbolTable& symbolTable) +namespace { - TIntermediate intermediate(infoSink); - TExtensionBehavior extBehavior; - InitExtensionBehavior(resources, extBehavior); - // The builtins deliberately don't specify precisions for the function - // arguments and return types. For that reason we don't try to check them. - TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink); - - GlobalParseContext = &parseContext; - - assert(symbolTable.isEmpty()); - // - // Parse the built-ins. This should only happen once per - // language symbol table. - // - // Push the symbol table to give it an initial scope. This - // push should not have a corresponding pop, so that built-ins - // are preserved, and the test for an empty table fails. - // - symbolTable.push(); - - for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i) - { - const char* builtInShaders = i->c_str(); - int builtInLengths = static_cast<int>(i->size()); - if (builtInLengths <= 0) - continue; - - if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0) - { - infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); - return false; - } - } - - IdentifyBuiltIns(type, spec, resources, symbolTable); - - return true; -} - class TScopedPoolAllocator { public: TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop) @@ -86,7 +43,8 @@ TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec) : shaderType(type), - shaderSpec(spec) + shaderSpec(spec), + maxCallStackDepth(UINT_MAX) { } @@ -96,6 +54,7 @@ bool TCompiler::Init(const ShBuiltInResources& resources) { + maxCallStackDepth = resources.MaxCallStackDepth; TScopedPoolAllocator scopedAlloc(&allocator, false); // Generate built-in symbol table. @@ -150,7 +109,7 @@ success = intermediate.postProcess(root); if (success) - success = detectRecursion(root); + success = validateCallDepth(root, infoSink); if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING)) success = validateLimitations(root); @@ -175,13 +134,46 @@ return success; } -bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources) +bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources &resources) { - TBuiltIns builtIns; + assert(symbolTable.isEmpty()); + + // + // Push the symbol table to give it an initial scope. This + // push should not have a corresponding pop, so that built-ins + // are preserved, and the test for an empty table fails. + // + symbolTable.push(); - builtIns.initialize(shaderType, shaderSpec, resources); - return InitializeSymbolTable(builtIns.getBuiltInStrings(), - shaderType, shaderSpec, resources, infoSink, symbolTable); + TPublicType integer; + integer.type = EbtInt; + integer.size = 1; + integer.matrix = false; + integer.array = false; + + TPublicType floatingPoint; + floatingPoint.type = EbtFloat; + floatingPoint.size = 1; + floatingPoint.matrix = false; + floatingPoint.array = false; + + switch(shaderType) + { + case SH_FRAGMENT_SHADER: + symbolTable.setDefaultPrecision(integer, EbpMedium); + break; + case SH_VERTEX_SHADER: + symbolTable.setDefaultPrecision(integer, EbpHigh); + symbolTable.setDefaultPrecision(floatingPoint, EbpHigh); + break; + default: assert(false && "Language not supported"); + } + + InsertBuiltInFunctions(shaderType, resources, symbolTable); + + IdentifyBuiltIns(shaderType, shaderSpec, resources, symbolTable); + + return true; } void TCompiler::clearResults() @@ -194,23 +186,32 @@ uniforms.clear(); } -bool TCompiler::detectRecursion(TIntermNode* root) +bool TCompiler::validateCallDepth(TIntermNode *root, TInfoSink &infoSink) { - DetectRecursion detect; - root->traverse(&detect); - switch (detect.detectRecursion()) { - case DetectRecursion::kErrorNone: - return true; - case DetectRecursion::kErrorMissingMain: - infoSink.info.message(EPrefixError, "Missing main()"); - return false; - case DetectRecursion::kErrorRecursion: - infoSink.info.message(EPrefixError, "Function recursion detected"); - return false; - default: - UNREACHABLE(); - return false; - } + AnalyzeCallDepth validator(root); + + unsigned int depth = validator.analyzeCallDepth(); + + if(depth == 0) + { + infoSink.info.prefix(EPrefixError); + infoSink.info << "Missing main()"; + return false; + } + else if(depth == UINT_MAX) + { + infoSink.info.prefix(EPrefixError); + infoSink.info << "Function recursion detected"; + return false; + } + else if(depth > maxCallStackDepth) + { + infoSink.info.prefix(EPrefixError); + infoSink.info << "Function call stack too deep"; + return false; + } + + return true; } bool TCompiler::validateLimitations(TIntermNode* root) {
diff --git a/src/GLES2/compiler/Compiler.vcxproj b/src/GLES2/compiler/Compiler.vcxproj index 9ca34db..7813fa9 100644 --- a/src/GLES2/compiler/Compiler.vcxproj +++ b/src/GLES2/compiler/Compiler.vcxproj
@@ -103,9 +103,9 @@ </ClCompile> </ItemDefinitionGroup> <ItemGroup> + <ClCompile Include="AnalyzeCallDepth.cpp" /> <ClCompile Include="Compiler.cpp" /> <ClCompile Include="debug.cpp" /> - <ClCompile Include="DetectRecursion.cpp" /> <ClCompile Include="Diagnostics.cpp" /> <ClCompile Include="DirectiveHandler.cpp" /> <ClCompile Include="InfoSink.cpp" /> @@ -172,11 +172,11 @@ </ItemGroup> <ItemGroup> <ClInclude Include="..\include\GLSLANG\ShaderLang.h" /> + <ClInclude Include="AnalyzeCallDepth.h" /> <ClInclude Include="BaseTypes.h" /> <ClInclude Include="Common.h" /> <ClInclude Include="ConstantUnion.h" /> <ClInclude Include="debug.h" /> - <ClInclude Include="DetectRecursion.h" /> <ClInclude Include="Diagnostics.h" /> <ClInclude Include="InfoSink.h" /> <ClInclude Include="Initialize.h" />
diff --git a/src/GLES2/compiler/Compiler.vcxproj.filters b/src/GLES2/compiler/Compiler.vcxproj.filters index cce0afb..369f97a 100644 --- a/src/GLES2/compiler/Compiler.vcxproj.filters +++ b/src/GLES2/compiler/Compiler.vcxproj.filters
@@ -77,9 +77,6 @@ <ClCompile Include="glslang_tab.cpp"> <Filter>Source Files\generated</Filter> </ClCompile> - <ClCompile Include="DetectRecursion.cpp"> - <Filter>Source Files</Filter> - </ClCompile> <ClCompile Include="OutputASM.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -98,6 +95,9 @@ <ClCompile Include="InitializeParseContext.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="AnalyzeCallDepth.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="BaseTypes.h"> @@ -169,9 +169,6 @@ <ClInclude Include="glslang_tab.h"> <Filter>Header Files\generated</Filter> </ClInclude> - <ClInclude Include="DetectRecursion.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\include\GLSLANG\ShaderLang.h"> <Filter>Header Files</Filter> </ClInclude> @@ -190,6 +187,9 @@ <ClInclude Include="Pragma.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="AnalyzeCallDepth.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <CustomBuild Include="glslang.l">
diff --git a/src/GLES2/compiler/ConstantUnion.h b/src/GLES2/compiler/ConstantUnion.h index bac2e9a..50af5e8 100644 --- a/src/GLES2/compiler/ConstantUnion.h +++ b/src/GLES2/compiler/ConstantUnion.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -14,6 +14,7 @@ ConstantUnion() { iConst = 0; + type = EbtVoid; } POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
diff --git a/src/GLES2/compiler/DetectRecursion.cpp b/src/GLES2/compiler/DetectRecursion.cpp deleted file mode 100644 index e79b70d..0000000 --- a/src/GLES2/compiler/DetectRecursion.cpp +++ /dev/null
@@ -1,125 +0,0 @@ -// -// Copyright (c) 2002-2012 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 "compiler/DetectRecursion.h" - -DetectRecursion::FunctionNode::FunctionNode(const TString& fname) - : name(fname), - visit(PreVisit) -{ -} - -const TString& DetectRecursion::FunctionNode::getName() const -{ - return name; -} - -void DetectRecursion::FunctionNode::addCallee( - DetectRecursion::FunctionNode* callee) -{ - for (size_t i = 0; i < callees.size(); ++i) { - if (callees[i] == callee) - return; - } - callees.push_back(callee); -} - -bool DetectRecursion::FunctionNode::detectRecursion() -{ - ASSERT(visit == PreVisit); - visit = InVisit; - for (size_t i = 0; i < callees.size(); ++i) { - switch (callees[i]->visit) { - case InVisit: - // cycle detected, i.e., recursion detected. - return true; - case PostVisit: - break; - case PreVisit: { - bool recursion = callees[i]->detectRecursion(); - if (recursion) - return true; - break; - } - default: - UNREACHABLE(); - break; - } - } - visit = PostVisit; - return false; -} - -DetectRecursion::DetectRecursion() - : currentFunction(NULL) -{ -} - -DetectRecursion::~DetectRecursion() -{ - for (size_t i = 0; i < functions.size(); ++i) - delete functions[i]; -} - -bool DetectRecursion::visitAggregate(Visit visit, TIntermAggregate* node) -{ - switch (node->getOp()) - { - case EOpPrototype: - // Function declaration. - // Don't add FunctionNode here because node->getName() is the - // unmangled function name. - break; - case EOpFunction: { - // Function definition. - if (visit == PreVisit) { - currentFunction = findFunctionByName(node->getName()); - if (currentFunction == NULL) { - currentFunction = new FunctionNode(node->getName()); - functions.push_back(currentFunction); - } - } - break; - } - case EOpFunctionCall: { - // Function call. - if (visit == PreVisit) { - ASSERT(currentFunction != NULL); - FunctionNode* func = findFunctionByName(node->getName()); - if (func == NULL) { - func = new FunctionNode(node->getName()); - functions.push_back(func); - } - currentFunction->addCallee(func); - } - break; - } - default: - break; - } - return true; -} - -DetectRecursion::ErrorCode DetectRecursion::detectRecursion() -{ - FunctionNode* main = findFunctionByName("main("); - if (main == NULL) - return kErrorMissingMain; - if (main->detectRecursion()) - return kErrorRecursion; - return kErrorNone; -} - -DetectRecursion::FunctionNode* DetectRecursion::findFunctionByName( - const TString& name) -{ - for (size_t i = 0; i < functions.size(); ++i) { - if (functions[i]->getName() == name) - return functions[i]; - } - return NULL; -} -
diff --git a/src/GLES2/compiler/DetectRecursion.h b/src/GLES2/compiler/DetectRecursion.h deleted file mode 100644 index bbac79d..0000000 --- a/src/GLES2/compiler/DetectRecursion.h +++ /dev/null
@@ -1,60 +0,0 @@ -// -// Copyright (c) 2002-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. -// - -#ifndef COMPILER_DETECT_RECURSION_H_ -#define COMPILER_DETECT_RECURSION_H_ - -#include "GLSLANG/ShaderLang.h" - -#include "compiler/intermediate.h" -#include "compiler/VariableInfo.h" - -// Traverses intermediate tree to detect function recursion. -class DetectRecursion : public TIntermTraverser { -public: - enum ErrorCode { - kErrorMissingMain, - kErrorRecursion, - kErrorNone - }; - - DetectRecursion(); - ~DetectRecursion(); - - virtual bool visitAggregate(Visit, TIntermAggregate*); - - ErrorCode detectRecursion(); - -private: - class FunctionNode { - public: - FunctionNode(const TString& fname); - - const TString& getName() const; - - // If a function is already in the callee list, this becomes a no-op. - void addCallee(FunctionNode* callee); - - // Return true if recursive function calls are detected. - bool detectRecursion(); - - private: - // mangled function name is unique. - TString name; - - // functions that are directly called by this function. - TVector<FunctionNode*> callees; - - Visit visit; - }; - - FunctionNode* findFunctionByName(const TString& name); - - TVector<FunctionNode*> functions; - FunctionNode* currentFunction; -}; - -#endif // COMPILER_DETECT_RECURSION_H_
diff --git a/src/GLES2/compiler/ExtensionBehavior.h b/src/GLES2/compiler/ExtensionBehavior.h index e369ddd..1318dd3 100644 --- a/src/GLES2/compiler/ExtensionBehavior.h +++ b/src/GLES2/compiler/ExtensionBehavior.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -16,7 +16,7 @@ EBhEnable, EBhWarn, EBhDisable, - EBhUndefined, + EBhUndefined } TBehavior; inline const char *getBehaviorString(TBehavior b)
diff --git a/src/GLES2/compiler/Initialize.cpp b/src/GLES2/compiler/Initialize.cpp index 401b9b8..180ca14 100644 --- a/src/GLES2/compiler/Initialize.cpp +++ b/src/GLES2/compiler/Initialize.cpp
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -14,500 +14,316 @@ #include "compiler/intermediate.h" -//============================================================================ -// -// Prototypes for built-in functions seen by both vertex and fragment shaders. -// -//============================================================================ -static TString BuiltInFunctionsCommon() +void InsertBuiltInFunctions(ShShaderType type, const ShBuiltInResources &resources, TSymbolTable &symbolTable) { - TString s; + TType *float1 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 1); + TType *float2 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 2); + TType *float3 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 3); + TType *float4 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 4); - // - // Angle and Trigonometric Functions. - // - s.append(TString("float radians(float degrees);")); - s.append(TString("vec2 radians(vec2 degrees);")); - s.append(TString("vec3 radians(vec3 degrees);")); - s.append(TString("vec4 radians(vec4 degrees);")); + TType *int2 = new TType(EbtInt, EbpUndefined, EvqGlobal, 2); + TType *int3 = new TType(EbtInt, EbpUndefined, EvqGlobal, 3); + TType *int4 = new TType(EbtInt, EbpUndefined, EvqGlobal, 4); - s.append(TString("float degrees(float radians);")); - s.append(TString("vec2 degrees(vec2 radians);")); - s.append(TString("vec3 degrees(vec3 radians);")); - s.append(TString("vec4 degrees(vec4 radians);")); + symbolTable.insertBuiltIn(float1, "radians", float1, "degrees"); + symbolTable.insertBuiltIn(float2, "radians", float2, "degrees"); + symbolTable.insertBuiltIn(float3, "radians", float3, "degrees"); + symbolTable.insertBuiltIn(float4, "radians", float4, "degrees"); + symbolTable.insertBuiltIn(float1, "degrees", float1, "radians"); + symbolTable.insertBuiltIn(float2, "degrees", float2, "radians"); + symbolTable.insertBuiltIn(float3, "degrees", float3, "radians"); + symbolTable.insertBuiltIn(float4, "degrees", float4, "radians"); + symbolTable.insertBuiltIn(float1, "sin", float1, "angle"); + symbolTable.insertBuiltIn(float2, "sin", float2, "angle"); + symbolTable.insertBuiltIn(float3, "sin", float3, "angle"); + symbolTable.insertBuiltIn(float4, "sin", float4, "angle"); + symbolTable.insertBuiltIn(float1, "cos", float1, "angle"); + symbolTable.insertBuiltIn(float2, "cos", float2, "angle"); + symbolTable.insertBuiltIn(float3, "cos", float3, "angle"); + symbolTable.insertBuiltIn(float4, "cos", float4, "angle"); + symbolTable.insertBuiltIn(float1, "tan", float1, "angle"); + symbolTable.insertBuiltIn(float2, "tan", float2, "angle"); + symbolTable.insertBuiltIn(float3, "tan", float3, "angle"); + symbolTable.insertBuiltIn(float4, "tan", float4, "angle"); + symbolTable.insertBuiltIn(float1, "asin", float1, "x"); + symbolTable.insertBuiltIn(float2, "asin", float2, "x"); + symbolTable.insertBuiltIn(float3, "asin", float3, "x"); + symbolTable.insertBuiltIn(float4, "asin", float4, "x"); + symbolTable.insertBuiltIn(float1, "acos", float1, "x"); + symbolTable.insertBuiltIn(float2, "acos", float2, "x"); + symbolTable.insertBuiltIn(float3, "acos", float3, "x"); + symbolTable.insertBuiltIn(float4, "acos", float4, "x"); + symbolTable.insertBuiltIn(float1, "atan", float1, "y", float1, "x"); + symbolTable.insertBuiltIn(float2, "atan", float2, "y", float2, "x"); + symbolTable.insertBuiltIn(float3, "atan", float3, "y", float3, "x"); + symbolTable.insertBuiltIn(float4, "atan", float4, "y", float4, "x"); + symbolTable.insertBuiltIn(float1, "atan", float1, "y_over_x"); + symbolTable.insertBuiltIn(float2, "atan", float2, "y_over_x"); + symbolTable.insertBuiltIn(float3, "atan", float3, "y_over_x"); + symbolTable.insertBuiltIn(float4, "atan", float4, "y_over_x"); + symbolTable.insertBuiltIn(float1, "pow", float1, "x", float1, "y"); + symbolTable.insertBuiltIn(float2, "pow", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(float3, "pow", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(float4, "pow", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(float1, "exp", float1, "x"); + symbolTable.insertBuiltIn(float2, "exp", float2, "x"); + symbolTable.insertBuiltIn(float3, "exp", float3, "x"); + symbolTable.insertBuiltIn(float4, "exp", float4, "x"); + symbolTable.insertBuiltIn(float1, "log", float1, "x"); + symbolTable.insertBuiltIn(float2, "log", float2, "x"); + symbolTable.insertBuiltIn(float3, "log", float3, "x"); + symbolTable.insertBuiltIn(float4, "log", float4, "x"); + symbolTable.insertBuiltIn(float1, "exp2", float1, "x"); + symbolTable.insertBuiltIn(float2, "exp2", float2, "x"); + symbolTable.insertBuiltIn(float3, "exp2", float3, "x"); + symbolTable.insertBuiltIn(float4, "exp2", float4, "x"); + symbolTable.insertBuiltIn(float1, "log2", float1, "x"); + symbolTable.insertBuiltIn(float2, "log2", float2, "x"); + symbolTable.insertBuiltIn(float3, "log2", float3, "x"); + symbolTable.insertBuiltIn(float4, "log2", float4, "x"); + symbolTable.insertBuiltIn(float1, "sqrt", float1, "x"); + symbolTable.insertBuiltIn(float2, "sqrt", float2, "x"); + symbolTable.insertBuiltIn(float3, "sqrt", float3, "x"); + symbolTable.insertBuiltIn(float4, "sqrt", float4, "x"); + symbolTable.insertBuiltIn(float1, "inversesqrt", float1, "x"); + symbolTable.insertBuiltIn(float2, "inversesqrt", float2, "x"); + symbolTable.insertBuiltIn(float3, "inversesqrt", float3, "x"); + symbolTable.insertBuiltIn(float4, "inversesqrt", float4, "x"); + symbolTable.insertBuiltIn(float1, "abs", float1, "x"); + symbolTable.insertBuiltIn(float2, "abs", float2, "x"); + symbolTable.insertBuiltIn(float3, "abs", float3, "x"); + symbolTable.insertBuiltIn(float4, "abs", float4, "x"); + symbolTable.insertBuiltIn(float1, "sign", float1, "x"); + symbolTable.insertBuiltIn(float2, "sign", float2, "x"); + symbolTable.insertBuiltIn(float3, "sign", float3, "x"); + symbolTable.insertBuiltIn(float4, "sign", float4, "x"); + symbolTable.insertBuiltIn(float1, "floor", float1, "x"); + symbolTable.insertBuiltIn(float2, "floor", float2, "x"); + symbolTable.insertBuiltIn(float3, "floor", float3, "x"); + symbolTable.insertBuiltIn(float4, "floor", float4, "x"); + symbolTable.insertBuiltIn(float1, "ceil", float1, "x"); + symbolTable.insertBuiltIn(float2, "ceil", float2, "x"); + symbolTable.insertBuiltIn(float3, "ceil", float3, "x"); + symbolTable.insertBuiltIn(float4, "ceil", float4, "x"); + symbolTable.insertBuiltIn(float1, "fract", float1, "x"); + symbolTable.insertBuiltIn(float2, "fract", float2, "x"); + symbolTable.insertBuiltIn(float3, "fract", float3, "x"); + symbolTable.insertBuiltIn(float4, "fract", float4, "x"); + symbolTable.insertBuiltIn(float1, "mod", float1, "x", float1, "y"); + symbolTable.insertBuiltIn(float2, "mod", float2, "x", float1, "y"); + symbolTable.insertBuiltIn(float3, "mod", float3, "x", float1, "y"); + symbolTable.insertBuiltIn(float4, "mod", float4, "x", float1, "y"); + symbolTable.insertBuiltIn(float2, "mod", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(float3, "mod", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(float4, "mod", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(float1, "min", float1, "x", float1, "y"); + symbolTable.insertBuiltIn(float2, "min", float2, "x", float1, "y"); + symbolTable.insertBuiltIn(float3, "min", float3, "x", float1, "y"); + symbolTable.insertBuiltIn(float4, "min", float4, "x", float1, "y"); + symbolTable.insertBuiltIn(float2, "min", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(float3, "min", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(float4, "min", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(float1, "max", float1, "x", float1, "y"); + symbolTable.insertBuiltIn(float2, "max", float2, "x", float1, "y"); + symbolTable.insertBuiltIn(float3, "max", float3, "x", float1, "y"); + symbolTable.insertBuiltIn(float4, "max", float4, "x", float1, "y"); + symbolTable.insertBuiltIn(float2, "max", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(float3, "max", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(float4, "max", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(float1, "clamp", float1, "x", float1, "minVal", float1, "maxVal"); + symbolTable.insertBuiltIn(float2, "clamp", float2, "x", float1, "minVal", float1, "maxVal"); + symbolTable.insertBuiltIn(float3, "clamp", float3, "x", float1, "minVal", float1, "maxVal"); + symbolTable.insertBuiltIn(float4, "clamp", float4, "x", float1, "minVal", float1, "maxVal"); + symbolTable.insertBuiltIn(float2, "clamp", float2, "x", float2, "minVal", float2, "maxVal"); + symbolTable.insertBuiltIn(float3, "clamp", float3, "x", float3, "minVal", float3, "maxVal"); + symbolTable.insertBuiltIn(float4, "clamp", float4, "x", float4, "minVal", float4, "maxVal"); + symbolTable.insertBuiltIn(float1, "mix", float1, "x", float1, "y", float1, "a"); + symbolTable.insertBuiltIn(float2, "mix", float2, "x", float2, "y", float1, "a"); + symbolTable.insertBuiltIn(float3, "mix", float3, "x", float3, "y", float1, "a"); + symbolTable.insertBuiltIn(float4, "mix", float4, "x", float4, "y", float1, "a"); + symbolTable.insertBuiltIn(float2, "mix", float2, "x", float2, "y", float2, "a"); + symbolTable.insertBuiltIn(float3, "mix", float3, "x", float3, "y", float3, "a"); + symbolTable.insertBuiltIn(float4, "mix", float4, "x", float4, "y", float4, "a"); + symbolTable.insertBuiltIn(float1, "step", float1, "edge", float1, "x"); + symbolTable.insertBuiltIn(float2, "step", float2, "edge", float2, "x"); + symbolTable.insertBuiltIn(float3, "step", float3, "edge", float3, "x"); + symbolTable.insertBuiltIn(float4, "step", float4, "edge", float4, "x"); + symbolTable.insertBuiltIn(float2, "step", float1, "edge", float2, "x"); + symbolTable.insertBuiltIn(float3, "step", float1, "edge", float3, "x"); + symbolTable.insertBuiltIn(float4, "step", float1, "edge", float4, "x"); + symbolTable.insertBuiltIn(float1, "smoothstep", float1, "edge0", float1, "edge1", float1, "x"); + symbolTable.insertBuiltIn(float2, "smoothstep", float2, "edge0", float2, "edge1", float2, "x"); + symbolTable.insertBuiltIn(float3, "smoothstep", float3, "edge0", float3, "edge1", float3, "x"); + symbolTable.insertBuiltIn(float4, "smoothstep", float4, "edge0", float4, "edge1", float4, "x"); + symbolTable.insertBuiltIn(float2, "smoothstep", float1, "edge0", float1, "edge1", float2, "x"); + symbolTable.insertBuiltIn(float3, "smoothstep", float1, "edge0", float1, "edge1", float3, "x"); + symbolTable.insertBuiltIn(float4, "smoothstep", float1, "edge0", float1, "edge1", float4, "x"); + symbolTable.insertBuiltIn(float1, "length", float1, "x"); + symbolTable.insertBuiltIn(float1, "length", float2, "x"); + symbolTable.insertBuiltIn(float1, "length", float3, "x"); + symbolTable.insertBuiltIn(float1, "length", float4, "x"); + symbolTable.insertBuiltIn(float1, "distance", float1, "p0", float1, "p1"); + symbolTable.insertBuiltIn(float1, "distance", float2, "p0", float2, "p1"); + symbolTable.insertBuiltIn(float1, "distance", float3, "p0", float3, "p1"); + symbolTable.insertBuiltIn(float1, "distance", float4, "p0", float4, "p1"); + symbolTable.insertBuiltIn(float1, "dot", float1, "x", float1, "y"); + symbolTable.insertBuiltIn(float1, "dot", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(float1, "dot", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(float1, "dot", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(float3, "cross", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(float1, "normalize", float1, "x"); + symbolTable.insertBuiltIn(float2, "normalize", float2, "x"); + symbolTable.insertBuiltIn(float3, "normalize", float3, "x"); + symbolTable.insertBuiltIn(float4, "normalize", float4, "x"); + symbolTable.insertBuiltIn(float1, "faceforward", float1, "N", float1, "I", float1, "Nref"); + symbolTable.insertBuiltIn(float2, "faceforward", float2, "N", float2, "I", float2, "Nref"); + symbolTable.insertBuiltIn(float3, "faceforward", float3, "N", float3, "I", float3, "Nref"); + symbolTable.insertBuiltIn(float4, "faceforward", float4, "N", float4, "I", float4, "Nref"); + symbolTable.insertBuiltIn(float1, "reflect", float1, "I", float1, "N"); + symbolTable.insertBuiltIn(float2, "reflect", float2, "I", float2, "N"); + symbolTable.insertBuiltIn(float3, "reflect", float3, "I", float3, "N"); + symbolTable.insertBuiltIn(float4, "reflect", float4, "I", float4, "N"); + symbolTable.insertBuiltIn(float1, "refract", float1, "I", float1, "N", float1, "eta"); + symbolTable.insertBuiltIn(float2, "refract", float2, "I", float2, "N", float1, "eta"); + symbolTable.insertBuiltIn(float3, "refract", float3, "I", float3, "N", float1, "eta"); + symbolTable.insertBuiltIn(float4, "refract", float4, "I", float4, "N", float1, "eta"); - s.append(TString("float sin(float angle);")); - s.append(TString("vec2 sin(vec2 angle);")); - s.append(TString("vec3 sin(vec3 angle);")); - s.append(TString("vec4 sin(vec4 angle);")); + TType *mat2 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 2, true); + TType *mat3 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 3, true); + TType *mat4 = new TType(EbtFloat, EbpUndefined, EvqGlobal, 4, true); - s.append(TString("float cos(float angle);")); - s.append(TString("vec2 cos(vec2 angle);")); - s.append(TString("vec3 cos(vec3 angle);")); - s.append(TString("vec4 cos(vec4 angle);")); + symbolTable.insertBuiltIn(mat2, "matrixCompMult", mat2, "x", mat2, "y"); + symbolTable.insertBuiltIn(mat3, "matrixCompMult", mat3, "x", mat3, "y"); + symbolTable.insertBuiltIn(mat4, "matrixCompMult", mat4, "x", mat4, "y"); - s.append(TString("float tan(float angle);")); - s.append(TString("vec2 tan(vec2 angle);")); - s.append(TString("vec3 tan(vec3 angle);")); - s.append(TString("vec4 tan(vec4 angle);")); + TType *bool1 = new TType(EbtBool, EbpUndefined, EvqGlobal, 1); + TType *bool2 = new TType(EbtBool, EbpUndefined, EvqGlobal, 2); + TType *bool3 = new TType(EbtBool, EbpUndefined, EvqGlobal, 3); + TType *bool4 = new TType(EbtBool, EbpUndefined, EvqGlobal, 4); - s.append(TString("float asin(float x);")); - s.append(TString("vec2 asin(vec2 x);")); - s.append(TString("vec3 asin(vec3 x);")); - s.append(TString("vec4 asin(vec4 x);")); + symbolTable.insertBuiltIn(bool2, "lessThan", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(bool3, "lessThan", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(bool4, "lessThan", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(bool2, "lessThan", int2, "x", int2, "y"); + symbolTable.insertBuiltIn(bool3, "lessThan", int3, "x", int3, "y"); + symbolTable.insertBuiltIn(bool4, "lessThan", int4, "x", int4, "y"); + symbolTable.insertBuiltIn(bool2, "lessThanEqual", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(bool3, "lessThanEqual", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(bool4, "lessThanEqual", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(bool2, "lessThanEqual", int2, "x", int2, "y"); + symbolTable.insertBuiltIn(bool3, "lessThanEqual", int3, "x", int3, "y"); + symbolTable.insertBuiltIn(bool4, "lessThanEqual", int4, "x", int4, "y"); + symbolTable.insertBuiltIn(bool2, "greaterThan", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(bool3, "greaterThan", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(bool4, "greaterThan", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(bool2, "greaterThan", int2, "x", int2, "y"); + symbolTable.insertBuiltIn(bool3, "greaterThan", int3, "x", int3, "y"); + symbolTable.insertBuiltIn(bool4, "greaterThan", int4, "x", int4, "y"); + symbolTable.insertBuiltIn(bool2, "greaterThanEqual", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(bool3, "greaterThanEqual", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(bool4, "greaterThanEqual", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(bool2, "greaterThanEqual", int2, "x", int2, "y"); + symbolTable.insertBuiltIn(bool3, "greaterThanEqual", int3, "x", int3, "y"); + symbolTable.insertBuiltIn(bool4, "greaterThanEqual", int4, "x", int4, "y"); + symbolTable.insertBuiltIn(bool2, "equal", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(bool3, "equal", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(bool4, "equal", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(bool2, "equal", int2, "x", int2, "y"); + symbolTable.insertBuiltIn(bool3, "equal", int3, "x", int3, "y"); + symbolTable.insertBuiltIn(bool4, "equal", int4, "x", int4, "y"); + symbolTable.insertBuiltIn(bool2, "equal", bool2, "x", bool2, "y"); + symbolTable.insertBuiltIn(bool3, "equal", bool3, "x", bool3, "y"); + symbolTable.insertBuiltIn(bool4, "equal", bool4, "x", bool4, "y"); + symbolTable.insertBuiltIn(bool2, "notEqual", float2, "x", float2, "y"); + symbolTable.insertBuiltIn(bool3, "notEqual", float3, "x", float3, "y"); + symbolTable.insertBuiltIn(bool4, "notEqual", float4, "x", float4, "y"); + symbolTable.insertBuiltIn(bool2, "notEqual", int2, "x", int2, "y"); + symbolTable.insertBuiltIn(bool3, "notEqual", int3, "x", int3, "y"); + symbolTable.insertBuiltIn(bool4, "notEqual", int4, "x", int4, "y"); + symbolTable.insertBuiltIn(bool2, "notEqual", bool2, "x", bool2, "y"); + symbolTable.insertBuiltIn(bool3, "notEqual", bool3, "x", bool3, "y"); + symbolTable.insertBuiltIn(bool4, "notEqual", bool4, "x", bool4, "y"); + symbolTable.insertBuiltIn(bool1, "any", bool2, "x"); + symbolTable.insertBuiltIn(bool1, "any", bool3, "x"); + symbolTable.insertBuiltIn(bool1, "any", bool4, "x"); + symbolTable.insertBuiltIn(bool1, "all", bool2, "x"); + symbolTable.insertBuiltIn(bool1, "all", bool3, "x"); + symbolTable.insertBuiltIn(bool1, "all", bool4, "x"); + symbolTable.insertBuiltIn(bool2, "not", bool2, "x"); + symbolTable.insertBuiltIn(bool3, "not", bool3, "x"); + symbolTable.insertBuiltIn(bool4, "not", bool4, "x"); - s.append(TString("float acos(float x);")); - s.append(TString("vec2 acos(vec2 x);")); - s.append(TString("vec3 acos(vec3 x);")); - s.append(TString("vec4 acos(vec4 x);")); + TType *sampler2D = new TType(EbtSampler2D, EbpUndefined, EvqGlobal, 1); + TType *samplerCube = new TType(EbtSamplerCube, EbpUndefined, EvqGlobal, 1); - s.append(TString("float atan(float y, float x);")); - s.append(TString("vec2 atan(vec2 y, vec2 x);")); - s.append(TString("vec3 atan(vec3 y, vec3 x);")); - s.append(TString("vec4 atan(vec4 y, vec4 x);")); + symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, "sampler", float2, "coord"); + symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, "sampler", float3, "coord"); + symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, "sampler", float4, "coord"); + symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, "sampler", float3, "coord"); - s.append(TString("float atan(float y_over_x);")); - s.append(TString("vec2 atan(vec2 y_over_x);")); - s.append(TString("vec3 atan(vec3 y_over_x);")); - s.append(TString("vec4 atan(vec4 y_over_x);")); - - // - // Exponential Functions. - // - s.append(TString("float pow(float x, float y);")); - s.append(TString("vec2 pow(vec2 x, vec2 y);")); - s.append(TString("vec3 pow(vec3 x, vec3 y);")); - s.append(TString("vec4 pow(vec4 x, vec4 y);")); - - s.append(TString("float exp(float x);")); - s.append(TString("vec2 exp(vec2 x);")); - s.append(TString("vec3 exp(vec3 x);")); - s.append(TString("vec4 exp(vec4 x);")); - - s.append(TString("float log(float x);")); - s.append(TString("vec2 log(vec2 x);")); - s.append(TString("vec3 log(vec3 x);")); - s.append(TString("vec4 log(vec4 x);")); - - s.append(TString("float exp2(float x);")); - s.append(TString("vec2 exp2(vec2 x);")); - s.append(TString("vec3 exp2(vec3 x);")); - s.append(TString("vec4 exp2(vec4 x);")); - - s.append(TString("float log2(float x);")); - s.append(TString("vec2 log2(vec2 x);")); - s.append(TString("vec3 log2(vec3 x);")); - s.append(TString("vec4 log2(vec4 x);")); - - s.append(TString("float sqrt(float x);")); - s.append(TString("vec2 sqrt(vec2 x);")); - s.append(TString("vec3 sqrt(vec3 x);")); - s.append(TString("vec4 sqrt(vec4 x);")); - - s.append(TString("float inversesqrt(float x);")); - s.append(TString("vec2 inversesqrt(vec2 x);")); - s.append(TString("vec3 inversesqrt(vec3 x);")); - s.append(TString("vec4 inversesqrt(vec4 x);")); - - // - // Common Functions. - // - s.append(TString("float abs(float x);")); - s.append(TString("vec2 abs(vec2 x);")); - s.append(TString("vec3 abs(vec3 x);")); - s.append(TString("vec4 abs(vec4 x);")); - - s.append(TString("float sign(float x);")); - s.append(TString("vec2 sign(vec2 x);")); - s.append(TString("vec3 sign(vec3 x);")); - s.append(TString("vec4 sign(vec4 x);")); - - s.append(TString("float floor(float x);")); - s.append(TString("vec2 floor(vec2 x);")); - s.append(TString("vec3 floor(vec3 x);")); - s.append(TString("vec4 floor(vec4 x);")); - - s.append(TString("float ceil(float x);")); - s.append(TString("vec2 ceil(vec2 x);")); - s.append(TString("vec3 ceil(vec3 x);")); - s.append(TString("vec4 ceil(vec4 x);")); - - s.append(TString("float fract(float x);")); - s.append(TString("vec2 fract(vec2 x);")); - s.append(TString("vec3 fract(vec3 x);")); - s.append(TString("vec4 fract(vec4 x);")); - - s.append(TString("float mod(float x, float y);")); - s.append(TString("vec2 mod(vec2 x, float y);")); - s.append(TString("vec3 mod(vec3 x, float y);")); - s.append(TString("vec4 mod(vec4 x, float y);")); - s.append(TString("vec2 mod(vec2 x, vec2 y);")); - s.append(TString("vec3 mod(vec3 x, vec3 y);")); - s.append(TString("vec4 mod(vec4 x, vec4 y);")); - - s.append(TString("float min(float x, float y);")); - s.append(TString("vec2 min(vec2 x, float y);")); - s.append(TString("vec3 min(vec3 x, float y);")); - s.append(TString("vec4 min(vec4 x, float y);")); - s.append(TString("vec2 min(vec2 x, vec2 y);")); - s.append(TString("vec3 min(vec3 x, vec3 y);")); - s.append(TString("vec4 min(vec4 x, vec4 y);")); - - s.append(TString("float max(float x, float y);")); - s.append(TString("vec2 max(vec2 x, float y);")); - s.append(TString("vec3 max(vec3 x, float y);")); - s.append(TString("vec4 max(vec4 x, float y);")); - s.append(TString("vec2 max(vec2 x, vec2 y);")); - s.append(TString("vec3 max(vec3 x, vec3 y);")); - s.append(TString("vec4 max(vec4 x, vec4 y);")); - - s.append(TString("float clamp(float x, float minVal, float maxVal);")); - s.append(TString("vec2 clamp(vec2 x, float minVal, float maxVal);")); - s.append(TString("vec3 clamp(vec3 x, float minVal, float maxVal);")); - s.append(TString("vec4 clamp(vec4 x, float minVal, float maxVal);")); - s.append(TString("vec2 clamp(vec2 x, vec2 minVal, vec2 maxVal);")); - s.append(TString("vec3 clamp(vec3 x, vec3 minVal, vec3 maxVal);")); - s.append(TString("vec4 clamp(vec4 x, vec4 minVal, vec4 maxVal);")); - - s.append(TString("float mix(float x, float y, float a);")); - s.append(TString("vec2 mix(vec2 x, vec2 y, float a);")); - s.append(TString("vec3 mix(vec3 x, vec3 y, float a);")); - s.append(TString("vec4 mix(vec4 x, vec4 y, float a);")); - s.append(TString("vec2 mix(vec2 x, vec2 y, vec2 a);")); - s.append(TString("vec3 mix(vec3 x, vec3 y, vec3 a);")); - s.append(TString("vec4 mix(vec4 x, vec4 y, vec4 a);")); - - s.append(TString("float step(float edge, float x);")); - s.append(TString("vec2 step(vec2 edge, vec2 x);")); - s.append(TString("vec3 step(vec3 edge, vec3 x);")); - s.append(TString("vec4 step(vec4 edge, vec4 x);")); - s.append(TString("vec2 step(float edge, vec2 x);")); - s.append(TString("vec3 step(float edge, vec3 x);")); - s.append(TString("vec4 step(float edge, vec4 x);")); - - s.append(TString("float smoothstep(float edge0, float edge1, float x);")); - s.append(TString("vec2 smoothstep(vec2 edge0, vec2 edge1, vec2 x);")); - s.append(TString("vec3 smoothstep(vec3 edge0, vec3 edge1, vec3 x);")); - s.append(TString("vec4 smoothstep(vec4 edge0, vec4 edge1, vec4 x);")); - s.append(TString("vec2 smoothstep(float edge0, float edge1, vec2 x);")); - s.append(TString("vec3 smoothstep(float edge0, float edge1, vec3 x);")); - s.append(TString("vec4 smoothstep(float edge0, float edge1, vec4 x);")); - - // - // Geometric Functions. - // - s.append(TString("float length(float x);")); - s.append(TString("float length(vec2 x);")); - s.append(TString("float length(vec3 x);")); - s.append(TString("float length(vec4 x);")); - - s.append(TString("float distance(float p0, float p1);")); - s.append(TString("float distance(vec2 p0, vec2 p1);")); - s.append(TString("float distance(vec3 p0, vec3 p1);")); - s.append(TString("float distance(vec4 p0, vec4 p1);")); - - s.append(TString("float dot(float x, float y);")); - s.append(TString("float dot(vec2 x, vec2 y);")); - s.append(TString("float dot(vec3 x, vec3 y);")); - s.append(TString("float dot(vec4 x, vec4 y);")); - - s.append(TString("vec3 cross(vec3 x, vec3 y);")); - s.append(TString("float normalize(float x);")); - s.append(TString("vec2 normalize(vec2 x);")); - s.append(TString("vec3 normalize(vec3 x);")); - s.append(TString("vec4 normalize(vec4 x);")); - - s.append(TString("float faceforward(float N, float I, float Nref);")); - s.append(TString("vec2 faceforward(vec2 N, vec2 I, vec2 Nref);")); - s.append(TString("vec3 faceforward(vec3 N, vec3 I, vec3 Nref);")); - s.append(TString("vec4 faceforward(vec4 N, vec4 I, vec4 Nref);")); - - s.append(TString("float reflect(float I, float N);")); - s.append(TString("vec2 reflect(vec2 I, vec2 N);")); - s.append(TString("vec3 reflect(vec3 I, vec3 N);")); - s.append(TString("vec4 reflect(vec4 I, vec4 N);")); - - s.append(TString("float refract(float I, float N, float eta);")); - s.append(TString("vec2 refract(vec2 I, vec2 N, float eta);")); - s.append(TString("vec3 refract(vec3 I, vec3 N, float eta);")); - s.append(TString("vec4 refract(vec4 I, vec4 N, float eta);")); - - // - // Matrix Functions. - // - s.append(TString("mat2 matrixCompMult(mat2 x, mat2 y);")); - s.append(TString("mat3 matrixCompMult(mat3 x, mat3 y);")); - s.append(TString("mat4 matrixCompMult(mat4 x, mat4 y);")); - - // - // Vector relational functions. - // - s.append(TString("bvec2 lessThan(vec2 x, vec2 y);")); - s.append(TString("bvec3 lessThan(vec3 x, vec3 y);")); - s.append(TString("bvec4 lessThan(vec4 x, vec4 y);")); - - s.append(TString("bvec2 lessThan(ivec2 x, ivec2 y);")); - s.append(TString("bvec3 lessThan(ivec3 x, ivec3 y);")); - s.append(TString("bvec4 lessThan(ivec4 x, ivec4 y);")); - - s.append(TString("bvec2 lessThanEqual(vec2 x, vec2 y);")); - s.append(TString("bvec3 lessThanEqual(vec3 x, vec3 y);")); - s.append(TString("bvec4 lessThanEqual(vec4 x, vec4 y);")); - - s.append(TString("bvec2 lessThanEqual(ivec2 x, ivec2 y);")); - s.append(TString("bvec3 lessThanEqual(ivec3 x, ivec3 y);")); - s.append(TString("bvec4 lessThanEqual(ivec4 x, ivec4 y);")); - - s.append(TString("bvec2 greaterThan(vec2 x, vec2 y);")); - s.append(TString("bvec3 greaterThan(vec3 x, vec3 y);")); - s.append(TString("bvec4 greaterThan(vec4 x, vec4 y);")); - - s.append(TString("bvec2 greaterThan(ivec2 x, ivec2 y);")); - s.append(TString("bvec3 greaterThan(ivec3 x, ivec3 y);")); - s.append(TString("bvec4 greaterThan(ivec4 x, ivec4 y);")); - - s.append(TString("bvec2 greaterThanEqual(vec2 x, vec2 y);")); - s.append(TString("bvec3 greaterThanEqual(vec3 x, vec3 y);")); - s.append(TString("bvec4 greaterThanEqual(vec4 x, vec4 y);")); - - s.append(TString("bvec2 greaterThanEqual(ivec2 x, ivec2 y);")); - s.append(TString("bvec3 greaterThanEqual(ivec3 x, ivec3 y);")); - s.append(TString("bvec4 greaterThanEqual(ivec4 x, ivec4 y);")); - - s.append(TString("bvec2 equal(vec2 x, vec2 y);")); - s.append(TString("bvec3 equal(vec3 x, vec3 y);")); - s.append(TString("bvec4 equal(vec4 x, vec4 y);")); - - s.append(TString("bvec2 equal(ivec2 x, ivec2 y);")); - s.append(TString("bvec3 equal(ivec3 x, ivec3 y);")); - s.append(TString("bvec4 equal(ivec4 x, ivec4 y);")); - - s.append(TString("bvec2 equal(bvec2 x, bvec2 y);")); - s.append(TString("bvec3 equal(bvec3 x, bvec3 y);")); - s.append(TString("bvec4 equal(bvec4 x, bvec4 y);")); - - s.append(TString("bvec2 notEqual(vec2 x, vec2 y);")); - s.append(TString("bvec3 notEqual(vec3 x, vec3 y);")); - s.append(TString("bvec4 notEqual(vec4 x, vec4 y);")); - - s.append(TString("bvec2 notEqual(ivec2 x, ivec2 y);")); - s.append(TString("bvec3 notEqual(ivec3 x, ivec3 y);")); - s.append(TString("bvec4 notEqual(ivec4 x, ivec4 y);")); - - s.append(TString("bvec2 notEqual(bvec2 x, bvec2 y);")); - s.append(TString("bvec3 notEqual(bvec3 x, bvec3 y);")); - s.append(TString("bvec4 notEqual(bvec4 x, bvec4 y);")); - - s.append(TString("bool any(bvec2 x);")); - s.append(TString("bool any(bvec3 x);")); - s.append(TString("bool any(bvec4 x);")); - - s.append(TString("bool all(bvec2 x);")); - s.append(TString("bool all(bvec3 x);")); - s.append(TString("bool all(bvec4 x);")); - - s.append(TString("bvec2 not(bvec2 x);")); - s.append(TString("bvec3 not(bvec3 x);")); - s.append(TString("bvec4 not(bvec4 x);")); - - // - // Texture Functions. - // - s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord);")); - s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord);")); - s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord);")); - s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord);")); - - // - // Noise functions. - // - //s.append(TString("float noise1(float x);")); - //s.append(TString("float noise1(vec2 x);")); - //s.append(TString("float noise1(vec3 x);")); - //s.append(TString("float noise1(vec4 x);")); - - //s.append(TString("vec2 noise2(float x);")); - //s.append(TString("vec2 noise2(vec2 x);")); - //s.append(TString("vec2 noise2(vec3 x);")); - //s.append(TString("vec2 noise2(vec4 x);")); - - //s.append(TString("vec3 noise3(float x);")); - //s.append(TString("vec3 noise3(vec2 x);")); - //s.append(TString("vec3 noise3(vec3 x);")); - //s.append(TString("vec3 noise3(vec4 x);")); - - //s.append(TString("vec4 noise4(float x);")); - //s.append(TString("vec4 noise4(vec2 x);")); - //s.append(TString("vec4 noise4(vec3 x);")); - //s.append(TString("vec4 noise4(vec4 x);")); - - return s; -} - -//============================================================================ -// -// Prototypes for built-in functions seen by vertex shaders only. -// -//============================================================================ -static TString BuiltInFunctionsVertex(const ShBuiltInResources& resources) -{ - TString s; - - // - // Geometric Functions. - // - //s.append(TString("vec4 ftransform();")); - - // - // Texture Functions. - // - s.append(TString("vec4 texture2DLod(sampler2D sampler, vec2 coord, float lod);")); - s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec3 coord, float lod);")); - s.append(TString("vec4 texture2DProjLod(sampler2D sampler, vec4 coord, float lod);")); - s.append(TString("vec4 textureCubeLod(samplerCube sampler, vec3 coord, float lod);")); - - return s; -} - -//============================================================================ -// -// Prototypes for built-in functions seen by fragment shaders only. -// -//============================================================================ -static TString BuiltInFunctionsFragment(const ShBuiltInResources& resources) -{ - TString s; - - // - // Texture Functions. - // - s.append(TString("vec4 texture2D(sampler2D sampler, vec2 coord, float bias);")); - s.append(TString("vec4 texture2DProj(sampler2D sampler, vec3 coord, float bias);")); - s.append(TString("vec4 texture2DProj(sampler2D sampler, vec4 coord, float bias);")); - s.append(TString("vec4 textureCube(samplerCube sampler, vec3 coord, float bias);")); - - if (resources.OES_standard_derivatives) + if(type == SH_FRAGMENT_SHADER) { - s.append(TString("float dFdx(float p);")); - s.append(TString("vec2 dFdx(vec2 p);")); - s.append(TString("vec3 dFdx(vec3 p);")); - s.append(TString("vec4 dFdx(vec4 p);")); + symbolTable.insertBuiltIn(float4, "texture2D", sampler2D, "sampler", float2, "coord", float1, "bias"); + symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, "sampler", float3, "coord", float1, "bias"); + symbolTable.insertBuiltIn(float4, "texture2DProj", sampler2D, "sampler", float4, "coord", float1, "bias"); + symbolTable.insertBuiltIn(float4, "textureCube", samplerCube, "sampler", float3, "coord", float1, "bias"); - s.append(TString("float dFdy(float p);")); - s.append(TString("vec2 dFdy(vec2 p);")); - s.append(TString("vec3 dFdy(vec3 p);")); - s.append(TString("vec4 dFdy(vec4 p);")); + if (resources.OES_standard_derivatives) + { + symbolTable.insertBuiltIn(float1, "dFdx", float1, "p"); + symbolTable.insertBuiltIn(float2, "dFdx", float2, "p"); + symbolTable.insertBuiltIn(float3, "dFdx", float3, "p"); + symbolTable.insertBuiltIn(float4, "dFdx", float4, "p"); + + symbolTable.insertBuiltIn(float1, "dFdy", float1, "p"); + symbolTable.insertBuiltIn(float2, "dFdy", float2, "p"); + symbolTable.insertBuiltIn(float3, "dFdy", float3, "p"); + symbolTable.insertBuiltIn(float4, "dFdy", float4, "p"); - s.append(TString("float fwidth(float p);")); - s.append(TString("vec2 fwidth(vec2 p);")); - s.append(TString("vec3 fwidth(vec3 p);")); - s.append(TString("vec4 fwidth(vec4 p);")); - } + symbolTable.insertBuiltIn(float1, "fwidth", float1, "p"); + symbolTable.insertBuiltIn(float2, "fwidth", float2, "p"); + symbolTable.insertBuiltIn(float3, "fwidth", float3, "p"); + symbolTable.insertBuiltIn(float4, "fwidth", float4, "p"); + } + } - return s; -} + if(type == SH_VERTEX_SHADER) + { + symbolTable.insertBuiltIn(float4, "texture2DLod", sampler2D, "sampler", float2, "coord", float1, "lod"); + symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, "sampler", float3, "coord", float1, "lod"); + symbolTable.insertBuiltIn(float4, "texture2DProjLod", sampler2D, "sampler", float4, "coord", float1, "lod"); + symbolTable.insertBuiltIn(float4, "textureCubeLod", samplerCube, "sampler", float3, "coord", float1, "lod"); + } -//============================================================================ -// -// Standard uniforms. -// -//============================================================================ -static TString StandardUniforms() -{ - TString s; + TTypeList *members = NewPoolTTypeList(); + TTypeLine near = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; + TTypeLine far = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; + TTypeLine diff = {new TType(EbtFloat, EbpHigh, EvqGlobal, 1), 0}; + near.type->setFieldName("near"); + far.type->setFieldName("far"); + diff.type->setFieldName("diff"); + members->push_back(near); + members->push_back(far); + members->push_back(diff); + TVariable *depthRangeParameters = new TVariable(NewPoolTString("gl_DepthRangeParameters"), TType(members, "gl_DepthRangeParameters"), true); + symbolTable.insert(*depthRangeParameters); + TVariable *depthRange = new TVariable(NewPoolTString("gl_DepthRange"), TType(members, "gl_DepthRangeParameters")); + depthRange->setQualifier(EvqUniform); + symbolTable.insert(*depthRange); - // - // Depth range in window coordinates - // - s.append(TString("struct gl_DepthRangeParameters {")); - s.append(TString(" highp float near;")); // n - s.append(TString(" highp float far;")); // f - s.append(TString(" highp float diff;")); // f - n - s.append(TString("};")); - s.append(TString("uniform gl_DepthRangeParameters gl_DepthRange;")); - - return s; -} - -//============================================================================ -// -// Default precision for vertex shaders. -// -//============================================================================ -static TString DefaultPrecisionVertex() -{ - TString s; - - s.append(TString("precision highp int;")); - s.append(TString("precision highp float;")); - - return s; -} - -//============================================================================ -// -// Default precision for fragment shaders. -// -//============================================================================ -static TString DefaultPrecisionFragment() -{ - TString s; - - s.append(TString("precision mediump int;")); - // No default precision for float in fragment shaders - - return s; -} - -//============================================================================ -// -// Implementation dependent built-in constants. -// -//============================================================================ -static TString BuiltInConstants(const ShBuiltInResources &resources) -{ - TStringStream s; - - s << "const int gl_MaxVertexAttribs = " << resources.MaxVertexAttribs << ";"; - s << "const int gl_MaxVertexUniformVectors = " << resources.MaxVertexUniformVectors << ";"; - - s << "const int gl_MaxVaryingVectors = " << resources.MaxVaryingVectors << ";"; - s << "const int gl_MaxVertexTextureImageUnits = " << resources.MaxVertexTextureImageUnits << ";"; - s << "const int gl_MaxCombinedTextureImageUnits = " << resources.MaxCombinedTextureImageUnits << ";"; - s << "const int gl_MaxTextureImageUnits = " << resources.MaxTextureImageUnits << ";"; - s << "const int gl_MaxFragmentUniformVectors = " << resources.MaxFragmentUniformVectors << ";"; - s << "const int gl_MaxDrawBuffers = " << resources.MaxDrawBuffers << ";"; - - return s.str(); -} - -void TBuiltIns::initialize(ShShaderType type, ShShaderSpec spec, - const ShBuiltInResources& resources) -{ - switch (type) { - case SH_FRAGMENT_SHADER: - builtInStrings.push_back(DefaultPrecisionFragment()); - builtInStrings.push_back(BuiltInFunctionsCommon()); - builtInStrings.push_back(BuiltInFunctionsFragment(resources)); - builtInStrings.push_back(StandardUniforms()); - break; - - case SH_VERTEX_SHADER: - builtInStrings.push_back(DefaultPrecisionVertex()); - builtInStrings.push_back(BuiltInFunctionsCommon()); - builtInStrings.push_back(BuiltInFunctionsVertex(resources)); - builtInStrings.push_back(StandardUniforms()); - break; - - default: assert(false && "Language not supported"); - } - - builtInStrings.push_back(BuiltInConstants(resources)); + symbolTable.insertConstInt("gl_MaxVertexAttribs", resources.MaxVertexAttribs); + symbolTable.insertConstInt("gl_MaxVertexUniformVectors", resources.MaxVertexUniformVectors); + symbolTable.insertConstInt("gl_MaxVaryingVectors", resources.MaxVaryingVectors); + symbolTable.insertConstInt("gl_MaxVertexTextureImageUnits", resources.MaxVertexTextureImageUnits); + symbolTable.insertConstInt("gl_MaxCombinedTextureImageUnits", resources.MaxCombinedTextureImageUnits); + symbolTable.insertConstInt("gl_MaxTextureImageUnits", resources.MaxTextureImageUnits); + symbolTable.insertConstInt("gl_MaxFragmentUniformVectors", resources.MaxFragmentUniformVectors); + symbolTable.insertConstInt("gl_MaxDrawBuffers", resources.MaxDrawBuffers); } void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources, - TSymbolTable& symbolTable) + TSymbolTable &symbolTable) { // // First, insert some special built-in variables that are not in @@ -625,4 +441,6 @@ { if (resources.OES_standard_derivatives) extBehavior["GL_OES_standard_derivatives"] = EBhUndefined; + if (resources.OES_fragment_precision_high) + extBehavior["GL_FRAGMENT_PRECISION_HIGH"] = EBhUndefined; }
diff --git a/src/GLES2/compiler/Initialize.h b/src/GLES2/compiler/Initialize.h index 8b0adc6..7bc007a 100644 --- a/src/GLES2/compiler/Initialize.h +++ b/src/GLES2/compiler/Initialize.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -11,19 +11,7 @@ #include "compiler/ShHandle.h" #include "compiler/SymbolTable.h" -typedef TVector<TString> TBuiltInStrings; - -class TBuiltIns { -public: - POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator) - - void initialize(ShShaderType type, ShShaderSpec spec, - const ShBuiltInResources& resources); - const TBuiltInStrings& getBuiltInStrings() { return builtInStrings; } - -protected: - TBuiltInStrings builtInStrings; -}; +void InsertBuiltInFunctions(ShShaderType type, const ShBuiltInResources &resources, TSymbolTable &table); void IdentifyBuiltIns(ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
diff --git a/src/GLES2/compiler/Intermediate.cpp b/src/GLES2/compiler/Intermediate.cpp index 5ef2789..b96e23e 100644 --- a/src/GLES2/compiler/Intermediate.cpp +++ b/src/GLES2/compiler/Intermediate.cpp
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -15,6 +15,7 @@ #include "compiler/localintermediate.h" #include "compiler/QualifierAlive.h" #include "compiler/RemoveTree.h" +#include "compiler/SymbolTable.h" bool CompareStructure(const TType& leftNodeType, ConstantUnion* rightUnionArray, ConstantUnion* leftUnionArray); @@ -143,7 +144,7 @@ // // Returns the added node. // -TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line, TSymbolTable& symbolTable) +TIntermTyped* TIntermediate::addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc line) { switch (op) { case EOpEqual: @@ -278,7 +279,7 @@ // // Returns the added node. // -TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line, TSymbolTable& symbolTable) +TIntermTyped* TIntermediate::addUnaryMath(TOperator op, TIntermNode* childNode, TSourceLoc line) { TIntermUnary* node; TIntermTyped* child = childNode->getAsTyped();
diff --git a/src/GLES2/compiler/OutputASM.cpp b/src/GLES2/compiler/OutputASM.cpp index 713f031..e37efac 100644 --- a/src/GLES2/compiler/OutputASM.cpp +++ b/src/GLES2/compiler/OutputASM.cpp
@@ -76,9 +76,10 @@ ConstantUnion constants[4]; }; - Uniform::Uniform(GLenum type, const std::string &name, int arraySize, int registerIndex) + Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex) { this->type = type; + this->precision = precision; this->name = name; this->arraySize = arraySize; this->registerIndex = registerIndex; @@ -361,14 +362,14 @@ mov->src[0].swizzle = swizzle; } break; - case EOpAddAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_ADD, result, left, left, right); break; - case EOpAdd: if(visit == PostVisit) emit(sw::Shader::OPCODE_ADD, result, left, right); break; - case EOpSubAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_SUB, result, left, left, right); break; - case EOpSub: if(visit == PostVisit) emit(sw::Shader::OPCODE_SUB, result, left, right); break; - case EOpMulAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_MUL, result, left, left, right); break; - case EOpMul: if(visit == PostVisit) emit(sw::Shader::OPCODE_MUL, result, left, right); break; - case EOpDivAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_DIV, result, left, left, right); break; - case EOpDiv: if(visit == PostVisit) emit(sw::Shader::OPCODE_DIV, result, left, right); break; + case EOpAddAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_ADD, result, left, left, right); break; + case EOpAdd: if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_ADD, result, left, right); break; + case EOpSubAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_SUB, result, left, left, right); break; + case EOpSub: if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_SUB, result, left, right); break; + case EOpMulAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_MUL, result, left, left, right); break; + case EOpMul: if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_MUL, result, left, right); break; + case EOpDivAssign: if(visit == PostVisit) emitAssign(sw::Shader::OPCODE_DIV, result, left, left, right); break; + case EOpDiv: if(visit == PostVisit) emitBinary(sw::Shader::OPCODE_DIV, result, left, right); break; case EOpEqual: if(visit == PostVisit) { @@ -1111,6 +1112,21 @@ return false; } + unsigned int iterations = loopCount(node); + + if(iterations == 0) + { + return false; + } + + bool unroll = (iterations <= 4); + + if(unroll) + { + DetectLoopDiscontinuity detectLoopDiscontinuity; + unroll = !detectLoopDiscontinuity.traverse(node); + } + TIntermNode *init = node->getInit(); TIntermTyped *condition = node->getCondition(); TIntermTyped *expression = node->getExpression(); @@ -1143,25 +1159,45 @@ init->traverse(this); } - condition->traverse(this); - - emit(sw::Shader::OPCODE_WHILE, 0, condition); - - if(body) + if(unroll) { - body->traverse(this); + for(unsigned int i = 0; i < iterations; i++) + { + // condition->traverse(this); // Condition could contain statements, but not in an unrollable loop + + if(body) + { + body->traverse(this); + } + + if(expression) + { + expression->traverse(this); + } + } } - - emit(sw::Shader::OPCODE_TEST); - - if(expression) + else { - expression->traverse(this); + condition->traverse(this); + + emit(sw::Shader::OPCODE_WHILE, 0, condition); + + if(body) + { + body->traverse(this); + } + + emit(sw::Shader::OPCODE_TEST); + + if(expression) + { + expression->traverse(this); + } + + condition->traverse(this); + + emit(sw::Shader::OPCODE_ENDWHILE); } - - condition->traverse(this); - - emit(sw::Shader::OPCODE_ENDWHILE); } return false; @@ -1198,11 +1234,11 @@ return true; } - Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2) + Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2, int index) { if(dst && registerType(dst) == sw::Shader::PARAMETER_SAMPLER) { - op = sw::Shader::OPCODE_NOP; // Can't assign to a sampler, but this will be hit when indexing sampler arrays + op = sw::Shader::OPCODE_NULL; // Can't assign to a sampler, but this is hit when indexing sampler arrays } Instruction *instruction = new Instruction(op); @@ -1210,23 +1246,31 @@ if(dst) { instruction->dst.type = registerType(dst); - instruction->dst.index = registerIndex(dst); + instruction->dst.index = registerIndex(dst) + index; instruction->dst.mask = writeMask(dst); instruction->dst.integer = (dst->getBasicType() == EbtInt); } - argument(instruction->src[0], src0); - argument(instruction->src[1], src1); - argument(instruction->src[2], src2); + argument(instruction->src[0], src0, index); + argument(instruction->src[1], src1, index); + argument(instruction->src[2], src2, index); shader->append(instruction); return instruction; } + void OutputASM::emitBinary(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2) + { + for(int index = 0; index < dst->elementRegisterCount(); index++) + { + emit(op, dst, src0, src1, src2, index); + } + } + void OutputASM::emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1) { - emit(op, result, src0, src1); + emitBinary(op, result, src0, src1); assignLvalue(lhs, result); } @@ -1997,7 +2041,7 @@ index = allocate(samplers, sampler); ActiveUniforms &activeUniforms = shaderObject->activeUniforms; const char *name = symbol->getSymbol().c_str(); - activeUniforms.push_back(Uniform(glVariableType(type), name, sampler->getArraySize(), index)); + activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name, sampler->getArraySize(), index)); for(int i = 0; i < sampler->totalRegisterCount(); i++) { @@ -2117,7 +2161,7 @@ if(!structure) { - activeUniforms.push_back(Uniform(glVariableType(type), name.c_str(), type.getArraySize(), index)); + activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), index)); } else { @@ -2234,6 +2278,37 @@ return GL_NONE; } + GLenum OutputASM::glVariablePrecision(const TType &type) + { + if(type.getBasicType() == EbtFloat) + { + switch(type.getPrecision()) + { + case EbpHigh: return GL_HIGH_FLOAT; + case EbpMedium: return GL_MEDIUM_FLOAT; + case EbpLow: return GL_LOW_FLOAT; + case EbpUndefined: + // Should be defined as the default precision by the parser + default: UNREACHABLE(); + } + } + else if (type.getBasicType() == EbtInt) + { + switch (type.getPrecision()) + { + case EbpHigh: return GL_HIGH_INT; + case EbpMedium: return GL_MEDIUM_INT; + case EbpLow: return GL_LOW_INT; + case EbpUndefined: + // Should be defined as the default precision by the parser + default: UNREACHABLE(); + } + } + + // Other types (boolean, sampler) don't have a precision + return GL_NONE; + } + int OutputASM::dim(TIntermNode *v) { TIntermTyped *vector = v->getAsTyped(); @@ -2247,4 +2322,189 @@ ASSERT(matrix && matrix->isMatrix() && !matrix->isArray()); return matrix->getNominalSize(); } + + // Returns ~0 if no loop count could be determined + unsigned int OutputASM::loopCount(TIntermLoop *node) + { + // Parse loops of the form: + // for(int index = initial; index [comparator] limit; index += increment) + TIntermSymbol *index = 0; + TOperator comparator = EOpNull; + int initial = 0; + int limit = 0; + int increment = 0; + + // Parse index name and intial value + if(node->getInit()) + { + TIntermAggregate *init = node->getInit()->getAsAggregate(); + + if(init) + { + TIntermSequence &sequence = init->getSequence(); + TIntermTyped *variable = sequence[0]->getAsTyped(); + + if(variable && variable->getQualifier() == EvqTemporary) + { + TIntermBinary *assign = variable->getAsBinaryNode(); + + if(assign->getOp() == EOpInitialize) + { + TIntermSymbol *symbol = assign->getLeft()->getAsSymbolNode(); + TIntermConstantUnion *constant = assign->getRight()->getAsConstantUnion(); + + if(symbol && constant) + { + if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1) + { + index = symbol; + initial = constant->getUnionArrayPointer()[0].getIConst(); + } + } + } + } + } + } + + // Parse comparator and limit value + if(index && node->getCondition()) + { + TIntermBinary *test = node->getCondition()->getAsBinaryNode(); + + if(test && test->getLeft()->getAsSymbolNode()->getId() == index->getId()) + { + TIntermConstantUnion *constant = test->getRight()->getAsConstantUnion(); + + if(constant) + { + if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1) + { + comparator = test->getOp(); + limit = constant->getUnionArrayPointer()[0].getIConst(); + } + } + } + } + + // Parse increment + if(index && comparator != EOpNull && node->getExpression()) + { + TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode(); + TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode(); + + if(binaryTerminal) + { + TOperator op = binaryTerminal->getOp(); + TIntermConstantUnion *constant = binaryTerminal->getRight()->getAsConstantUnion(); + + if(constant) + { + if(constant->getBasicType() == EbtInt && constant->getNominalSize() == 1) + { + int value = constant->getUnionArrayPointer()[0].getIConst(); + + switch(op) + { + case EOpAddAssign: increment = value; break; + case EOpSubAssign: increment = -value; break; + default: UNIMPLEMENTED(); + } + } + } + } + else if(unaryTerminal) + { + TOperator op = unaryTerminal->getOp(); + + switch(op) + { + case EOpPostIncrement: increment = 1; break; + case EOpPostDecrement: increment = -1; break; + case EOpPreIncrement: increment = 1; break; + case EOpPreDecrement: increment = -1; break; + default: UNIMPLEMENTED(); + } + } + } + + if(index && comparator != EOpNull && increment != 0) + { + if(comparator == EOpLessThanEqual) + { + comparator = EOpLessThan; + limit += 1; + } + + if(comparator == EOpLessThan) + { + int iterations = (limit - initial) / increment; + + if(iterations <= 0) + { + iterations = 0; + } + + return iterations; + } + else UNIMPLEMENTED(); // Falls through + } + + return ~0; + } + + bool DetectLoopDiscontinuity::traverse(TIntermNode *node) + { + loopDepth = 0; + loopDiscontinuity = false; + + node->traverse(this); + + return loopDiscontinuity; + } + + bool DetectLoopDiscontinuity::visitLoop(Visit visit, TIntermLoop *loop) + { + if(visit == PreVisit) + { + loopDepth++; + } + else if(visit == PostVisit) + { + loopDepth++; + } + + return true; + } + + bool DetectLoopDiscontinuity::visitBranch(Visit visit, TIntermBranch *node) + { + if(loopDiscontinuity) + { + return false; + } + + if(!loopDepth) + { + return true; + } + + switch(node->getFlowOp()) + { + case EOpKill: + break; + case EOpBreak: + case EOpContinue: + case EOpReturn: + loopDiscontinuity = true; + break; + default: UNREACHABLE(); + } + + return !loopDiscontinuity; + } + + bool DetectLoopDiscontinuity::visitAggregate(Visit visit, TIntermAggregate *node) + { + return !loopDiscontinuity; + } }
diff --git a/src/GLES2/compiler/OutputASM.h b/src/GLES2/compiler/OutputASM.h index c07864f..0a2dd7e 100644 --- a/src/GLES2/compiler/OutputASM.h +++ b/src/GLES2/compiler/OutputASM.h
@@ -33,9 +33,10 @@ { struct Uniform { - Uniform(GLenum type, const std::string &name, int arraySize, int registerIndex); + Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex); GLenum type; + GLenum precision; std::string name; int arraySize; @@ -87,7 +88,7 @@ void freeTemporary(Temporary *temporary); - protected: + private: enum Scope { GLOBAL, @@ -105,7 +106,8 @@ virtual bool visitLoop(Visit visit, TIntermLoop*); virtual bool visitBranch(Visit visit, TIntermBranch*); - Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0); + Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, int index = 0); + void emitBinary(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0); void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0); void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0); void argument(sw::Shader::SourceParameter ¶meter, TIntermNode *argument, int index = 0); @@ -134,9 +136,11 @@ void declareUniform(const TType &type, const TString &name, int index); GLenum glVariableType(const TType &type); + GLenum glVariablePrecision(const TType &type); static int dim(TIntermNode *v); static int dim2(TIntermNode *m); + static unsigned int loopCount(TIntermLoop *node); gl::Shader *const shaderObject; sw::Shader *shader; @@ -157,6 +161,21 @@ TParseContext &mContext; }; + + // Checks whether a loop can run for a variable number of iterations + class DetectLoopDiscontinuity : public TIntermTraverser + { + public: + bool traverse(TIntermNode *node); + + private: + bool visitBranch(Visit visit, TIntermBranch *node); + bool visitLoop(Visit visit, TIntermLoop *loop); + bool visitAggregate(Visit visit, TIntermAggregate *node); + + int loopDepth; + bool loopDiscontinuity; + }; } #endif // COMPILER_OUTPUTASM_H_
diff --git a/src/GLES2/compiler/ParseHelper.cpp b/src/GLES2/compiler/ParseHelper.cpp index 2107300..af8fbbf 100644 --- a/src/GLES2/compiler/ParseHelper.cpp +++ b/src/GLES2/compiler/ParseHelper.cpp
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -33,7 +33,7 @@ enum { exyzw, ergba, - estpq, + estpq } fieldSet[4]; for (int i = 0; i < fields.num; ++i) { @@ -1191,10 +1191,10 @@ bool returnVal = false; ConstantUnion* unionArray = new ConstantUnion[type.getObjectSize()]; if (aggrNode->getSequence().size() == 1) { - returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable, type, true); + returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type, true); } else { - returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), symbolTable, type); + returnVal = intermediate.parseConstTree(aggrNode->getLine(), aggrNode, unionArray, aggrNode->getOp(), type); } if (returnVal) return 0; @@ -1251,7 +1251,7 @@ return 0; } - newNode = intermediate.addUnaryMath(basicOp, node, node->getLine(), symbolTable); + newNode = intermediate.addUnaryMath(basicOp, node, node->getLine()); if (newNode == 0) { error(line, "can't convert", "constructor"); return 0;
diff --git a/src/GLES2/compiler/ShHandle.h b/src/GLES2/compiler/ShHandle.h index a0105ab..8294abf 100644 --- a/src/GLES2/compiler/ShHandle.h +++ b/src/GLES2/compiler/ShHandle.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -65,15 +65,15 @@ bool InitBuiltInSymbolTable(const ShBuiltInResources& resources); // Clears the results from the previous compilation. void clearResults(); - // Return true if function recursion is detected. - bool detectRecursion(TIntermNode* root); + // Return true if function recursion is detected or call depth exceeded. + bool validateCallDepth(TIntermNode *root, TInfoSink &infoSink); // Returns true if the given shader does not exceed the minimum // functionality mandated in GLSL 1.0 spec Appendix A. - bool validateLimitations(TIntermNode* root); + bool validateLimitations(TIntermNode *root); // Collect info for all attribs and uniforms. - void collectAttribsUniforms(TIntermNode* root); + void collectAttribsUniforms(TIntermNode *root); // Translate to object code. - virtual void translate(TIntermNode* root) = 0; + virtual void translate(TIntermNode *root) = 0; // Get built-in extensions with default behavior. const TExtensionBehavior& getExtensionBehavior() const; @@ -81,6 +81,8 @@ ShShaderType shaderType; ShShaderSpec shaderSpec; + unsigned int maxCallStackDepth; + // Built-in symbol table for the given language, spec, and resources. // It is preserved from compile-to-compile. TSymbolTable symbolTable;
diff --git a/src/GLES2/compiler/ShaderLang.cpp b/src/GLES2/compiler/ShaderLang.cpp index 0da8247..85b5654 100644 --- a/src/GLES2/compiler/ShaderLang.cpp +++ b/src/GLES2/compiler/ShaderLang.cpp
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -15,6 +15,8 @@ #include "compiler/preprocessor/length_limits.h" #include "compiler/ShHandle.h" +#include <limits.h> + // // This is the platform independent interface between an OGL driver // and the shading language compiler. @@ -107,6 +109,9 @@ // Extensions. resources->OES_standard_derivatives = 0; + resources->OES_fragment_precision_high = 0; + + resources->MaxCallStackDepth = UINT_MAX; } //
diff --git a/src/GLES2/compiler/SymbolTable.cpp b/src/GLES2/compiler/SymbolTable.cpp index adf56a8..7113a3a 100644 --- a/src/GLES2/compiler/SymbolTable.cpp +++ b/src/GLES2/compiler/SymbolTable.cpp
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -22,6 +22,8 @@ #define snprintf _snprintf #endif +int TSymbolTableLevel::uniqueId = 0; + TType::TType(const TPublicType &p) : type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0) @@ -124,39 +126,6 @@ } // -// Dump functions. -// - -void TVariable::dump(TInfoSink& infoSink) const -{ - infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString(); - if (type.isArray()) { - infoSink.debug << "[0]"; - } - infoSink.debug << "\n"; -} - -void TFunction::dump(TInfoSink &infoSink) const -{ - infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n"; -} - -void TSymbolTableLevel::dump(TInfoSink &infoSink) const -{ - tLevel::const_iterator it; - for (it = level.begin(); it != level.end(); ++it) - (*it).second->dump(infoSink); -} - -void TSymbolTable::dump(TInfoSink &infoSink) const -{ - for (int level = currentLevel(); level >= 0; --level) { - infoSink.debug << "LEVEL " << level << "\n"; - table[level]->dump(infoSink); - } -} - -// // Functions have buried pointers to delete. // TFunction::~TFunction() @@ -212,73 +181,4 @@ TSymbol::TSymbol(const TSymbol& copyOf) { name = NewPoolTString(copyOf.name->c_str()); - uniqueId = copyOf.uniqueId; -} - -TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf) -{ - type.copyType(copyOf.type, remapper); - userType = copyOf.userType; - // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL - assert(copyOf.arrayInformationType == 0); - arrayInformationType = 0; - - if (copyOf.unionArray) { - assert(!copyOf.type.getStruct()); - assert(copyOf.type.getObjectSize() == 1); - unionArray = new ConstantUnion[1]; - unionArray[0] = copyOf.unionArray[0]; - } else - unionArray = 0; -} - -TVariable* TVariable::clone(TStructureMap& remapper) -{ - TVariable *variable = new TVariable(*this, remapper); - - return variable; -} - -TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf) -{ - for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) { - TParameter param; - parameters.push_back(param); - parameters.back().copyParam(copyOf.parameters[i], remapper); - } - - returnType.copyType(copyOf.returnType, remapper); - mangledName = copyOf.mangledName; - op = copyOf.op; - defined = copyOf.defined; -} - -TFunction* TFunction::clone(TStructureMap& remapper) -{ - TFunction *function = new TFunction(*this, remapper); - - return function; -} - -TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper) -{ - TSymbolTableLevel *symTableLevel = new TSymbolTableLevel(); - tLevel::iterator iter; - for (iter = level.begin(); iter != level.end(); ++iter) { - symTableLevel->insert(*iter->second->clone(remapper)); - } - - return symTableLevel; -} - -void TSymbolTable::copyTable(const TSymbolTable& copyOf) -{ - TStructureMap remapper; - uniqueId = copyOf.uniqueId; - for (unsigned int i = 0; i < copyOf.table.size(); ++i) { - table.push_back(copyOf.table[i]->clone(remapper)); - } - for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) { - precisionStack.push_back( copyOf.precisionStack[i] ); - } }
diff --git a/src/GLES2/compiler/SymbolTable.h b/src/GLES2/compiler/SymbolTable.h index 40d7012..20f5205 100644 --- a/src/GLES2/compiler/SymbolTable.h +++ b/src/GLES2/compiler/SymbolTable.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -49,9 +49,7 @@ virtual bool isVariable() const { return false; } void setUniqueId(int id) { uniqueId = id; } int getUniqueId() const { return uniqueId; } - virtual void dump(TInfoSink &infoSink) const = 0; TSymbol(const TSymbol&); - virtual TSymbol* clone(TStructureMap& remapper) = 0; protected: const TString *name; @@ -80,8 +78,6 @@ void updateArrayInformationType(TType *t) { arrayInformationType = t; } TType* getArrayInformationType() { return arrayInformationType; } - virtual void dump(TInfoSink &infoSink) const; - ConstantUnion* getConstPointer() { if (!unionArray) @@ -100,8 +96,6 @@ delete[] unionArray; unionArray = constArray; } - TVariable(const TVariable&, TStructureMap& remapper); // copy constructor - virtual TVariable* clone(TStructureMap& remapper); protected: TType type; @@ -118,12 +112,7 @@ // struct TParameter { TString *name; - TType* type; - void copyParam(const TParameter& param, TStructureMap& remapper) - { - name = NewPoolTString(param.name->c_str()); - type = param.type->clone(remapper); - } + TType *type; }; // @@ -172,10 +161,6 @@ int getParamCount() const { return static_cast<int>(parameters.size()); } const TParameter& getParam(int i) const { return parameters[i]; } - virtual void dump(TInfoSink &infoSink) const; - TFunction(const TFunction&, TStructureMap& remapper); - virtual TFunction* clone(TStructureMap& remapper); - protected: typedef TVector<TParameter> TParamList; TParamList parameters; @@ -198,8 +183,10 @@ TSymbolTableLevel() { } ~TSymbolTableLevel(); - bool insert(TSymbol& symbol) + bool insert(TSymbol &symbol) { + symbol.setUniqueId(++uniqueId); + // // returning true means symbol was added to the table // @@ -218,28 +205,17 @@ return (*it).second; } - const_iterator begin() const - { - return level.begin(); - } - - const_iterator end() const - { - return level.end(); - } - void relateToOperator(const char* name, TOperator op); void relateToExtension(const char* name, const TString& ext); - void dump(TInfoSink &infoSink) const; - TSymbolTableLevel* clone(TStructureMap& remapper); protected: tLevel level; + static int uniqueId; // for unique identification in code generation }; class TSymbolTable { public: - TSymbolTable() : uniqueId(0) + TSymbolTable() { // // The symbol table cannot be used until push() is called, but @@ -278,10 +254,38 @@ bool insert(TSymbol& symbol) { - symbol.setUniqueId(++uniqueId); return table[currentLevel()]->insert(symbol); } + bool insertConstInt(const char *name, int value) + { + TVariable *constant = new TVariable(NewPoolTString(name), TType(EbtInt, EbpUndefined, EvqConst, 1)); + constant->getConstPointer()->setIConst(value); + return insert(*constant); + } + + bool insertBuiltIn(TType *rvalue, const char *name, TType *ptype1, const char *pname1, TType *ptype2 = 0, const char *pname2 = 0, TType *ptype3 = 0, const char *pname3 = 0) + { + TFunction *function = new TFunction(NewPoolTString(name), *rvalue); + + TParameter param1 = {NewPoolTString(pname1), ptype1}; + function->addParameter(param1); + + if(pname2) + { + TParameter param2 = {NewPoolTString(pname2), ptype2}; + function->addParameter(param2); + } + + if(pname3) + { + TParameter param3 = {NewPoolTString(pname3), ptype3}; + function->addParameter(param3); + } + + return insert(*function); + } + TSymbol* find(const TString& name, bool* builtIn = 0, bool *sameScope = 0) { int level = currentLevel(); @@ -319,14 +323,17 @@ void relateToExtension(const char* name, const TString& ext) { table[0]->relateToExtension(name, ext); } - int getMaxSymbolId() { return uniqueId; } - void dump(TInfoSink &infoSink) const; - void copyTable(const TSymbolTable& copyOf); - void setDefaultPrecision( TBasicType type, TPrecision prec ){ - if( type != EbtFloat && type != EbtInt ) return; // Only set default precision for int/float + bool setDefaultPrecision( const TPublicType& type, TPrecision prec ){ + if (IsSampler(type.type)) + return true; // Skip sampler types for the time being + if (type.type != EbtFloat && type.type != EbtInt) + return false; // Only set default precision for int/float + if (type.size != 1 || type.matrix || type.array) + return false; // Not allowed to set for aggregate types int indexOfLastElement = static_cast<int>(precisionStack.size()) - 1; - precisionStack[indexOfLastElement][type] = prec; // Uses map operator [], overwrites the current value + precisionStack[indexOfLastElement][type.type] = prec; // Uses map operator [], overwrites the current value + return true; } // Searches down the precisionStack for a precision qualifier for the specified TBasicType @@ -353,7 +360,6 @@ std::vector<TSymbolTableLevel*> table; typedef std::map< TBasicType, TPrecision > PrecisionStackLevel; std::vector< PrecisionStackLevel > precisionStack; - int uniqueId; // for unique identification in code generation }; #endif // _SYMBOL_TABLE_INCLUDED_
diff --git a/src/GLES2/compiler/Types.h b/src/GLES2/compiler/Types.h index 460a433..dad1949 100644 --- a/src/GLES2/compiler/Types.h +++ b/src/GLES2/compiler/Types.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -29,9 +29,6 @@ return new(memory) TTypeList; } -typedef TMap<TTypeList*, TTypeList*> TStructureMap; -typedef TMap<TTypeList*, TTypeList*>::iterator TStructureMapIterator; - // // Base class for things that have a type. // @@ -53,59 +50,6 @@ typeName = NewPoolTString(n.c_str()); } - void copyType(const TType& copyOf, TStructureMap& remapper) - { - type = copyOf.type; - precision = copyOf.precision; - qualifier = copyOf.qualifier; - size = copyOf.size; - matrix = copyOf.matrix; - array = copyOf.array; - arraySize = copyOf.arraySize; - - TStructureMapIterator iter; - if (copyOf.structure) { - if ((iter = remapper.find(structure)) == remapper.end()) { - // create the new structure here - structure = NewPoolTTypeList(); - for (unsigned int i = 0; i < copyOf.structure->size(); ++i) { - TTypeLine typeLine; - typeLine.line = (*copyOf.structure)[i].line; - typeLine.type = (*copyOf.structure)[i].type->clone(remapper); - structure->push_back(typeLine); - } - } else { - structure = iter->second; - } - } else - structure = 0; - - fieldName = 0; - if (copyOf.fieldName) - fieldName = NewPoolTString(copyOf.fieldName->c_str()); - typeName = 0; - if (copyOf.typeName) - typeName = NewPoolTString(copyOf.typeName->c_str()); - - mangled = 0; - if (copyOf.mangled) - mangled = NewPoolTString(copyOf.mangled->c_str()); - - structureSize = copyOf.structureSize; - maxArraySize = copyOf.maxArraySize; - deepestStructNesting = copyOf.deepestStructNesting; - assert(copyOf.arrayInformationType == 0); - arrayInformationType = 0; // arrayInformationType should not be set for builtIn symbol table level - } - - TType* clone(TStructureMap& remapper) - { - TType *newType = new TType(); - newType->copyType(*this, remapper); - - return newType; - } - TBasicType getBasicType() const { return type; } void setBasicType(TBasicType t) { type = t; }
diff --git a/src/GLES2/compiler/glslang.y b/src/GLES2/compiler/glslang.y index ba8a0b8..fb44af0 100644 --- a/src/GLES2/compiler/glslang.y +++ b/src/GLES2/compiler/glslang.y
@@ -1,6 +1,6 @@ /* // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -15,7 +15,7 @@ %{ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -38,6 +38,9 @@ #include "compiler/ParseHelper.h" #include "GLSLANG/ShaderLang.h" +#define YYENABLE_NLS 0 +#define YYLTYPE_IS_TRIVIAL 1 + #define YYLEX_PARAM context->scanner %} @@ -418,7 +421,7 @@ | postfix_expression INC_OP { if (context->lValueErrorCheck($2.line, "++", $1)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPostIncrement, $1, $2.line); if ($$ == 0) { context->unaryOpError($2.line, "++", $1->getCompleteString()); context->recover(); @@ -428,7 +431,7 @@ | postfix_expression DEC_OP { if (context->lValueErrorCheck($2.line, "--", $1)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPostDecrement, $1, $2.line); if ($$ == 0) { context->unaryOpError($2.line, "--", $1->getCompleteString()); context->recover(); @@ -496,7 +499,7 @@ // // Treat it like a built-in unary operator. // - $$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0, context->symbolTable); + $$ = context->intermediate.addUnaryMath(op, $1.intermNode, 0); if ($$ == 0) { std::stringstream extraInfoStream; extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>($1.intermNode)->getCompleteString(); @@ -680,7 +683,7 @@ | INC_OP unary_expression { if (context->lValueErrorCheck($1.line, "++", $2)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPreIncrement, $2, $1.line); if ($$ == 0) { context->unaryOpError($1.line, "++", $2->getCompleteString()); context->recover(); @@ -690,7 +693,7 @@ | DEC_OP unary_expression { if (context->lValueErrorCheck($1.line, "--", $2)) context->recover(); - $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line, context->symbolTable); + $$ = context->intermediate.addUnaryMath(EOpPreDecrement, $2, $1.line); if ($$ == 0) { context->unaryOpError($1.line, "--", $2->getCompleteString()); context->recover(); @@ -699,7 +702,7 @@ } | unary_operator unary_expression { if ($1.op != EOpNull) { - $$ = context->intermediate.addUnaryMath($1.op, $2, $1.line, context->symbolTable); + $$ = context->intermediate.addUnaryMath($1.op, $2, $1.line); if ($$ == 0) { const char* errorOp = ""; switch($1.op) { @@ -728,7 +731,7 @@ : unary_expression { $$ = $1; } | multiplicative_expression STAR unary_expression { FRAG_VERT_ONLY("*", $2.line); - $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpMul, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "*", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -737,7 +740,7 @@ } | multiplicative_expression SLASH unary_expression { FRAG_VERT_ONLY("/", $2.line); - $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpDiv, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "/", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -749,7 +752,7 @@ additive_expression : multiplicative_expression { $$ = $1; } | additive_expression PLUS multiplicative_expression { - $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpAdd, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "+", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -757,7 +760,7 @@ } } | additive_expression DASH multiplicative_expression { - $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpSub, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "-", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -773,7 +776,7 @@ relational_expression : shift_expression { $$ = $1; } | relational_expression LEFT_ANGLE shift_expression { - $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLessThan, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "<", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -783,7 +786,7 @@ } } | relational_expression RIGHT_ANGLE shift_expression { - $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpGreaterThan, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, ">", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -793,7 +796,7 @@ } } | relational_expression LE_OP shift_expression { - $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLessThanEqual, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "<=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -803,7 +806,7 @@ } } | relational_expression GE_OP shift_expression { - $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpGreaterThanEqual, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, ">=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -817,7 +820,7 @@ equality_expression : relational_expression { $$ = $1; } | equality_expression EQ_OP relational_expression { - $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpEqual, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "==", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -827,7 +830,7 @@ } } | equality_expression NE_OP relational_expression { - $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpNotEqual, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "!=", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -853,7 +856,7 @@ logical_and_expression : inclusive_or_expression { $$ = $1; } | logical_and_expression AND_OP inclusive_or_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalAnd, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "&&", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -867,7 +870,7 @@ logical_xor_expression : logical_and_expression { $$ = $1; } | logical_xor_expression XOR_OP logical_and_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalXor, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "^^", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -881,7 +884,7 @@ logical_or_expression : logical_xor_expression { $$ = $1; } | logical_or_expression OR_OP logical_xor_expression { - $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line, context->symbolTable); + $$ = context->intermediate.addBinaryMath(EOpLogicalOr, $1, $3, $2.line); if ($$ == 0) { context->binaryOpError($2.line, "||", $1->getCompleteString(), $3->getCompleteString()); context->recover(); @@ -967,9 +970,9 @@ const TParameter ¶m = function.getParam(i); if (param.name != 0) { - TVariable *variable = new TVariable(param.name, *param.type); + TVariable variable(param.name, *param.type); - prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), $1.line), $1.line); + prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), $1.line), $1.line); } else { @@ -988,7 +991,10 @@ $$ = $1.intermAggregate; } | PRECISION precision_qualifier type_specifier_no_prec SEMICOLON { - context->symbolTable.setDefaultPrecision( $3.type, $2 ); + if (!context->symbolTable.setDefaultPrecision( $3, $2 )) { + context->error($1.line, "illegal type argument for default precision qualifier", getBasicString($3.type)); + context->recover(); + } $$ = 0; } ;
diff --git a/src/GLES2/compiler/glslang_tab.cpp b/src/GLES2/compiler/glslang_tab.cpp index 3784c5e..a49ad92 100644 --- a/src/GLES2/compiler/glslang_tab.cpp +++ b/src/GLES2/compiler/glslang_tab.cpp
@@ -68,7 +68,7 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -91,6 +91,9 @@ #include "compiler/ParseHelper.h" #include "GLSLANG/ShaderLang.h" +#define YYENABLE_NLS 0 +#define YYLTYPE_IS_TRIVIAL 1 + #define YYLEX_PARAM context->scanner @@ -653,26 +656,26 @@ /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 165, 165, 200, 203, 216, 221, 226, 232, 235, - 314, 317, 418, 428, 441, 449, 549, 552, 560, 564, - 571, 575, 582, 588, 597, 605, 660, 667, 677, 680, - 690, 700, 721, 722, 723, 728, 729, 738, 750, 751, - 759, 770, 774, 775, 785, 795, 805, 818, 819, 829, - 842, 846, 850, 854, 855, 868, 869, 882, 883, 896, - 897, 914, 915, 928, 929, 930, 931, 932, 936, 939, - 950, 958, 985, 990, 997, 1035, 1038, 1045, 1053, 1074, - 1095, 1106, 1135, 1140, 1150, 1155, 1165, 1168, 1171, 1174, - 1180, 1187, 1190, 1212, 1230, 1254, 1277, 1281, 1299, 1307, - 1339, 1359, 1448, 1457, 1480, 1483, 1489, 1497, 1505, 1513, - 1523, 1530, 1533, 1536, 1542, 1545, 1560, 1564, 1568, 1572, - 1581, 1586, 1591, 1596, 1601, 1606, 1611, 1616, 1621, 1626, - 1632, 1638, 1644, 1649, 1654, 1659, 1672, 1672, 1686, 1686, - 1695, 1698, 1713, 1749, 1753, 1759, 1767, 1783, 1787, 1791, - 1792, 1798, 1799, 1800, 1801, 1802, 1806, 1807, 1807, 1807, - 1817, 1818, 1822, 1822, 1823, 1823, 1828, 1831, 1841, 1844, - 1850, 1851, 1855, 1863, 1867, 1877, 1882, 1899, 1899, 1904, - 1904, 1911, 1911, 1919, 1922, 1928, 1931, 1937, 1941, 1948, - 1955, 1962, 1969, 1980, 1989, 1993, 2000, 2003, 2009, 2009 + 0, 168, 168, 203, 206, 219, 224, 229, 235, 238, + 317, 320, 421, 431, 444, 452, 552, 555, 563, 567, + 574, 578, 585, 591, 600, 608, 663, 670, 680, 683, + 693, 703, 724, 725, 726, 731, 732, 741, 753, 754, + 762, 773, 777, 778, 788, 798, 808, 821, 822, 832, + 845, 849, 853, 857, 858, 871, 872, 885, 886, 899, + 900, 917, 918, 931, 932, 933, 934, 935, 939, 942, + 953, 961, 988, 993, 1003, 1041, 1044, 1051, 1059, 1080, + 1101, 1112, 1141, 1146, 1156, 1161, 1171, 1174, 1177, 1180, + 1186, 1193, 1196, 1218, 1236, 1260, 1283, 1287, 1305, 1313, + 1345, 1365, 1454, 1463, 1486, 1489, 1495, 1503, 1511, 1519, + 1529, 1536, 1539, 1542, 1548, 1551, 1566, 1570, 1574, 1578, + 1587, 1592, 1597, 1602, 1607, 1612, 1617, 1622, 1627, 1632, + 1638, 1644, 1650, 1655, 1660, 1665, 1678, 1678, 1692, 1692, + 1701, 1704, 1719, 1755, 1759, 1765, 1773, 1789, 1793, 1797, + 1798, 1804, 1805, 1806, 1807, 1808, 1812, 1813, 1813, 1813, + 1823, 1824, 1828, 1828, 1829, 1829, 1834, 1837, 1847, 1850, + 1856, 1857, 1861, 1869, 1873, 1883, 1888, 1905, 1905, 1910, + 1910, 1917, 1917, 1925, 1928, 1934, 1937, 1943, 1947, 1954, + 1961, 1968, 1975, 1986, 1995, 1999, 2006, 2009, 2015, 2015 }; #endif @@ -2343,7 +2346,7 @@ { if (context->lValueErrorCheck((yyvsp[(2) - (2)].lex).line, "++", (yyvsp[(1) - (2)].interm.intermTypedNode))) context->recover(); - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostIncrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->unaryOpError((yyvsp[(2) - (2)].lex).line, "++", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2357,7 +2360,7 @@ { if (context->lValueErrorCheck((yyvsp[(2) - (2)].lex).line, "--", (yyvsp[(1) - (2)].interm.intermTypedNode))) context->recover(); - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPostDecrement, (yyvsp[(1) - (2)].interm.intermTypedNode), (yyvsp[(2) - (2)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->unaryOpError((yyvsp[(2) - (2)].lex).line, "--", (yyvsp[(1) - (2)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2427,7 +2430,7 @@ // // Treat it like a built-in unary operator. // - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, 0, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(op, (yyvsp[(1) - (1)].interm).intermNode, 0); if ((yyval.interm.intermTypedNode) == 0) { std::stringstream extraInfoStream; extraInfoStream << "built in unary operator function. Type: " << static_cast<TIntermTyped*>((yyvsp[(1) - (1)].interm).intermNode)->getCompleteString(); @@ -2644,7 +2647,7 @@ { if (context->lValueErrorCheck((yyvsp[(1) - (2)].lex).line, "++", (yyvsp[(2) - (2)].interm.intermTypedNode))) context->recover(); - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreIncrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->unaryOpError((yyvsp[(1) - (2)].lex).line, "++", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2658,7 +2661,7 @@ { if (context->lValueErrorCheck((yyvsp[(1) - (2)].lex).line, "--", (yyvsp[(2) - (2)].interm.intermTypedNode))) context->recover(); - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath(EOpPreDecrement, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->unaryOpError((yyvsp[(1) - (2)].lex).line, "--", (yyvsp[(2) - (2)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2671,7 +2674,7 @@ { if ((yyvsp[(1) - (2)].interm).op != EOpNull) { - (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].interm).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addUnaryMath((yyvsp[(1) - (2)].interm).op, (yyvsp[(2) - (2)].interm.intermTypedNode), (yyvsp[(1) - (2)].interm).line); if ((yyval.interm.intermTypedNode) == 0) { const char* errorOp = ""; switch((yyvsp[(1) - (2)].interm).op) { @@ -2712,7 +2715,7 @@ { FRAG_VERT_ONLY("*", (yyvsp[(2) - (3)].lex).line); - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpMul, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "*", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2725,7 +2728,7 @@ { FRAG_VERT_ONLY("/", (yyvsp[(2) - (3)].lex).line); - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpDiv, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "/", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2742,7 +2745,7 @@ case 39: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpAdd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "+", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2754,7 +2757,7 @@ case 40: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpSub, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "-", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2776,7 +2779,7 @@ case 43: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "<", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2790,7 +2793,7 @@ case 44: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThan, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, ">", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2804,7 +2807,7 @@ case 45: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLessThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "<=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2818,7 +2821,7 @@ case 46: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpGreaterThanEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, ">=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2837,7 +2840,7 @@ case 48: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "==", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2851,7 +2854,7 @@ case 49: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpNotEqual, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "!=", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2885,7 +2888,7 @@ case 54: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalAnd, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "&&", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2904,7 +2907,7 @@ case 56: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalXor, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "^^", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -2923,7 +2926,7 @@ case 58: { - (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line, context->symbolTable); + (yyval.interm.intermTypedNode) = context->intermediate.addBinaryMath(EOpLogicalOr, (yyvsp[(1) - (3)].interm.intermTypedNode), (yyvsp[(3) - (3)].interm.intermTypedNode), (yyvsp[(2) - (3)].lex).line); if ((yyval.interm.intermTypedNode) == 0) { context->binaryOpError((yyvsp[(2) - (3)].lex).line, "||", (yyvsp[(1) - (3)].interm.intermTypedNode)->getCompleteString(), (yyvsp[(3) - (3)].interm.intermTypedNode)->getCompleteString()); context->recover(); @@ -3043,9 +3046,9 @@ const TParameter ¶m = function.getParam(i); if (param.name != 0) { - TVariable *variable = new TVariable(param.name, *param.type); + TVariable variable(param.name, *param.type); - prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), (yyvsp[(1) - (2)].interm).line), (yyvsp[(1) - (2)].interm).line); + prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), (yyvsp[(1) - (2)].interm).line), (yyvsp[(1) - (2)].interm).line); } else { @@ -3072,7 +3075,10 @@ case 73: { - context->symbolTable.setDefaultPrecision( (yyvsp[(3) - (4)].interm.type).type, (yyvsp[(2) - (4)].interm.precision) ); + if (!context->symbolTable.setDefaultPrecision( (yyvsp[(3) - (4)].interm.type), (yyvsp[(2) - (4)].interm.precision) )) { + context->error((yyvsp[(1) - (4)].lex).line, "illegal type argument for default precision qualifier", getBasicString((yyvsp[(3) - (4)].interm.type).type)); + context->recover(); + } (yyval.interm.intermNode) = 0; } break;
diff --git a/src/GLES2/compiler/intermOut.cpp b/src/GLES2/compiler/intermOut.cpp index 798a69a..8572330 100644 --- a/src/GLES2/compiler/intermOut.cpp +++ b/src/GLES2/compiler/intermOut.cpp
@@ -1,10 +1,11 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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 "compiler/localintermediate.h" +#include "compiler/SymbolTable.h" // // Two purposes:
diff --git a/src/GLES2/compiler/intermediate.h b/src/GLES2/compiler/intermediate.h index 5ed5f54..0e65d17 100644 --- a/src/GLES2/compiler/intermediate.h +++ b/src/GLES2/compiler/intermediate.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -181,7 +181,7 @@ EOpVectorTimesScalarAssign, EOpMatrixTimesScalarAssign, EOpMatrixTimesMatrixAssign, - EOpDivAssign, + EOpDivAssign }; extern const char* getOperatorString(TOperator op); @@ -275,7 +275,7 @@ enum TLoopType { ELoopFor, ELoopWhile, - ELoopDoWhile, + ELoopDoWhile }; class TIntermLoop : public TIntermNode {
diff --git a/src/GLES2/compiler/localintermediate.h b/src/GLES2/compiler/localintermediate.h index 56890bd..0e5ed0a 100644 --- a/src/GLES2/compiler/localintermediate.h +++ b/src/GLES2/compiler/localintermediate.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -9,7 +9,6 @@ #include "GLSLANG/ShaderLang.h" #include "compiler/intermediate.h" -#include "compiler/SymbolTable.h" struct TVectorFields { int offsets[4]; @@ -27,10 +26,10 @@ TIntermediate(TInfoSink& i) : infoSink(i) { } TIntermSymbol* addSymbol(int Id, const TString&, const TType&, TSourceLoc); TIntermTyped* addConversion(TOperator, const TType&, TIntermTyped*); - TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc, TSymbolTable&); + TIntermTyped* addBinaryMath(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addAssign(TOperator op, TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermTyped* addIndex(TOperator op, TIntermTyped* base, TIntermTyped* index, TSourceLoc); - TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, TSourceLoc, TSymbolTable&); + TIntermTyped* addUnaryMath(TOperator op, TIntermNode* child, TSourceLoc); TIntermAggregate* growAggregate(TIntermNode* left, TIntermNode* right, TSourceLoc); TIntermAggregate* makeAggregate(TIntermNode* node, TSourceLoc); TIntermAggregate* setAggregateOperator(TIntermNode*, TOperator, TSourceLoc); @@ -39,7 +38,7 @@ TIntermTyped* addComma(TIntermTyped* left, TIntermTyped* right, TSourceLoc); TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, TSourceLoc); TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ; - bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false); + bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TType, bool singleConstantParam = false); TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, TSourceLoc); TIntermBranch* addBranch(TOperator, TSourceLoc); TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
diff --git a/src/GLES2/compiler/osinclude.h b/src/GLES2/compiler/osinclude.h index 42379f0..1c965fb 100644 --- a/src/GLES2/compiler/osinclude.h +++ b/src/GLES2/compiler/osinclude.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -32,7 +32,7 @@ #include <pthread.h> #include <semaphore.h> #include <errno.h> -#endif +#endif // ANGLE_OS_WIN #include "compiler/debug.h" @@ -44,9 +44,9 @@ typedef DWORD OS_TLSIndex; #define OS_INVALID_TLS_INDEX (TLS_OUT_OF_INDEXES) #elif defined(ANGLE_OS_POSIX) -typedef unsigned int OS_TLSIndex; -#define OS_INVALID_TLS_INDEX 0xFFFFFFFF -#endif +typedef pthread_key_t OS_TLSIndex; +#define OS_INVALID_TLS_INDEX (static_cast<OS_TLSIndex>(-1)) +#endif // ANGLE_OS_WIN OS_TLSIndex OS_AllocTLSIndex(); bool OS_SetTLSValue(OS_TLSIndex nIndex, void *lpvValue);
diff --git a/src/GLES2/compiler/parseConst.cpp b/src/GLES2/compiler/parseConst.cpp index 9a8a50c..f8fb6be 100644 --- a/src/GLES2/compiler/parseConst.cpp +++ b/src/GLES2/compiler/parseConst.cpp
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -12,7 +12,7 @@ // class TConstTraverser : public TIntermTraverser { public: - TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TSymbolTable& symTable, TType& t) + TConstTraverser(ConstantUnion* cUnion, bool singleConstParam, TOperator constructType, TInfoSink& sink, TType& t) : error(false), index(0), unionArray(cUnion), @@ -20,7 +20,6 @@ constructorType(constructType), singleConstantParam(singleConstParam), infoSink(sink), - symbolTable(symTable), size(0), isMatrix(false), matrixSize(0) { @@ -44,7 +43,6 @@ TOperator constructorType; bool singleConstantParam; TInfoSink& infoSink; - TSymbolTable& symbolTable; int size; // size of the constructor ( 4 for vec4) bool isMatrix; int matrixSize; // dimension of the matrix (nominal size and not the instance size) @@ -223,12 +221,12 @@ // Individual functions can be initialized to 0 to skip processing of that // type of node. It's children will still be processed. // -bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TSymbolTable& symbolTable, TType t, bool singleConstantParam) +bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, ConstantUnion* unionArray, TOperator constructorType, TType t, bool singleConstantParam) { if (root == 0) return false; - TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, symbolTable, t); + TConstTraverser it(unionArray, singleConstantParam, constructorType, infoSink, t); root->traverse(&it); if (it.error)
diff --git a/src/GLES2/compiler/preprocessor/ExpressionParser.cpp b/src/GLES2/compiler/preprocessor/ExpressionParser.cpp index 6bcae27..228639f 100644 --- a/src/GLES2/compiler/preprocessor/ExpressionParser.cpp +++ b/src/GLES2/compiler/preprocessor/ExpressionParser.cpp
@@ -1,1926 +1,1934 @@ - -/* A Bison parser, made by GNU Bison 2.4.1. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.4.1" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 1 - -/* Push parsers. */ -#define YYPUSH 0 - -/* Pull parsers. */ -#define YYPULL 1 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - -/* Substitute the variable and function names. */ -#define yyparse ppparse -#define yylex pplex -#define yyerror pperror -#define yylval pplval -#define yychar ppchar -#define yydebug ppdebug -#define yynerrs ppnerrs - - -/* Copy the first part of user declarations. */ - - -// -// Copyright (c) 2012 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. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! - -#if defined(__GNUC__) -// Triggered by the auto-generated pplval variable. -#pragma GCC diagnostic ignored "-Wuninitialized" -#elif defined(_MSC_VER) -#pragma warning(disable: 4065 4701) -#endif - -#include "ExpressionParser.h" - -#include <cassert> -#include <sstream> - -#include "Diagnostics.h" -#include "Lexer.h" -#include "Token.h" - -#if defined(_MSC_VER) -typedef __int64 YYSTYPE; -#else -#include <stdint.h> -typedef intmax_t YYSTYPE; -#endif // _MSC_VER -#define YYSTYPE_IS_TRIVIAL 1 -#define YYSTYPE_IS_DECLARED 1 - -namespace { -struct Context -{ - pp::Diagnostics* diagnostics; - pp::Lexer* lexer; - pp::Token* token; - int* result; -}; -} // namespace - - -static int yylex(YYSTYPE* lvalp, Context* context); -static void yyerror(Context* context, const char* reason); - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - TOK_CONST_INT = 258, - TOK_OP_OR = 259, - TOK_OP_AND = 260, - TOK_OP_NE = 261, - TOK_OP_EQ = 262, - TOK_OP_GE = 263, - TOK_OP_LE = 264, - TOK_OP_RIGHT = 265, - TOK_OP_LEFT = 266, - TOK_UNARY = 267 - }; -#endif - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef int YYSTYPE; -# define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -#endif - - -/* Copy the second part of user declarations. */ - - - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) -#else -static int -YYID (yyi) - int yyi; -#endif -{ - return yyi; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss_alloc; - YYSTYPE yyvs_alloc; -}; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 14 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 175 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 27 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 3 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 26 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 52 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 267 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 23, 2, 2, 2, 21, 8, 2, - 25, 26, 19, 17, 2, 18, 2, 20, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 11, 2, 12, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 6, 2, 24, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 9, 10, 13, 14, 15, 16, 22 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint8 yyprhs[] = -{ - 0, 0, 3, 5, 7, 11, 15, 19, 23, 27, - 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, - 71, 75, 79, 82, 85, 88, 91 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 28, 0, -1, 29, -1, 3, -1, 29, 4, 29, - -1, 29, 5, 29, -1, 29, 6, 29, -1, 29, - 7, 29, -1, 29, 8, 29, -1, 29, 9, 29, - -1, 29, 10, 29, -1, 29, 13, 29, -1, 29, - 14, 29, -1, 29, 12, 29, -1, 29, 11, 29, - -1, 29, 15, 29, -1, 29, 16, 29, -1, 29, - 18, 29, -1, 29, 17, 29, -1, 29, 21, 29, - -1, 29, 20, 29, -1, 29, 19, 29, -1, 23, - 29, -1, 24, 29, -1, 18, 29, -1, 17, 29, - -1, 25, 29, 26, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint8 yyrline[] = -{ - 0, 85, 85, 92, 93, 96, 99, 102, 105, 108, - 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, - 151, 164, 167, 170, 173, 176, 179 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_OP_OR", - "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_NE", "TOK_OP_EQ", "'<'", - "'>'", "TOK_OP_GE", "TOK_OP_LE", "TOK_OP_RIGHT", "TOK_OP_LEFT", "'+'", - "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", "')'", - "$accept", "input", "expression", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 124, 94, 38, 261, - 262, 60, 62, 263, 264, 265, 266, 43, 45, 42, - 47, 37, 267, 33, 126, 40, 41 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = -{ - 0, 27, 28, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 1, 1, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 3 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = -{ - 0, 3, 0, 0, 0, 0, 0, 0, 2, 25, - 24, 22, 23, 0, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 26, 4, 5, 6, 7, 8, 9, - 10, 14, 13, 11, 12, 15, 16, 18, 17, 21, - 20, 19 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int8 yydefgoto[] = -{ - -1, 7, 8 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -11 -static const yytype_int16 yypact[] = -{ - 46, -11, 46, 46, 46, 46, 46, 12, 68, -11, - -11, -11, -11, 27, -11, 46, 46, 46, 46, 46, - 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, - 46, 46, 46, -11, 85, 101, 116, 130, 143, 154, - 154, -10, -10, -10, -10, 37, 37, 31, 31, -11, - -11, -11 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int8 yypgoto[] = -{ - -11, -11, -2 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const yytype_uint8 yytable[] = -{ - 9, 10, 11, 12, 13, 26, 27, 28, 29, 30, - 31, 32, 14, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 1, - 30, 31, 32, 33, 28, 29, 30, 31, 32, 0, - 0, 0, 0, 2, 3, 0, 0, 0, 0, 4, - 5, 6, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 19, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 32 -}; - -static const yytype_int8 yycheck[] = -{ - 2, 3, 4, 5, 6, 15, 16, 17, 18, 19, - 20, 21, 0, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 3, - 19, 20, 21, 26, 17, 18, 19, 20, 21, -1, - -1, -1, -1, 17, 18, -1, -1, -1, -1, 23, - 24, 25, 4, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = -{ - 0, 3, 17, 18, 23, 24, 25, 28, 29, 29, - 29, 29, 29, 29, 0, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, 26, 29, 29, 29, 29, 29, 29, - 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, - 29, 29 -}; - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (context, YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (&yylval, YYLEX_PARAM) -#else -# define YYLEX yylex (&yylval, context) -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value, context); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Context *context) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep, context) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - Context *context; -#endif -{ - if (!yyvaluep) - return; - YYUSE (context); -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Context *context) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep, context) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; - Context *context; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep, context); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; yybottom <= yytop; yybottom++) - { - int yybot = *yybottom; - YYFPRINTF (stderr, " %d", yybot); - } - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Context *context) -#else -static void -yy_reduce_print (yyvsp, yyrule, context) - YYSTYPE *yyvsp; - int yyrule; - Context *context; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - , context); - YYFPRINTF (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule, context); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Context *context) -#else -static void -yydestruct (yymsg, yytype, yyvaluep, context) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; - Context *context; -#endif -{ - YYUSE (yyvaluep); - YYUSE (context); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - -/* Prevent warnings from -Wmissing-prototypes. */ -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (Context *context); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - - - -/*-------------------------. -| yyparse or yypush_parse. | -`-------------------------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (Context *context) -#else -int -yyparse (context) - Context *context; -#endif -#endif -{ -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - - /* Number of syntax errors so far. */ - int yynerrs; - - int yystate; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - - /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs; - YYSTYPE *yyvsp; - - YYSIZE_T yystacksize; - - int yyn; - int yyresult; - /* Lookahead token as an internal (translated) token number. */ - int yytoken; - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - yytoken = 0; - yyss = yyssa; - yyvs = yyvsa; - yystacksize = YYINITDEPTH; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - if (yystate == YYFINAL) - YYACCEPT; - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - lookahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to lookahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the lookahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token. */ - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: - - { - *(context->result) = static_cast<int>((yyvsp[(1) - (1)])); - YYACCEPT; - } - break; - - case 4: - - { - (yyval) = (yyvsp[(1) - (3)]) || (yyvsp[(3) - (3)]); - } - break; - - case 5: - - { - (yyval) = (yyvsp[(1) - (3)]) && (yyvsp[(3) - (3)]); - } - break; - - case 6: - - { - (yyval) = (yyvsp[(1) - (3)]) | (yyvsp[(3) - (3)]); - } - break; - - case 7: - - { - (yyval) = (yyvsp[(1) - (3)]) ^ (yyvsp[(3) - (3)]); - } - break; - - case 8: - - { - (yyval) = (yyvsp[(1) - (3)]) & (yyvsp[(3) - (3)]); - } - break; - - case 9: - - { - (yyval) = (yyvsp[(1) - (3)]) != (yyvsp[(3) - (3)]); - } - break; - - case 10: - - { - (yyval) = (yyvsp[(1) - (3)]) == (yyvsp[(3) - (3)]); - } - break; - - case 11: - - { - (yyval) = (yyvsp[(1) - (3)]) >= (yyvsp[(3) - (3)]); - } - break; - - case 12: - - { - (yyval) = (yyvsp[(1) - (3)]) <= (yyvsp[(3) - (3)]); - } - break; - - case 13: - - { - (yyval) = (yyvsp[(1) - (3)]) > (yyvsp[(3) - (3)]); - } - break; - - case 14: - - { - (yyval) = (yyvsp[(1) - (3)]) < (yyvsp[(3) - (3)]); - } - break; - - case 15: - - { - (yyval) = (yyvsp[(1) - (3)]) >> (yyvsp[(3) - (3)]); - } - break; - - case 16: - - { - (yyval) = (yyvsp[(1) - (3)]) << (yyvsp[(3) - (3)]); - } - break; - - case 17: - - { - (yyval) = (yyvsp[(1) - (3)]) - (yyvsp[(3) - (3)]); - } - break; - - case 18: - - { - (yyval) = (yyvsp[(1) - (3)]) + (yyvsp[(3) - (3)]); - } - break; - - case 19: - - { - if ((yyvsp[(3) - (3)]) == 0) { - std::ostringstream stream; - stream << (yyvsp[(1) - (3)]) << " % " << (yyvsp[(3) - (3)]); - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { - (yyval) = (yyvsp[(1) - (3)]) % (yyvsp[(3) - (3)]); - } - } - break; - - case 20: - - { - if ((yyvsp[(3) - (3)]) == 0) { - std::ostringstream stream; - stream << (yyvsp[(1) - (3)]) << " / " << (yyvsp[(3) - (3)]); - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { - (yyval) = (yyvsp[(1) - (3)]) / (yyvsp[(3) - (3)]); - } - } - break; - - case 21: - - { - (yyval) = (yyvsp[(1) - (3)]) * (yyvsp[(3) - (3)]); - } - break; - - case 22: - - { - (yyval) = ! (yyvsp[(2) - (2)]); - } - break; - - case 23: - - { - (yyval) = ~ (yyvsp[(2) - (2)]); - } - break; - - case 24: - - { - (yyval) = - (yyvsp[(2) - (2)]); - } - break; - - case 25: - - { - (yyval) = + (yyvsp[(2) - (2)]); - } - break; - - case 26: - - { - (yyval) = (yyvsp[(2) - (3)]); - } - break; - - - - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (context, YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (context, yymsg); - } - else - { - yyerror (context, YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval, context); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp, context); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#if !defined(yyoverflow) || YYERROR_VERBOSE -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (context, YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval, context); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp, context); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - - - - -int yylex(YYSTYPE* lvalp, Context* context) -{ - int type = 0; - - pp::Token* token = context->token; - switch (token->type) - { - case pp::Token::CONST_INT: - { - unsigned int val = 0; - if (!token->uValue(&val)) - { - context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW, - token->location, token->text); - } - *lvalp = static_cast<YYSTYPE>(val); - type = TOK_CONST_INT; - break; - } - case pp::Token::OP_OR: type = TOK_OP_OR; break; - case pp::Token::OP_AND: type = TOK_OP_AND; break; - case pp::Token::OP_NE: type = TOK_OP_NE; break; - case pp::Token::OP_EQ: type = TOK_OP_EQ; break; - case pp::Token::OP_GE: type = TOK_OP_GE; break; - case pp::Token::OP_LE: type = TOK_OP_LE; break; - case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break; - case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break; - case '|': type = '|'; break; - case '^': type = '^'; break; - case '&': type = '&'; break; - case '>': type = '>'; break; - case '<': type = '<'; break; - case '-': type = '-'; break; - case '+': type = '+'; break; - case '%': type = '%'; break; - case '/': type = '/'; break; - case '*': type = '*'; break; - case '!': type = '!'; break; - case '~': type = '~'; break; - case '(': type = '('; break; - case ')': type = ')'; break; - - default: break; - } - - // Advance to the next token if the current one is valid. - if (type != 0) context->lexer->lex(token); - - return type; -} - -void yyerror(Context* context, const char* reason) -{ - context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION, - context->token->location, - reason); -} - -namespace pp { - -ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) : - mLexer(lexer), - mDiagnostics(diagnostics) -{ -} - -bool ExpressionParser::parse(Token* token, int* result) -{ - Context context; - context.diagnostics = mDiagnostics; - context.lexer = mLexer; - context.token = token; - context.result = result; - int ret = yyparse(&context); - switch (ret) - { - case 0: - case 1: - break; - - case 2: - mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, ""); - break; - - default: - assert(false); - mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, ""); - break; - } - - return ret == 0; -} - -} // namespace pp - +/* A Bison parser, made by GNU Bison 2.4.2. */ + +/* Skeleton implementation for Bison's Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2006, 2009-2010 Free Software + Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "2.4.2" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 1 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + +/* Using locations. */ +#define YYLSP_NEEDED 0 + +/* Substitute the variable and function names. */ +#define yyparse ppparse +#define yylex pplex +#define yyerror pperror +#define yylval pplval +#define yychar ppchar +#define yydebug ppdebug +#define yynerrs ppnerrs + + +/* Copy the first part of user declarations. */ + + +// +// Copyright (c) 2012 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. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +#if defined(__GNUC__) +// Triggered by the auto-generated pplval variable. +#pragma GCC diagnostic ignored "-Wuninitialized" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065 4701) +#endif + +#include "ExpressionParser.h" + +#include <cassert> +#include <sstream> + +#include "Diagnostics.h" +#include "Lexer.h" +#include "Token.h" + +#if defined(_MSC_VER) +typedef __int64 YYSTYPE; +#else +#include <stdint.h> +typedef intmax_t YYSTYPE; +#endif // _MSC_VER +#define YYSTYPE_IS_TRIVIAL 1 +#define YYSTYPE_IS_DECLARED 1 + +namespace { +struct Context +{ + pp::Diagnostics* diagnostics; + pp::Lexer* lexer; + pp::Token* token; + int* result; +}; +} // namespace + + +static int yylex(YYSTYPE* lvalp, Context* context); +static void yyerror(Context* context, const char* reason); + + + +/* Enabling traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* Enabling the token table. */ +#ifndef YYTOKEN_TABLE +# define YYTOKEN_TABLE 0 +#endif + + +/* Tokens. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + /* Put the tokens into the symbol table, so that GDB and other debuggers + know about them. */ + enum yytokentype { + TOK_CONST_INT = 258, + TOK_OP_OR = 259, + TOK_OP_AND = 260, + TOK_OP_NE = 261, + TOK_OP_EQ = 262, + TOK_OP_GE = 263, + TOK_OP_LE = 264, + TOK_OP_RIGHT = 265, + TOK_OP_LEFT = 266, + TOK_UNARY = 267 + }; +#endif + + + +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED +typedef int YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define yystype YYSTYPE /* obsolescent; will be withdrawn */ +# define YYSTYPE_IS_DECLARED 1 +#endif + + +/* Copy the second part of user declarations. */ + + + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#elif (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +typedef signed char yytype_int8; +#else +typedef short int yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ +# define YY_(msgid) dgettext ("bison-runtime", msgid) +# endif +# endif +# ifndef YY_ +# define YY_(msgid) msgid +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(e) ((void) (e)) +#else +# define YYUSE(e) /* empty */ +#endif + +/* Identity function, used to suppress warnings about constant conditions. */ +#ifndef lint +# define YYID(n) (n) +#else +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static int +YYID (int yyi) +#else +static int +YYID (yyi) + int yyi; +#endif +{ + return yyi; +} +#endif + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's `empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined _STDLIB_H \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ +# ifndef _STDLIB_H +# define _STDLIB_H 1 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +/* Copy COUNT objects from FROM to TO. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(To, From, Count) \ + __builtin_memcpy (To, From, (Count) * sizeof (*(From))) +# else +# define YYCOPY(To, From, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (To)[yyi] = (From)[yyi]; \ + } \ + while (YYID (0)) +# endif +# endif + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (YYID (0)) + +#endif + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 14 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 175 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 27 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 3 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 26 +/* YYNRULES -- Number of states. */ +#define YYNSTATES 52 + +/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 267 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 23, 2, 2, 2, 21, 8, 2, + 25, 26, 19, 17, 2, 18, 2, 20, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 11, 2, 12, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 7, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 6, 2, 24, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 9, 10, 13, 14, 15, 16, 22 +}; + +#if YYDEBUG +/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in + YYRHS. */ +static const yytype_uint8 yyprhs[] = +{ + 0, 0, 3, 5, 7, 11, 15, 19, 23, 27, + 31, 35, 39, 43, 47, 51, 55, 59, 63, 67, + 71, 75, 79, 82, 85, 88, 91 +}; + +/* YYRHS -- A `-1'-separated list of the rules' RHS. */ +static const yytype_int8 yyrhs[] = +{ + 28, 0, -1, 29, -1, 3, -1, 29, 4, 29, + -1, 29, 5, 29, -1, 29, 6, 29, -1, 29, + 7, 29, -1, 29, 8, 29, -1, 29, 9, 29, + -1, 29, 10, 29, -1, 29, 13, 29, -1, 29, + 14, 29, -1, 29, 12, 29, -1, 29, 11, 29, + -1, 29, 15, 29, -1, 29, 16, 29, -1, 29, + 18, 29, -1, 29, 17, 29, -1, 29, 21, 29, + -1, 29, 20, 29, -1, 29, 19, 29, -1, 23, + 29, -1, 24, 29, -1, 18, 29, -1, 17, 29, + -1, 25, 29, 26, -1 +}; + +/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ +static const yytype_uint8 yyrline[] = +{ + 0, 85, 85, 92, 93, 96, 99, 102, 105, 108, + 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, + 151, 164, 167, 170, 173, 176, 179 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "TOK_CONST_INT", "TOK_OP_OR", + "TOK_OP_AND", "'|'", "'^'", "'&'", "TOK_OP_NE", "TOK_OP_EQ", "'<'", + "'>'", "TOK_OP_GE", "TOK_OP_LE", "TOK_OP_RIGHT", "TOK_OP_LEFT", "'+'", + "'-'", "'*'", "'/'", "'%'", "TOK_UNARY", "'!'", "'~'", "'('", "')'", + "$accept", "input", "expression", 0 +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to + token YYLEX-NUM. */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 124, 94, 38, 261, + 262, 60, 62, 263, 264, 265, 266, 43, 45, 42, + 47, 37, 267, 33, 126, 40, 41 +}; +# endif + +/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 27, 28, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29 +}; + +/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 1, 1, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 2, 2, 2, 2, 3 +}; + +/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state + STATE-NUM when YYTABLE doesn't specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 3, 0, 0, 0, 0, 0, 0, 2, 25, + 24, 22, 23, 0, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 26, 4, 5, 6, 7, 8, 9, + 10, 14, 13, 11, 12, 15, 16, 18, 17, 21, + 20, 19 +}; + +/* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int8 yydefgoto[] = +{ + -1, 7, 8 +}; + +/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +#define YYPACT_NINF -11 +static const yytype_int16 yypact[] = +{ + 46, -11, 46, 46, 46, 46, 46, 12, 68, -11, + -11, -11, -11, 27, -11, 46, 46, 46, 46, 46, + 46, 46, 46, 46, 46, 46, 46, 46, 46, 46, + 46, 46, 46, -11, 85, 101, 116, 130, 143, 154, + 154, -10, -10, -10, -10, 37, 37, 31, 31, -11, + -11, -11 +}; + +/* YYPGOTO[NTERM-NUM]. */ +static const yytype_int8 yypgoto[] = +{ + -11, -11, -2 +}; + +/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule which + number is the opposite. If zero, do what YYDEFACT says. + If YYTABLE_NINF, syntax error. */ +#define YYTABLE_NINF -1 +static const yytype_uint8 yytable[] = +{ + 9, 10, 11, 12, 13, 26, 27, 28, 29, 30, + 31, 32, 14, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, 31, 32, 1, + 30, 31, 32, 33, 28, 29, 30, 31, 32, 0, + 0, 0, 0, 2, 3, 0, 0, 0, 0, 4, + 5, 6, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, + 31, 32, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 22, 23, 24, 25, 26, + 27, 28, 29, 30, 31, 32 +}; + +static const yytype_int8 yycheck[] = +{ + 2, 3, 4, 5, 6, 15, 16, 17, 18, 19, + 20, 21, 0, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, + 32, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 3, + 19, 20, 21, 26, 17, 18, 19, 20, 21, -1, + -1, -1, -1, 17, 18, -1, -1, -1, -1, 23, + 24, 25, 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21 +}; + +/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 3, 17, 18, 23, 24, 25, 28, 29, 29, + 29, 29, 29, 29, 0, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 26, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29 +}; + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +/* Like YYERROR except do call yyerror. This remains here temporarily + to ease the transition to the new meaning of YYERROR, for GCC. + Once GCC version 2 has supplanted version 1, this can go. However, + YYFAIL appears to be in use. Nevertheless, it is formally deprecated + in Bison 2.4.2's NEWS entry, where a plan to phase it out is + discussed. */ + +#define YYFAIL goto yyerrlab +#if defined YYFAIL + /* This is here to suppress warnings from the GCC cpp's + -Wunused-macros. Normally we don't worry about that warning, but + some users do, and we want to make it easy for users to remove + YYFAIL uses, which will produce warnings from Bison 2.5. */ +#endif + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY && yylen == 1) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + yytoken = YYTRANSLATE (yychar); \ + YYPOPSTACK (1); \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (context, YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (YYID (0)) + + +#define YYTERROR 1 +#define YYERRCODE 256 + + +/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. + If N is 0, then set CURRENT to the empty location which ends + the previous symbol: RHS[0] (always defined). */ + +#define YYRHSLOC(Rhs, K) ((Rhs)[K]) +#ifndef YYLLOC_DEFAULT +# define YYLLOC_DEFAULT(Current, Rhs, N) \ + do \ + if (YYID (N)) \ + { \ + (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ + (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ + (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ + } \ + else \ + { \ + (Current).first_line = (Current).last_line = \ + YYRHSLOC (Rhs, 0).last_line; \ + (Current).first_column = (Current).last_column = \ + YYRHSLOC (Rhs, 0).last_column; \ + } \ + while (YYID (0)) +#endif + + +/* YY_LOCATION_PRINT -- Print the location on the stream. + This macro was not mandated originally: define only if we know + we won't break user code: when these are the locations we know. */ + +#ifndef YY_LOCATION_PRINT +# if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL +# define YY_LOCATION_PRINT(File, Loc) \ + fprintf (File, "%d.%d-%d.%d", \ + (Loc).first_line, (Loc).first_column, \ + (Loc).last_line, (Loc).last_column) +# else +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +# endif +#endif + + +/* YYLEX -- calling `yylex' with the right arguments. */ + +#ifdef YYLEX_PARAM +# define YYLEX yylex (&yylval, YYLEX_PARAM) +#else +# define YYLEX yylex (&yylval, context) +#endif + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (YYID (0)) + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value, context); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (YYID (0)) + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Context *context) +#else +static void +yy_symbol_value_print (yyoutput, yytype, yyvaluep, context) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + Context *context; +#endif +{ + if (!yyvaluep) + return; + YYUSE (context); +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# else + YYUSE (yyoutput); +# endif + switch (yytype) + { + default: + break; + } +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, Context *context) +#else +static void +yy_symbol_print (yyoutput, yytype, yyvaluep, context) + FILE *yyoutput; + int yytype; + YYSTYPE const * const yyvaluep; + Context *context; +#endif +{ + if (yytype < YYNTOKENS) + YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); + else + YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep, context); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +#else +static void +yy_stack_print (yybottom, yytop) + yytype_int16 *yybottom; + yytype_int16 *yytop; +#endif +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (YYID (0)) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yy_reduce_print (YYSTYPE *yyvsp, int yyrule, Context *context) +#else +static void +yy_reduce_print (yyvsp, yyrule, context) + YYSTYPE *yyvsp; + int yyrule; + Context *context; +#endif +{ + int yynrhs = yyr2[yyrule]; + int yyi; + unsigned long int yylno = yyrline[yyrule]; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], + &(yyvsp[(yyi + 1) - (yynrhs)]) + , context); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyvsp, Rule, context); \ +} while (YYID (0)) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static YYSIZE_T +yystrlen (const char *yystr) +#else +static YYSIZE_T +yystrlen (yystr) + const char *yystr; +#endif +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static char * +yystpcpy (char *yydest, const char *yysrc) +#else +static char * +yystpcpy (yydest, yysrc) + char *yydest; + const char *yysrc; +#endif +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into YYRESULT an error message about the unexpected token + YYCHAR while in state YYSTATE. Return the number of bytes copied, + including the terminating null byte. If YYRESULT is null, do not + copy anything; just return the number of bytes that would be + copied. As a special case, return 0 if an ordinary "syntax error" + message will do. Return YYSIZE_MAXIMUM if overflow occurs during + size calculation. */ +static YYSIZE_T +yysyntax_error (char *yyresult, int yystate, int yychar) +{ + int yyn = yypact[yystate]; + + if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) + return 0; + else + { + int yytype = YYTRANSLATE (yychar); + YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); + YYSIZE_T yysize = yysize0; + YYSIZE_T yysize1; + int yysize_overflow = 0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + int yyx; + +# if 0 + /* This is so xgettext sees the translatable formats that are + constructed on the fly. */ + YY_("syntax error, unexpected %s"); + YY_("syntax error, unexpected %s, expecting %s"); + YY_("syntax error, unexpected %s, expecting %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s"); + YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); +# endif + char *yyfmt; + char const *yyf; + static char const yyunexpected[] = "syntax error, unexpected %s"; + static char const yyexpecting[] = ", expecting %s"; + static char const yyor[] = " or %s"; + char yyformat[sizeof yyunexpected + + sizeof yyexpecting - 1 + + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) + * (sizeof yyor - 1))]; + char const *yyprefix = yyexpecting; + + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yycount = 1; + + yyarg[0] = yytname[yytype]; + yyfmt = yystpcpy (yyformat, yyunexpected); + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + yyformat[sizeof yyunexpected - 1] = '\0'; + break; + } + yyarg[yycount++] = yytname[yyx]; + yysize1 = yysize + yytnamerr (0, yytname[yyx]); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + yyfmt = yystpcpy (yyfmt, yyprefix); + yyprefix = yyor; + } + + yyf = YY_(yyformat); + yysize1 = yysize + yystrlen (yyf); + yysize_overflow |= (yysize1 < yysize); + yysize = yysize1; + + if (yysize_overflow) + return YYSIZE_MAXIMUM; + + if (yyresult) + { + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + char *yyp = yyresult; + int yyi = 0; + while ((*yyp = *yyf) != '\0') + { + if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyf += 2; + } + else + { + yyp++; + yyf++; + } + } + } + return yysize; + } +} +#endif /* YYERROR_VERBOSE */ + + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +/*ARGSUSED*/ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, Context *context) +#else +static void +yydestruct (yymsg, yytype, yyvaluep, context) + const char *yymsg; + int yytype; + YYSTYPE *yyvaluep; + Context *context; +#endif +{ + YYUSE (yyvaluep); + YYUSE (context); + + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + switch (yytype) + { + + default: + break; + } +} + +/* Prevent warnings from -Wmissing-prototypes. */ +#ifdef YYPARSE_PARAM +#if defined __STDC__ || defined __cplusplus +int yyparse (void *YYPARSE_PARAM); +#else +int yyparse (); +#endif +#else /* ! YYPARSE_PARAM */ +#if defined __STDC__ || defined __cplusplus +int yyparse (Context *context); +#else +int yyparse (); +#endif +#endif /* ! YYPARSE_PARAM */ + + + + + +/*-------------------------. +| yyparse or yypush_parse. | +`-------------------------*/ + +#ifdef YYPARSE_PARAM +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (void *YYPARSE_PARAM) +#else +int +yyparse (YYPARSE_PARAM) + void *YYPARSE_PARAM; +#endif +#else /* ! YYPARSE_PARAM */ +#if (defined __STDC__ || defined __C99__FUNC__ \ + || defined __cplusplus || defined _MSC_VER) +int +yyparse (Context *context) +#else +int +yyparse (context) + Context *context; +#endif +#endif +{ +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; + + /* Number of syntax errors so far. */ + int yynerrs; + + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + `yyss': related to states. + `yyvs': related to semantic values. + + Refer to the stacks thru separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yytoken = 0; + yyss = yyssa; + yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + + /* Initialize stack pointers. + Waste one element of value and location stack + so that they stay on the same level as the state stack. + The wasted elements are never initialized. */ + yyssp = yyss; + yyvsp = yyvs; + + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yyn == YYPACT_NINF) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = YYLEX; + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yyn == 0 || yyn == YYTABLE_NINF) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + *++yyvsp = yylval; + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + `$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: + + { + *(context->result) = static_cast<int>((yyvsp[(1) - (1)])); + YYACCEPT; + } + break; + + case 4: + + { + (yyval) = (yyvsp[(1) - (3)]) || (yyvsp[(3) - (3)]); + } + break; + + case 5: + + { + (yyval) = (yyvsp[(1) - (3)]) && (yyvsp[(3) - (3)]); + } + break; + + case 6: + + { + (yyval) = (yyvsp[(1) - (3)]) | (yyvsp[(3) - (3)]); + } + break; + + case 7: + + { + (yyval) = (yyvsp[(1) - (3)]) ^ (yyvsp[(3) - (3)]); + } + break; + + case 8: + + { + (yyval) = (yyvsp[(1) - (3)]) & (yyvsp[(3) - (3)]); + } + break; + + case 9: + + { + (yyval) = (yyvsp[(1) - (3)]) != (yyvsp[(3) - (3)]); + } + break; + + case 10: + + { + (yyval) = (yyvsp[(1) - (3)]) == (yyvsp[(3) - (3)]); + } + break; + + case 11: + + { + (yyval) = (yyvsp[(1) - (3)]) >= (yyvsp[(3) - (3)]); + } + break; + + case 12: + + { + (yyval) = (yyvsp[(1) - (3)]) <= (yyvsp[(3) - (3)]); + } + break; + + case 13: + + { + (yyval) = (yyvsp[(1) - (3)]) > (yyvsp[(3) - (3)]); + } + break; + + case 14: + + { + (yyval) = (yyvsp[(1) - (3)]) < (yyvsp[(3) - (3)]); + } + break; + + case 15: + + { + (yyval) = (yyvsp[(1) - (3)]) >> (yyvsp[(3) - (3)]); + } + break; + + case 16: + + { + (yyval) = (yyvsp[(1) - (3)]) << (yyvsp[(3) - (3)]); + } + break; + + case 17: + + { + (yyval) = (yyvsp[(1) - (3)]) - (yyvsp[(3) - (3)]); + } + break; + + case 18: + + { + (yyval) = (yyvsp[(1) - (3)]) + (yyvsp[(3) - (3)]); + } + break; + + case 19: + + { + if ((yyvsp[(3) - (3)]) == 0) { + std::ostringstream stream; + stream << (yyvsp[(1) - (3)]) << " % " << (yyvsp[(3) - (3)]); + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + YYABORT; + } else { + (yyval) = (yyvsp[(1) - (3)]) % (yyvsp[(3) - (3)]); + } + } + break; + + case 20: + + { + if ((yyvsp[(3) - (3)]) == 0) { + std::ostringstream stream; + stream << (yyvsp[(1) - (3)]) << " / " << (yyvsp[(3) - (3)]); + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + YYABORT; + } else { + (yyval) = (yyvsp[(1) - (3)]) / (yyvsp[(3) - (3)]); + } + } + break; + + case 21: + + { + (yyval) = (yyvsp[(1) - (3)]) * (yyvsp[(3) - (3)]); + } + break; + + case 22: + + { + (yyval) = ! (yyvsp[(2) - (2)]); + } + break; + + case 23: + + { + (yyval) = ~ (yyvsp[(2) - (2)]); + } + break; + + case 24: + + { + (yyval) = - (yyvsp[(2) - (2)]); + } + break; + + case 25: + + { + (yyval) = + (yyvsp[(2) - (2)]); + } + break; + + case 26: + + { + (yyval) = (yyvsp[(2) - (3)]); + } + break; + + + + default: break; + } + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now `shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*------------------------------------. +| yyerrlab -- here on detecting error | +`------------------------------------*/ +yyerrlab: + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (context, YY_("syntax error")); +#else + { + YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); + if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) + { + YYSIZE_T yyalloc = 2 * yysize; + if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) + yyalloc = YYSTACK_ALLOC_MAXIMUM; + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yyalloc); + if (yymsg) + yymsg_alloc = yyalloc; + else + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + } + } + + if (0 < yysize && yysize <= yymsg_alloc) + { + (void) yysyntax_error (yymsg, yystate, yychar); + yyerror (context, yymsg); + } + else + { + yyerror (context, YY_("syntax error")); + if (yysize != 0) + goto yyexhaustedlab; + } + } +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval, context); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule which action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (yyn != YYPACT_NINF) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp, context); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + *++yyvsp = yylval; + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined(yyoverflow) || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (context, YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval, context); + /* Do not reclaim the symbols of the rule which action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp, context); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + /* Make sure YYID is used. */ + return YYID (yyresult); +} + + + + + +int yylex(YYSTYPE* lvalp, Context* context) +{ + int type = 0; + + pp::Token* token = context->token; + switch (token->type) + { + case pp::Token::CONST_INT: + { + unsigned int val = 0; + if (!token->uValue(&val)) + { + context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW, + token->location, token->text); + } + *lvalp = static_cast<YYSTYPE>(val); + type = TOK_CONST_INT; + break; + } + case pp::Token::OP_OR: type = TOK_OP_OR; break; + case pp::Token::OP_AND: type = TOK_OP_AND; break; + case pp::Token::OP_NE: type = TOK_OP_NE; break; + case pp::Token::OP_EQ: type = TOK_OP_EQ; break; + case pp::Token::OP_GE: type = TOK_OP_GE; break; + case pp::Token::OP_LE: type = TOK_OP_LE; break; + case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break; + case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break; + case '|': type = '|'; break; + case '^': type = '^'; break; + case '&': type = '&'; break; + case '>': type = '>'; break; + case '<': type = '<'; break; + case '-': type = '-'; break; + case '+': type = '+'; break; + case '%': type = '%'; break; + case '/': type = '/'; break; + case '*': type = '*'; break; + case '!': type = '!'; break; + case '~': type = '~'; break; + case '(': type = '('; break; + case ')': type = ')'; break; + + default: break; + } + + // Advance to the next token if the current one is valid. + if (type != 0) context->lexer->lex(token); + + return type; +} + +void yyerror(Context* context, const char* reason) +{ + context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION, + context->token->location, + reason); +} + +namespace pp { + +ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) : + mLexer(lexer), + mDiagnostics(diagnostics) +{ +} + +bool ExpressionParser::parse(Token* token, int* result) +{ + Context context; + context.diagnostics = mDiagnostics; + context.lexer = mLexer; + context.token = token; + context.result = result; + int ret = yyparse(&context); + switch (ret) + { + case 0: + case 1: + break; + + case 2: + mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, ""); + break; + + default: + assert(false); + mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, ""); + break; + } + + return ret == 0; +} + +} // namespace pp +
diff --git a/src/GLES2/compiler/preprocessor/ExpressionParser.y b/src/GLES2/compiler/preprocessor/ExpressionParser.y index 2104d77..832ad40 100644 --- a/src/GLES2/compiler/preprocessor/ExpressionParser.y +++ b/src/GLES2/compiler/preprocessor/ExpressionParser.y
@@ -1,279 +1,279 @@ -/* -// -// Copyright (c) 2012 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. -// - -This file contains the Yacc grammar for GLSL ES preprocessor expression. - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, -WHICH GENERATES THE GLSL ES preprocessor expression parser. -*/ - -%{ -// -// Copyright (c) 2012 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. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! - -#if defined(__GNUC__) -// Triggered by the auto-generated pplval variable. -#pragma GCC diagnostic ignored "-Wuninitialized" -#elif defined(_MSC_VER) -#pragma warning(disable: 4065 4701) -#endif - -#include "ExpressionParser.h" - -#include <cassert> -#include <sstream> - -#include "Diagnostics.h" -#include "Lexer.h" -#include "Token.h" - -#if defined(_MSC_VER) -typedef __int64 YYSTYPE; -#else -#include <stdint.h> -typedef intmax_t YYSTYPE; -#endif // _MSC_VER -#define YYSTYPE_IS_TRIVIAL 1 -#define YYSTYPE_IS_DECLARED 1 - -namespace { -struct Context -{ - pp::Diagnostics* diagnostics; - pp::Lexer* lexer; - pp::Token* token; - int* result; -}; -} // namespace -%} - -%pure-parser -%name-prefix="pp" -%parse-param {Context *context} -%lex-param {Context *context} - -%{ -static int yylex(YYSTYPE* lvalp, Context* context); -static void yyerror(Context* context, const char* reason); -%} - -%token TOK_CONST_INT -%left TOK_OP_OR -%left TOK_OP_AND -%left '|' -%left '^' -%left '&' -%left TOK_OP_EQ TOK_OP_NE -%left '<' '>' TOK_OP_LE TOK_OP_GE -%left TOK_OP_LEFT TOK_OP_RIGHT -%left '+' '-' -%left '*' '/' '%' -%right TOK_UNARY - -%% - -input - : expression { - *(context->result) = static_cast<int>($1); - YYACCEPT; - } -; - -expression - : TOK_CONST_INT - | expression TOK_OP_OR expression { - $$ = $1 || $3; - } - | expression TOK_OP_AND expression { - $$ = $1 && $3; - } - | expression '|' expression { - $$ = $1 | $3; - } - | expression '^' expression { - $$ = $1 ^ $3; - } - | expression '&' expression { - $$ = $1 & $3; - } - | expression TOK_OP_NE expression { - $$ = $1 != $3; - } - | expression TOK_OP_EQ expression { - $$ = $1 == $3; - } - | expression TOK_OP_GE expression { - $$ = $1 >= $3; - } - | expression TOK_OP_LE expression { - $$ = $1 <= $3; - } - | expression '>' expression { - $$ = $1 > $3; - } - | expression '<' expression { - $$ = $1 < $3; - } - | expression TOK_OP_RIGHT expression { - $$ = $1 >> $3; - } - | expression TOK_OP_LEFT expression { - $$ = $1 << $3; - } - | expression '-' expression { - $$ = $1 - $3; - } - | expression '+' expression { - $$ = $1 + $3; - } - | expression '%' expression { - if ($3 == 0) { - std::ostringstream stream; - stream << $1 << " % " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { - $$ = $1 % $3; - } - } - | expression '/' expression { - if ($3 == 0) { - std::ostringstream stream; - stream << $1 << " / " << $3; - std::string text = stream.str(); - context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, - context->token->location, - text.c_str()); - YYABORT; - } else { - $$ = $1 / $3; - } - } - | expression '*' expression { - $$ = $1 * $3; - } - | '!' expression %prec TOK_UNARY { - $$ = ! $2; - } - | '~' expression %prec TOK_UNARY { - $$ = ~ $2; - } - | '-' expression %prec TOK_UNARY { - $$ = - $2; - } - | '+' expression %prec TOK_UNARY { - $$ = + $2; - } - | '(' expression ')' { - $$ = $2; - } -; - -%% - -int yylex(YYSTYPE* lvalp, Context* context) -{ - int type = 0; - - pp::Token* token = context->token; - switch (token->type) - { - case pp::Token::CONST_INT: - { - unsigned int val = 0; - if (!token->uValue(&val)) - { - context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW, - token->location, token->text); - } - *lvalp = static_cast<YYSTYPE>(val); - type = TOK_CONST_INT; - break; - } - case pp::Token::OP_OR: type = TOK_OP_OR; break; - case pp::Token::OP_AND: type = TOK_OP_AND; break; - case pp::Token::OP_NE: type = TOK_OP_NE; break; - case pp::Token::OP_EQ: type = TOK_OP_EQ; break; - case pp::Token::OP_GE: type = TOK_OP_GE; break; - case pp::Token::OP_LE: type = TOK_OP_LE; break; - case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break; - case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break; - case '|': type = '|'; break; - case '^': type = '^'; break; - case '&': type = '&'; break; - case '>': type = '>'; break; - case '<': type = '<'; break; - case '-': type = '-'; break; - case '+': type = '+'; break; - case '%': type = '%'; break; - case '/': type = '/'; break; - case '*': type = '*'; break; - case '!': type = '!'; break; - case '~': type = '~'; break; - case '(': type = '('; break; - case ')': type = ')'; break; - - default: break; - } - - // Advance to the next token if the current one is valid. - if (type != 0) context->lexer->lex(token); - - return type; -} - -void yyerror(Context* context, const char* reason) -{ - context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION, - context->token->location, - reason); -} - -namespace pp { - -ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) : - mLexer(lexer), - mDiagnostics(diagnostics) -{ -} - -bool ExpressionParser::parse(Token* token, int* result) -{ - Context context; - context.diagnostics = mDiagnostics; - context.lexer = mLexer; - context.token = token; - context.result = result; - int ret = yyparse(&context); - switch (ret) - { - case 0: - case 1: - break; - - case 2: - mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, ""); - break; - - default: - assert(false); - mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, ""); - break; - } - - return ret == 0; -} - -} // namespace pp +/* +// +// Copyright (c) 2012 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. +// + +This file contains the Yacc grammar for GLSL ES preprocessor expression. + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh, +WHICH GENERATES THE GLSL ES preprocessor expression parser. +*/ + +%{ +// +// Copyright (c) 2012 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. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + +#if defined(__GNUC__) +// Triggered by the auto-generated pplval variable. +#pragma GCC diagnostic ignored "-Wuninitialized" +#elif defined(_MSC_VER) +#pragma warning(disable: 4065 4701) +#endif + +#include "ExpressionParser.h" + +#include <cassert> +#include <sstream> + +#include "Diagnostics.h" +#include "Lexer.h" +#include "Token.h" + +#if defined(_MSC_VER) +typedef __int64 YYSTYPE; +#else +#include <stdint.h> +typedef intmax_t YYSTYPE; +#endif // _MSC_VER +#define YYSTYPE_IS_TRIVIAL 1 +#define YYSTYPE_IS_DECLARED 1 + +namespace { +struct Context +{ + pp::Diagnostics* diagnostics; + pp::Lexer* lexer; + pp::Token* token; + int* result; +}; +} // namespace +%} + +%pure-parser +%name-prefix="pp" +%parse-param {Context *context} +%lex-param {Context *context} + +%{ +static int yylex(YYSTYPE* lvalp, Context* context); +static void yyerror(Context* context, const char* reason); +%} + +%token TOK_CONST_INT +%left TOK_OP_OR +%left TOK_OP_AND +%left '|' +%left '^' +%left '&' +%left TOK_OP_EQ TOK_OP_NE +%left '<' '>' TOK_OP_LE TOK_OP_GE +%left TOK_OP_LEFT TOK_OP_RIGHT +%left '+' '-' +%left '*' '/' '%' +%right TOK_UNARY + +%% + +input + : expression { + *(context->result) = static_cast<int>($1); + YYACCEPT; + } +; + +expression + : TOK_CONST_INT + | expression TOK_OP_OR expression { + $$ = $1 || $3; + } + | expression TOK_OP_AND expression { + $$ = $1 && $3; + } + | expression '|' expression { + $$ = $1 | $3; + } + | expression '^' expression { + $$ = $1 ^ $3; + } + | expression '&' expression { + $$ = $1 & $3; + } + | expression TOK_OP_NE expression { + $$ = $1 != $3; + } + | expression TOK_OP_EQ expression { + $$ = $1 == $3; + } + | expression TOK_OP_GE expression { + $$ = $1 >= $3; + } + | expression TOK_OP_LE expression { + $$ = $1 <= $3; + } + | expression '>' expression { + $$ = $1 > $3; + } + | expression '<' expression { + $$ = $1 < $3; + } + | expression TOK_OP_RIGHT expression { + $$ = $1 >> $3; + } + | expression TOK_OP_LEFT expression { + $$ = $1 << $3; + } + | expression '-' expression { + $$ = $1 - $3; + } + | expression '+' expression { + $$ = $1 + $3; + } + | expression '%' expression { + if ($3 == 0) { + std::ostringstream stream; + stream << $1 << " % " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + YYABORT; + } else { + $$ = $1 % $3; + } + } + | expression '/' expression { + if ($3 == 0) { + std::ostringstream stream; + stream << $1 << " / " << $3; + std::string text = stream.str(); + context->diagnostics->report(pp::Diagnostics::DIVISION_BY_ZERO, + context->token->location, + text.c_str()); + YYABORT; + } else { + $$ = $1 / $3; + } + } + | expression '*' expression { + $$ = $1 * $3; + } + | '!' expression %prec TOK_UNARY { + $$ = ! $2; + } + | '~' expression %prec TOK_UNARY { + $$ = ~ $2; + } + | '-' expression %prec TOK_UNARY { + $$ = - $2; + } + | '+' expression %prec TOK_UNARY { + $$ = + $2; + } + | '(' expression ')' { + $$ = $2; + } +; + +%% + +int yylex(YYSTYPE* lvalp, Context* context) +{ + int type = 0; + + pp::Token* token = context->token; + switch (token->type) + { + case pp::Token::CONST_INT: + { + unsigned int val = 0; + if (!token->uValue(&val)) + { + context->diagnostics->report(pp::Diagnostics::INTEGER_OVERFLOW, + token->location, token->text); + } + *lvalp = static_cast<YYSTYPE>(val); + type = TOK_CONST_INT; + break; + } + case pp::Token::OP_OR: type = TOK_OP_OR; break; + case pp::Token::OP_AND: type = TOK_OP_AND; break; + case pp::Token::OP_NE: type = TOK_OP_NE; break; + case pp::Token::OP_EQ: type = TOK_OP_EQ; break; + case pp::Token::OP_GE: type = TOK_OP_GE; break; + case pp::Token::OP_LE: type = TOK_OP_LE; break; + case pp::Token::OP_RIGHT: type = TOK_OP_RIGHT; break; + case pp::Token::OP_LEFT: type = TOK_OP_LEFT; break; + case '|': type = '|'; break; + case '^': type = '^'; break; + case '&': type = '&'; break; + case '>': type = '>'; break; + case '<': type = '<'; break; + case '-': type = '-'; break; + case '+': type = '+'; break; + case '%': type = '%'; break; + case '/': type = '/'; break; + case '*': type = '*'; break; + case '!': type = '!'; break; + case '~': type = '~'; break; + case '(': type = '('; break; + case ')': type = ')'; break; + + default: break; + } + + // Advance to the next token if the current one is valid. + if (type != 0) context->lexer->lex(token); + + return type; +} + +void yyerror(Context* context, const char* reason) +{ + context->diagnostics->report(pp::Diagnostics::INVALID_EXPRESSION, + context->token->location, + reason); +} + +namespace pp { + +ExpressionParser::ExpressionParser(Lexer* lexer, Diagnostics* diagnostics) : + mLexer(lexer), + mDiagnostics(diagnostics) +{ +} + +bool ExpressionParser::parse(Token* token, int* result) +{ + Context context; + context.diagnostics = mDiagnostics; + context.lexer = mLexer; + context.token = token; + context.result = result; + int ret = yyparse(&context); + switch (ret) + { + case 0: + case 1: + break; + + case 2: + mDiagnostics->report(Diagnostics::OUT_OF_MEMORY, token->location, ""); + break; + + default: + assert(false); + mDiagnostics->report(Diagnostics::INTERNAL_ERROR, token->location, ""); + break; + } + + return ret == 0; +} + +} // namespace pp
diff --git a/src/GLES2/compiler/preprocessor/Tokenizer.cpp b/src/GLES2/compiler/preprocessor/Tokenizer.cpp index aecc06c..4f74201 100644 --- a/src/GLES2/compiler/preprocessor/Tokenizer.cpp +++ b/src/GLES2/compiler/preprocessor/Tokenizer.cpp
@@ -1,2370 +1,2365 @@ -#line 16 "./Tokenizer.l" -// -// 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. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! - - - -#line 13 "./Tokenizer.cpp" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 35 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L - -/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, - * if you want the limit (max/min) macros for int types. - */ -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS 1 -#endif - -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! C99 */ - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -/* C99 requires __STDC__ to be defined as 1. */ -#if defined (__STDC__) - -#define YY_USE_CONST - -#endif /* defined (__STDC__) */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* An opaque pointer. */ -#ifndef YY_TYPEDEF_YY_SCANNER_T -#define YY_TYPEDEF_YY_SCANNER_T -typedef void* yyscan_t; -#endif - -/* For convenience, these vars (plus the bison vars far below) - are macros in the reentrant scanner. */ -#define yyin yyg->yyin_r -#define yyout yyg->yyout_r -#define yyextra yyg->yyextra_r -#define yyleng yyg->yyleng_r -#define yytext yyg->yytext_r -#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) -#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) -#define yy_flex_debug yyg->yy_flex_debug_r - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN yyg->yy_start = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START ((yyg->yy_start - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE pprestart(yyin ,yyscanner ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else -#define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ -#endif - -/* The state buf must be large enough to hold one state per character in the main buffer. - */ -#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = yyg->yy_hold_char; \ - YY_RESTORE_YY_MORE_OFFSET \ - yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef size_t yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via pprestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ - ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] - -void pprestart (FILE *input_file ,yyscan_t yyscanner ); -void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -YY_BUFFER_STATE pp_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); -void pp_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void pp_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); -void pppush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); -void pppop_buffer_state (yyscan_t yyscanner ); - -static void ppensure_buffer_stack (yyscan_t yyscanner ); -static void pp_load_buffer_state (yyscan_t yyscanner ); -static void pp_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); - -#define YY_FLUSH_BUFFER pp_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) - -YY_BUFFER_STATE pp_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); -YY_BUFFER_STATE pp_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); -YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); - -void *ppalloc (yy_size_t ,yyscan_t yyscanner ); -void *pprealloc (void *,yy_size_t ,yyscan_t yyscanner ); -void ppfree (void * ,yyscan_t yyscanner ); - -#define yy_new_buffer pp_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - ppensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - ppensure_buffer_stack (yyscanner); \ - YY_CURRENT_BUFFER_LVALUE = \ - pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define ppwrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -typedef int yy_state_type; - -#define yytext_ptr yytext_r - -static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); -static int yy_get_next_buffer (yyscan_t yyscanner ); -static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - yyg->yytext_ptr = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - yyg->yy_hold_char = *yy_cp; \ - *yy_cp = '\0'; \ - yyg->yy_c_buf_p = yy_cp; - -#define YY_NUM_RULES 37 -#define YY_END_OF_BUFFER 38 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[84] = - { 0, - 0, 0, 0, 0, 38, 36, 34, 35, 35, 33, - 7, 33, 33, 33, 33, 33, 33, 33, 33, 9, - 9, 33, 33, 33, 8, 33, 33, 3, 5, 5, - 4, 34, 35, 19, 27, 20, 30, 25, 12, 23, - 13, 24, 10, 2, 1, 26, 10, 9, 11, 11, - 11, 11, 9, 14, 16, 18, 17, 15, 8, 31, - 21, 32, 22, 3, 5, 6, 11, 10, 11, 1, - 10, 11, 0, 10, 9, 28, 29, 0, 10, 10, - 10, 10, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, - 9, 10, 11, 9, 12, 13, 14, 15, 16, 16, - 16, 16, 16, 16, 16, 17, 17, 9, 9, 18, - 19, 20, 9, 1, 21, 21, 21, 21, 22, 21, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, - 9, 1, 9, 25, 23, 1, 21, 21, 21, 21, - - 22, 21, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, - 23, 23, 9, 26, 9, 9, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[27] = - { 0, - 1, 1, 2, 2, 1, 1, 1, 1, 1, 3, - 1, 1, 4, 1, 5, 5, 5, 1, 1, 1, - 5, 5, 5, 5, 1, 1 - } ; - -static yyconst flex_int16_t yy_base[89] = - { 0, - 0, 0, 24, 26, 158, 159, 150, 159, 145, 128, - 159, 112, 23, 159, 111, 21, 25, 30, 29, 36, - 46, 36, 100, 45, 0, 16, 47, 0, 159, 84, - 65, 73, 159, 159, 159, 159, 159, 159, 159, 159, - 159, 159, 61, 159, 0, 159, 73, 32, 56, 83, - 95, 68, 0, 31, 159, 159, 159, 19, 0, 159, - 159, 159, 159, 0, 159, 159, 98, 0, 110, 0, - 0, 117, 52, 90, 80, 159, 159, 101, 97, 112, - 120, 123, 159, 140, 28, 145, 150, 152 - } ; - -static yyconst flex_int16_t yy_def[89] = - { 0, - 83, 1, 84, 84, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 20, 83, 83, 83, 85, 83, 83, 86, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 87, 83, 83, 20, 20, 47, - 50, 88, 21, 83, 83, 83, 83, 83, 85, 83, - 83, 83, 83, 86, 83, 83, 43, 43, 67, 87, - 47, 50, 83, 51, 88, 83, 83, 83, 69, 72, - 83, 83, 0, 83, 83, 83, 83, 83 - } ; - -static yyconst flex_int16_t yy_nxt[186] = - { 0, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, - 25, 25, 25, 25, 26, 27, 29, 30, 29, 30, - 36, 39, 59, 31, 60, 31, 41, 77, 44, 40, - 61, 37, 45, 42, 43, 43, 43, 46, 47, 76, - 48, 48, 49, 54, 55, 50, 50, 51, 50, 52, - 53, 53, 53, 57, 58, 62, 81, 81, 81, 50, - 49, 49, 63, 67, 32, 68, 68, 68, 66, 50, - 50, 67, 69, 67, 67, 50, 65, 71, 71, 71, - 50, 50, 50, 50, 72, 50, 50, 50, 50, 50, - - 83, 83, 50, 50, 50, 73, 73, 83, 83, 74, - 74, 74, 67, 67, 67, 82, 82, 82, 56, 67, - 78, 78, 83, 83, 79, 79, 79, 78, 78, 38, - 35, 80, 80, 80, 81, 81, 81, 82, 82, 82, - 28, 28, 28, 28, 28, 64, 34, 33, 64, 64, - 70, 32, 70, 70, 70, 75, 75, 83, 5, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83 - } ; - -static yyconst flex_int16_t yy_chk[186] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 3, 3, 4, 4, - 13, 16, 85, 3, 26, 4, 17, 58, 19, 16, - 26, 13, 19, 17, 18, 18, 18, 19, 20, 54, - 20, 20, 20, 22, 22, 48, 20, 20, 20, 20, - 21, 21, 21, 24, 24, 27, 73, 73, 73, 21, - 49, 49, 27, 43, 32, 43, 43, 43, 31, 49, - 52, 43, 43, 43, 43, 47, 30, 47, 47, 47, - 52, 52, 75, 47, 47, 47, 47, 50, 50, 50, - - 74, 74, 75, 75, 50, 51, 51, 79, 79, 51, - 51, 51, 67, 67, 67, 78, 78, 78, 23, 67, - 69, 69, 80, 80, 69, 69, 69, 72, 72, 15, - 12, 72, 72, 72, 81, 81, 81, 82, 82, 82, - 84, 84, 84, 84, 84, 86, 10, 9, 86, 86, - 87, 7, 87, 87, 87, 88, 88, 5, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83, 83, 83, 83, 83, 83, - 83, 83, 83, 83, 83 - } ; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -/* -// -// Copyright (c) 2002-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. -// - -This file contains the Lex specification for GLSL ES preprocessor. -Based on Microsoft Visual Studio 2010 Preprocessor Grammar: -http://msdn.microsoft.com/en-us/library/2scxys89.aspx - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. -*/ - -#include "Tokenizer.h" - -#include "Diagnostics.h" -#include "Token.h" - -#if defined(__GNUC__) -// Triggered by the auto-generated yy_fatal_error function. -#pragma GCC diagnostic ignored "-Wmissing-noreturn" -#endif - -typedef std::string YYSTYPE; -typedef pp::SourceLocation YYLTYPE; - -// Use the unused yycolumn variable to track file (string) number. -#define yyfileno yycolumn - -#define YY_USER_INIT \ - do { \ - yyfileno = 0; \ - yylineno = 1; \ - yyextra->leadingSpace = false; \ - yyextra->lineStart = true; \ - } while(0); - -#define YY_USER_ACTION \ - do \ - { \ - pp::Input* input = &yyextra->input; \ - pp::Input::Location* scanLoc = &yyextra->scanLoc; \ - while ((scanLoc->sIndex < input->count()) && \ - (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \ - { \ - scanLoc->cIndex -= input->length(scanLoc->sIndex++); \ - ++yyfileno; yylineno = 1; \ - } \ - yylloc->file = yyfileno; \ - yylloc->line = yylineno; \ - scanLoc->cIndex += yyleng; \ - } while(0); - -#define YY_INPUT(buf, result, maxSize) \ - result = yyextra->input.read(buf, maxSize); - -#define INITIAL 0 -#define COMMENT 1 - -#define YY_EXTRA_TYPE pp::Tokenizer::Context* - -/* Holds the entire state of the reentrant scanner. */ -struct yyguts_t - { - - /* User-defined. Not touched by flex. */ - YY_EXTRA_TYPE yyextra_r; - - /* The rest are the same as the globals declared in the non-reentrant scanner. */ - FILE *yyin_r, *yyout_r; - size_t yy_buffer_stack_top; /**< index of top of stack. */ - size_t yy_buffer_stack_max; /**< capacity of stack. */ - YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ - char yy_hold_char; - int yy_n_chars; - int yyleng_r; - char *yy_c_buf_p; - int yy_init; - int yy_start; - int yy_did_buffer_switch_on_eof; - int yy_start_stack_ptr; - int yy_start_stack_depth; - int *yy_start_stack; - yy_state_type yy_last_accepting_state; - char* yy_last_accepting_cpos; - - int yylineno_r; - int yy_flex_debug_r; - - char *yytext_r; - int yy_more_flag; - int yy_more_len; - - YYSTYPE * yylval_r; - - YYLTYPE * yylloc_r; - - }; /* end struct yyguts_t */ - -static int yy_init_globals (yyscan_t yyscanner ); - - /* This must go here because YYSTYPE and YYLTYPE are included - * from bison output in section 1.*/ - # define yylval yyg->yylval_r - - # define yylloc yyg->yylloc_r - -int pplex_init (yyscan_t* scanner); - -int pplex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); - -/* Accessor methods to globals. - These are made visible to non-reentrant scanners for convenience. */ - -int pplex_destroy (yyscan_t yyscanner ); - -int ppget_debug (yyscan_t yyscanner ); - -void ppset_debug (int debug_flag ,yyscan_t yyscanner ); - -YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner ); - -void ppset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); - -FILE *ppget_in (yyscan_t yyscanner ); - -void ppset_in (FILE * in_str ,yyscan_t yyscanner ); - -FILE *ppget_out (yyscan_t yyscanner ); - -void ppset_out (FILE * out_str ,yyscan_t yyscanner ); - -int ppget_leng (yyscan_t yyscanner ); - -char *ppget_text (yyscan_t yyscanner ); - -int ppget_lineno (yyscan_t yyscanner ); - -void ppset_lineno (int line_number ,yyscan_t yyscanner ); - -YYSTYPE * ppget_lval (yyscan_t yyscanner ); - -void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); - - YYLTYPE *ppget_lloc (yyscan_t yyscanner ); - - void ppset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int ppwrap (yyscan_t yyscanner ); -#else -extern int ppwrap (yyscan_t yyscanner ); -#endif -#endif - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (yyscan_t yyscanner ); -#else -static int input (yyscan_t yyscanner ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else -#define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int pplex \ - (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); - -#define YY_DECL int pplex \ - (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Line comment */ - - yylval = yylval_param; - - yylloc = yylloc_param; - - if ( !yyg->yy_init ) - { - yyg->yy_init = 1; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! yyg->yy_start ) - yyg->yy_start = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - ppensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - pp_load_buffer_state(yyscanner ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = yyg->yy_c_buf_p; - - /* Support of yytext. */ - *yy_cp = yyg->yy_hold_char; - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = yyg->yy_start; -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 84 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_current_state != 83 ); - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = yyg->yy_hold_char; - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - -case 1: -YY_RULE_SETUP - - YY_BREAK -/* Block comment */ -/* Line breaks are just counted - not returned. */ -/* The comment is replaced by a single space. */ -case 2: -YY_RULE_SETUP -{ BEGIN(COMMENT); } - YY_BREAK -case 3: -YY_RULE_SETUP - - YY_BREAK -case 4: -YY_RULE_SETUP - - YY_BREAK -case 5: -/* rule 5 can match eol */ -YY_RULE_SETUP -{ ++yylineno; } - YY_BREAK -case 6: -YY_RULE_SETUP -{ - yyextra->leadingSpace = true; - BEGIN(INITIAL); -} - YY_BREAK -case 7: -YY_RULE_SETUP -{ - // # is only valid at start of line for preprocessor directives. - yylval->assign(1, yytext[0]); - return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER; -} - YY_BREAK -case 8: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::IDENTIFIER; -} - YY_BREAK -case 9: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::CONST_INT; -} - YY_BREAK -case 10: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::CONST_FLOAT; -} - YY_BREAK -/* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */ -/* Rule to catch all invalid integers and floats. */ -case 11: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::PP_NUMBER; -} - YY_BREAK -case 12: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_INC; -} - YY_BREAK -case 13: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_DEC; -} - YY_BREAK -case 14: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_LEFT; -} - YY_BREAK -case 15: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_RIGHT; -} - YY_BREAK -case 16: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_LE; -} - YY_BREAK -case 17: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_GE; -} - YY_BREAK -case 18: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_EQ; -} - YY_BREAK -case 19: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_NE; -} - YY_BREAK -case 20: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_AND; -} - YY_BREAK -case 21: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_XOR; -} - YY_BREAK -case 22: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_OR; -} - YY_BREAK -case 23: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_ADD_ASSIGN; -} - YY_BREAK -case 24: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_SUB_ASSIGN; -} - YY_BREAK -case 25: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_MUL_ASSIGN; -} - YY_BREAK -case 26: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_DIV_ASSIGN; -} - YY_BREAK -case 27: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_MOD_ASSIGN; -} - YY_BREAK -case 28: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_LEFT_ASSIGN; -} - YY_BREAK -case 29: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_RIGHT_ASSIGN; -} - YY_BREAK -case 30: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_AND_ASSIGN; -} - YY_BREAK -case 31: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_XOR_ASSIGN; -} - YY_BREAK -case 32: -YY_RULE_SETUP -{ - yylval->assign(yytext, yyleng); - return pp::Token::OP_OR_ASSIGN; -} - YY_BREAK -case 33: -YY_RULE_SETUP -{ - yylval->assign(1, yytext[0]); - return yytext[0]; -} - YY_BREAK -case 34: -YY_RULE_SETUP -{ yyextra->leadingSpace = true; } - YY_BREAK -case 35: -/* rule 35 can match eol */ -YY_RULE_SETUP -{ - ++yylineno; - yylval->assign(1, '\n'); - return '\n'; -} - YY_BREAK -case 36: -YY_RULE_SETUP -{ - yylval->assign(1, yytext[0]); - return pp::Token::PP_OTHER; -} - YY_BREAK -case YY_STATE_EOF(INITIAL): -case YY_STATE_EOF(COMMENT): -{ - // YY_USER_ACTION is not invoked for handling EOF. - // Set the location for EOF token manually. - pp::Input* input = &yyextra->input; - pp::Input::Location* scanLoc = &yyextra->scanLoc; - int sIndexMax = std::max(0, input->count() - 1); - if (scanLoc->sIndex != sIndexMax) - { - // We can only reach here if there are empty strings at the - // end of the input. - scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0; - yyfileno = sIndexMax; yylineno = 1; - } - yylloc->file = yyfileno; - yylloc->line = yylineno; - yylval->clear(); - - if (YY_START == COMMENT) - { - yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT, - pp::SourceLocation(yyfileno, yylineno), - ""); - } - yyterminate(); -} - YY_BREAK -case 37: -YY_RULE_SETUP -ECHO; - YY_BREAK - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = yyg->yy_hold_char; - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * pplex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); - - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++yyg->yy_c_buf_p; - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = yyg->yy_last_accepting_cpos; - yy_current_state = yyg->yy_last_accepting_state; - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_END_OF_FILE: - { - yyg->yy_did_buffer_switch_on_eof = 0; - - if ( ppwrap(yyscanner ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = - yyg->yytext_ptr + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - yyg->yy_c_buf_p = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; - - yy_current_state = yy_get_previous_state( yyscanner ); - - yy_cp = yyg->yy_c_buf_p; - yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of pplex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = yyg->yytext_ptr; - register int number_to_move, i; - int ret_val; - - if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; - - else - { - int num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) (yyg->yy_c_buf_p - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - pprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - yyg->yy_n_chars, (size_t) num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - if ( yyg->yy_n_chars == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - pprestart(yyin ,yyscanner); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { - /* Extend the array by 50%, plus the number we really need. */ - yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); - if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); - } - - yyg->yy_n_chars += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; - - yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (yyscan_t yyscanner) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - yy_current_state = yyg->yy_start; - - for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 84 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) -{ - register int yy_is_jam; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ - register char *yy_cp = yyg->yy_c_buf_p; - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - yyg->yy_last_accepting_state = yy_current_state; - yyg->yy_last_accepting_cpos = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 84 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 83); - - return yy_is_jam ? 0 : yy_current_state; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (yyscan_t yyscanner) -#else - static int input (yyscan_t yyscanner) -#endif - -{ - int c; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - *yyg->yy_c_buf_p = yyg->yy_hold_char; - - if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) - /* This was really a NUL. */ - *yyg->yy_c_buf_p = '\0'; - - else - { /* need more input */ - int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; - ++yyg->yy_c_buf_p; - - switch ( yy_get_next_buffer( yyscanner ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - pprestart(yyin ,yyscanner); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( ppwrap(yyscanner ) ) - return EOF; - - if ( ! yyg->yy_did_buffer_switch_on_eof ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(yyscanner); -#else - return input(yyscanner); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - yyg->yy_c_buf_p = yyg->yytext_ptr + offset; - break; - } - } - } - - c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ - *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ - yyg->yy_hold_char = *++yyg->yy_c_buf_p; - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * @param yyscanner The scanner object. - * @note This function does not reset the start condition to @c INITIAL . - */ - void pprestart (FILE * input_file , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! YY_CURRENT_BUFFER ){ - ppensure_buffer_stack (yyscanner); - YY_CURRENT_BUFFER_LVALUE = - pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); - } - - pp_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); - pp_load_buffer_state(yyscanner ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * @param yyscanner The scanner object. - */ - void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* TODO. We should be able to replace this entire function body - * with - * pppop_buffer_state(); - * pppush_buffer_state(new_buffer); - */ - ppensure_buffer_stack (yyscanner); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - pp_load_buffer_state(yyscanner ); - - /* We don't actually know whether we did this switch during - * EOF (ppwrap()) processing, but the only time this flag - * is looked at is after ppwrap() is called, so it's safe - * to go ahead and always set it. - */ - yyg->yy_did_buffer_switch_on_eof = 1; -} - -static void pp_load_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - yyg->yy_hold_char = *yyg->yy_c_buf_p; -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * @param yyscanner The scanner object. - * @return the allocated buffer state. - */ - YY_BUFFER_STATE pp_create_buffer (FILE * file, int size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) ppalloc(b->yy_buf_size + 2 ,yyscanner ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - pp_init_buffer(b,file ,yyscanner); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with pp_create_buffer() - * @param yyscanner The scanner object. - */ - void pp_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - ppfree((void *) b->yy_ch_buf ,yyscanner ); - - ppfree((void *) b ,yyscanner ); -} - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a pprestart() or at EOF. - */ - static void pp_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) - -{ - int oerrno = errno; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - pp_flush_buffer(b ,yyscanner); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then pp_init_buffer was _probably_ - * called from pprestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * @param yyscanner The scanner object. - */ - void pp_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - pp_load_buffer_state(yyscanner ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * @param yyscanner The scanner object. - */ -void pppush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (new_buffer == NULL) - return; - - ppensure_buffer_stack(yyscanner); - - /* This block is copied from pp_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *yyg->yy_c_buf_p = yyg->yy_hold_char; - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - yyg->yy_buffer_stack_top++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from pp_switch_to_buffer. */ - pp_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * @param yyscanner The scanner object. - */ -void pppop_buffer_state (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - if (!YY_CURRENT_BUFFER) - return; - - pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); - YY_CURRENT_BUFFER_LVALUE = NULL; - if (yyg->yy_buffer_stack_top > 0) - --yyg->yy_buffer_stack_top; - - if (YY_CURRENT_BUFFER) { - pp_load_buffer_state(yyscanner ); - yyg->yy_did_buffer_switch_on_eof = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void ppensure_buffer_stack (yyscan_t yyscanner) -{ - int num_to_alloc; - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (!yyg->yy_buffer_stack) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - yyg->yy_buffer_stack = (struct yy_buffer_state**)ppalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); - - memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - yyg->yy_buffer_stack_max = num_to_alloc; - yyg->yy_buffer_stack_top = 0; - return; - } - - if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = yyg->yy_buffer_stack_max + grow_size; - yyg->yy_buffer_stack = (struct yy_buffer_state**)pprealloc - (yyg->yy_buffer_stack, - num_to_alloc * sizeof(struct yy_buffer_state*) - , yyscanner); - if ( ! yyg->yy_buffer_stack ) - YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); - - /* zero only the new slots.*/ - memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); - yyg->yy_buffer_stack_max = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - pp_switch_to_buffer(b ,yyscanner ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to pplex() will - * scan from a @e copy of @a str. - * @param yystr a NUL-terminated string to scan - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * pp_scan_bytes() instead. - */ -YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner) -{ - - return pp_scan_bytes(yystr,strlen(yystr) ,yyscanner); -} - -/** Setup the input buffer state to scan the given bytes. The next call to pplex() will - * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. - * @param yyscanner The scanner object. - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = _yybytes_len + 2; - buf = (char *) ppalloc(n ,yyscanner ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" ); - - for ( i = 0; i < _yybytes_len; ++i ) - buf[i] = yybytes[i]; - - buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; - - b = pp_scan_buffer(buf,n ,yyscanner); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in pp_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = yyg->yy_hold_char; \ - yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ - yyg->yy_hold_char = *yyg->yy_c_buf_p; \ - *yyg->yy_c_buf_p = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the user-defined data for this scanner. - * @param yyscanner The scanner object. - */ -YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyextra; -} - -/** Get the current line number. - * @param yyscanner The scanner object. - */ -int ppget_lineno (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yylineno; -} - -/** Get the current column number. - * @param yyscanner The scanner object. - */ -int ppget_column (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - if (! YY_CURRENT_BUFFER) - return 0; - - return yycolumn; -} - -/** Get the input stream. - * @param yyscanner The scanner object. - */ -FILE *ppget_in (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyin; -} - -/** Get the output stream. - * @param yyscanner The scanner object. - */ -FILE *ppget_out (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyout; -} - -/** Get the length of the current token. - * @param yyscanner The scanner object. - */ -int ppget_leng (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yyleng; -} - -/** Get the current token. - * @param yyscanner The scanner object. - */ - -char *ppget_text (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yytext; -} - -/** Set the user-defined data. This data is never touched by the scanner. - * @param user_defined The data to be associated with this scanner. - * @param yyscanner The scanner object. - */ -void ppset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyextra = user_defined ; -} - -/** Set the current line number. - * @param line_number - * @param yyscanner The scanner object. - */ -void ppset_lineno (int line_number , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* lineno is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "ppset_lineno called with no buffer" , yyscanner); - - yylineno = line_number; -} - -/** Set the current column. - * @param line_number - * @param yyscanner The scanner object. - */ -void ppset_column (int column_no , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* column is only valid if an input buffer exists. */ - if (! YY_CURRENT_BUFFER ) - yy_fatal_error( "ppset_column called with no buffer" , yyscanner); - - yycolumn = column_no; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * @param yyscanner The scanner object. - * @see pp_switch_to_buffer - */ -void ppset_in (FILE * in_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyin = in_str ; -} - -void ppset_out (FILE * out_str , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yyout = out_str ; -} - -int ppget_debug (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yy_flex_debug; -} - -void ppset_debug (int bdebug , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yy_flex_debug = bdebug ; -} - -/* Accessor methods for yylval and yylloc */ - -YYSTYPE * ppget_lval (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylval; -} - -void ppset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylval = yylval_param; -} - -YYLTYPE *ppget_lloc (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - return yylloc; -} - -void ppset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - yylloc = yylloc_param; -} - -/* User-visible API */ - -/* pplex_init is special because it creates the scanner itself, so it is - * the ONLY reentrant function that doesn't take the scanner as the last argument. - * That's why we explicitly handle the declaration, instead of using our macros. - */ - -int pplex_init(yyscan_t* ptr_yy_globals) - -{ - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), NULL ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - return yy_init_globals ( *ptr_yy_globals ); -} - -/* pplex_init_extra has the same functionality as pplex_init, but follows the - * convention of taking the scanner as the last argument. Note however, that - * this is a *pointer* to a scanner, as it will be allocated by this call (and - * is the reason, too, why this function also must handle its own declaration). - * The user defined value in the first argument will be available to ppalloc in - * the yyextra field. - */ - -int pplex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) - -{ - struct yyguts_t dummy_yyguts; - - ppset_extra (yy_user_defined, &dummy_yyguts); - - if (ptr_yy_globals == NULL){ - errno = EINVAL; - return 1; - } - - *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); - - if (*ptr_yy_globals == NULL){ - errno = ENOMEM; - return 1; - } - - /* By setting to 0xAA, we expose bugs in - yy_init_globals. Leave at 0x00 for releases. */ - memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); - - ppset_extra (yy_user_defined, *ptr_yy_globals); - - return yy_init_globals ( *ptr_yy_globals ); -} - -static int yy_init_globals (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - /* Initialization is the same as for the non-reentrant scanner. - * This function is called from pplex_destroy(), so don't allocate here. - */ - - yyg->yy_buffer_stack = 0; - yyg->yy_buffer_stack_top = 0; - yyg->yy_buffer_stack_max = 0; - yyg->yy_c_buf_p = (char *) 0; - yyg->yy_init = 0; - yyg->yy_start = 0; - - yyg->yy_start_stack_ptr = 0; - yyg->yy_start_stack_depth = 0; - yyg->yy_start_stack = NULL; - -/* Defined in main.c */ -#ifdef YY_STDINIT - yyin = stdin; - yyout = stdout; -#else - yyin = (FILE *) 0; - yyout = (FILE *) 0; -#endif - - /* For future reference: Set errno on error, since we are called by - * pplex_init() - */ - return 0; -} - -/* pplex_destroy is for both reentrant and non-reentrant scanners. */ -int pplex_destroy (yyscan_t yyscanner) -{ - struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); - YY_CURRENT_BUFFER_LVALUE = NULL; - pppop_buffer_state(yyscanner); - } - - /* Destroy the stack itself. */ - ppfree(yyg->yy_buffer_stack ,yyscanner); - yyg->yy_buffer_stack = NULL; - - /* Destroy the start condition stack. */ - ppfree(yyg->yy_start_stack ,yyscanner ); - yyg->yy_start_stack = NULL; - - /* Reset the globals. This is important in a non-reentrant scanner so the next time - * pplex() is called, initialization will occur. */ - yy_init_globals( yyscanner); - - /* Destroy the main struct (reentrant only). */ - ppfree ( yyscanner , yyscanner ); - yyscanner = NULL; - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *ppalloc (yy_size_t size , yyscan_t yyscanner) -{ - return (void *) malloc( size ); -} - -void *pprealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void ppfree (void * ptr , yyscan_t yyscanner) -{ - free( (char *) ptr ); /* see pprealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -namespace pp { - -// TODO(alokp): Maximum token length should ideally be specified by -// the preprocessor client, i.e., the compiler. -const size_t Tokenizer::kMaxTokenLength = 256; - -Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0) -{ - mContext.diagnostics = diagnostics; -} - -Tokenizer::~Tokenizer() -{ - destroyScanner(); -} - -bool Tokenizer::init(int count, const char* const string[], const int length[]) -{ - if (count < 0) return false; - if ((count > 0) && (string == 0)) return false; - - mContext.input = Input(count, string, length); - return initScanner(); -} - -void Tokenizer::setFileNumber(int file) -{ - // We use column number as file number. - // See macro yyfileno. - ppset_column(file,mHandle); -} - -void Tokenizer::setLineNumber(int line) -{ - ppset_lineno(line,mHandle); -} - -void Tokenizer::lex(Token* token) -{ - token->type = pplex(&token->text,&token->location,mHandle); - if (token->text.size() > kMaxTokenLength) - { - mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG, - token->location, token->text); - token->text.erase(kMaxTokenLength); - } - - token->flags = 0; - - token->setAtStartOfLine(mContext.lineStart); - mContext.lineStart = token->type == '\n'; - - token->setHasLeadingSpace(mContext.leadingSpace); - mContext.leadingSpace = false; -} - -bool Tokenizer::initScanner() -{ - if ((mHandle == NULL) && pplex_init_extra(&mContext,&mHandle)) - return false; - - pprestart(0,mHandle); - return true; -} - -void Tokenizer::destroyScanner() -{ - if (mHandle == NULL) - return; - - pplex_destroy(mHandle); - mHandle = NULL; -} - -} // namespace pp - +#line 16 "./Tokenizer.l" +// +// Copyright (c) 2011-2013 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. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! + + + +#line 13 "./Tokenizer.cpp" + +#define YY_INT_ALIGNED short int + +/* A lexical scanner generated by flex */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 +#define YY_FLEX_SUBMINOR_VERSION 35 +#if YY_FLEX_SUBMINOR_VERSION > 0 +#define FLEX_BETA +#endif + +/* First, we deal with platform-specific or compiler-specific issues. */ + +/* begin standard C headers. */ +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdlib.h> + +/* end standard C headers. */ + +/* flex integer type definitions */ + +#ifndef FLEXINT_H +#define FLEXINT_H + +/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ + +#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + +/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, + * if you want the limit (max/min) macros for int types. + */ +#ifndef __STDC_LIMIT_MACROS +#define __STDC_LIMIT_MACROS 1 +#endif + +#include <inttypes.h> +typedef int8_t flex_int8_t; +typedef uint8_t flex_uint8_t; +typedef int16_t flex_int16_t; +typedef uint16_t flex_uint16_t; +typedef int32_t flex_int32_t; +typedef uint32_t flex_uint32_t; +#else +typedef signed char flex_int8_t; +typedef short int flex_int16_t; +typedef int flex_int32_t; +typedef unsigned char flex_uint8_t; +typedef unsigned short int flex_uint16_t; +typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ + +/* Limits of integral types. */ +#ifndef INT8_MIN +#define INT8_MIN (-128) +#endif +#ifndef INT16_MIN +#define INT16_MIN (-32767-1) +#endif +#ifndef INT32_MIN +#define INT32_MIN (-2147483647-1) +#endif +#ifndef INT8_MAX +#define INT8_MAX (127) +#endif +#ifndef INT16_MAX +#define INT16_MAX (32767) +#endif +#ifndef INT32_MAX +#define INT32_MAX (2147483647) +#endif +#ifndef UINT8_MAX +#define UINT8_MAX (255U) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (65535U) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (4294967295U) +#endif + +#endif /* ! FLEXINT_H */ + +#ifdef __cplusplus + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +/* C99 requires __STDC__ to be defined as 1. */ +#if defined (__STDC__) + +#define YY_USE_CONST + +#endif /* defined (__STDC__) */ +#endif /* ! __cplusplus */ + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* An opaque pointer. */ +#ifndef YY_TYPEDEF_YY_SCANNER_T +#define YY_TYPEDEF_YY_SCANNER_T +typedef void* yyscan_t; +#endif + +/* For convenience, these vars (plus the bison vars far below) + are macros in the reentrant scanner. */ +#define yyin yyg->yyin_r +#define yyout yyg->yyout_r +#define yyextra yyg->yyextra_r +#define yyleng yyg->yyleng_r +#define yytext yyg->yytext_r +#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno) +#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column) +#define yy_flex_debug yyg->yy_flex_debug_r + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yyg->yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yyg->yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE pprestart(yyin ,yyscanner ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#ifndef YY_BUF_SIZE +#define YY_BUF_SIZE 16384 +#endif + +/* The state buf must be large enough to hold one state per character in the main buffer. + */ +#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) + +#ifndef YY_TYPEDEF_YY_BUFFER_STATE +#define YY_TYPEDEF_YY_BUFFER_STATE +typedef struct yy_buffer_state *YY_BUFFER_STATE; +#endif + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + + #define YY_LESS_LINENO(n) + +/* Return all but the first "n" matched characters back to the input stream. */ +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + *yy_cp = yyg->yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner ) + +#ifndef YY_TYPEDEF_YY_SIZE_T +#define YY_TYPEDEF_YY_SIZE_T +typedef size_t yy_size_t; +#endif + +#ifndef YY_STRUCT_YY_BUFFER_STATE +#define YY_STRUCT_YY_BUFFER_STATE +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + int yy_bs_lineno; /**< The line count. */ + int yy_bs_column; /**< The column count. */ + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; + +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via pprestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + + }; +#endif /* !YY_STRUCT_YY_BUFFER_STATE */ + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + * + * Returns the top of the stack, or NULL. + */ +#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \ + ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \ + : NULL) + +/* Same as previous macro, but useful when we know that the buffer stack is not + * NULL or when we need an lvalue. For internal use only. + */ +#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] + +void pprestart (FILE *input_file ,yyscan_t yyscanner ); +void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_create_buffer (FILE *file,int size ,yyscan_t yyscanner ); +void pp_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void pp_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner ); +void pppush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner ); +void pppop_buffer_state (yyscan_t yyscanner ); + +static void ppensure_buffer_stack (yyscan_t yyscanner ); +static void pp_load_buffer_state (yyscan_t yyscanner ); +static void pp_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner ); + +#define YY_FLUSH_BUFFER pp_flush_buffer(YY_CURRENT_BUFFER ,yyscanner) + +YY_BUFFER_STATE pp_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_scan_string (yyconst char *yy_str ,yyscan_t yyscanner ); +YY_BUFFER_STATE pp_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner ); + +void *ppalloc (yy_size_t ,yyscan_t yyscanner ); +void *pprealloc (void *,yy_size_t ,yyscan_t yyscanner ); +void ppfree (void * ,yyscan_t yyscanner ); + +#define yy_new_buffer pp_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! YY_CURRENT_BUFFER ){ \ + ppensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! YY_CURRENT_BUFFER ){\ + ppensure_buffer_stack (yyscanner); \ + YY_CURRENT_BUFFER_LVALUE = \ + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \ + } \ + YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) + +/* Begin user sect3 */ + +#define ppwrap(n) 1 +#define YY_SKIP_YYWRAP + +typedef unsigned char YY_CHAR; + +typedef int yy_state_type; + +#define yytext_ptr yytext_r + +static yy_state_type yy_get_previous_state (yyscan_t yyscanner ); +static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner); +static int yy_get_next_buffer (yyscan_t yyscanner ); +static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yyg->yytext_ptr = yy_bp; \ + yyleng = (size_t) (yy_cp - yy_bp); \ + yyg->yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yyg->yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 38 +#define YY_END_OF_BUFFER 39 +/* This struct is not used in this scanner, + but its presence is necessary. */ +struct yy_trans_info + { + flex_int32_t yy_verify; + flex_int32_t yy_nxt; + }; +static yyconst flex_int16_t yy_accept[87] = + { 0, + 0, 0, 0, 0, 39, 37, 34, 35, 35, 33, + 7, 33, 33, 33, 33, 33, 33, 33, 33, 9, + 9, 33, 33, 33, 8, 37, 33, 33, 3, 5, + 5, 4, 34, 35, 19, 27, 20, 30, 25, 12, + 23, 13, 24, 10, 2, 1, 26, 10, 9, 11, + 11, 11, 11, 9, 14, 16, 18, 17, 15, 8, + 36, 36, 31, 21, 32, 22, 3, 5, 6, 11, + 10, 11, 1, 10, 11, 0, 10, 9, 28, 29, + 0, 10, 10, 10, 10, 0 + } ; + +static yyconst flex_int32_t yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 2, 2, 4, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 5, 1, 6, 1, 7, 8, 1, 9, + 9, 10, 11, 9, 12, 13, 14, 15, 16, 16, + 16, 16, 16, 16, 16, 17, 17, 9, 9, 18, + 19, 20, 9, 1, 21, 21, 21, 21, 22, 21, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 24, 23, 23, + 9, 25, 9, 26, 23, 1, 21, 21, 21, 21, + + 22, 21, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 24, + 23, 23, 9, 27, 9, 9, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 + } ; + +static yyconst flex_int32_t yy_meta[28] = + { 0, + 1, 1, 2, 2, 1, 1, 1, 1, 1, 3, + 1, 1, 4, 1, 5, 5, 5, 1, 1, 1, + 5, 5, 5, 5, 1, 1, 1 + } ; + +static yyconst flex_int16_t yy_base[92] = + { 0, + 0, 0, 25, 27, 162, 163, 159, 163, 152, 132, + 163, 131, 24, 163, 116, 22, 26, 31, 30, 37, + 40, 44, 115, 46, 0, 64, 50, 15, 0, 163, + 124, 91, 88, 163, 163, 163, 163, 163, 163, 163, + 163, 163, 163, 64, 163, 0, 163, 76, 54, 58, + 79, 91, 91, 0, 56, 163, 163, 163, 32, 0, + 163, 36, 163, 163, 163, 163, 0, 163, 163, 94, + 0, 106, 0, 0, 113, 55, 72, 113, 163, 163, + 116, 101, 108, 123, 126, 163, 143, 31, 148, 153, + 155 + + } ; + +static yyconst flex_int16_t yy_def[92] = + { 0, + 86, 1, 87, 87, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 20, 86, 86, 86, 88, 86, 86, 86, 89, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 90, 86, 86, 20, 20, + 48, 51, 91, 21, 86, 86, 86, 86, 86, 88, + 86, 86, 86, 86, 86, 86, 89, 86, 86, 44, + 44, 70, 90, 48, 51, 86, 52, 91, 86, 86, + 86, 72, 75, 86, 86, 0, 86, 86, 86, 86, + 86 + + } ; + +static yyconst flex_int16_t yy_nxt[191] = + { 0, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 21, 22, 23, 24, + 25, 25, 25, 25, 26, 27, 28, 30, 31, 30, + 31, 37, 40, 65, 32, 60, 32, 42, 61, 45, + 41, 66, 38, 46, 43, 44, 44, 44, 47, 48, + 80, 49, 49, 50, 54, 54, 54, 51, 52, 51, + 53, 55, 56, 51, 58, 59, 61, 62, 63, 84, + 84, 84, 50, 50, 79, 64, 70, 51, 71, 71, + 71, 51, 86, 86, 70, 72, 70, 70, 51, 33, + 74, 74, 74, 51, 51, 51, 51, 75, 51, 51, + + 51, 76, 76, 51, 69, 77, 77, 77, 70, 70, + 70, 86, 86, 51, 51, 70, 81, 81, 86, 86, + 82, 82, 82, 81, 81, 51, 68, 83, 83, 83, + 85, 85, 85, 57, 39, 51, 51, 84, 84, 84, + 85, 85, 85, 29, 29, 29, 29, 29, 67, 36, + 35, 67, 67, 73, 34, 73, 73, 73, 78, 78, + 33, 86, 5, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86 + } ; + +static yyconst flex_int16_t yy_chk[191] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 3, 3, 4, + 4, 13, 16, 28, 3, 88, 4, 17, 62, 19, + 16, 28, 13, 19, 17, 18, 18, 18, 19, 20, + 59, 20, 20, 20, 21, 21, 21, 20, 20, 20, + 20, 22, 22, 21, 24, 24, 26, 26, 27, 76, + 76, 76, 50, 50, 55, 27, 44, 49, 44, 44, + 44, 50, 77, 77, 44, 44, 44, 44, 48, 33, + 48, 48, 48, 51, 51, 51, 48, 48, 48, 48, + + 51, 52, 52, 53, 32, 52, 52, 52, 70, 70, + 70, 82, 82, 53, 53, 70, 72, 72, 83, 83, + 72, 72, 72, 75, 75, 78, 31, 75, 75, 75, + 81, 81, 81, 23, 15, 78, 78, 84, 84, 84, + 85, 85, 85, 87, 87, 87, 87, 87, 89, 12, + 10, 89, 89, 90, 9, 90, 90, 90, 91, 91, + 7, 5, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86, + 86, 86, 86, 86, 86, 86, 86, 86, 86, 86 + } ; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +/* +// +// Copyright (c) 2002-2013 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. +// + +This file contains the Lex specification for GLSL ES preprocessor. +Based on Microsoft Visual Studio 2010 Preprocessor Grammar: +http://msdn.microsoft.com/en-us/library/2scxys89.aspx + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. +*/ + +#include "Tokenizer.h" + +#include "Diagnostics.h" +#include "Token.h" + +#if defined(__GNUC__) +// Triggered by the auto-generated yy_fatal_error function. +#pragma GCC diagnostic ignored "-Wmissing-noreturn" +#endif + +typedef std::string YYSTYPE; +typedef pp::SourceLocation YYLTYPE; + +// Use the unused yycolumn variable to track file (string) number. +#define yyfileno yycolumn + +#define YY_USER_INIT \ + do { \ + yyfileno = 0; \ + yylineno = 1; \ + yyextra->leadingSpace = false; \ + yyextra->lineStart = true; \ + } while(0); + +#define YY_USER_ACTION \ + do \ + { \ + pp::Input* input = &yyextra->input; \ + pp::Input::Location* scanLoc = &yyextra->scanLoc; \ + while ((scanLoc->sIndex < input->count()) && \ + (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \ + { \ + scanLoc->cIndex -= input->length(scanLoc->sIndex++); \ + ++yyfileno; yylineno = 1; \ + } \ + yylloc->file = yyfileno; \ + yylloc->line = yylineno; \ + scanLoc->cIndex += yyleng; \ + } while(0); + +#define YY_INPUT(buf, result, maxSize) \ + result = yyextra->input.read(buf, maxSize); + +#define INITIAL 0 +#define COMMENT 1 + +#define YY_EXTRA_TYPE pp::Tokenizer::Context* + +/* Holds the entire state of the reentrant scanner. */ +struct yyguts_t + { + + /* User-defined. Not touched by flex. */ + YY_EXTRA_TYPE yyextra_r; + + /* The rest are the same as the globals declared in the non-reentrant scanner. */ + FILE *yyin_r, *yyout_r; + size_t yy_buffer_stack_top; /**< index of top of stack. */ + size_t yy_buffer_stack_max; /**< capacity of stack. */ + YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */ + char yy_hold_char; + int yy_n_chars; + int yyleng_r; + char *yy_c_buf_p; + int yy_init; + int yy_start; + int yy_did_buffer_switch_on_eof; + int yy_start_stack_ptr; + int yy_start_stack_depth; + int *yy_start_stack; + yy_state_type yy_last_accepting_state; + char* yy_last_accepting_cpos; + + int yylineno_r; + int yy_flex_debug_r; + + char *yytext_r; + int yy_more_flag; + int yy_more_len; + + YYSTYPE * yylval_r; + + YYLTYPE * yylloc_r; + + }; /* end struct yyguts_t */ + +static int yy_init_globals (yyscan_t yyscanner ); + + /* This must go here because YYSTYPE and YYLTYPE are included + * from bison output in section 1.*/ + # define yylval yyg->yylval_r + + # define yylloc yyg->yylloc_r + +int pplex_init (yyscan_t* scanner); + +int pplex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner); + +/* Accessor methods to globals. + These are made visible to non-reentrant scanners for convenience. */ + +int pplex_destroy (yyscan_t yyscanner ); + +int ppget_debug (yyscan_t yyscanner ); + +void ppset_debug (int debug_flag ,yyscan_t yyscanner ); + +YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner ); + +void ppset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner ); + +FILE *ppget_in (yyscan_t yyscanner ); + +void ppset_in (FILE * in_str ,yyscan_t yyscanner ); + +FILE *ppget_out (yyscan_t yyscanner ); + +void ppset_out (FILE * out_str ,yyscan_t yyscanner ); + +int ppget_leng (yyscan_t yyscanner ); + +char *ppget_text (yyscan_t yyscanner ); + +int ppget_lineno (yyscan_t yyscanner ); + +void ppset_lineno (int line_number ,yyscan_t yyscanner ); + +YYSTYPE * ppget_lval (yyscan_t yyscanner ); + +void ppset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner ); + + YYLTYPE *ppget_lloc (yyscan_t yyscanner ); + + void ppset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner ); + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int ppwrap (yyscan_t yyscanner ); +#else +extern int ppwrap (yyscan_t yyscanner ); +#endif +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner); +#endif + +#ifndef YY_NO_INPUT + +#ifdef __cplusplus +static int yyinput (yyscan_t yyscanner ); +#else +static int input (yyscan_t yyscanner ); +#endif + +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ + { \ + int c = '*'; \ + int n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else \ + { \ + errno=0; \ + while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ + { \ + if( errno != EINTR) \ + { \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + break; \ + } \ + errno=0; \ + clearerr(yyin); \ + } \ + }\ +\ + +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner) +#endif + +/* end tables serialization structures and prototypes */ + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL_IS_OURS 1 + +extern int pplex \ + (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner); + +#define YY_DECL int pplex \ + (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner) +#endif /* !YY_DECL */ + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +/** The main scanner function which does all the work. + */ +YY_DECL +{ + register yy_state_type yy_current_state; + register char *yy_cp, *yy_bp; + register int yy_act; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Line comment */ + + yylval = yylval_param; + + yylloc = yylloc_param; + + if ( !yyg->yy_init ) + { + yyg->yy_init = 1; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yyg->yy_start ) + yyg->yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! YY_CURRENT_BUFFER ) { + ppensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + pp_load_buffer_state(yyscanner ); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yyg->yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yyg->yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yyg->yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 87 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_current_state != 86 ); + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + + YY_DO_BEFORE_ACTION; + +do_action: /* This label is used only to access EOF actions. */ + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yyg->yy_hold_char; + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP + + YY_BREAK +/* Block comment */ +/* Line breaks are just counted - not returned. */ +/* The comment is replaced by a single space. */ +case 2: +YY_RULE_SETUP +{ BEGIN(COMMENT); } + YY_BREAK +case 3: +YY_RULE_SETUP + + YY_BREAK +case 4: +YY_RULE_SETUP + + YY_BREAK +case 5: +/* rule 5 can match eol */ +YY_RULE_SETUP +{ ++yylineno; } + YY_BREAK +case 6: +YY_RULE_SETUP +{ + yyextra->leadingSpace = true; + BEGIN(INITIAL); +} + YY_BREAK +case 7: +YY_RULE_SETUP +{ + // # is only valid at start of line for preprocessor directives. + yylval->assign(1, yytext[0]); + return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER; +} + YY_BREAK +case 8: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::IDENTIFIER; +} + YY_BREAK +case 9: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::CONST_INT; +} + YY_BREAK +case 10: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::CONST_FLOAT; +} + YY_BREAK +/* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */ +/* Rule to catch all invalid integers and floats. */ +case 11: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::PP_NUMBER; +} + YY_BREAK +case 12: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_INC; +} + YY_BREAK +case 13: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_DEC; +} + YY_BREAK +case 14: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_LEFT; +} + YY_BREAK +case 15: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_RIGHT; +} + YY_BREAK +case 16: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_LE; +} + YY_BREAK +case 17: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_GE; +} + YY_BREAK +case 18: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_EQ; +} + YY_BREAK +case 19: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_NE; +} + YY_BREAK +case 20: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_AND; +} + YY_BREAK +case 21: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_XOR; +} + YY_BREAK +case 22: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_OR; +} + YY_BREAK +case 23: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_ADD_ASSIGN; +} + YY_BREAK +case 24: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_SUB_ASSIGN; +} + YY_BREAK +case 25: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_MUL_ASSIGN; +} + YY_BREAK +case 26: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_DIV_ASSIGN; +} + YY_BREAK +case 27: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_MOD_ASSIGN; +} + YY_BREAK +case 28: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_LEFT_ASSIGN; +} + YY_BREAK +case 29: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_RIGHT_ASSIGN; +} + YY_BREAK +case 30: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_AND_ASSIGN; +} + YY_BREAK +case 31: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_XOR_ASSIGN; +} + YY_BREAK +case 32: +YY_RULE_SETUP +{ + yylval->assign(yytext, yyleng); + return pp::Token::OP_OR_ASSIGN; +} + YY_BREAK +case 33: +YY_RULE_SETUP +{ + yylval->assign(1, yytext[0]); + return yytext[0]; +} + YY_BREAK +case 34: +YY_RULE_SETUP +{ yyextra->leadingSpace = true; } + YY_BREAK +case 35: +/* rule 35 can match eol */ +YY_RULE_SETUP +{ + ++yylineno; + yylval->assign(1, '\n'); + return '\n'; +} + YY_BREAK +case 36: +/* rule 36 can match eol */ +YY_RULE_SETUP +{ ++yylineno; } + YY_BREAK +case 37: +YY_RULE_SETUP +{ + yylval->assign(1, yytext[0]); + return pp::Token::PP_OTHER; +} + YY_BREAK +case YY_STATE_EOF(INITIAL): +case YY_STATE_EOF(COMMENT): +{ + // YY_USER_ACTION is not invoked for handling EOF. + // Set the location for EOF token manually. + pp::Input* input = &yyextra->input; + pp::Input::Location* scanLoc = &yyextra->scanLoc; + int sIndexMax = std::max(0, input->count() - 1); + if (scanLoc->sIndex != sIndexMax) + { + // We can only reach here if there are empty strings at the + // end of the input. + scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0; + yyfileno = sIndexMax; yylineno = 1; + } + yylloc->file = yyfileno; + yylloc->line = yylineno; + yylval->clear(); + + if (YY_START == COMMENT) + { + yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT, + pp::SourceLocation(yyfileno, yylineno), + ""); + } + yyterminate(); +} + YY_BREAK +case 38: +YY_RULE_SETUP +ECHO; + YY_BREAK + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yyg->yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * pplex(). If so, then we have to assure + * consistency between YY_CURRENT_BUFFER and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner); + + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yyg->yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yyg->yy_last_accepting_cpos; + yy_current_state = yyg->yy_last_accepting_state; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_END_OF_FILE: + { + yyg->yy_did_buffer_switch_on_eof = 0; + + if ( ppwrap(yyscanner ) ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = + yyg->yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yyg->yy_c_buf_p = + &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars]; + + yy_current_state = yy_get_previous_state( yyscanner ); + + yy_cp = yyg->yy_c_buf_p; + yy_bp = yyg->yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ +} /* end of pplex */ + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ +static int yy_get_next_buffer (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; + register char *source = yyg->yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0; + + else + { + int num_to_read = + YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = YY_CURRENT_BUFFER; + + int yy_c_buf_p_offset = + (int) (yyg->yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + pprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - + number_to_move - 1; + + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), + yyg->yy_n_chars, (size_t) num_to_read ); + + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + if ( yyg->yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + pprestart(yyin ,yyscanner); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) { + /* Extend the array by 50%, plus the number we really need. */ + yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1); + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner ); + if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" ); + } + + yyg->yy_n_chars += number_to_move; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR; + YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; + + return ret_val; +} + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + + static yy_state_type yy_get_previous_state (yyscan_t yyscanner) +{ + register yy_state_type yy_current_state; + register char *yy_cp; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + yy_current_state = yyg->yy_start; + + for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 87 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; +} + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner) +{ + register int yy_is_jam; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */ + register char *yy_cp = yyg->yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yyg->yy_last_accepting_state = yy_current_state; + yyg->yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 87 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 86); + + return yy_is_jam ? 0 : yy_current_state; +} + +#ifndef YY_NO_INPUT +#ifdef __cplusplus + static int yyinput (yyscan_t yyscanner) +#else + static int input (yyscan_t yyscanner) +#endif + +{ + int c; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + *yyg->yy_c_buf_p = yyg->yy_hold_char; + + if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] ) + /* This was really a NUL. */ + *yyg->yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yyg->yy_c_buf_p - yyg->yytext_ptr; + ++yyg->yy_c_buf_p; + + switch ( yy_get_next_buffer( yyscanner ) ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + pprestart(yyin ,yyscanner); + + /*FALLTHROUGH*/ + + case EOB_ACT_END_OF_FILE: + { + if ( ppwrap(yyscanner ) ) + return EOF; + + if ( ! yyg->yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(yyscanner); +#else + return input(yyscanner); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yyg->yy_c_buf_p = yyg->yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */ + *yyg->yy_c_buf_p = '\0'; /* preserve yytext */ + yyg->yy_hold_char = *++yyg->yy_c_buf_p; + + return c; +} +#endif /* ifndef YY_NO_INPUT */ + +/** Immediately switch to a different input stream. + * @param input_file A readable stream. + * @param yyscanner The scanner object. + * @note This function does not reset the start condition to @c INITIAL . + */ + void pprestart (FILE * input_file , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! YY_CURRENT_BUFFER ){ + ppensure_buffer_stack (yyscanner); + YY_CURRENT_BUFFER_LVALUE = + pp_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); + } + + pp_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner); + pp_load_buffer_state(yyscanner ); +} + +/** Switch to a different input buffer. + * @param new_buffer The new input buffer. + * @param yyscanner The scanner object. + */ + void pp_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* TODO. We should be able to replace this entire function body + * with + * pppop_buffer_state(); + * pppush_buffer_state(new_buffer); + */ + ppensure_buffer_stack (yyscanner); + if ( YY_CURRENT_BUFFER == new_buffer ) + return; + + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + YY_CURRENT_BUFFER_LVALUE = new_buffer; + pp_load_buffer_state(yyscanner ); + + /* We don't actually know whether we did this switch during + * EOF (ppwrap()) processing, but the only time this flag + * is looked at is after ppwrap() is called, so it's safe + * to go ahead and always set it. + */ + yyg->yy_did_buffer_switch_on_eof = 1; +} + +static void pp_load_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; + yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; + yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; + yyg->yy_hold_char = *yyg->yy_c_buf_p; +} + +/** Allocate and initialize an input buffer state. + * @param file A readable stream. + * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. + * @param yyscanner The scanner object. + * @return the allocated buffer state. + */ + YY_BUFFER_STATE pp_create_buffer (FILE * file, int size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) ppalloc(b->yy_buf_size + 2 ,yyscanner ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in pp_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + pp_init_buffer(b,file ,yyscanner); + + return b; +} + +/** Destroy the buffer. + * @param b a buffer created with pp_create_buffer() + * @param yyscanner The scanner object. + */ + void pp_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if ( ! b ) + return; + + if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ + YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + ppfree((void *) b->yy_ch_buf ,yyscanner ); + + ppfree((void *) b ,yyscanner ); +} + +/* Initializes or reinitializes a buffer. + * This function is sometimes called more than once on the same buffer, + * such as during a pprestart() or at EOF. + */ + static void pp_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner) + +{ + int oerrno = errno; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + pp_flush_buffer(b ,yyscanner); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + + /* If b is the current buffer, then pp_init_buffer was _probably_ + * called from pprestart() or through yy_get_next_buffer. + * In that case, we don't want to reset the lineno or column. + */ + if (b != YY_CURRENT_BUFFER){ + b->yy_bs_lineno = 1; + b->yy_bs_column = 0; + } + + b->yy_is_interactive = 0; + + errno = oerrno; +} + +/** Discard all buffered characters. On the next scan, YY_INPUT will be called. + * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. + * @param yyscanner The scanner object. + */ + void pp_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == YY_CURRENT_BUFFER ) + pp_load_buffer_state(yyscanner ); +} + +/** Pushes the new state onto the stack. The new state becomes + * the current state. This function will allocate the stack + * if necessary. + * @param new_buffer The new state. + * @param yyscanner The scanner object. + */ +void pppush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (new_buffer == NULL) + return; + + ppensure_buffer_stack(yyscanner); + + /* This block is copied from pp_switch_to_buffer. */ + if ( YY_CURRENT_BUFFER ) + { + /* Flush out information for old buffer. */ + *yyg->yy_c_buf_p = yyg->yy_hold_char; + YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p; + YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars; + } + + /* Only push if top exists. Otherwise, replace top. */ + if (YY_CURRENT_BUFFER) + yyg->yy_buffer_stack_top++; + YY_CURRENT_BUFFER_LVALUE = new_buffer; + + /* copied from pp_switch_to_buffer. */ + pp_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; +} + +/** Removes and deletes the top of the stack, if present. + * The next element becomes the new top. + * @param yyscanner The scanner object. + */ +void pppop_buffer_state (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + if (!YY_CURRENT_BUFFER) + return; + + pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner); + YY_CURRENT_BUFFER_LVALUE = NULL; + if (yyg->yy_buffer_stack_top > 0) + --yyg->yy_buffer_stack_top; + + if (YY_CURRENT_BUFFER) { + pp_load_buffer_state(yyscanner ); + yyg->yy_did_buffer_switch_on_eof = 1; + } +} + +/* Allocates the stack if it does not exist. + * Guarantees space for at least one push. + */ +static void ppensure_buffer_stack (yyscan_t yyscanner) +{ + int num_to_alloc; + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (!yyg->yy_buffer_stack) { + + /* First allocation is just for 2 elements, since we don't know if this + * scanner will even need a stack. We use 2 instead of 1 to avoid an + * immediate realloc on the next call. + */ + num_to_alloc = 1; + yyg->yy_buffer_stack = (struct yy_buffer_state**)ppalloc + (num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); + + memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*)); + + yyg->yy_buffer_stack_max = num_to_alloc; + yyg->yy_buffer_stack_top = 0; + return; + } + + if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){ + + /* Increase the buffer to prepare for a possible push. */ + int grow_size = 8 /* arbitrary grow size */; + + num_to_alloc = yyg->yy_buffer_stack_max + grow_size; + yyg->yy_buffer_stack = (struct yy_buffer_state**)pprealloc + (yyg->yy_buffer_stack, + num_to_alloc * sizeof(struct yy_buffer_state*) + , yyscanner); + if ( ! yyg->yy_buffer_stack ) + YY_FATAL_ERROR( "out of dynamic memory in ppensure_buffer_stack()" ); + + /* zero only the new slots.*/ + memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*)); + yyg->yy_buffer_stack_max = num_to_alloc; + } +} + +/** Setup the input buffer state to scan directly from a user-specified character buffer. + * @param base the character buffer + * @param size the size in bytes of the character buffer + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE pp_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) ppalloc(sizeof( struct yy_buffer_state ) ,yyscanner ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in pp_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + pp_switch_to_buffer(b ,yyscanner ); + + return b; +} + +/** Setup the input buffer state to scan a string. The next call to pplex() will + * scan from a @e copy of @a str. + * @param yystr a NUL-terminated string to scan + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + * @note If you want to scan bytes that may contain NUL values, then use + * pp_scan_bytes() instead. + */ +YY_BUFFER_STATE pp_scan_string (yyconst char * yystr , yyscan_t yyscanner) +{ + + return pp_scan_bytes(yystr,strlen(yystr) ,yyscanner); +} + +/** Setup the input buffer state to scan the given bytes. The next call to pplex() will + * scan from a @e copy of @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. + * @param yyscanner The scanner object. + * @return the newly allocated buffer state object. + */ +YY_BUFFER_STATE pp_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner) +{ + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = _yybytes_len + 2; + buf = (char *) ppalloc(n ,yyscanner ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in pp_scan_bytes()" ); + + for ( i = 0; i < _yybytes_len; ++i ) + buf[i] = yybytes[i]; + + buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; + + b = pp_scan_buffer(buf,n ,yyscanner); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in pp_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; +} + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner) +{ + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); +} + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + int yyless_macro_arg = (n); \ + YY_LESS_LINENO(yyless_macro_arg);\ + yytext[yyleng] = yyg->yy_hold_char; \ + yyg->yy_c_buf_p = yytext + yyless_macro_arg; \ + yyg->yy_hold_char = *yyg->yy_c_buf_p; \ + *yyg->yy_c_buf_p = '\0'; \ + yyleng = yyless_macro_arg; \ + } \ + while ( 0 ) + +/* Accessor methods (get/set functions) to struct members. */ + +/** Get the user-defined data for this scanner. + * @param yyscanner The scanner object. + */ +YY_EXTRA_TYPE ppget_extra (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyextra; +} + +/** Get the current line number. + * @param yyscanner The scanner object. + */ +int ppget_lineno (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yylineno; +} + +/** Get the current column number. + * @param yyscanner The scanner object. + */ +int ppget_column (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + if (! YY_CURRENT_BUFFER) + return 0; + + return yycolumn; +} + +/** Get the input stream. + * @param yyscanner The scanner object. + */ +FILE *ppget_in (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyin; +} + +/** Get the output stream. + * @param yyscanner The scanner object. + */ +FILE *ppget_out (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyout; +} + +/** Get the length of the current token. + * @param yyscanner The scanner object. + */ +int ppget_leng (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yyleng; +} + +/** Get the current token. + * @param yyscanner The scanner object. + */ + +char *ppget_text (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yytext; +} + +/** Set the user-defined data. This data is never touched by the scanner. + * @param user_defined The data to be associated with this scanner. + * @param yyscanner The scanner object. + */ +void ppset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyextra = user_defined ; +} + +/** Set the current line number. + * @param line_number + * @param yyscanner The scanner object. + */ +void ppset_lineno (int line_number , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* lineno is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "ppset_lineno called with no buffer" , yyscanner); + + yylineno = line_number; +} + +/** Set the current column. + * @param line_number + * @param yyscanner The scanner object. + */ +void ppset_column (int column_no , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* column is only valid if an input buffer exists. */ + if (! YY_CURRENT_BUFFER ) + yy_fatal_error( "ppset_column called with no buffer" , yyscanner); + + yycolumn = column_no; +} + +/** Set the input stream. This does not discard the current + * input buffer. + * @param in_str A readable stream. + * @param yyscanner The scanner object. + * @see pp_switch_to_buffer + */ +void ppset_in (FILE * in_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyin = in_str ; +} + +void ppset_out (FILE * out_str , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yyout = out_str ; +} + +int ppget_debug (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yy_flex_debug; +} + +void ppset_debug (int bdebug , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yy_flex_debug = bdebug ; +} + +/* Accessor methods for yylval and yylloc */ + +YYSTYPE * ppget_lval (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylval; +} + +void ppset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylval = yylval_param; +} + +YYLTYPE *ppget_lloc (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + return yylloc; +} + +void ppset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + yylloc = yylloc_param; +} + +/* User-visible API */ + +/* pplex_init is special because it creates the scanner itself, so it is + * the ONLY reentrant function that doesn't take the scanner as the last argument. + * That's why we explicitly handle the declaration, instead of using our macros. + */ + +int pplex_init(yyscan_t* ptr_yy_globals) + +{ + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), NULL ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + return yy_init_globals ( *ptr_yy_globals ); +} + +/* pplex_init_extra has the same functionality as pplex_init, but follows the + * convention of taking the scanner as the last argument. Note however, that + * this is a *pointer* to a scanner, as it will be allocated by this call (and + * is the reason, too, why this function also must handle its own declaration). + * The user defined value in the first argument will be available to ppalloc in + * the yyextra field. + */ + +int pplex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals ) + +{ + struct yyguts_t dummy_yyguts; + + ppset_extra (yy_user_defined, &dummy_yyguts); + + if (ptr_yy_globals == NULL){ + errno = EINVAL; + return 1; + } + + *ptr_yy_globals = (yyscan_t) ppalloc ( sizeof( struct yyguts_t ), &dummy_yyguts ); + + if (*ptr_yy_globals == NULL){ + errno = ENOMEM; + return 1; + } + + /* By setting to 0xAA, we expose bugs in + yy_init_globals. Leave at 0x00 for releases. */ + memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t)); + + ppset_extra (yy_user_defined, *ptr_yy_globals); + + return yy_init_globals ( *ptr_yy_globals ); +} + +static int yy_init_globals (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + /* Initialization is the same as for the non-reentrant scanner. + * This function is called from pplex_destroy(), so don't allocate here. + */ + + yyg->yy_buffer_stack = 0; + yyg->yy_buffer_stack_top = 0; + yyg->yy_buffer_stack_max = 0; + yyg->yy_c_buf_p = (char *) 0; + yyg->yy_init = 0; + yyg->yy_start = 0; + + yyg->yy_start_stack_ptr = 0; + yyg->yy_start_stack_depth = 0; + yyg->yy_start_stack = NULL; + +/* Defined in main.c */ +#ifdef YY_STDINIT + yyin = stdin; + yyout = stdout; +#else + yyin = (FILE *) 0; + yyout = (FILE *) 0; +#endif + + /* For future reference: Set errno on error, since we are called by + * pplex_init() + */ + return 0; +} + +/* pplex_destroy is for both reentrant and non-reentrant scanners. */ +int pplex_destroy (yyscan_t yyscanner) +{ + struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; + + /* Pop the buffer stack, destroying each element. */ + while(YY_CURRENT_BUFFER){ + pp_delete_buffer(YY_CURRENT_BUFFER ,yyscanner ); + YY_CURRENT_BUFFER_LVALUE = NULL; + pppop_buffer_state(yyscanner); + } + + /* Destroy the stack itself. */ + ppfree(yyg->yy_buffer_stack ,yyscanner); + yyg->yy_buffer_stack = NULL; + + /* Destroy the start condition stack. */ + ppfree(yyg->yy_start_stack ,yyscanner ); + yyg->yy_start_stack = NULL; + + /* Reset the globals. This is important in a non-reentrant scanner so the next time + * pplex() is called, initialization will occur. */ + yy_init_globals( yyscanner); + + /* Destroy the main struct (reentrant only). */ + ppfree ( yyscanner , yyscanner ); + yyscanner = NULL; + return 0; +} + +/* + * Internal utility routines. + */ + +#ifndef yytext_ptr +static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner) +{ + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; +} +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner) +{ + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; +} +#endif + +void *ppalloc (yy_size_t size , yyscan_t yyscanner) +{ + return (void *) malloc( size ); +} + +void *pprealloc (void * ptr, yy_size_t size , yyscan_t yyscanner) +{ + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); +} + +void ppfree (void * ptr , yyscan_t yyscanner) +{ + free( (char *) ptr ); /* see pprealloc() for (char *) cast */ +} + +#define YYTABLES_NAME "yytables" + +namespace pp { + +// TODO(alokp): Maximum token length should ideally be specified by +// the preprocessor client, i.e., the compiler. +const size_t Tokenizer::kMaxTokenLength = 256; + +Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0) +{ + mContext.diagnostics = diagnostics; +} + +Tokenizer::~Tokenizer() +{ + destroyScanner(); +} + +bool Tokenizer::init(int count, const char* const string[], const int length[]) +{ + if (count < 0) return false; + if ((count > 0) && (string == 0)) return false; + + mContext.input = Input(count, string, length); + return initScanner(); +} + +void Tokenizer::setFileNumber(int file) +{ + // We use column number as file number. + // See macro yyfileno. + ppset_column(file,mHandle); +} + +void Tokenizer::setLineNumber(int line) +{ + ppset_lineno(line,mHandle); +} + +void Tokenizer::lex(Token* token) +{ + token->type = pplex(&token->text,&token->location,mHandle); + if (token->text.size() > kMaxTokenLength) + { + mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG, + token->location, token->text); + token->text.erase(kMaxTokenLength); + } + + token->flags = 0; + + token->setAtStartOfLine(mContext.lineStart); + mContext.lineStart = token->type == '\n'; + + token->setHasLeadingSpace(mContext.leadingSpace); + mContext.leadingSpace = false; +} + +bool Tokenizer::initScanner() +{ + if ((mHandle == NULL) && pplex_init_extra(&mContext,&mHandle)) + return false; + + pprestart(0,mHandle); + return true; +} + +void Tokenizer::destroyScanner() +{ + if (mHandle == NULL) + return; + + pplex_destroy(mHandle); + mHandle = NULL; +} + +} // namespace pp +
diff --git a/src/GLES2/compiler/preprocessor/Tokenizer.l b/src/GLES2/compiler/preprocessor/Tokenizer.l index a641707..3aef2df 100644 --- a/src/GLES2/compiler/preprocessor/Tokenizer.l +++ b/src/GLES2/compiler/preprocessor/Tokenizer.l
@@ -1,340 +1,342 @@ -/* -// -// Copyright (c) 2002-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. -// - -This file contains the Lex specification for GLSL ES preprocessor. -Based on Microsoft Visual Studio 2010 Preprocessor Grammar: -http://msdn.microsoft.com/en-us/library/2scxys89.aspx - -IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. -*/ - -%top{ -// -// 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. -// - -// This file is auto-generated by generate_parser.sh. DO NOT EDIT! -} - -%{ -#include "Tokenizer.h" - -#include "Diagnostics.h" -#include "Token.h" - -#if defined(__GNUC__) -// Triggered by the auto-generated yy_fatal_error function. -#pragma GCC diagnostic ignored "-Wmissing-noreturn" -#endif - -typedef std::string YYSTYPE; -typedef pp::SourceLocation YYLTYPE; - -// Use the unused yycolumn variable to track file (string) number. -#define yyfileno yycolumn - -#define YY_USER_INIT \ - do { \ - yyfileno = 0; \ - yylineno = 1; \ - yyextra->leadingSpace = false; \ - yyextra->lineStart = true; \ - } while(0); - -#define YY_USER_ACTION \ - do \ - { \ - pp::Input* input = &yyextra->input; \ - pp::Input::Location* scanLoc = &yyextra->scanLoc; \ - while ((scanLoc->sIndex < input->count()) && \ - (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \ - { \ - scanLoc->cIndex -= input->length(scanLoc->sIndex++); \ - ++yyfileno; yylineno = 1; \ - } \ - yylloc->file = yyfileno; \ - yylloc->line = yylineno; \ - scanLoc->cIndex += yyleng; \ - } while(0); - -#define YY_INPUT(buf, result, maxSize) \ - result = yyextra->input.read(buf, maxSize); - -%} - -%option noyywrap nounput never-interactive -%option reentrant bison-bridge bison-locations -%option prefix="pp" -%option extra-type="pp::Tokenizer::Context*" -%x COMMENT - -NEWLINE \n|\r|\r\n -IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* -PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?] - -DECIMAL_CONSTANT [1-9][0-9]* -OCTAL_CONSTANT 0[0-7]* -HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+ - -DIGIT [0-9] -EXPONENT_PART [eE][+-]?{DIGIT}+ -FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") - -%% - - /* Line comment */ -"//"[^\r\n]* - - /* Block comment */ - /* Line breaks are just counted - not returned. */ - /* The comment is replaced by a single space. */ -"/*" { BEGIN(COMMENT); } -<COMMENT>[^*\r\n]+ -<COMMENT>"*" -<COMMENT>{NEWLINE} { ++yylineno; } -<COMMENT>"*/" { - yyextra->leadingSpace = true; - BEGIN(INITIAL); -} - -# { - // # is only valid at start of line for preprocessor directives. - yylval->assign(1, yytext[0]); - return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER; -} - -{IDENTIFIER} { - yylval->assign(yytext, yyleng); - return pp::Token::IDENTIFIER; -} - -{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} { - yylval->assign(yytext, yyleng); - return pp::Token::CONST_INT; -} - -({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) { - yylval->assign(yytext, yyleng); - return pp::Token::CONST_FLOAT; -} - - /* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */ - /* Rule to catch all invalid integers and floats. */ -({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) { - yylval->assign(yytext, yyleng); - return pp::Token::PP_NUMBER; -} - -"++" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_INC; -} -"--" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_DEC; -} -"<<" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_LEFT; -} -">>" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_RIGHT; -} -"<=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_LE; -} -">=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_GE; -} -"==" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_EQ; -} -"!=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_NE; -} -"&&" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_AND; -} -"^^" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_XOR; -} -"||" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_OR; -} -"+=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_ADD_ASSIGN; -} -"-=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_SUB_ASSIGN; -} -"*=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_MUL_ASSIGN; -} -"/=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_DIV_ASSIGN; -} -"%=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_MOD_ASSIGN; -} -"<<=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_LEFT_ASSIGN; -} -">>=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_RIGHT_ASSIGN; -} -"&=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_AND_ASSIGN; -} -"^=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_XOR_ASSIGN; -} -"|=" { - yylval->assign(yytext, yyleng); - return pp::Token::OP_OR_ASSIGN; -} - -{PUNCTUATOR} { - yylval->assign(1, yytext[0]); - return yytext[0]; -} - -[ \t\v\f]+ { yyextra->leadingSpace = true; } - -{NEWLINE} { - ++yylineno; - yylval->assign(1, '\n'); - return '\n'; -} - -. { - yylval->assign(1, yytext[0]); - return pp::Token::PP_OTHER; -} - -<*><<EOF>> { - // YY_USER_ACTION is not invoked for handling EOF. - // Set the location for EOF token manually. - pp::Input* input = &yyextra->input; - pp::Input::Location* scanLoc = &yyextra->scanLoc; - int sIndexMax = std::max(0, input->count() - 1); - if (scanLoc->sIndex != sIndexMax) - { - // We can only reach here if there are empty strings at the - // end of the input. - scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0; - yyfileno = sIndexMax; yylineno = 1; - } - yylloc->file = yyfileno; - yylloc->line = yylineno; - yylval->clear(); - - if (YY_START == COMMENT) - { - yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT, - pp::SourceLocation(yyfileno, yylineno), - ""); - } - yyterminate(); -} - -%% - -namespace pp { - -// TODO(alokp): Maximum token length should ideally be specified by -// the preprocessor client, i.e., the compiler. -const size_t Tokenizer::kMaxTokenLength = 256; - -Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0) -{ - mContext.diagnostics = diagnostics; -} - -Tokenizer::~Tokenizer() -{ - destroyScanner(); -} - -bool Tokenizer::init(int count, const char* const string[], const int length[]) -{ - if (count < 0) return false; - if ((count > 0) && (string == 0)) return false; - - mContext.input = Input(count, string, length); - return initScanner(); -} - -void Tokenizer::setFileNumber(int file) -{ - // We use column number as file number. - // See macro yyfileno. - yyset_column(file, mHandle); -} - -void Tokenizer::setLineNumber(int line) -{ - yyset_lineno(line, mHandle); -} - -void Tokenizer::lex(Token* token) -{ - token->type = yylex(&token->text, &token->location, mHandle); - if (token->text.size() > kMaxTokenLength) - { - mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG, - token->location, token->text); - token->text.erase(kMaxTokenLength); - } - - token->flags = 0; - - token->setAtStartOfLine(mContext.lineStart); - mContext.lineStart = token->type == '\n'; - - token->setHasLeadingSpace(mContext.leadingSpace); - mContext.leadingSpace = false; -} - -bool Tokenizer::initScanner() -{ - if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle)) - return false; - - yyrestart(0, mHandle); - return true; -} - -void Tokenizer::destroyScanner() -{ - if (mHandle == NULL) - return; - - yylex_destroy(mHandle); - mHandle = NULL; -} - -} // namespace pp - +/* +// +// Copyright (c) 2002-2013 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. +// + +This file contains the Lex specification for GLSL ES preprocessor. +Based on Microsoft Visual Studio 2010 Preprocessor Grammar: +http://msdn.microsoft.com/en-us/library/2scxys89.aspx + +IF YOU MODIFY THIS FILE YOU ALSO NEED TO RUN generate_parser.sh. +*/ + +%top{ +// +// Copyright (c) 2011-2013 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. +// + +// This file is auto-generated by generate_parser.sh. DO NOT EDIT! +} + +%{ +#include "Tokenizer.h" + +#include "Diagnostics.h" +#include "Token.h" + +#if defined(__GNUC__) +// Triggered by the auto-generated yy_fatal_error function. +#pragma GCC diagnostic ignored "-Wmissing-noreturn" +#endif + +typedef std::string YYSTYPE; +typedef pp::SourceLocation YYLTYPE; + +// Use the unused yycolumn variable to track file (string) number. +#define yyfileno yycolumn + +#define YY_USER_INIT \ + do { \ + yyfileno = 0; \ + yylineno = 1; \ + yyextra->leadingSpace = false; \ + yyextra->lineStart = true; \ + } while(0); + +#define YY_USER_ACTION \ + do \ + { \ + pp::Input* input = &yyextra->input; \ + pp::Input::Location* scanLoc = &yyextra->scanLoc; \ + while ((scanLoc->sIndex < input->count()) && \ + (scanLoc->cIndex >= input->length(scanLoc->sIndex))) \ + { \ + scanLoc->cIndex -= input->length(scanLoc->sIndex++); \ + ++yyfileno; yylineno = 1; \ + } \ + yylloc->file = yyfileno; \ + yylloc->line = yylineno; \ + scanLoc->cIndex += yyleng; \ + } while(0); + +#define YY_INPUT(buf, result, maxSize) \ + result = yyextra->input.read(buf, maxSize); + +%} + +%option noyywrap nounput never-interactive +%option reentrant bison-bridge bison-locations +%option prefix="pp" +%option extra-type="pp::Tokenizer::Context*" +%x COMMENT + +NEWLINE \n|\r|\r\n +IDENTIFIER [_a-zA-Z][_a-zA-Z0-9]* +PUNCTUATOR [][<>(){}.+-/*%^|&~=!:;,?] + +DECIMAL_CONSTANT [1-9][0-9]* +OCTAL_CONSTANT 0[0-7]* +HEXADECIMAL_CONSTANT 0[xX][0-9a-fA-F]+ + +DIGIT [0-9] +EXPONENT_PART [eE][+-]?{DIGIT}+ +FRACTIONAL_CONSTANT ({DIGIT}*"."{DIGIT}+)|({DIGIT}+".") + +%% + + /* Line comment */ +"//"[^\r\n]* + + /* Block comment */ + /* Line breaks are just counted - not returned. */ + /* The comment is replaced by a single space. */ +"/*" { BEGIN(COMMENT); } +<COMMENT>[^*\r\n]+ +<COMMENT>"*" +<COMMENT>{NEWLINE} { ++yylineno; } +<COMMENT>"*/" { + yyextra->leadingSpace = true; + BEGIN(INITIAL); +} + +# { + // # is only valid at start of line for preprocessor directives. + yylval->assign(1, yytext[0]); + return yyextra->lineStart ? pp::Token::PP_HASH : pp::Token::PP_OTHER; +} + +{IDENTIFIER} { + yylval->assign(yytext, yyleng); + return pp::Token::IDENTIFIER; +} + +{DECIMAL_CONSTANT}|{OCTAL_CONSTANT}|{HEXADECIMAL_CONSTANT} { + yylval->assign(yytext, yyleng); + return pp::Token::CONST_INT; +} + +({DIGIT}+{EXPONENT_PART})|({FRACTIONAL_CONSTANT}{EXPONENT_PART}?) { + yylval->assign(yytext, yyleng); + return pp::Token::CONST_FLOAT; +} + + /* Anything that starts with a {DIGIT} or .{DIGIT} must be a number. */ + /* Rule to catch all invalid integers and floats. */ +({DIGIT}+[_a-zA-Z0-9.]*)|("."{DIGIT}+[_a-zA-Z0-9.]*) { + yylval->assign(yytext, yyleng); + return pp::Token::PP_NUMBER; +} + +"++" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_INC; +} +"--" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_DEC; +} +"<<" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_LEFT; +} +">>" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_RIGHT; +} +"<=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_LE; +} +">=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_GE; +} +"==" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_EQ; +} +"!=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_NE; +} +"&&" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_AND; +} +"^^" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_XOR; +} +"||" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_OR; +} +"+=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_ADD_ASSIGN; +} +"-=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_SUB_ASSIGN; +} +"*=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_MUL_ASSIGN; +} +"/=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_DIV_ASSIGN; +} +"%=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_MOD_ASSIGN; +} +"<<=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_LEFT_ASSIGN; +} +">>=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_RIGHT_ASSIGN; +} +"&=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_AND_ASSIGN; +} +"^=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_XOR_ASSIGN; +} +"|=" { + yylval->assign(yytext, yyleng); + return pp::Token::OP_OR_ASSIGN; +} + +{PUNCTUATOR} { + yylval->assign(1, yytext[0]); + return yytext[0]; +} + +[ \t\v\f]+ { yyextra->leadingSpace = true; } + +{NEWLINE} { + ++yylineno; + yylval->assign(1, '\n'); + return '\n'; +} + +\\{NEWLINE} { ++yylineno; } + +. { + yylval->assign(1, yytext[0]); + return pp::Token::PP_OTHER; +} + +<*><<EOF>> { + // YY_USER_ACTION is not invoked for handling EOF. + // Set the location for EOF token manually. + pp::Input* input = &yyextra->input; + pp::Input::Location* scanLoc = &yyextra->scanLoc; + int sIndexMax = std::max(0, input->count() - 1); + if (scanLoc->sIndex != sIndexMax) + { + // We can only reach here if there are empty strings at the + // end of the input. + scanLoc->sIndex = sIndexMax; scanLoc->cIndex = 0; + yyfileno = sIndexMax; yylineno = 1; + } + yylloc->file = yyfileno; + yylloc->line = yylineno; + yylval->clear(); + + if (YY_START == COMMENT) + { + yyextra->diagnostics->report(pp::Diagnostics::EOF_IN_COMMENT, + pp::SourceLocation(yyfileno, yylineno), + ""); + } + yyterminate(); +} + +%% + +namespace pp { + +// TODO(alokp): Maximum token length should ideally be specified by +// the preprocessor client, i.e., the compiler. +const size_t Tokenizer::kMaxTokenLength = 256; + +Tokenizer::Tokenizer(Diagnostics* diagnostics) : mHandle(0) +{ + mContext.diagnostics = diagnostics; +} + +Tokenizer::~Tokenizer() +{ + destroyScanner(); +} + +bool Tokenizer::init(int count, const char* const string[], const int length[]) +{ + if (count < 0) return false; + if ((count > 0) && (string == 0)) return false; + + mContext.input = Input(count, string, length); + return initScanner(); +} + +void Tokenizer::setFileNumber(int file) +{ + // We use column number as file number. + // See macro yyfileno. + yyset_column(file, mHandle); +} + +void Tokenizer::setLineNumber(int line) +{ + yyset_lineno(line, mHandle); +} + +void Tokenizer::lex(Token* token) +{ + token->type = yylex(&token->text, &token->location, mHandle); + if (token->text.size() > kMaxTokenLength) + { + mContext.diagnostics->report(Diagnostics::TOKEN_TOO_LONG, + token->location, token->text); + token->text.erase(kMaxTokenLength); + } + + token->flags = 0; + + token->setAtStartOfLine(mContext.lineStart); + mContext.lineStart = token->type == '\n'; + + token->setHasLeadingSpace(mContext.leadingSpace); + mContext.leadingSpace = false; +} + +bool Tokenizer::initScanner() +{ + if ((mHandle == NULL) && yylex_init_extra(&mContext, &mHandle)) + return false; + + yyrestart(0, mHandle); + return true; +} + +void Tokenizer::destroyScanner() +{ + if (mHandle == NULL) + return; + + yylex_destroy(mHandle); + mHandle = NULL; +} + +} // namespace pp +
diff --git a/src/GLES2/compiler/preprocessor/generate_parser.sh b/src/GLES2/compiler/preprocessor/generate_parser.sh index 8ffe0e5..14ffa6a 100644 --- a/src/GLES2/compiler/preprocessor/generate_parser.sh +++ b/src/GLES2/compiler/preprocessor/generate_parser.sh
@@ -1,26 +1,26 @@ -#!/bin/bash -# Copyright (c) 2012 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. - -# Generates various components of GLSL ES preprocessor. - -run_flex() -{ -input_file=$script_dir/$1 -output_source=$script_dir/$2 -flex --noline --nounistd --outfile=$output_source $input_file -} - -run_bison() -{ -input_file=$script_dir/$1 -output_source=$script_dir/$2 -bison --no-lines --skeleton=yacc.c --output=$output_source $input_file -} - -script_dir=$(dirname $0) - -# Generate preprocessor -run_flex Tokenizer.l Tokenizer.cpp -run_bison ExpressionParser.y ExpressionParser.cpp +#!/bin/bash +# Copyright (c) 2012-2013 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. + +# Generates various components of GLSL ES preprocessor. + +run_flex() +{ +input_file=$script_dir/$1 +output_source=$script_dir/$2 +flex --noline --nounistd --outfile=$output_source $input_file +} + +run_bison() +{ +input_file=$script_dir/$1 +output_source=$script_dir/$2 +bison --no-lines --skeleton=yacc.c --output=$output_source $input_file +} + +script_dir=$(dirname $0) + +# Generate preprocessor +run_flex Tokenizer.l Tokenizer.cpp +run_bison ExpressionParser.y ExpressionParser.cpp
diff --git a/src/GLES2/include/GLSLANG/ShaderLang.h b/src/GLES2/include/GLSLANG/ShaderLang.h index 0d78834..4346986 100644 --- a/src/GLES2/include/GLSLANG/ShaderLang.h +++ b/src/GLES2/include/GLSLANG/ShaderLang.h
@@ -1,5 +1,5 @@ // -// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. +// Copyright (c) 2002-2013 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. // @@ -17,7 +17,7 @@ // Version number for shader translation API. // It is incremented everytime the API changes. -#define SH_VERSION 104 +#define SH_VERSION 105 // // The names of the following enums have been derived by replacing GL prefix @@ -107,6 +107,9 @@ // Extensions. // Set to 1 to enable the extension, else 0. int OES_standard_derivatives; + int OES_fragment_precision_high; + + unsigned int MaxCallStackDepth; } ShBuiltInResources; //
diff --git a/src/GLES2/include/KHR/khrplatform.h b/src/GLES2/include/KHR/khrplatform.h index 8ec0d19..b9d831b 100644 --- a/src/GLES2/include/KHR/khrplatform.h +++ b/src/GLES2/include/KHR/khrplatform.h
@@ -114,6 +114,8 @@ #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) /* Win32 but not WinCE */ # define KHRONOS_APIENTRY __stdcall +#elif defined(__GNUC__) && defined(__i386__) +# define KHRONOS_APIENTRY __attribute__((__force_align_arg_pointer__)) #else # define KHRONOS_APIENTRY #endif
diff --git a/src/GLES2/libEGL/Config.cpp b/src/GLES2/libEGL/Config.cpp index 76bbdf0..8e6dd36 100644 --- a/src/GLES2/libEGL/Config.cpp +++ b/src/GLES2/libEGL/Config.cpp
@@ -1,6 +1,6 @@ // SwiftShader Software Renderer // -// Copyright(c) 2005-2012 TransGaming Inc. +// Copyright(c) 2005-2013 TransGaming Inc. // // All rights reserved. No part of this software may be copied, distributed, transmitted, // transcribed, stored in a retrieval system, translated into any human or computer @@ -295,6 +295,7 @@ case EGL_CONFIG_ID: match = config->mConfigID == attribute[1]; break; case EGL_LEVEL: match = config->mLevel >= attribute[1]; break; case EGL_NATIVE_RENDERABLE: match = config->mNativeRenderable == attribute[1]; break; + case EGL_NATIVE_VISUAL_ID: match = config->mNativeVisualID == attribute[1]; break; case EGL_NATIVE_VISUAL_TYPE: match = config->mNativeVisualType == attribute[1]; break; case EGL_SAMPLES: match = config->mSamples >= attribute[1]; break; case EGL_SAMPLE_BUFFERS: match = config->mSampleBuffers >= attribute[1]; break;
diff --git a/src/GLES2/libEGL/Display.cpp b/src/GLES2/libEGL/Display.cpp index 623ba0c..9f196d4 100644 --- a/src/GLES2/libEGL/Display.cpp +++ b/src/GLES2/libEGL/Display.cpp
@@ -1,6 +1,6 @@ // SwiftShader Software Renderer // -// Copyright(c) 2005-2012 TransGaming Inc. +// Copyright(c) 2005-2013 TransGaming Inc. // // All rights reserved. No part of this software may be copied, distributed, transmitted, // transcribed, stored in a retrieval system, translated into any human or computer @@ -208,6 +208,7 @@ case EGL_CONFIG_ID: *value = configuration->mConfigID; break; case EGL_LEVEL: *value = configuration->mLevel; break; case EGL_NATIVE_RENDERABLE: *value = configuration->mNativeRenderable; break; + case EGL_NATIVE_VISUAL_ID: *value = configuration->mNativeVisualID; break; case EGL_NATIVE_VISUAL_TYPE: *value = configuration->mNativeVisualType; break; case EGL_SAMPLES: *value = configuration->mSamples; break; case EGL_SAMPLE_BUFFERS: *value = configuration->mSampleBuffers; break;
diff --git a/src/GLES2/libEGL/Surface.cpp b/src/GLES2/libEGL/Surface.cpp index dc2abb8..1252471 100644 --- a/src/GLES2/libEGL/Surface.cpp +++ b/src/GLES2/libEGL/Surface.cpp
@@ -1,6 +1,6 @@ // SwiftShader Software Renderer // -// Copyright(c) 2005-2012 TransGaming Inc. +// Copyright(c) 2005-2013 TransGaming Inc. // // All rights reserved. No part of this software may be copied, distributed, transmitted, // transcribed, stored in a retrieval system, translated into any human or computer @@ -23,7 +23,6 @@ #include "Main/FrameBuffer.hpp" #if defined(_WIN32) -#include <dwmapi.h> #include <tchar.h> #endif @@ -84,37 +83,7 @@ { ASSERT(!frameBuffer && !backBuffer && !mDepthStencil); - if(!reset()) - { - return false; - } - - #if defined(_WIN32) - // Modify present parameters for this window, if we are composited, - // to minimize the amount of queuing done by DWM between our calls to - // present and the actual screen. - if(mWindow && LOBYTE(GetVersion()) >= 6) - { - BOOL isComposited; - HRESULT result = DwmIsCompositionEnabled(&isComposited); - - if(SUCCEEDED(result) && isComposited) - { - DWM_PRESENT_PARAMETERS presentParams = {0}; - presentParams.cbSize = sizeof(DWM_PRESENT_PARAMETERS); - presentParams.cBuffer = 2; - - result = DwmSetPresentParameters(mWindow, &presentParams); - - if(FAILED(result)) - { - ERR("Unable to set present parameters: %081X", result); - } - } - } - #endif - - return true; + return reset(); } void Surface::release() @@ -190,12 +159,7 @@ } backBuffer = gl::createBackBuffer(backBufferWidth, backBufferHeight, mConfig); - - if(backBuffer) - { - backBuffer->addRef(); - } - + if(!backBuffer) { ERR("Could not create back buffer");
diff --git a/src/GLES2/libEGL/libEGL.vcxproj b/src/GLES2/libEGL/libEGL.vcxproj index 8e9325d..dc6a85d 100644 --- a/src/GLES2/libEGL/libEGL.vcxproj +++ b/src/GLES2/libEGL/libEGL.vcxproj
@@ -77,14 +77,11 @@ <BrowseInformation>true</BrowseInformation> </ClCompile> <Link> - <AdditionalDependencies>dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>libEGL.def</ModuleDefinitionFile> - <DelayLoadDLLs>dwmapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs> + <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> <TargetMachine>MachineX86</TargetMachine> </Link> <PostBuildEvent> @@ -106,16 +103,13 @@ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> </ClCompile> <Link> - <AdditionalDependencies>dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>libEGL.def</ModuleDefinitionFile> - <DelayLoadDLLs>dwmapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs> + <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> - <RandomizedBaseAddress>true</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> <TargetMachine>MachineX86</TargetMachine> </Link> <PostBuildEvent> @@ -138,16 +132,13 @@ <OmitFramePointers>false</OmitFramePointers> </ClCompile> <Link> - <AdditionalDependencies>dwmapi.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>libEGL.def</ModuleDefinitionFile> - <DelayLoadDLLs>dwmapi.dll;%(DelayLoadDLLs)</DelayLoadDLLs> + <DelayLoadDLLs>%(DelayLoadDLLs)</DelayLoadDLLs> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> <TargetMachine>MachineX86</TargetMachine> </Link> <PostBuildEvent>
diff --git a/src/GLES2/libEGL/main.cpp b/src/GLES2/libEGL/main.cpp index aeef1ec..cb3db37 100644 --- a/src/GLES2/libEGL/main.cpp +++ b/src/GLES2/libEGL/main.cpp
@@ -1,6 +1,6 @@ // SwiftShader Software Renderer // -// Copyright(c) 2005-2012 TransGaming Inc. +// Copyright(c) 2005-2013 TransGaming Inc. // // All rights reserved. No part of this software may be copied, distributed, transmitted, // transcribed, stored in a retrieval system, translated into any human or computer @@ -136,72 +136,84 @@ namespace egl { +static Current *eglGetCurrent(void) +{ + Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + + if(!current) + { + eglAttachThread(); + } + + return (Current*)sw::Thread::getLocalStorage(currentTLS); +} + void setCurrentError(EGLint error) { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); current->error = error; } EGLint getCurrentError() { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); return current->error; } void setCurrentAPI(EGLenum API) { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); current->API = API; } EGLenum getCurrentAPI() { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); return current->API; } void setCurrentDisplay(EGLDisplay dpy) { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); current->display = dpy; } EGLDisplay getCurrentDisplay() { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); return current->display; } void setCurrentDrawSurface(EGLSurface surface) { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); current->drawSurface = surface; } EGLSurface getCurrentDrawSurface() { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); return current->drawSurface; } void setCurrentReadSurface(EGLSurface surface) { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); current->readSurface = surface; } EGLSurface getCurrentReadSurface() { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = eglGetCurrent(); return current->readSurface; } @@ -245,4 +257,4 @@ sw::FrameBuffer *(*createFrameBuffer)(EGLNativeWindowType window, int width, int height) = 0; } -void *libGLESv2 = 0; // Handle to the libGLESv2 module \ No newline at end of file +void *libGLESv2 = 0; // Handle to the libGLESv2 module
diff --git a/src/GLES2/libGLESv2/Buffer.cpp b/src/GLES2/libGLESv2/Buffer.cpp index e98d8eb..fc535ac 100644 --- a/src/GLES2/libGLESv2/Buffer.cpp +++ b/src/GLES2/libGLESv2/Buffer.cpp
@@ -61,11 +61,6 @@ if(data) { memcpy((void*)mContents->getBuffer(), data, size); - memset((char*)mContents->getBuffer() + size, 0, padding); - } - else - { - memset((void*)mContents->getBuffer(), 0, size + padding); } } }
diff --git a/src/GLES2/libGLESv2/Context.cpp b/src/GLES2/libGLESv2/Context.cpp index 445962c..a50e3a1 100644 --- a/src/GLES2/libGLESv2/Context.cpp +++ b/src/GLES2/libGLESv2/Context.cpp
@@ -1336,7 +1336,7 @@ switch(pname) { case GL_SAMPLE_BUFFERS: - if(samples != 0) + if(samples > 1) { *params = 1; } @@ -1346,11 +1346,11 @@ } break; case GL_SAMPLES: - *params = samples; + *params = samples & ~1; break; } } - else + else { *params = 0; } @@ -2366,12 +2366,16 @@ (mState.colorMaskGreen ? 0x2 : 0) | (mState.colorMaskBlue ? 0x4 : 0) | (mState.colorMaskAlpha ? 0x8 : 0); - device->clearColor(color, rgbaMask); + + if(rgbaMask != 0) + { + device->clearColor(color, rgbaMask); + } } if(mask & GL_DEPTH_BUFFER_BIT) { - if(mState.depthMask) + if(mState.depthMask != 0) { device->clearDepth(depth); } @@ -2379,7 +2383,10 @@ if(mask & GL_STENCIL_BUFFER_BIT) { - device->clearStencil(stencil, mState.stencilWritemask); + if(mState.stencilWritemask != 0) + { + device->clearStencil(stencil, mState.stencilWritemask); + } } } @@ -2567,14 +2574,14 @@ return GL_NO_ERROR; } -int Context::getNearestSupportedSamples(sw::Format format, int requested) const +int Context::getSupportedMultiSampleDepth(sw::Format format, int requested) { if(requested <= 1) { - return requested; + return 1; } - if(requested <= 2) + if(requested == 2) { return 2; } @@ -2790,7 +2797,7 @@ return error(GL_INVALID_FRAMEBUFFER_OPERATION); } - if(drawBufferSamples != 0) + if(drawBufferSamples > 1) { return error(GL_INVALID_OPERATION); } @@ -2950,7 +2957,7 @@ return error(GL_INVALID_OPERATION); } - if(partialBufferCopy && readBufferSamples != 0) + if(partialBufferCopy && readBufferSamples > 1) { return error(GL_INVALID_OPERATION); } @@ -3004,8 +3011,8 @@ return error(GL_INVALID_OPERATION); // Only whole-buffer copies are permitted } - if((drawDSBuffer && drawDSBuffer->getSamples() != 0) || - (readDSBuffer && readDSBuffer->getSamples() != 0)) + if((drawDSBuffer && drawDSBuffer->getSamples() > 1) || + (readDSBuffer && readDSBuffer->getSamples() > 1)) { return error(GL_INVALID_OPERATION); }
diff --git a/src/GLES2/libGLESv2/Context.h b/src/GLES2/libGLESv2/Context.h index 1ca0d55..d998f62 100644 --- a/src/GLES2/libGLESv2/Context.h +++ b/src/GLES2/libGLESv2/Context.h
@@ -409,7 +409,7 @@ GLenum getError(); - int getNearestSupportedSamples(sw::Format format, int requested) const; + static int getSupportedMultiSampleDepth(sw::Format format, int requested); const char *getExtensionString() const; void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
diff --git a/src/GLES2/libGLESv2/Device.cpp b/src/GLES2/libGLESv2/Device.cpp index 64b888d..e7b1ec9 100644 --- a/src/GLES2/libGLESv2/Device.cpp +++ b/src/GLES2/libGLESv2/Device.cpp
@@ -280,8 +280,6 @@ return 0; } - surface->addRef(); - return surface; } @@ -302,8 +300,6 @@ ERR("Out of memory"); return 0; } - - surface->addRef(); return surface; }
diff --git a/src/GLES2/libGLESv2/Image.cpp b/src/GLES2/libGLESv2/Image.cpp index 0b8220e..5b43aae 100644 --- a/src/GLES2/libGLESv2/Image.cpp +++ b/src/GLES2/libGLESv2/Image.cpp
@@ -11,6 +11,7 @@ #include "Image.hpp" +#include "Texture.h" #include "utilities.h" #include "../common/debug.h" #include "Common/Thread.hpp" @@ -19,14 +20,29 @@ namespace gl { - Image::Image(sw::Resource *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type) : sw::Surface(parentTexture, width, height, 1, selectInternalFormat(format, type), true, true), width(width), height(height), internalFormat(selectInternalFormat(format, type)), format(format), type(type), multiSampleDepth(1) + static sw::Resource *getParentResource(Texture *texture) { - referenceCount = 0; + if(texture) + { + return texture->getResource(); + } + + return 0; } - Image::Image(sw::Resource *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, GLenum format, GLenum type, int multiSampleDepth, bool lockable, bool renderTarget) : sw::Surface(parentTexture, width, height, multiSampleDepth, internalFormat, lockable, renderTarget), width(width), height(height), internalFormat(internalFormat), format(format), type(type), multiSampleDepth(multiSampleDepth) + Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type) + : parentTexture(parentTexture), width(width), height(height), format(format), type(type) + , internalFormat(selectInternalFormat(format, type)), multiSampleDepth(1) + , sw::Surface(getParentResource(parentTexture), width, height, 1, selectInternalFormat(format, type), true, true) { - referenceCount = 0; + referenceCount = 1; + } + + Image::Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, GLenum format, GLenum type, int multiSampleDepth, bool lockable, bool renderTarget) + : parentTexture(parentTexture), width(width), height(height), internalFormat(internalFormat), format(format), type(type), multiSampleDepth(multiSampleDepth) + , sw::Surface(getParentResource(parentTexture), width, height, multiSampleDepth, internalFormat, lockable, renderTarget) + { + referenceCount = 1; } Image::~Image() @@ -81,11 +97,21 @@ void Image::addRef() { + if(parentTexture) + { + return parentTexture->addRef(); + } + sw::atomicIncrement(&referenceCount); } void Image::release() { + if(parentTexture) + { + return parentTexture->release(); + } + if(referenceCount > 0) { sw::atomicDecrement(&referenceCount); @@ -97,6 +123,13 @@ } } + void Image::unbind() + { + parentTexture = 0; + + release(); + } + sw::Format Image::selectInternalFormat(GLenum format, GLenum type) { #if S3TC_SUPPORT @@ -163,6 +196,18 @@ } else UNREACHABLE(); } + else if(type == GL_UNSIGNED_SHORT_4_4_4_4) + { + return sw::FORMAT_A8R8G8B8; + } + else if(type == GL_UNSIGNED_SHORT_5_5_5_1) + { + return sw::FORMAT_A8R8G8B8; + } + else if(type == GL_UNSIGNED_SHORT_5_6_5) + { + return sw::FORMAT_X8R8G8B8; + } else UNREACHABLE(); return sw::FORMAT_A8R8G8B8; @@ -288,9 +333,9 @@ break; default: UNREACHABLE(); } - - unlock(); } + + unlock(); } void Image::loadAlphaImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const @@ -653,8 +698,8 @@ { memcpy((void*)((GLbyte*)buffer + i * getPitch()), (void*)((GLbyte*)pixels + i * inputPitch), inputPitch); } - - unlock(); } + + unlock(); } } \ No newline at end of file
diff --git a/src/GLES2/libGLESv2/Image.hpp b/src/GLES2/libGLESv2/Image.hpp index baf963d..1520504 100644 --- a/src/GLES2/libGLESv2/Image.hpp +++ b/src/GLES2/libGLESv2/Image.hpp
@@ -19,11 +19,13 @@ namespace gl { + class Texture; + class Image : public sw::Surface { public: - Image(sw::Resource *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type); - Image(sw::Resource *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, GLenum format, GLenum type, int multiSampleDepth, bool lockable, bool renderTarget); + Image(Texture *parentTexture, GLsizei width, GLsizei height, GLenum format, GLenum type); + Image(Texture *parentTexture, GLsizei width, GLsizei height, sw::Format internalFormat, GLenum format, GLenum type, int multiSampleDepth, bool lockable, bool renderTarget); void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *input); void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLsizei imageSize, const void *pixels); @@ -41,6 +43,7 @@ virtual void addRef(); virtual void release(); + void unbind(); // Break parent ownership and release static sw::Format selectInternalFormat(GLenum format, GLenum type); static int bytes(sw::Format format); @@ -71,6 +74,8 @@ void loadD32ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer) const; void loadD24S8ImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, int inputPitch, const void *input, void *buffer); + Texture *parentTexture; + const GLsizei width; const GLsizei height; const GLenum format;
diff --git a/src/GLES2/libGLESv2/Program.cpp b/src/GLES2/libGLESv2/Program.cpp index a1ad45e..41fa7bf 100644 --- a/src/GLES2/libGLESv2/Program.cpp +++ b/src/GLES2/libGLESv2/Program.cpp
@@ -35,7 +35,7 @@ return buffer; } - Uniform::Uniform(GLenum type, const std::string &name, unsigned int arraySize) : type(type), name(name), arraySize(arraySize) + Uniform::Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize) : type(type), precision(precision), name(name), arraySize(arraySize) { int bytes = UniformTypeSize(type) * size(); data = new unsigned char[bytes]; @@ -1132,7 +1132,6 @@ if(in + registers > MAX_VARYING_VECTORS) { appendToInfoLog("Too many varyings"); - return false; } @@ -1141,7 +1140,6 @@ if(out + registers > MAX_VARYING_VECTORS) { appendToInfoLog("Too many varyings"); - return false; } @@ -1239,7 +1237,6 @@ if(rows + location > MAX_VERTEX_ATTRIBS) { appendToInfoLog("Active attribute (%s) at location %d is too big to fit", attribute->name.c_str(), location); - return false; } @@ -1263,7 +1260,6 @@ if(availableIndex == -1 || availableIndex + rows > MAX_VERTEX_ATTRIBS) { appendToInfoLog("Too many active attributes (%s)", attribute->name.c_str()); - return false; // Fail to link } @@ -1306,7 +1302,7 @@ { const sh::Uniform &uniform = activeUniforms[uniformIndex]; - if(!defineUniform(shader->getType(), uniform.type, uniform.name, uniform.arraySize, uniform.registerIndex)) + if(!defineUniform(shader->getType(), uniform.type, uniform.precision, uniform.name, uniform.arraySize, uniform.registerIndex)) { return false; } @@ -1315,7 +1311,7 @@ return true; } - bool Program::defineUniform(GLenum shader, GLenum type, const std::string &name, unsigned int arraySize, int registerIndex) + bool Program::defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &name, unsigned int arraySize, int registerIndex) { if(type == GL_SAMPLER_2D || type == GL_SAMPLER_CUBE) { @@ -1367,12 +1363,19 @@ if(uniform->type != type) { + appendToInfoLog("Types for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); + return false; + } + + if(uniform->precision != precision) + { + appendToInfoLog("Precisions for uniform %s do not match between the vertex and fragment shader", uniform->name.c_str()); return false; } } else { - uniform = new Uniform(type, name, arraySize); + uniform = new Uniform(type, precision, name, arraySize); } if(!uniform) @@ -1880,15 +1883,17 @@ if(!infoLog) { - infoLog = new char[infoLength + 1]; + infoLog = new char[infoLength + 2]; strcpy(infoLog, info); + strcpy(infoLog + infoLength, "\n"); } else { size_t logLength = strlen(infoLog); - char *newLog = new char[logLength + infoLength + 1]; + char *newLog = new char[logLength + infoLength + 2]; strcpy(newLog, infoLog); strcpy(newLog + logLength, info); + strcpy(newLog + logLength + infoLength, "\n"); delete[] infoLog; infoLog = newLog; @@ -2045,7 +2050,7 @@ } } - void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) + void Program::getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const { // Skip over inactive attributes unsigned int activeAttribute = 0; @@ -2083,7 +2088,7 @@ *type = linkedAttribute[attribute].type; } - GLint Program::getActiveAttributeCount() + GLint Program::getActiveAttributeCount() const { int count = 0; @@ -2098,7 +2103,7 @@ return count; } - GLint Program::getActiveAttributeMaxLength() + GLint Program::getActiveAttributeMaxLength() const { int maxLength = 0; @@ -2113,7 +2118,7 @@ return maxLength; } - void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) + void Program::getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const { if(bufsize > 0) { @@ -2138,12 +2143,12 @@ *type = uniforms[index]->type; } - GLint Program::getActiveUniformCount() + GLint Program::getActiveUniformCount() const { return uniforms.size(); } - GLint Program::getActiveUniformMaxLength() + GLint Program::getActiveUniformMaxLength() const { int maxLength = 0;
diff --git a/src/GLES2/libGLESv2/Program.h b/src/GLES2/libGLESv2/Program.h index 404a208..33e358c 100644 --- a/src/GLES2/libGLESv2/Program.h +++ b/src/GLES2/libGLESv2/Program.h
@@ -1,6 +1,6 @@ // SwiftShader Software Renderer // -// Copyright(c) 2005-2012 TransGaming Inc. +// Copyright(c) 2005-2013 TransGaming Inc. // // All rights reserved. No part of this software may be copied, distributed, transmitted, // transcribed, stored in a retrieval system, translated into any human or computer @@ -34,7 +34,7 @@ // Helper struct representing a single shader uniform struct Uniform { - Uniform(GLenum type, const std::string &name, unsigned int arraySize); + Uniform(GLenum type, GLenum precision, const std::string &name, unsigned int arraySize); ~Uniform(); @@ -43,6 +43,7 @@ int registerCount() const; const GLenum type; + const GLenum precision; const std::string name; const unsigned int arraySize; @@ -109,13 +110,13 @@ void getInfoLog(GLsizei bufSize, GLsizei *length, char *infoLog); void getAttachedShaders(GLsizei maxCount, GLsizei *count, GLuint *shaders); - void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); - GLint getActiveAttributeCount(); - GLint getActiveAttributeMaxLength(); + void getActiveAttribute(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; + GLint getActiveAttributeCount() const; + GLint getActiveAttributeMaxLength() const; - void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); - GLint getActiveUniformCount(); - GLint getActiveUniformMaxLength(); + void getActiveUniform(GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name) const; + GLint getActiveUniformCount() const; + GLint getActiveUniformMaxLength() const; void addRef(); void release(); @@ -139,7 +140,7 @@ int getAttributeBinding(const std::string &name); bool linkUniforms(Shader *shader); - bool defineUniform(GLenum shader, GLenum type, const std::string &_name, unsigned int arraySize, int registerIndex); + bool defineUniform(GLenum shader, GLenum type, GLenum precision, const std::string &_name, unsigned int arraySize, int registerIndex); bool applyUniform1bv(GLint location, GLsizei count, const GLboolean *v); bool applyUniform2bv(GLint location, GLsizei count, const GLboolean *v); bool applyUniform3bv(GLint location, GLsizei count, const GLboolean *v);
diff --git a/src/GLES2/libGLESv2/Renderbuffer.cpp b/src/GLES2/libGLESv2/Renderbuffer.cpp index 133b592..79df223 100644 --- a/src/GLES2/libGLESv2/Renderbuffer.cpp +++ b/src/GLES2/libGLESv2/Renderbuffer.cpp
@@ -332,7 +332,7 @@ mHeight = renderTarget->getHeight(); internalFormat = renderTarget->getInternalFormat(); format = sw2es::ConvertBackBufferFormat(internalFormat); - mSamples = renderTarget->getMultiSampleDepth(); + mSamples = renderTarget->getMultiSampleDepth() & ~1; } } @@ -341,14 +341,7 @@ Device *device = getDevice(); sw::Format requestedFormat = es2sw::ConvertRenderbufferFormat(format); - int supportedSamples = getContext()->getNearestSupportedSamples(requestedFormat, samples); - - if(supportedSamples == -1) - { - error(GL_OUT_OF_MEMORY); - - return; - } + int supportedSamples = Context::getSupportedMultiSampleDepth(requestedFormat, samples); if(width > 0 && height > 0) { @@ -365,7 +358,7 @@ mHeight = height; this->format = format; internalFormat = requestedFormat; - mSamples = supportedSamples; + mSamples = supportedSamples & ~1; } Colorbuffer::~Colorbuffer() @@ -398,7 +391,7 @@ mHeight = depthStencil->getHeight(); internalFormat = depthStencil->getInternalFormat(); format = sw2es::ConvertDepthStencilFormat(internalFormat); - mSamples = depthStencil->getMultiSampleDepth(); + mSamples = depthStencil->getMultiSampleDepth() & ~1; } } @@ -408,14 +401,7 @@ mDepthStencil = NULL; - int supportedSamples = getContext()->getNearestSupportedSamples(sw::FORMAT_D24S8, samples); - - if(supportedSamples == -1) - { - error(GL_OUT_OF_MEMORY); - - return; - } + int supportedSamples = Context::getSupportedMultiSampleDepth(sw::FORMAT_D24S8, samples); if(width > 0 && height > 0) { @@ -432,7 +418,7 @@ mHeight = height; format = GL_DEPTH24_STENCIL8_OES; internalFormat = sw::FORMAT_D24S8; - mSamples = supportedSamples; + mSamples = supportedSamples & ~1; } DepthStencilbuffer::~DepthStencilbuffer()
diff --git a/src/GLES2/libGLESv2/Shader.cpp b/src/GLES2/libGLESv2/Shader.cpp index f144a24..e4cb5ee 100644 --- a/src/GLES2/libGLESv2/Shader.cpp +++ b/src/GLES2/libGLESv2/Shader.cpp
@@ -1,6 +1,6 @@ // SwiftShader Software Renderer // -// Copyright(c) 2005-2012 TransGaming Inc. +// Copyright(c) 2005-2013 TransGaming Inc. // // All rights reserved. No part of this software may be copied, distributed, transmitted, // transcribed, stored in a retrieval system, translated into any human or computer @@ -24,16 +24,12 @@ namespace gl { -void *Shader::mFragmentCompiler = NULL; -void *Shader::mVertexCompiler = NULL; - Shader::Shader(ResourceManager *manager, GLuint handle) : mHandle(handle), mResourceManager(manager) { mSource = NULL; mInfoLog = NULL; clear(); - initializeCompiler(); mRefCount = 0; mDeleteStatus = false; @@ -156,6 +152,30 @@ } } +TranslatorASM *Shader::createCompiler(ShShaderType type) +{ + ShInitialize(); + + TranslatorASM *assembler = new TranslatorASM(this, type, SH_GLES2_SPEC); + + ShBuiltInResources resources; + ShInitBuiltInResources(&resources); + resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS; + resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS; + resources.MaxVaryingVectors = MAX_VARYING_VECTORS; + resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; + resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; + resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; + resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS; + resources.MaxDrawBuffers = MAX_DRAW_BUFFERS; + resources.OES_standard_derivatives = 1; + resources.OES_fragment_precision_high = 1; + resources.MaxCallStackDepth = 16; + assembler->Init(resources); + + return assembler; +} + void Shader::clear() { delete[] mInfoLog; @@ -210,43 +230,8 @@ mDeleteStatus = true; } -// Perform a one-time initialization of the shader compiler (or after being destructed by releaseCompiler) -void Shader::initializeCompiler() -{ - if(!mFragmentCompiler) - { - int result = ShInitialize(); - - if(result) - { - ShBuiltInResources resources; - ShInitBuiltInResources(&resources); - Context *context = getContext(); - - resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS; - resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS; - resources.MaxVaryingVectors = MAX_VARYING_VECTORS; - resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; - resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; - resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; - resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS; - resources.MaxDrawBuffers = MAX_DRAW_BUFFERS; - resources.OES_standard_derivatives = 1; - - mFragmentCompiler = ShConstructCompiler(SH_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources); - mVertexCompiler = ShConstructCompiler(SH_VERTEX_SHADER, SH_GLES2_SPEC, &resources); - } - } -} - void Shader::releaseCompiler() { - ShDestruct(mFragmentCompiler); - ShDestruct(mVertexCompiler); - - mFragmentCompiler = NULL; - mVertexCompiler = NULL; - ShFinalize(); } @@ -386,25 +371,11 @@ void VertexShader::compile() { clear(); - initializeCompiler(); delete vertexShader; vertexShader = new sw::VertexShader(); - TranslatorASM *assembler = new TranslatorASM(this, SH_VERTEX_SHADER, SH_GLES2_SPEC); - - ShBuiltInResources resources; - ShInitBuiltInResources(&resources); - resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS; - resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS; - resources.MaxVaryingVectors = MAX_VARYING_VECTORS; - resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; - resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; - resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; - resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS; - resources.MaxDrawBuffers = MAX_DRAW_BUFFERS; - resources.OES_standard_derivatives = 1; - assembler->Init(resources); + TranslatorASM *compiler = createCompiler(SH_VERTEX_SHADER); // Ensure we don't pass a NULL source to the compiler char *source = "\0"; @@ -413,7 +384,7 @@ source = mSource; } - int success = ShCompile(assembler, &source, 1, SH_OBJECT_CODE); + int success = ShCompile(compiler, &source, 1, SH_OBJECT_CODE); if(false) { @@ -433,13 +404,13 @@ vertexShader = 0; int infoLogLen = 0; - ShGetInfo(assembler, SH_INFO_LOG_LENGTH, &infoLogLen); + ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); mInfoLog = new char[infoLogLen]; - ShGetInfoLog(assembler, mInfoLog); + ShGetInfoLog(compiler, mInfoLog); TRACE("\n%s", mInfoLog); } - delete assembler; + delete compiler; } int VertexShader::getSemanticIndex(const std::string &attributeName) @@ -486,25 +457,11 @@ void FragmentShader::compile() { clear(); - initializeCompiler(); delete pixelShader; pixelShader = new sw::PixelShader(); - TranslatorASM *assembler = new TranslatorASM(this, SH_FRAGMENT_SHADER, SH_GLES2_SPEC); - - ShBuiltInResources resources; - ShInitBuiltInResources(&resources); - resources.MaxVertexAttribs = MAX_VERTEX_ATTRIBS; - resources.MaxVertexUniformVectors = MAX_VERTEX_UNIFORM_VECTORS; - resources.MaxVaryingVectors = MAX_VARYING_VECTORS; - resources.MaxVertexTextureImageUnits = MAX_VERTEX_TEXTURE_IMAGE_UNITS; - resources.MaxCombinedTextureImageUnits = MAX_COMBINED_TEXTURE_IMAGE_UNITS; - resources.MaxTextureImageUnits = MAX_TEXTURE_IMAGE_UNITS; - resources.MaxFragmentUniformVectors = MAX_FRAGMENT_UNIFORM_VECTORS; - resources.MaxDrawBuffers = MAX_DRAW_BUFFERS; - resources.OES_standard_derivatives = 1; - assembler->Init(resources); + TranslatorASM *compiler = createCompiler(SH_FRAGMENT_SHADER); // Ensure we don't pass a NULL source to the compiler char *source = "\0"; @@ -513,7 +470,7 @@ source = mSource; } - int success = ShCompile(assembler, &source, 1, SH_OBJECT_CODE); + int success = ShCompile(compiler, &source, 1, SH_OBJECT_CODE); if(false) { @@ -533,13 +490,13 @@ pixelShader = 0; int infoLogLen = 0; - ShGetInfo(assembler, SH_INFO_LOG_LENGTH, &infoLogLen); + ShGetInfo(compiler, SH_INFO_LOG_LENGTH, &infoLogLen); mInfoLog = new char[infoLogLen]; - ShGetInfoLog(assembler, mInfoLog); + ShGetInfoLog(compiler, mInfoLog); TRACE("\n%s", mInfoLog); } - delete assembler; + delete compiler; } sw::Shader *FragmentShader::getShader() const
diff --git a/src/GLES2/libGLESv2/Shader.h b/src/GLES2/libGLESv2/Shader.h index 6629c39..b6e7e70 100644 --- a/src/GLES2/libGLESv2/Shader.h +++ b/src/GLES2/libGLESv2/Shader.h
@@ -1,6 +1,6 @@ // SwiftShader Software Renderer // -// Copyright(c) 2005-2012 TransGaming Inc. +// Copyright(c) 2005-2013 TransGaming Inc. // // All rights reserved. No part of this software may be copied, distributed, transmitted, // transcribed, stored in a retrieval system, translated into any human or computer @@ -97,8 +97,8 @@ static void releaseCompiler(); protected: + TranslatorASM *createCompiler(ShShaderType type); void clear(); - void initializeCompiler(); static GLenum parseType(const std::string &type); static bool compareVarying(const Varying &x, const Varying &y); @@ -116,9 +116,6 @@ bool mDeleteStatus; // Flag to indicate that the shader can be deleted when no longer in use ResourceManager *mResourceManager; - - static void *mFragmentCompiler; - static void *mVertexCompiler; }; class VertexShader : public Shader
diff --git a/src/GLES2/libGLESv2/Texture.cpp b/src/GLES2/libGLESv2/Texture.cpp index dedc7cb..a6f3886 100644 --- a/src/GLES2/libGLESv2/Texture.cpp +++ b/src/GLES2/libGLESv2/Texture.cpp
@@ -284,7 +284,7 @@ { if(image[i]) { - image[i]->release(); + image[i]->unbind(); image[i] = 0; } } @@ -378,18 +378,16 @@ { if(image[level]) { - image[level]->release(); + image[level]->unbind(); } - image[level] = new Image(resource, width, height, format, type); + image[level] = new Image(this, width, height, format, type); if(!image[level]) { return error(GL_OUT_OF_MEMORY); } - image[level]->addRef(); - Texture::setImage(format, type, unpackAlignment, pixels, image[level]); } @@ -414,7 +412,7 @@ { if(image[level]) { - image[level]->release(); + image[level]->unbind(); image[level] = 0; } } @@ -431,7 +429,7 @@ { if(image[level]) { - image[level]->release(); + image[level]->unbind(); image[level] = 0; } } @@ -441,18 +439,16 @@ { if(image[level]) { - image[level]->release(); + image[level]->unbind(); } - image[level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE); + image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE); if(!image[level]) { return error(GL_OUT_OF_MEMORY); } - image[level]->addRef(); - Texture::setCompressedImage(imageSize, pixels, image[level]); } @@ -478,18 +474,16 @@ if(image[level]) { - image[level]->release(); + image[level]->unbind(); } - image[level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE); + image[level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE); if(!image[level]) { return error(GL_OUT_OF_MEMORY); } - image[level]->addRef(); - if(width != 0 && height != 0) { sw::Rect sourceRect = {x, y, x + width, y + height}; @@ -618,18 +612,16 @@ { if(image[i]) { - image[i]->release(); + image[i]->unbind(); } - image[i] = new Image(resource, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType()); + image[i] = new Image(this, std::max(image[0]->getWidth() >> i, 1), std::max(image[0]->getHeight() >> i, 1), image[0]->getFormat(), image[0]->getType()); if(!image[i]) { return error(GL_OUT_OF_MEMORY); } - image[i]->addRef(); - getDevice()->stretchRect(image[i - 1], 0, image[i], 0, true); } } @@ -693,7 +685,7 @@ { if(image[f][i]) { - image[f][i]->release(); + image[f][i]->unbind(); image[f][i] = 0; } } @@ -801,18 +793,16 @@ if(image[face][level]) { - image[face][level]->release(); + image[face][level]->unbind(); } - image[face][level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE); + image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE); if(!image[face][level]) { return error(GL_OUT_OF_MEMORY); } - image[face][level]->addRef(); - Texture::setCompressedImage(imageSize, pixels, image[face][level]); } @@ -939,18 +929,16 @@ if(image[face][level]) { - image[face][level]->release(); + image[face][level]->unbind(); } - image[face][level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE); + image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE); if(!image[face][level]) { return error(GL_OUT_OF_MEMORY); } - image[face][level]->addRef(); - Texture::setImage(format, type, unpackAlignment, pixels, image[face][level]); } @@ -968,18 +956,16 @@ if(image[face][level]) { - image[face][level]->release(); + image[face][level]->unbind(); } - image[face][level] = new Image(resource, width, height, format, GL_UNSIGNED_BYTE); + image[face][level] = new Image(this, width, height, format, GL_UNSIGNED_BYTE); if(!image[face][level]) { return error(GL_OUT_OF_MEMORY); } - image[face][level]->addRef(); - if(width != 0 && height != 0) { sw::Rect sourceRect = {x, y, x + width, y + height}; @@ -1048,18 +1034,16 @@ { if(image[f][i]) { - image[f][i]->release(); + image[f][i]->unbind(); } - image[f][i] = new Image(resource, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType()); + image[f][i] = new Image(this, std::max(image[0][0]->getWidth() >> i, 1), std::max(image[0][0]->getHeight() >> i, 1), image[0][0]->getFormat(), image[0][0]->getType()); if(!image[f][i]) { return error(GL_OUT_OF_MEMORY); } - image[f][i]->addRef(); - getDevice()->stretchRect(image[f][i - 1], 0, image[f][i], 0, true); } }
diff --git a/src/GLES2/libGLESv2/Texture.h b/src/GLES2/libGLESv2/Texture.h index d62a537..302c7f0 100644 --- a/src/GLES2/libGLESv2/Texture.h +++ b/src/GLES2/libGLESv2/Texture.h
@@ -90,8 +90,6 @@ virtual void generateMipmaps() = 0; virtual void copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source) = 0; - static const GLuint INCOMPLETE_TEXTURE_ID = static_cast<GLuint>(-1); // Every texture takes an id at creation time. The value is arbitrary because it is never registered with the resource manager. - protected: void setImage(GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image); void subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image); @@ -116,7 +114,7 @@ public: explicit Texture2D(GLuint id); - ~Texture2D(); + virtual ~Texture2D(); virtual bool isTexture2D(); @@ -172,7 +170,7 @@ public: explicit TextureCubeMap(GLuint id); - ~TextureCubeMap(); + virtual ~TextureCubeMap(); virtual bool isTextureCubeMap();
diff --git a/src/GLES2/libGLESv2/libGLESv2.cbp b/src/GLES2/libGLESv2/libGLESv2.cbp index 8f5d976..443c986 100644 --- a/src/GLES2/libGLESv2/libGLESv2.cbp +++ b/src/GLES2/libGLESv2/libGLESv2.cbp
@@ -141,12 +141,12 @@ <Unit filename="./../../Common/Version.h" /> <Unit filename="./../common/debug.cpp" /> <Unit filename="./../common/debug.h" /> + <Unit filename="../compiler/AnalyzeCallDepth.cpp" /> + <Unit filename="../compiler/AnalyzeCallDepth.h" /> <Unit filename="../compiler/BaseTypes.h" /> <Unit filename="../compiler/Common.h" /> <Unit filename="../compiler/Compiler.cpp" /> <Unit filename="../compiler/ConstantUnion.h" /> - <Unit filename="../compiler/DetectRecursion.cpp" /> - <Unit filename="../compiler/DetectRecursion.h" /> <Unit filename="../compiler/Diagnostics.cpp" /> <Unit filename="../compiler/Diagnostics.h" /> <Unit filename="../compiler/DirectiveHandler.cpp" />
diff --git a/src/GLES2/libGLESv2/libGLESv2.cpp b/src/GLES2/libGLESv2/libGLESv2.cpp index 0448330..96f004e 100644 --- a/src/GLES2/libGLESv2/libGLESv2.cpp +++ b/src/GLES2/libGLESv2/libGLESv2.cpp
@@ -24,6 +24,7 @@ #include "Query.h" #include "common/debug.h" #include "Common/Version.h" +#include "Main/Register.hpp" #define GL_APICALL #include <GLES2/gl2.h> @@ -1119,7 +1120,7 @@ return error(GL_INVALID_FRAMEBUFFER_OPERATION); } - if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0) + if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() > 1) { return error(GL_INVALID_OPERATION); } @@ -1255,7 +1256,7 @@ return error(GL_INVALID_FRAMEBUFFER_OPERATION); } - if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0) + if(context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() > 1) { return error(GL_INVALID_OPERATION); } @@ -3200,26 +3201,17 @@ switch(pname) { - case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; - case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; - case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break; - case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; - case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; - case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; - case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; - case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; - case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; - case GL_RENDERBUFFER_SAMPLES_ANGLE: - if(gl::IMPLEMENTATION_MAX_SAMPLES != 0) - { - *params = renderbuffer->getSamples(); - } - else - { - return error(GL_INVALID_ENUM); - } - break; - default: + case GL_RENDERBUFFER_WIDTH: *params = renderbuffer->getWidth(); break; + case GL_RENDERBUFFER_HEIGHT: *params = renderbuffer->getHeight(); break; + case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat(); break; + case GL_RENDERBUFFER_RED_SIZE: *params = renderbuffer->getRedSize(); break; + case GL_RENDERBUFFER_GREEN_SIZE: *params = renderbuffer->getGreenSize(); break; + case GL_RENDERBUFFER_BLUE_SIZE: *params = renderbuffer->getBlueSize(); break; + case GL_RENDERBUFFER_ALPHA_SIZE: *params = renderbuffer->getAlphaSize(); break; + case GL_RENDERBUFFER_DEPTH_SIZE: *params = renderbuffer->getDepthSize(); break; + case GL_RENDERBUFFER_STENCIL_SIZE: *params = renderbuffer->getStencilSize(); break; + case GL_RENDERBUFFER_SAMPLES_ANGLE: *params = renderbuffer->getSamples(); break; + default: return error(GL_INVALID_ENUM); } } @@ -6118,4 +6110,9 @@ } } +void GL_APIENTRY Register(const char *licenseKey) +{ + RegisterLicenseKey(licenseKey); +} + }
diff --git a/src/GLES2/libGLESv2/libGLESv2.vcxproj b/src/GLES2/libGLESv2/libGLESv2.vcxproj index 924cd42..622d914 100644 --- a/src/GLES2/libGLESv2/libGLESv2.vcxproj +++ b/src/GLES2/libGLESv2/libGLESv2.vcxproj
@@ -80,13 +80,10 @@ <BrowseInformation>true</BrowseInformation> </ClCompile> <Link> - <AdditionalDependencies>dxguid.lib;dwmapi.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> <TargetMachine>MachineX86</TargetMachine> </Link> <PostBuildEvent> @@ -114,16 +111,13 @@ <IntrinsicFunctions>false</IntrinsicFunctions> </ClCompile> <Link> - <AdditionalDependencies>dxguid.lib;dwmapi.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> - <RandomizedBaseAddress>false</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> <TargetMachine>MachineX86</TargetMachine> </Link> <PostBuildEvent> @@ -150,16 +144,13 @@ <IntrinsicFunctions>false</IntrinsicFunctions> </ClCompile> <Link> - <AdditionalDependencies>dxguid.lib;dwmapi.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> + <AdditionalDependencies>dxguid.lib;WS2_32.lib;%(AdditionalDependencies)</AdditionalDependencies> <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries> <ModuleDefinitionFile>libGLESv2.def</ModuleDefinitionFile> <GenerateDebugInformation>true</GenerateDebugInformation> <SubSystem>Windows</SubSystem> <OptimizeReferences>true</OptimizeReferences> <EnableCOMDATFolding>true</EnableCOMDATFolding> - <RandomizedBaseAddress>true</RandomizedBaseAddress> - <DataExecutionPrevention> - </DataExecutionPrevention> <TargetMachine>MachineX86</TargetMachine> </Link> <PostBuildEvent> @@ -238,4 +229,4 @@ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <ImportGroup Label="ExtensionTargets"> </ImportGroup> -</Project> +</Project> \ No newline at end of file
diff --git a/src/GLES2/libGLESv2/main.cpp b/src/GLES2/libGLESv2/main.cpp index 4393ae7..9ddca97 100644 --- a/src/GLES2/libGLESv2/main.cpp +++ b/src/GLES2/libGLESv2/main.cpp
@@ -1,6 +1,6 @@ // SwiftShader Software Renderer // -// Copyright(c) 2005-2012 TransGaming Inc. +// Copyright(c) 2005-2013 TransGaming Inc. // // All rights reserved. No part of this software may be copied, distributed, transmitted, // transcribed, stored in a retrieval system, translated into any human or computer @@ -107,9 +107,21 @@ namespace gl { +static gl::Current *getCurrent(void) +{ + Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + + if(!current) + { + glAttachThread(); + } + + return (Current*)sw::Thread::getLocalStorage(currentTLS); +} + void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = getCurrent(); current->context = context; current->display = display; @@ -122,14 +134,14 @@ Context *getContext() { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = getCurrent(); return current->context; } egl::Display *getDisplay() { - Current *current = (Current*)sw::Thread::getLocalStorage(currentTLS); + Current *current = getCurrent(); return current->display; }