/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES Utilities
 * ------------------------------------------------
 *
 * Copyright 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Shader .test file utilities.
 *//*--------------------------------------------------------------------*/

#include "gluShaderLibrary.hpp"

#include "tcuStringTemplate.hpp"
#include "tcuResource.hpp"
#include "tcuTestLog.hpp"

#include "deStringUtil.hpp"
#include "deUniquePtr.hpp"
#include "deFilePath.hpp"

#include "glwEnums.hpp"

#include <sstream>
#include <map>
#include <cstdlib>

#if 0
#	define PARSE_DBG(X) printf X
#else
#	define PARSE_DBG(X) DE_NULL_STATEMENT
#endif

namespace glu
{
namespace sl
{

using namespace tcu;

using std::vector;
using std::string;
using std::map;
using std::ostringstream;
using std::pair;
using de::UniquePtr;

// Specification

bool isValid (const ValueBlock& block)
{
	for (size_t storageNdx = 0; storageNdx < 3; ++storageNdx)
	{
		const vector<Value>&	values		= storageNdx == 0 ? block.inputs	:
											  storageNdx == 1 ? block.outputs	:
																block.uniforms;
		const size_t			refArrayLen	= values.empty() ? 0 : (values[0].elements.size() / (size_t)values[0].type.getScalarSize());

		for (size_t valNdx = 0; valNdx < values.size(); ++valNdx)
		{
			const Value&	value	= values[valNdx];

			if (!value.type.isBasicType())
			{
				print("ERROR: Value '%s' is of unsupported type!\n", value.name.c_str());
				return false;
			}

			if (value.elements.size() != refArrayLen*(size_t)value.type.getScalarSize())
			{
				print("ERROR: Value '%s' has invalid number of scalars!\n", value.name.c_str());
				return false;
			}
		}
	}

	return true;
}

bool isValid (const ShaderCaseSpecification& spec)
{
	const deUint32	vtxFragMask			= (1u << SHADERTYPE_VERTEX)
										| (1u << SHADERTYPE_FRAGMENT);
	const deUint32	tessCtrlEvalMask	= (1u << SHADERTYPE_TESSELLATION_CONTROL)
										| (1u << SHADERTYPE_TESSELLATION_EVALUATION);
	const deUint32	supportedStageMask	= vtxFragMask | tessCtrlEvalMask
										| (1u << SHADERTYPE_GEOMETRY);
	const bool		isSeparable			= !spec.programs.empty() && spec.programs[0].sources.separable;

	if (spec.programs.empty())
	{
		print("ERROR: No programs specified!\n");
		return false;
	}

	if (isCapabilityRequired(CAPABILITY_FULL_GLSL_ES_100_SUPPORT, spec))
	{
		if (spec.targetVersion != GLSL_VERSION_100_ES)
		{
			print("ERROR: Full GLSL ES 1.00 support requested for other GLSL version!\n");
			return false;
		}

		if (spec.expectResult != EXPECT_PASS			&&
			spec.expectResult != EXPECT_VALIDATION_FAIL	&&
			spec.expectResult != EXPECT_BUILD_SUCCESSFUL)
		{
			print("ERROR: Full GLSL ES 1.00 support doesn't make sense when expecting compile/link failure!\n");
			return false;
		}
	}

	if (!de::inBounds(spec.caseType, (CaseType)0, CASETYPE_LAST))
	{
		print("ERROR: Invalid case type!\n");
		return false;
	}

	if (!de::inBounds(spec.expectResult, (ExpectResult)0, EXPECT_LAST))
	{
		print("ERROR: Invalid expected result!\n");
		return false;
	}

	if (!isValid(spec.values))
		return false;

	if (!spec.values.inputs.empty() && !spec.values.outputs.empty() &&
		spec.values.inputs[0].elements.size() / spec.values.inputs[0].type.getScalarSize() != spec.values.outputs[0].elements.size() / spec.values.outputs[0].type.getScalarSize())
	{
		print("ERROR: Number of input and output elements don't match!\n");
		return false;
	}

	if (isSeparable)
	{
		deUint32	usedStageMask	= 0u;

		if (spec.caseType != CASETYPE_COMPLETE)
		{
			print("ERROR: Separable shaders supported only for complete cases!\n");
			return false;
		}

		for (size_t progNdx = 0; progNdx < spec.programs.size(); ++progNdx)
		{
			for (int shaderStageNdx = 0; shaderStageNdx < SHADERTYPE_LAST; ++shaderStageNdx)
			{
				const deUint32	curStageMask	= (1u << shaderStageNdx);

				if (supportedStageMask & curStageMask)
				{
					const bool		hasShader	= !spec.programs[progNdx].sources.sources[shaderStageNdx].empty();
					const bool		isEnabled	= (spec.programs[progNdx].activeStages & curStageMask) != 0;

					if (hasShader != isEnabled)
					{
						print("ERROR: Inconsistent source/enable for shader stage %s!\n", getShaderTypeName((ShaderType)shaderStageNdx));
						return false;
					}

					if (hasShader && (usedStageMask & curStageMask) != 0)
					{
						print("ERROR: Stage %s enabled on multiple programs!\n", getShaderTypeName((ShaderType)shaderStageNdx));
						return false;
					}

					if (isEnabled)
						usedStageMask |= curStageMask;
				}
				else if (!spec.programs[progNdx].sources.sources[shaderStageNdx].empty())
				{
					print("ERROR: Source specified for unsupported shader stage %s!\n", getShaderTypeName((ShaderType)shaderStageNdx));
					return false;
				}
			}
		}

		if ((usedStageMask & vtxFragMask) != vtxFragMask)
		{
			print("ERROR: Vertex and fragment shaders are mandatory!\n");
			return false;
		}

		if ((usedStageMask & tessCtrlEvalMask) != 0 && (usedStageMask & tessCtrlEvalMask) != tessCtrlEvalMask)
		{
			print("ERROR: Both tessellation control and eval shaders must be either enabled or disabled!\n");
			return false;
		}
	}
	else
	{
		const bool	hasVertex		= !spec.programs[0].sources.sources[SHADERTYPE_VERTEX].empty();
		const bool	hasFragment		= !spec.programs[0].sources.sources[SHADERTYPE_FRAGMENT].empty();

		if (spec.programs.size() != 1)
		{
			print("ERROR: Only cases using separable programs can have multiple programs!\n");
			return false;
		}

		if (spec.caseType == CASETYPE_VERTEX_ONLY && (!hasVertex || hasFragment))
		{
			print("ERROR: Vertex-only case must have only vertex shader!\n");
			return false;
		}

		if (spec.caseType == CASETYPE_FRAGMENT_ONLY && (hasVertex || !hasFragment))
		{
			print("ERROR: Fragment-only case must have only fragment shader!\n");
			return false;
		}

		if (spec.caseType == CASETYPE_COMPLETE && (!hasVertex || !hasFragment))
		{
			print("ERROR: Complete case must have at least vertex and fragment shaders\n");
			return false;
		}
	}

	return true;
}

bool isCapabilityRequired(CapabilityFlag capabilityFlag, const ShaderCaseSpecification& spec)
{
	std::vector<RequiredCapability>::const_iterator currRequirement = spec.requiredCaps.begin();
	while (currRequirement != spec.requiredCaps.end())
	{
		if ((currRequirement->type == CAPABILITY_FLAG) && (currRequirement->flagName == capabilityFlag))
			return true;
		++currRequirement;
	}

	return false;
}

// Parser

static const glu::GLSLVersion DEFAULT_GLSL_VERSION = glu::GLSL_VERSION_100_ES;

DE_INLINE deBool isWhitespace (char c)
{
	return (c == ' ') || (c == '\t') || (c == '\r') || (c == '\n');
}

DE_INLINE deBool isEOL (char c)
{
	return (c == '\r') || (c == '\n');
}

DE_INLINE deBool isNumeric (char c)
{
	return deInRange32(c, '0', '9');
}

DE_INLINE deBool isAlpha (char c)
{
	return deInRange32(c, 'a', 'z') || deInRange32(c, 'A', 'Z');
}

DE_INLINE deBool isCaseNameChar (char c)
{
	return deInRange32(c, 'a', 'z') || deInRange32(c, 'A', 'Z') || deInRange32(c, '0', '9') || (c == '_') || (c == '-') || (c == '.');
}

class ShaderParser
{
public:
							ShaderParser			(const tcu::Archive& archive, const std::string& filename, ShaderCaseFactory* caseFactory);
							~ShaderParser			(void);

	vector<tcu::TestNode*>	parse					(void);

private:
	enum Token
	{
		TOKEN_INVALID = 0,
		TOKEN_EOF,
		TOKEN_STRING,
		TOKEN_SHADER_SOURCE,

		TOKEN_INT_LITERAL,
		TOKEN_FLOAT_LITERAL,

		// identifiers
		TOKEN_IDENTIFIER,
		TOKEN_TRUE,
		TOKEN_FALSE,
		TOKEN_DESC,
		TOKEN_EXPECT,
		TOKEN_GROUP,
		TOKEN_CASE,
		TOKEN_END,
		TOKEN_OUTPUT_COLOR,
		TOKEN_FORMAT,
		TOKEN_VALUES,
		TOKEN_BOTH,
		TOKEN_VERTEX,
		TOKEN_FRAGMENT,
		TOKEN_UNIFORM,
		TOKEN_INPUT,
		TOKEN_OUTPUT,
		TOKEN_FLOAT,
		TOKEN_FLOAT_VEC2,
		TOKEN_FLOAT_VEC3,
		TOKEN_FLOAT_VEC4,
		TOKEN_FLOAT_MAT2,
		TOKEN_FLOAT_MAT2X3,
		TOKEN_FLOAT_MAT2X4,
		TOKEN_FLOAT_MAT3X2,
		TOKEN_FLOAT_MAT3,
		TOKEN_FLOAT_MAT3X4,
		TOKEN_FLOAT_MAT4X2,
		TOKEN_FLOAT_MAT4X3,
		TOKEN_FLOAT_MAT4,
		TOKEN_INT,
		TOKEN_INT_VEC2,
		TOKEN_INT_VEC3,
		TOKEN_INT_VEC4,
		TOKEN_UINT,
		TOKEN_UINT_VEC2,
		TOKEN_UINT_VEC3,
		TOKEN_UINT_VEC4,
		TOKEN_BOOL,
		TOKEN_BOOL_VEC2,
		TOKEN_BOOL_VEC3,
		TOKEN_BOOL_VEC4,
		TOKEN_VERSION,
		TOKEN_TESSELLATION_CONTROL,
		TOKEN_TESSELLATION_EVALUATION,
		TOKEN_GEOMETRY,
		TOKEN_REQUIRE,
		TOKEN_IN,
		TOKEN_IMPORT,
		TOKEN_PIPELINE_PROGRAM,
		TOKEN_ACTIVE_STAGES,

		// symbols
		TOKEN_ASSIGN,
		TOKEN_PLUS,
		TOKEN_MINUS,
		TOKEN_COMMA,
		TOKEN_VERTICAL_BAR,
		TOKEN_SEMI_COLON,
		TOKEN_LEFT_PAREN,
		TOKEN_RIGHT_PAREN,
		TOKEN_LEFT_BRACKET,
		TOKEN_RIGHT_BRACKET,
		TOKEN_LEFT_BRACE,
		TOKEN_RIGHT_BRACE,
		TOKEN_GREATER,

		TOKEN_LAST
	};

	void						parseError					(const std::string& errorStr);
	float						parseFloatLiteral			(const char* str);
	int							parseIntLiteral				(const char* str);
	string						parseStringLiteral			(const char* str);
	string						parseShaderSource			(const char* str);
	void						advanceToken				(void);
	void						advanceToken				(Token assumed);
	void						assumeToken					(Token token);
	DataType					mapDataTypeToken			(Token token);
	const char*					getTokenName				(Token token);
	deUint32					getShaderStageLiteralFlag	(void);
	deUint32					getGLEnumFromName			(const std::string& enumName);

	void						parseValueElement			(DataType dataType, Value& result);
	void						parseValue					(ValueBlock& valueBlock);
	void						parseValueBlock				(ValueBlock& valueBlock);
	deUint32					parseShaderStageList		(void);
	void						parseRequirement			(vector<RequiredCapability> &requiredCaps, vector<RequiredExtension> &requiredExts);
	void						parseExpectResult			(ExpectResult& expectResult);
	void						parseFormat					(DataType& format);
	void						parseGLSLVersion			(glu::GLSLVersion& version);
	void						parsePipelineProgram		(ProgramSpecification& program);
	void						parseShaderCase				(vector<tcu::TestNode*>& shaderNodeList);
	void						parseShaderGroup			(vector<tcu::TestNode*>& shaderNodeList);
	void						parseImport					(vector<tcu::TestNode*>& shaderNodeList);

	const tcu::Archive&			m_archive;
	const string				m_filename;
	ShaderCaseFactory* const	m_caseFactory;

	UniquePtr<tcu::Resource>	m_resource;
	vector<char>				m_input;

	const char*					m_curPtr;
	Token						m_curToken;
	std::string					m_curTokenStr;
};

ShaderParser::ShaderParser (const tcu::Archive& archive, const string& filename, ShaderCaseFactory* caseFactroy)
	: m_archive			(archive)
	, m_filename		(filename)
	, m_caseFactory		(caseFactroy)
	, m_resource		(archive.getResource(m_filename.c_str()))
	, m_curPtr			(DE_NULL)
	, m_curToken		(TOKEN_LAST)
{
}

ShaderParser::~ShaderParser (void)
{
}

void ShaderParser::parseError (const std::string& errorStr)
{
	string atStr = string(m_curPtr, 80);
	throw tcu::InternalError((string("Parser error: ") + errorStr + " near '" + atStr + " ...'").c_str(), DE_NULL, __FILE__, __LINE__);
}

float ShaderParser::parseFloatLiteral (const char* str)
{
	return (float)atof(str);
}

int ShaderParser::parseIntLiteral (const char* str)
{
	return atoi(str);
}

string ShaderParser::parseStringLiteral (const char* str)
{
	const char*		p		= str;
	char			endChar = *p++;
	ostringstream	o;

	while (*p != endChar && *p)
	{
		if (*p == '\\')
		{
			switch (p[1])
			{
				case 0:		DE_ASSERT(DE_FALSE);	break;
				case 'n':	o << '\n';				break;
				case 't':	o << '\t';				break;
				default:	o << p[1];				break;
			}

			p += 2;
		}
		else
			o << *p++;
	}

	return o.str();
}

static string removeExtraIndentation (const string& source)
{
	// Detect indentation from first line.
	int numIndentChars = 0;
	for (int ndx = 0; ndx < (int)source.length() && isWhitespace(source[ndx]); ndx++)
		numIndentChars += source[ndx] == '\t' ? 4 : 1;

	// Process all lines and remove preceding indentation.
	ostringstream processed;
	{
		bool	atLineStart			= true;
		int		indentCharsOmitted	= 0;

		for (int pos = 0; pos < (int)source.length(); pos++)
		{
			char c = source[pos];

			if (atLineStart && indentCharsOmitted < numIndentChars && (c == ' ' || c == '\t'))
			{
				indentCharsOmitted += c == '\t' ? 4 : 1;
			}
			else if (isEOL(c))
			{
				if (source[pos] == '\r' && source[pos+1] == '\n')
				{
					pos += 1;
					processed << '\n';
				}
				else
					processed << c;

				atLineStart			= true;
				indentCharsOmitted	= 0;
			}
			else
			{
				processed << c;
				atLineStart = false;
			}
		}
	}

	return processed.str();
}

string ShaderParser::parseShaderSource (const char* str)
{
	const char*		p = str+2;
	ostringstream	o;

	// Eat first empty line from beginning.
	while (*p == ' ') p++;
	if (*p == '\r') p++;
	if (*p == '\n') p++;

	while ((p[0] != '"') || (p[1] != '"'))
	{
		if (*p == '\\')
		{
			switch (p[1])
			{
				case 0:		DE_ASSERT(DE_FALSE);	break;
				case 'n':	o << '\n';				break;
				case 't':	o << '\t';				break;
				default:	o << p[1];				break;
			}

			p += 2;
		}
		else
			o << *p++;
	}

	return removeExtraIndentation(o.str());
}

void ShaderParser::advanceToken (void)
{
	// Skip old token.
	m_curPtr += m_curTokenStr.length();

	// Reset token (for safety).
	m_curToken		= TOKEN_INVALID;
	m_curTokenStr	= "";

	// Eat whitespace & comments while they last.
	for (;;)
	{
		while (isWhitespace(*m_curPtr))
			m_curPtr++;

		// Check for EOL comment.
		if (*m_curPtr == '#')
		{
			while (*m_curPtr && !isEOL(*m_curPtr))
				m_curPtr++;
		}
		else
			break;
	}

	if (!*m_curPtr)
	{
		m_curToken = TOKEN_EOF;
		m_curTokenStr = "<EOF>";
	}
	else if (isAlpha(*m_curPtr))
	{
		struct Named
		{
			const char*		str;
			Token			token;
		};

		static const Named s_named[] =
		{
			{ "true",						TOKEN_TRUE						},
			{ "false",						TOKEN_FALSE						},
			{ "desc",						TOKEN_DESC						},
			{ "expect",						TOKEN_EXPECT					},
			{ "group",						TOKEN_GROUP						},
			{ "case",						TOKEN_CASE						},
			{ "end",						TOKEN_END						},
			{ "output_color",				TOKEN_OUTPUT_COLOR				},
			{ "format",						TOKEN_FORMAT					},
			{ "values",						TOKEN_VALUES					},
			{ "both",						TOKEN_BOTH						},
			{ "vertex",						TOKEN_VERTEX					},
			{ "fragment",					TOKEN_FRAGMENT					},
			{ "uniform",					TOKEN_UNIFORM					},
			{ "input",						TOKEN_INPUT						},
			{ "output",						TOKEN_OUTPUT					},
			{ "float",						TOKEN_FLOAT						},
			{ "vec2",						TOKEN_FLOAT_VEC2				},
			{ "vec3",						TOKEN_FLOAT_VEC3				},
			{ "vec4",						TOKEN_FLOAT_VEC4				},
			{ "mat2",						TOKEN_FLOAT_MAT2				},
			{ "mat2x3",						TOKEN_FLOAT_MAT2X3				},
			{ "mat2x4",						TOKEN_FLOAT_MAT2X4				},
			{ "mat3x2",						TOKEN_FLOAT_MAT3X2				},
			{ "mat3",						TOKEN_FLOAT_MAT3				},
			{ "mat3x4",						TOKEN_FLOAT_MAT3X4				},
			{ "mat4x2",						TOKEN_FLOAT_MAT4X2				},
			{ "mat4x3",						TOKEN_FLOAT_MAT4X3				},
			{ "mat4",						TOKEN_FLOAT_MAT4				},
			{ "int",						TOKEN_INT						},
			{ "ivec2",						TOKEN_INT_VEC2					},
			{ "ivec3",						TOKEN_INT_VEC3					},
			{ "ivec4",						TOKEN_INT_VEC4					},
			{ "uint",						TOKEN_UINT						},
			{ "uvec2",						TOKEN_UINT_VEC2					},
			{ "uvec3",						TOKEN_UINT_VEC3					},
			{ "uvec4",						TOKEN_UINT_VEC4					},
			{ "bool",						TOKEN_BOOL						},
			{ "bvec2",						TOKEN_BOOL_VEC2					},
			{ "bvec3",						TOKEN_BOOL_VEC3					},
			{ "bvec4",						TOKEN_BOOL_VEC4					},
			{ "version",					TOKEN_VERSION					},
			{ "tessellation_control",		TOKEN_TESSELLATION_CONTROL		},
			{ "tessellation_evaluation",	TOKEN_TESSELLATION_EVALUATION	},
			{ "geometry",					TOKEN_GEOMETRY					},
			{ "require",					TOKEN_REQUIRE					},
			{ "in",							TOKEN_IN						},
			{ "import",						TOKEN_IMPORT					},
			{ "pipeline_program",			TOKEN_PIPELINE_PROGRAM			},
			{ "active_stages",				TOKEN_ACTIVE_STAGES				},
		};

		const char* end = m_curPtr + 1;
		while (isCaseNameChar(*end))
			end++;
		m_curTokenStr = string(m_curPtr, end - m_curPtr);

		m_curToken = TOKEN_IDENTIFIER;

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_named); ndx++)
		{
			if (m_curTokenStr == s_named[ndx].str)
			{
				m_curToken = s_named[ndx].token;
				break;
			}
		}
	}
	else if (isNumeric(*m_curPtr))
	{
		/* \todo [2010-03-31 petri] Hex? */
		const char* p = m_curPtr;
		while (isNumeric(*p))
			p++;
		if (*p == '.')
		{
			p++;
			while (isNumeric(*p))
				p++;

			if (*p == 'e' || *p == 'E')
			{
				p++;
				if (*p == '+' || *p == '-')
					p++;
				DE_ASSERT(isNumeric(*p));
				while (isNumeric(*p))
					p++;
			}

			m_curToken = TOKEN_FLOAT_LITERAL;
			m_curTokenStr = string(m_curPtr, p - m_curPtr);
		}
		else
		{
			m_curToken = TOKEN_INT_LITERAL;
			m_curTokenStr = string(m_curPtr, p - m_curPtr);
		}
	}
	else if (*m_curPtr == '"' && m_curPtr[1] == '"')
	{
		const char*	p = m_curPtr + 2;

		while ((p[0] != '"') || (p[1] != '"'))
		{
			DE_ASSERT(*p);
			if (*p == '\\')
			{
				DE_ASSERT(p[1] != 0);
				p += 2;
			}
			else
				p++;
		}
		p += 2;

		m_curToken		= TOKEN_SHADER_SOURCE;
		m_curTokenStr	= string(m_curPtr, (int)(p - m_curPtr));
	}
	else if (*m_curPtr == '"' || *m_curPtr == '\'')
	{
		char		endChar = *m_curPtr;
		const char*	p		= m_curPtr + 1;

		while (*p != endChar)
		{
			DE_ASSERT(*p);
			if (*p == '\\')
			{
				DE_ASSERT(p[1] != 0);
				p += 2;
			}
			else
				p++;
		}
		p++;

		m_curToken		= TOKEN_STRING;
		m_curTokenStr	= string(m_curPtr, (int)(p - m_curPtr));
	}
	else
	{
		struct SimpleToken
		{
			const char*		str;
			Token			token;
		};

		static const SimpleToken s_simple[] =
		{
			{ "=",			TOKEN_ASSIGN		},
			{ "+",			TOKEN_PLUS			},
			{ "-",			TOKEN_MINUS			},
			{ ",",			TOKEN_COMMA			},
			{ "|",			TOKEN_VERTICAL_BAR	},
			{ ";",			TOKEN_SEMI_COLON	},
			{ "(",			TOKEN_LEFT_PAREN	},
			{ ")",			TOKEN_RIGHT_PAREN	},
			{ "[",			TOKEN_LEFT_BRACKET	},
			{ "]",			TOKEN_RIGHT_BRACKET },
			{ "{",			TOKEN_LEFT_BRACE	},
			{ "}",			TOKEN_RIGHT_BRACE	},
			{ ">",			TOKEN_GREATER		},
		};

		for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_simple); ndx++)
		{
			if (strncmp(s_simple[ndx].str, m_curPtr, strlen(s_simple[ndx].str)) == 0)
			{
				m_curToken		= s_simple[ndx].token;
				m_curTokenStr	= s_simple[ndx].str;
				return;
			}
		}

		// Otherwise invalid token.
		m_curToken = TOKEN_INVALID;
		m_curTokenStr = *m_curPtr;
	}
}

void ShaderParser::advanceToken (Token assumed)
{
	assumeToken(assumed);
	advanceToken();
}

void ShaderParser::assumeToken (Token token)
{
	if (m_curToken != token)
		parseError((string("unexpected token '") + m_curTokenStr + "', expecting '" + getTokenName(token) + "'").c_str());
	DE_TEST_ASSERT(m_curToken == token);
}

DataType ShaderParser::mapDataTypeToken (Token token)
{
	switch (token)
	{
		case TOKEN_FLOAT:			return TYPE_FLOAT;
		case TOKEN_FLOAT_VEC2:		return TYPE_FLOAT_VEC2;
		case TOKEN_FLOAT_VEC3:		return TYPE_FLOAT_VEC3;
		case TOKEN_FLOAT_VEC4:		return TYPE_FLOAT_VEC4;
		case TOKEN_FLOAT_MAT2:		return TYPE_FLOAT_MAT2;
		case TOKEN_FLOAT_MAT2X3:	return TYPE_FLOAT_MAT2X3;
		case TOKEN_FLOAT_MAT2X4:	return TYPE_FLOAT_MAT2X4;
		case TOKEN_FLOAT_MAT3X2:	return TYPE_FLOAT_MAT3X2;
		case TOKEN_FLOAT_MAT3:		return TYPE_FLOAT_MAT3;
		case TOKEN_FLOAT_MAT3X4:	return TYPE_FLOAT_MAT3X4;
		case TOKEN_FLOAT_MAT4X2:	return TYPE_FLOAT_MAT4X2;
		case TOKEN_FLOAT_MAT4X3:	return TYPE_FLOAT_MAT4X3;
		case TOKEN_FLOAT_MAT4:		return TYPE_FLOAT_MAT4;
		case TOKEN_INT:				return TYPE_INT;
		case TOKEN_INT_VEC2:		return TYPE_INT_VEC2;
		case TOKEN_INT_VEC3:		return TYPE_INT_VEC3;
		case TOKEN_INT_VEC4:		return TYPE_INT_VEC4;
		case TOKEN_UINT:			return TYPE_UINT;
		case TOKEN_UINT_VEC2:		return TYPE_UINT_VEC2;
		case TOKEN_UINT_VEC3:		return TYPE_UINT_VEC3;
		case TOKEN_UINT_VEC4:		return TYPE_UINT_VEC4;
		case TOKEN_BOOL:			return TYPE_BOOL;
		case TOKEN_BOOL_VEC2:		return TYPE_BOOL_VEC2;
		case TOKEN_BOOL_VEC3:		return TYPE_BOOL_VEC3;
		case TOKEN_BOOL_VEC4:		return TYPE_BOOL_VEC4;
		default:					return TYPE_INVALID;
	}
}

const char* ShaderParser::getTokenName (Token token)
{
	switch (token)
	{
		case TOKEN_INVALID:					return "<invalid>";
		case TOKEN_EOF:						return "<eof>";
		case TOKEN_STRING:					return "<string>";
		case TOKEN_SHADER_SOURCE:			return "source";

		case TOKEN_INT_LITERAL:				return "<int>";
		case TOKEN_FLOAT_LITERAL:			return "<float>";

		// identifiers
		case TOKEN_IDENTIFIER:				return "<identifier>";
		case TOKEN_TRUE:					return "true";
		case TOKEN_FALSE:					return "false";
		case TOKEN_DESC:					return "desc";
		case TOKEN_EXPECT:					return "expect";
		case TOKEN_GROUP:					return "group";
		case TOKEN_CASE:					return "case";
		case TOKEN_END:						return "end";
		case TOKEN_VALUES:					return "values";
		case TOKEN_BOTH:					return "both";
		case TOKEN_VERTEX:					return "vertex";
		case TOKEN_FRAGMENT:				return "fragment";
		case TOKEN_TESSELLATION_CONTROL:	return "tessellation_control";
		case TOKEN_TESSELLATION_EVALUATION:	return "tessellation_evaluation";
		case TOKEN_GEOMETRY:				return "geometry";
		case TOKEN_REQUIRE:					return "require";
		case TOKEN_UNIFORM:					return "uniform";
		case TOKEN_INPUT:					return "input";
		case TOKEN_OUTPUT:					return "output";
		case TOKEN_FLOAT:					return "float";
		case TOKEN_FLOAT_VEC2:				return "vec2";
		case TOKEN_FLOAT_VEC3:				return "vec3";
		case TOKEN_FLOAT_VEC4:				return "vec4";
		case TOKEN_FLOAT_MAT2:				return "mat2";
		case TOKEN_FLOAT_MAT2X3:			return "mat2x3";
		case TOKEN_FLOAT_MAT2X4:			return "mat2x4";
		case TOKEN_FLOAT_MAT3X2:			return "mat3x2";
		case TOKEN_FLOAT_MAT3:				return "mat3";
		case TOKEN_FLOAT_MAT3X4:			return "mat3x4";
		case TOKEN_FLOAT_MAT4X2:			return "mat4x2";
		case TOKEN_FLOAT_MAT4X3:			return "mat4x3";
		case TOKEN_FLOAT_MAT4:				return "mat4";
		case TOKEN_INT:						return "int";
		case TOKEN_INT_VEC2:				return "ivec2";
		case TOKEN_INT_VEC3:				return "ivec3";
		case TOKEN_INT_VEC4:				return "ivec4";
		case TOKEN_UINT:					return "uint";
		case TOKEN_UINT_VEC2:				return "uvec2";
		case TOKEN_UINT_VEC3:				return "uvec3";
		case TOKEN_UINT_VEC4:				return "uvec4";
		case TOKEN_BOOL:					return "bool";
		case TOKEN_BOOL_VEC2:				return "bvec2";
		case TOKEN_BOOL_VEC3:				return "bvec3";
		case TOKEN_BOOL_VEC4:				return "bvec4";
		case TOKEN_IN:						return "in";
		case TOKEN_IMPORT:					return "import";
		case TOKEN_PIPELINE_PROGRAM:		return "pipeline_program";
		case TOKEN_ACTIVE_STAGES:			return "active_stages";

		case TOKEN_ASSIGN:					return "=";
		case TOKEN_PLUS:					return "+";
		case TOKEN_MINUS:					return "-";
		case TOKEN_COMMA:					return ",";
		case TOKEN_VERTICAL_BAR:			return "|";
		case TOKEN_SEMI_COLON:				return ";";
		case TOKEN_LEFT_PAREN:				return "(";
		case TOKEN_RIGHT_PAREN:				return ")";
		case TOKEN_LEFT_BRACKET:			return "[";
		case TOKEN_RIGHT_BRACKET:			return "]";
		case TOKEN_LEFT_BRACE:				return "{";
		case TOKEN_RIGHT_BRACE:				return "}";
		case TOKEN_GREATER:					return ">";

		default:							return "<unknown>";
	}
}

deUint32 ShaderParser::getShaderStageLiteralFlag (void)
{
	switch (m_curToken)
	{
		case TOKEN_VERTEX:					return (1 << glu::SHADERTYPE_VERTEX);
		case TOKEN_FRAGMENT:				return (1 << glu::SHADERTYPE_FRAGMENT);
		case TOKEN_GEOMETRY:				return (1 << glu::SHADERTYPE_GEOMETRY);
		case TOKEN_TESSELLATION_CONTROL:	return (1 << glu::SHADERTYPE_TESSELLATION_CONTROL);
		case TOKEN_TESSELLATION_EVALUATION:	return (1 << glu::SHADERTYPE_TESSELLATION_EVALUATION);

		default:
			parseError(std::string() + "invalid shader stage name, got " + m_curTokenStr);
			return 0;
	}
}

deUint32 ShaderParser::getGLEnumFromName (const std::string& enumName)
{
	static const struct
	{
		const char*	name;
		deUint32	value;
	} names[] =
	{
		{ "GL_MAX_VERTEX_IMAGE_UNIFORMS",			GL_MAX_VERTEX_IMAGE_UNIFORMS			},
		{ "GL_MAX_VERTEX_ATOMIC_COUNTERS",			GL_MAX_VERTEX_ATOMIC_COUNTERS			},
		{ "GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS",	GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS		},
		{ "GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS",	GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS	},
	};

	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(names); ++ndx)
		if (names[ndx].name == enumName)
			return names[ndx].value;

	parseError(std::string() + "unknown enum name, got " + enumName);
	return 0;
}

void ShaderParser::parseValueElement (DataType expectedDataType, Value& result)
{
	DataType	scalarType	= getDataTypeScalarType(expectedDataType);
	int			scalarSize	= getDataTypeScalarSize(expectedDataType);

	/* \todo [2010-04-19 petri] Support arrays. */
	Value::Element elems[16];

	if (scalarSize > 1)
	{
		DE_ASSERT(mapDataTypeToken(m_curToken) == expectedDataType);
		advanceToken(); // data type (float, vec2, etc.)
		advanceToken(TOKEN_LEFT_PAREN);
	}

	for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
	{
		if (scalarType == TYPE_FLOAT)
		{
			float signMult = 1.0f;
			if (m_curToken == TOKEN_MINUS)
			{
				signMult = -1.0f;
				advanceToken();
			}

			assumeToken(TOKEN_FLOAT_LITERAL);
			elems[scalarNdx].float32 = signMult * parseFloatLiteral(m_curTokenStr.c_str());
			advanceToken(TOKEN_FLOAT_LITERAL);
		}
		else if (scalarType == TYPE_INT || scalarType == TYPE_UINT)
		{
			int signMult = 1;
			if (m_curToken == TOKEN_MINUS)
			{
				signMult = -1;
				advanceToken();
			}

			assumeToken(TOKEN_INT_LITERAL);
			elems[scalarNdx].int32 = signMult * parseIntLiteral(m_curTokenStr.c_str());
			advanceToken(TOKEN_INT_LITERAL);
		}
		else
		{
			DE_ASSERT(scalarType == TYPE_BOOL);
			elems[scalarNdx].bool32 = (m_curToken == TOKEN_TRUE);
			if (m_curToken != TOKEN_TRUE && m_curToken != TOKEN_FALSE)
				parseError(string("unexpected token, expecting bool: " + m_curTokenStr));
			advanceToken(); // true/false
		}

		if (scalarNdx != (scalarSize - 1))
			advanceToken(TOKEN_COMMA);
	}

	if (scalarSize > 1)
		advanceToken(TOKEN_RIGHT_PAREN);

	// Store results.
	for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
		result.elements.push_back(elems[scalarNdx]);
}

void ShaderParser::parseValue (ValueBlock& valueBlock)
{
	PARSE_DBG(("      parseValue()\n"));

	// Parsed results.
	vector<Value>*	dstBlock	= DE_NULL;
	DataType		basicType	= TYPE_LAST;
	std::string		valueName;

	// Parse storage.
	if (m_curToken == TOKEN_UNIFORM)
		dstBlock = &valueBlock.uniforms;
	else if (m_curToken == TOKEN_INPUT)
		dstBlock = &valueBlock.inputs;
	else if (m_curToken == TOKEN_OUTPUT)
		dstBlock = &valueBlock.outputs;
	else
		parseError(string("unexpected token encountered when parsing value classifier"));
	advanceToken();

	// Parse data type.
	basicType = mapDataTypeToken(m_curToken);
	if (basicType == TYPE_INVALID)
		parseError(string("unexpected token when parsing value data type: " + m_curTokenStr));
	advanceToken();

	// Parse value name.
	if (m_curToken == TOKEN_IDENTIFIER || m_curToken == TOKEN_STRING)
	{
		if (m_curToken == TOKEN_IDENTIFIER)
			valueName = m_curTokenStr;
		else
			valueName = parseStringLiteral(m_curTokenStr.c_str());
	}
	else
		parseError(string("unexpected token when parsing value name: " + m_curTokenStr));
	advanceToken();

	// Parse assignment operator.
	advanceToken(TOKEN_ASSIGN);

	{
		Value value;
		value.name	= valueName;
		value.type	= VarType(basicType, PRECISION_LAST);
		dstBlock->push_back(value);
	}

	// Parse actual value.
	if (m_curToken == TOKEN_LEFT_BRACKET) // value list
	{
		int	arrayLength	= 0; // \todo [2015-08-03 pyry] Currently unused

		advanceToken(TOKEN_LEFT_BRACKET);

		for (;;)
		{
			parseValueElement(basicType, dstBlock->back());
			arrayLength++;

			if (m_curToken == TOKEN_RIGHT_BRACKET)
				break;
			else if (m_curToken == TOKEN_VERTICAL_BAR)
			{
				advanceToken();
				continue;
			}
			else
				parseError(string("unexpected token in value element array: " + m_curTokenStr));
		}

		advanceToken(TOKEN_RIGHT_BRACKET);
	}
	else //  single elements
	{
		parseValueElement(basicType, dstBlock->back());
	}

	advanceToken(TOKEN_SEMI_COLON); // end of declaration
}

void ShaderParser::parseValueBlock (ValueBlock& valueBlock)
{
	PARSE_DBG(("    parseValueBlock()\n"));
	advanceToken(TOKEN_VALUES);
	advanceToken(TOKEN_LEFT_BRACE);

	for (;;)
	{
		if (m_curToken == TOKEN_UNIFORM || m_curToken == TOKEN_INPUT || m_curToken == TOKEN_OUTPUT)
			parseValue(valueBlock);
		else if (m_curToken == TOKEN_RIGHT_BRACE)
			break;
		else
			parseError(string("unexpected token when parsing a value block: " + m_curTokenStr));
	}

	advanceToken(TOKEN_RIGHT_BRACE);
}

deUint32 ShaderParser::parseShaderStageList (void)
{
	deUint32 mask = 0;

	assumeToken(TOKEN_LEFT_BRACE);

	// don't allow 0-sized lists
	advanceToken();
	mask |= getShaderStageLiteralFlag();
	advanceToken();

	for (;;)
	{
		if (m_curToken == TOKEN_RIGHT_BRACE)
			break;
		else if (m_curToken == TOKEN_COMMA)
		{
			deUint32 stageFlag;
			advanceToken();

			stageFlag = getShaderStageLiteralFlag();
			if (stageFlag & mask)
				parseError(string("stage already set in the shader stage set: " + m_curTokenStr));

			mask |= stageFlag;
			advanceToken();
		}
		else
			parseError(string("invalid shader stage set token: " + m_curTokenStr));
	}
	advanceToken(TOKEN_RIGHT_BRACE);

	return mask;
}

void ShaderParser::parseRequirement (vector<RequiredCapability>& requiredCaps, vector<RequiredExtension>& requiredExts)
{
	PARSE_DBG(("    parseRequirement()\n"));

	advanceToken();
	assumeToken(TOKEN_IDENTIFIER);

	if (m_curTokenStr == "extension")
	{
		std::vector<std::string>	anyExtensionStringList;
		deUint32					affectedCasesFlags		= -1; // by default all stages

		advanceToken();
		assumeToken(TOKEN_LEFT_BRACE);

		advanceToken();
		assumeToken(TOKEN_STRING);

		anyExtensionStringList.push_back(parseStringLiteral(m_curTokenStr.c_str()));
		advanceToken();

		for (;;)
		{
			if (m_curToken == TOKEN_RIGHT_BRACE)
				break;
			else if (m_curToken == TOKEN_VERTICAL_BAR)
			{
				advanceToken();
				assumeToken(TOKEN_STRING);

				anyExtensionStringList.push_back(parseStringLiteral(m_curTokenStr.c_str()));
				advanceToken();
			}
			else
				parseError(string("invalid extension list token: " + m_curTokenStr));
		}
		advanceToken(TOKEN_RIGHT_BRACE);

		if (m_curToken == TOKEN_IN)
		{
			advanceToken();
			affectedCasesFlags = parseShaderStageList();
		}

		requiredExts.push_back(RequiredExtension(anyExtensionStringList, affectedCasesFlags));
	}
	else if (m_curTokenStr == "limit")
	{
		deUint32	limitEnum;
		int			limitValue;

		advanceToken();

		assumeToken(TOKEN_STRING);
		limitEnum = getGLEnumFromName(parseStringLiteral(m_curTokenStr.c_str()));
		advanceToken();

		assumeToken(TOKEN_GREATER);
		advanceToken();

		assumeToken(TOKEN_INT_LITERAL);
		limitValue = parseIntLiteral(m_curTokenStr.c_str());
		advanceToken();

		requiredCaps.push_back(RequiredCapability(limitEnum, limitValue));
	}
	else if (m_curTokenStr == "full_glsl_es_100_support")
	{
		advanceToken();

		requiredCaps.push_back(RequiredCapability(CAPABILITY_FULL_GLSL_ES_100_SUPPORT));
	}
	else if (m_curTokenStr == "only_glsl_es_100_support")
	{
		advanceToken();

		requiredCaps.push_back(RequiredCapability(CAPABILITY_ONLY_GLSL_ES_100_SUPPORT));
	}
	else if (m_curTokenStr == "exactly_one_draw_buffer")
	{
		advanceToken();

		requiredCaps.push_back(RequiredCapability(CAPABILITY_EXACTLY_ONE_DRAW_BUFFER));
	}
	else
		parseError(string("invalid requirement value: " + m_curTokenStr));
}

void ShaderParser::parseExpectResult (ExpectResult& expectResult)
{
	assumeToken(TOKEN_IDENTIFIER);

	if (m_curTokenStr == "pass")
		expectResult = EXPECT_PASS;
	else if (m_curTokenStr == "compile_fail")
		expectResult = EXPECT_COMPILE_FAIL;
	else if (m_curTokenStr == "link_fail")
		expectResult = EXPECT_LINK_FAIL;
	else if (m_curTokenStr == "compile_or_link_fail")
		expectResult = EXPECT_COMPILE_LINK_FAIL;
	else if (m_curTokenStr == "validation_fail")
		expectResult = EXPECT_VALIDATION_FAIL;
	else if (m_curTokenStr == "build_successful")
		expectResult = EXPECT_BUILD_SUCCESSFUL;
	else
		parseError(string("invalid expected result value: " + m_curTokenStr));

	advanceToken();
}

void ShaderParser::parseFormat (DataType& format)
{
	format = mapDataTypeToken(m_curToken);
	advanceToken();
}

void ShaderParser::parseGLSLVersion (glu::GLSLVersion& version)
{
	int			versionNum		= 0;
	std::string	postfix			= "";

	assumeToken(TOKEN_INT_LITERAL);
	versionNum = parseIntLiteral(m_curTokenStr.c_str());
	advanceToken();

	if (m_curToken == TOKEN_IDENTIFIER)
	{
		postfix = m_curTokenStr;
		advanceToken();
	}

	DE_STATIC_ASSERT(glu::GLSL_VERSION_LAST == 15);

	if		(versionNum == 100 && postfix == "es")	version = glu::GLSL_VERSION_100_ES;
	else if (versionNum == 300 && postfix == "es")	version = glu::GLSL_VERSION_300_ES;
	else if (versionNum == 310 && postfix == "es")	version = glu::GLSL_VERSION_310_ES;
	else if (versionNum == 320 && postfix == "es")	version = glu::GLSL_VERSION_320_ES;
	else if (versionNum == 130)						version = glu::GLSL_VERSION_130;
	else if (versionNum == 140)						version = glu::GLSL_VERSION_140;
	else if (versionNum == 150)						version = glu::GLSL_VERSION_150;
	else if (versionNum == 330)						version = glu::GLSL_VERSION_330;
	else if (versionNum == 400)						version = glu::GLSL_VERSION_400;
	else if (versionNum == 410)						version = glu::GLSL_VERSION_410;
	else if (versionNum == 420)						version = glu::GLSL_VERSION_420;
	else if (versionNum == 430)						version = glu::GLSL_VERSION_430;
	else if (versionNum == 440)						version = glu::GLSL_VERSION_440;
	else if (versionNum == 450)						version = glu::GLSL_VERSION_450;
	else if (versionNum == 460)						version = glu::GLSL_VERSION_460;
	else
		parseError("Unknown GLSL version");
}

void ShaderParser::parsePipelineProgram (ProgramSpecification& program)
{
	advanceToken(TOKEN_PIPELINE_PROGRAM);

	for (;;)
	{
		if (m_curToken == TOKEN_END)
			break;
		else if (m_curToken == TOKEN_ACTIVE_STAGES)
		{
			advanceToken();
			program.activeStages = parseShaderStageList();
		}
		else if (m_curToken == TOKEN_REQUIRE)
		{
			vector<RequiredCapability> unusedCaps;
			size_t size = program.requiredExtensions.size();
			parseRequirement(unusedCaps, program.requiredExtensions);

			if (size == program.requiredExtensions.size())
				parseError("only extension requirements are allowed inside pipeline program");
		}
		else if (m_curToken == TOKEN_VERTEX						||
				 m_curToken == TOKEN_FRAGMENT					||
				 m_curToken == TOKEN_TESSELLATION_CONTROL		||
				 m_curToken == TOKEN_TESSELLATION_EVALUATION	||
				 m_curToken == TOKEN_GEOMETRY)
		{
			const Token	token = m_curToken;
			string		source;

			advanceToken();
			assumeToken(TOKEN_SHADER_SOURCE);
			source = parseShaderSource(m_curTokenStr.c_str());
			advanceToken();

			switch (token)
			{
				case TOKEN_VERTEX:					program.sources.sources[SHADERTYPE_VERTEX].push_back(source);					break;
				case TOKEN_FRAGMENT:				program.sources.sources[SHADERTYPE_FRAGMENT].push_back(source);					break;
				case TOKEN_TESSELLATION_CONTROL:	program.sources.sources[SHADERTYPE_TESSELLATION_CONTROL].push_back(source);		break;
				case TOKEN_TESSELLATION_EVALUATION:	program.sources.sources[SHADERTYPE_TESSELLATION_EVALUATION].push_back(source);	break;
				case TOKEN_GEOMETRY:				program.sources.sources[SHADERTYPE_GEOMETRY].push_back(source);					break;
				default:
					DE_FATAL("Unreachable");
			}
		}
		else
			parseError(string("invalid pipeline program value: " + m_curTokenStr));
	}
	advanceToken(TOKEN_END);

	if (program.activeStages == 0)
		parseError("program pipeline object must have active stages");
}

void ShaderParser::parseShaderCase (vector<tcu::TestNode*>& shaderNodeList)
{
	// Parse 'case'.
	PARSE_DBG(("  parseShaderCase()\n"));
	advanceToken(TOKEN_CASE);

	// Parse case name.
	string caseName = m_curTokenStr;
	advanceToken(); // \note [pyry] All token types are allowed here.

	// \todo [pyry] Optimize by parsing most stuff directly to ShaderCaseSpecification

	// Setup case.
	GLSLVersion						version			= DEFAULT_GLSL_VERSION;
	ExpectResult					expectResult	= EXPECT_PASS;
	OutputType						outputType		= OUTPUT_RESULT;
	DataType						format			= TYPE_LAST;
	string							description;
	string							bothSource;
	vector<string>					vertexSources;
	vector<string>					fragmentSources;
	vector<string>					tessellationCtrlSources;
	vector<string>					tessellationEvalSources;
	vector<string>					geometrySources;
	ValueBlock						valueBlock;
	bool							valueBlockSeen	= false;
	vector<RequiredCapability>		requiredCaps;
	vector<RequiredExtension>		requiredExts;
	vector<ProgramSpecification>	pipelinePrograms;

	for (;;)
	{
		if (m_curToken == TOKEN_END)
			break;
		else if (m_curToken == TOKEN_DESC)
		{
			advanceToken();
			assumeToken(TOKEN_STRING);
			description = parseStringLiteral(m_curTokenStr.c_str());
			advanceToken();
		}
		else if (m_curToken == TOKEN_EXPECT)
		{
			advanceToken();
			parseExpectResult(expectResult);
		}
		else if (m_curToken == TOKEN_OUTPUT_COLOR)
		{
			outputType = OUTPUT_COLOR;
			advanceToken();
			parseFormat(format);
		}
		else if (m_curToken == TOKEN_VALUES)
		{
			if (valueBlockSeen)
				parseError("multiple value blocks");
			parseValueBlock(valueBlock);
			valueBlockSeen = true;
		}
		else if (m_curToken == TOKEN_BOTH						||
				 m_curToken == TOKEN_VERTEX						||
				 m_curToken == TOKEN_FRAGMENT					||
				 m_curToken == TOKEN_TESSELLATION_CONTROL		||
				 m_curToken == TOKEN_TESSELLATION_EVALUATION	||
				 m_curToken == TOKEN_GEOMETRY)
		{
			const Token	token = m_curToken;
			string		source;

			advanceToken();
			assumeToken(TOKEN_SHADER_SOURCE);
			source = parseShaderSource(m_curTokenStr.c_str());
			advanceToken();

			switch (token)
			{
				case TOKEN_VERTEX:					vertexSources.push_back(source);			break;
				case TOKEN_FRAGMENT:				fragmentSources.push_back(source);			break;
				case TOKEN_TESSELLATION_CONTROL:	tessellationCtrlSources.push_back(source);	break;
				case TOKEN_TESSELLATION_EVALUATION:	tessellationEvalSources.push_back(source);	break;
				case TOKEN_GEOMETRY:				geometrySources.push_back(source);			break;
				case TOKEN_BOTH:
				{
					if (!bothSource.empty())
						parseError("multiple 'both' blocks");
					bothSource = source;
					break;
				}

				default:
					DE_FATAL("Unreachable");
			}
		}
		else if (m_curToken == TOKEN_VERSION)
		{
			advanceToken();
			parseGLSLVersion(version);
		}
		else if (m_curToken == TOKEN_REQUIRE)
		{
			parseRequirement(requiredCaps, requiredExts);
		}
		else if (m_curToken == TOKEN_PIPELINE_PROGRAM)
		{
			ProgramSpecification pipelineProgram;
			parsePipelineProgram(pipelineProgram);
			pipelineProgram.sources.separable = true;
			pipelinePrograms.push_back(pipelineProgram);
		}
		else
			parseError(string("unexpected token while parsing shader case: " + m_curTokenStr));
	}

	advanceToken(TOKEN_END); // case end

	if (!bothSource.empty())
	{
		if (!vertexSources.empty()				||
			!fragmentSources.empty()			||
			!tessellationCtrlSources.empty()	||
			!tessellationEvalSources.empty()	||
			!geometrySources.empty()			||
			!pipelinePrograms.empty())
		{
			parseError("'both' cannot be mixed with other shader stages");
		}

		// vertex
		{
			ShaderCaseSpecification	spec;
			spec.caseType				= CASETYPE_VERTEX_ONLY;
			spec.expectResult			= expectResult;
			spec.targetVersion			= version;
			spec.requiredCaps			= requiredCaps;
			spec.values					= valueBlock;

			spec.programs.resize(1);
			spec.programs[0].sources << VertexSource(bothSource);
			spec.programs[0].requiredExtensions	= requiredExts;

			shaderNodeList.push_back(m_caseFactory->createCase(caseName + "_vertex", description, ShaderCaseSpecification(spec)));
		}

		// fragment
		{
			ShaderCaseSpecification	spec;
			spec.caseType				= CASETYPE_FRAGMENT_ONLY;
			spec.expectResult			= expectResult;
			spec.targetVersion			= version;
			spec.requiredCaps			= requiredCaps;
			spec.values					= valueBlock;

			spec.programs.resize(1);
			spec.programs[0].sources << FragmentSource(bothSource);
			spec.programs[0].requiredExtensions	= requiredExts;

			shaderNodeList.push_back(m_caseFactory->createCase(caseName + "_fragment", description, ShaderCaseSpecification(spec)));
		}
	}
	else if (pipelinePrograms.empty())
	{
		ShaderCaseSpecification	spec;
		spec.caseType				= CASETYPE_COMPLETE;
		spec.expectResult			= expectResult;
		spec.outputType				= outputType;
		spec.outputFormat			= format;
		spec.targetVersion			= version;
		spec.requiredCaps			= requiredCaps;
		spec.values					= valueBlock;

		spec.programs.resize(1);
		spec.programs[0].sources.sources[SHADERTYPE_VERTEX].swap(vertexSources);
		spec.programs[0].sources.sources[SHADERTYPE_FRAGMENT].swap(fragmentSources);
		spec.programs[0].sources.sources[SHADERTYPE_TESSELLATION_CONTROL].swap(tessellationCtrlSources);
		spec.programs[0].sources.sources[SHADERTYPE_TESSELLATION_EVALUATION].swap(tessellationEvalSources);
		spec.programs[0].sources.sources[SHADERTYPE_GEOMETRY].swap(geometrySources);
		spec.programs[0].requiredExtensions.swap(requiredExts);

		shaderNodeList.push_back(m_caseFactory->createCase(caseName, description, ShaderCaseSpecification(spec)));
	}
	else
	{
		if (!vertexSources.empty()				||
			!fragmentSources.empty()			||
			!tessellationCtrlSources.empty()	||
			!tessellationEvalSources.empty()	||
			!geometrySources.empty())
		{
			parseError("pipeline programs cannot be mixed with complete programs");
		}

		if (!requiredExts.empty())
			parseError("global extension requirements cannot be mixed with pipeline programs");

		// Pipeline case, multiple programs
		{
			ShaderCaseSpecification	spec;
			spec.caseType				= CASETYPE_COMPLETE;
			spec.expectResult			= expectResult;
			spec.targetVersion			= version;
			spec.requiredCaps			= requiredCaps;
			spec.values					= valueBlock;

			spec.programs.swap(pipelinePrograms);

			shaderNodeList.push_back(m_caseFactory->createCase(caseName, description, ShaderCaseSpecification(spec)));
		}
	}
}

void ShaderParser::parseShaderGroup (vector<tcu::TestNode*>& shaderNodeList)
{
	// Parse 'case'.
	PARSE_DBG(("  parseShaderGroup()\n"));
	advanceToken(TOKEN_GROUP);

	// Parse case name.
	string name = m_curTokenStr;
	advanceToken(); // \note [pyry] We don't want to check token type here (for instance to allow "uniform") group.

	// Parse description.
	assumeToken(TOKEN_STRING);
	string description = parseStringLiteral(m_curTokenStr.c_str());
	advanceToken(TOKEN_STRING);

	std::vector<tcu::TestNode*> children;

	// Parse group children.
	for (;;)
	{
		if (m_curToken == TOKEN_END)
			break;
		else if (m_curToken == TOKEN_GROUP)
			parseShaderGroup(children);
		else if (m_curToken == TOKEN_CASE)
			parseShaderCase(children);
		else if (m_curToken == TOKEN_IMPORT)
			parseImport(children);
		else
			parseError(string("unexpected token while parsing shader group: " + m_curTokenStr));
	}

	advanceToken(TOKEN_END); // group end

	// Create group node.
	tcu::TestCaseGroup* groupNode = m_caseFactory->createGroup(name, description, children);
	shaderNodeList.push_back(groupNode);
}

void ShaderParser::parseImport (vector<tcu::TestNode*>& shaderNodeList)
{
	std::string	importFileName;

	advanceToken(TOKEN_IMPORT);

	assumeToken(TOKEN_STRING);
	importFileName = parseStringLiteral(m_curTokenStr.c_str());
	advanceToken(TOKEN_STRING);

	{
		ShaderParser					subParser		(m_archive, de::FilePath::join(de::FilePath(m_filename).getDirName(), importFileName).getPath(), m_caseFactory);
		const vector<tcu::TestNode*>	importedCases = subParser.parse();

		// \todo [2015-08-03 pyry] Not exception safe
		shaderNodeList.insert(shaderNodeList.end(), importedCases.begin(), importedCases.end());
	}
}

vector<tcu::TestNode*> ShaderParser::parse (void)
{
	const int	dataLen		= m_resource->getSize();

	m_input.resize(dataLen+1);
	m_resource->setPosition(0);
	m_resource->read((deUint8*)&m_input[0], dataLen);
	m_input[dataLen] = '\0';

	// Initialize parser.
	m_curPtr		= &m_input[0];
	m_curToken		= TOKEN_INVALID;
	m_curTokenStr	= "";
	advanceToken();

	vector<tcu::TestNode*> nodeList;

	// Parse all cases.
	PARSE_DBG(("parse()\n"));
	for (;;)
	{
		if (m_curToken == TOKEN_CASE)
			parseShaderCase(nodeList);
		else if (m_curToken == TOKEN_GROUP)
			parseShaderGroup(nodeList);
		else if (m_curToken == TOKEN_IMPORT)
			parseImport(nodeList);
		else if (m_curToken == TOKEN_EOF)
			break;
		else
			parseError(string("invalid token encountered at main level: '") + m_curTokenStr + "'");
	}

	assumeToken(TOKEN_EOF);
//	printf("  parsed %d test cases.\n", caseList.size());
	return nodeList;
}

std::vector<tcu::TestNode*> parseFile (const tcu::Archive& archive, const std::string& filename, ShaderCaseFactory* caseFactory)
{
	sl::ShaderParser	parser	(archive, filename, caseFactory);

	return parser.parse();
}

// Execution utilities

static void dumpValue (tcu::TestLog& log, const Value& val, const char* storageName, int arrayNdx)
{
	const char* const	valueName		= val.name.c_str();
	const DataType		dataType		= val.type.getBasicType();
	int					scalarSize		= getDataTypeScalarSize(dataType);
	ostringstream		result;

	result << "    " << storageName << " ";

	result << getDataTypeName(dataType) << " " << valueName << ":";

	if (isDataTypeScalar(dataType))
		result << " ";
	if (isDataTypeVector(dataType))
		result << " [ ";
	else if (isDataTypeMatrix(dataType))
		result << "\n";

	if (isDataTypeScalarOrVector(dataType))
	{
		for (int scalarNdx = 0; scalarNdx < scalarSize; scalarNdx++)
		{
			int						elemNdx	= arrayNdx;
			const Value::Element&	e		= val.elements[elemNdx*scalarSize + scalarNdx];
			result << ((scalarNdx != 0) ? ", " : "");

			if (isDataTypeFloatOrVec(dataType))
				result << e.float32;
			else if (isDataTypeIntOrIVec(dataType))
				result << e.int32;
			else if (isDataTypeUintOrUVec(dataType))
				result << (deUint32)e.int32;
			else if (isDataTypeBoolOrBVec(dataType))
				result << (e.bool32 ? "true" : "false");
		}
	}
	else if (isDataTypeMatrix(dataType))
	{
		int numRows = getDataTypeMatrixNumRows(dataType);
		int numCols = getDataTypeMatrixNumColumns(dataType);
		for (int rowNdx = 0; rowNdx < numRows; rowNdx++)
		{
			result << "       [ ";
			for (int colNdx = 0; colNdx < numCols; colNdx++)
			{
				int		elemNdx = arrayNdx;
				float	v		= val.elements[elemNdx*scalarSize + rowNdx*numCols + colNdx].float32;
				result << ((colNdx==0) ? "" : ", ") << v;
			}
			result << " ]\n";
		}
	}

	if (isDataTypeScalar(dataType))
		result << "\n";
	else if (isDataTypeVector(dataType))
		result << " ]\n";

	log << TestLog::Message << result.str() << TestLog::EndMessage;
}

static void dumpValues (tcu::TestLog& log, const vector<Value>& values, const char* storageName, int arrayNdx)
{
	for (size_t valNdx = 0; valNdx < values.size(); valNdx++)
		dumpValue(log, values[valNdx], storageName, arrayNdx);
}

void dumpValues (tcu::TestLog& log, const ValueBlock& values, int arrayNdx)
{
	dumpValues(log, values.inputs,		"input",	arrayNdx);
	dumpValues(log, values.outputs,		"expected",	arrayNdx);
	dumpValues(log, values.uniforms,	"uniform",	arrayNdx);
}

static void generateExtensionStatements (std::ostringstream& buf, const std::vector<RequiredExtension>& extensions, glu::ShaderType type)
{
	for (size_t ndx = 0; ndx < extensions.size(); ++ndx)
	{
		DE_ASSERT(extensions[ndx].effectiveStages != 0u &&
				  extensions[ndx].alternatives.size() == 1);

		if ((extensions[ndx].effectiveStages & (1u << (deUint32)type)) != 0)
			buf << "#extension " << extensions[ndx].alternatives[0] << " : require\n";
	}
}

// Injects #extension XXX : require lines after the last preprocessor directive in the shader code. Does not support line continuations
std::string injectExtensionRequirements (const std::string& baseCode, const std::vector<RequiredExtension>& extensions, glu::ShaderType shaderType)
{
	std::istringstream	baseCodeBuf					(baseCode);
	std::ostringstream	resultBuf;
	std::string			line;
	bool				firstNonPreprocessorLine	= true;
	std::ostringstream	extStr;

	generateExtensionStatements(extStr, extensions, shaderType);

	// skip if no requirements
	if (extStr.str().empty())
		return baseCode;

	while (std::getline(baseCodeBuf, line))
	{
		// begins with '#'?
		const std::string::size_type	firstNonWhitespace		= line.find_first_not_of("\t ");
		const bool						isPreprocessorDirective	= (firstNonWhitespace != std::string::npos && line.at(firstNonWhitespace) == '#');

		// Inject #extensions
		if (!isPreprocessorDirective && firstNonPreprocessorLine)
		{
			firstNonPreprocessorLine = false;
			resultBuf << extStr.str();
		}

		resultBuf << line << "\n";
	}

	return resultBuf.str();
}

void genCompareFunctions (ostringstream& stream, const ValueBlock& valueBlock, bool useFloatTypes)
{
	bool cmpTypeFound[TYPE_LAST];
	for (int i = 0; i < TYPE_LAST; i++)
		cmpTypeFound[i] = false;

	for (size_t valueNdx = 0; valueNdx < valueBlock.outputs.size(); valueNdx++)
	{
		const Value& val = valueBlock.outputs[valueNdx];
		cmpTypeFound[(size_t)val.type.getBasicType()] = true;
	}

	if (useFloatTypes)
	{
		if (cmpTypeFound[TYPE_BOOL])		stream << "bool isOk (float a, bool b) { return ((a > 0.5) == b); }\n";
		if (cmpTypeFound[TYPE_BOOL_VEC2])	stream << "bool isOk (vec2 a, bvec2 b) { return (greaterThan(a, vec2(0.5)) == b); }\n";
		if (cmpTypeFound[TYPE_BOOL_VEC3])	stream << "bool isOk (vec3 a, bvec3 b) { return (greaterThan(a, vec3(0.5)) == b); }\n";
		if (cmpTypeFound[TYPE_BOOL_VEC4])	stream << "bool isOk (vec4 a, bvec4 b) { return (greaterThan(a, vec4(0.5)) == b); }\n";
		if (cmpTypeFound[TYPE_INT])			stream << "bool isOk (float a, int b)  { float atemp = a+0.5; return (float(b) <= atemp && atemp <= float(b+1)); }\n";
		if (cmpTypeFound[TYPE_INT_VEC2])	stream << "bool isOk (vec2 a, ivec2 b) { return (ivec2(floor(a + 0.5)) == b); }\n";
		if (cmpTypeFound[TYPE_INT_VEC3])	stream << "bool isOk (vec3 a, ivec3 b) { return (ivec3(floor(a + 0.5)) == b); }\n";
		if (cmpTypeFound[TYPE_INT_VEC4])	stream << "bool isOk (vec4 a, ivec4 b) { return (ivec4(floor(a + 0.5)) == b); }\n";
		if (cmpTypeFound[TYPE_UINT])		stream << "bool isOk (float a, uint b) { float atemp = a+0.5; return (float(b) <= atemp && atemp <= float(b+1u)); }\n";
		if (cmpTypeFound[TYPE_UINT_VEC2])	stream << "bool isOk (vec2 a, uvec2 b) { return (uvec2(floor(a + 0.5)) == b); }\n";
		if (cmpTypeFound[TYPE_UINT_VEC3])	stream << "bool isOk (vec3 a, uvec3 b) { return (uvec3(floor(a + 0.5)) == b); }\n";
		if (cmpTypeFound[TYPE_UINT_VEC4])	stream << "bool isOk (vec4 a, uvec4 b) { return (uvec4(floor(a + 0.5)) == b); }\n";
	}
	else
	{
		if (cmpTypeFound[TYPE_BOOL])		stream << "bool isOk (bool a, bool b)   { return (a == b); }\n";
		if (cmpTypeFound[TYPE_BOOL_VEC2])	stream << "bool isOk (bvec2 a, bvec2 b) { return (a == b); }\n";
		if (cmpTypeFound[TYPE_BOOL_VEC3])	stream << "bool isOk (bvec3 a, bvec3 b) { return (a == b); }\n";
		if (cmpTypeFound[TYPE_BOOL_VEC4])	stream << "bool isOk (bvec4 a, bvec4 b) { return (a == b); }\n";
		if (cmpTypeFound[TYPE_INT])			stream << "bool isOk (int a, int b)     { return (a == b); }\n";
		if (cmpTypeFound[TYPE_INT_VEC2])	stream << "bool isOk (ivec2 a, ivec2 b) { return (a == b); }\n";
		if (cmpTypeFound[TYPE_INT_VEC3])	stream << "bool isOk (ivec3 a, ivec3 b) { return (a == b); }\n";
		if (cmpTypeFound[TYPE_INT_VEC4])	stream << "bool isOk (ivec4 a, ivec4 b) { return (a == b); }\n";
		if (cmpTypeFound[TYPE_UINT])		stream << "bool isOk (uint a, uint b)   { return (a == b); }\n";
		if (cmpTypeFound[TYPE_UINT_VEC2])	stream << "bool isOk (uvec2 a, uvec2 b) { return (a == b); }\n";
		if (cmpTypeFound[TYPE_UINT_VEC3])	stream << "bool isOk (uvec3 a, uvec3 b) { return (a == b); }\n";
		if (cmpTypeFound[TYPE_UINT_VEC4])	stream << "bool isOk (uvec4 a, uvec4 b) { return (a == b); }\n";
	}

	if (cmpTypeFound[TYPE_FLOAT])		stream << "bool isOk (float a, float b, float eps) { return (abs(a-b) <= (eps*abs(b) + eps)); }\n";
	if (cmpTypeFound[TYPE_FLOAT_VEC2])	stream << "bool isOk (vec2 a, vec2 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_VEC3])	stream << "bool isOk (vec3 a, vec3 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_VEC4])	stream << "bool isOk (vec4 a, vec4 b, float eps) { return all(lessThanEqual(abs(a-b), (eps*abs(b) + eps))); }\n";

	if (cmpTypeFound[TYPE_FLOAT_MAT2])		stream << "bool isOk (mat2 a, mat2 b, float eps) { vec2 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return all(lessThanEqual(diff, vec2(eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_MAT2X3])	stream << "bool isOk (mat2x3 a, mat2x3 b, float eps) { vec3 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return all(lessThanEqual(diff, vec3(eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_MAT2X4])	stream << "bool isOk (mat2x4 a, mat2x4 b, float eps) { vec4 diff = max(abs(a[0]-b[0]), abs(a[1]-b[1])); return all(lessThanEqual(diff, vec4(eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_MAT3X2])	stream << "bool isOk (mat3x2 a, mat3x2 b, float eps) { vec2 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), abs(a[2]-b[2])); return all(lessThanEqual(diff, vec2(eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_MAT3])		stream << "bool isOk (mat3 a, mat3 b, float eps) { vec3 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), abs(a[2]-b[2])); return all(lessThanEqual(diff, vec3(eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_MAT3X4])	stream << "bool isOk (mat3x4 a, mat3x4 b, float eps) { vec4 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), abs(a[2]-b[2])); return all(lessThanEqual(diff, vec4(eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_MAT4X2])	stream << "bool isOk (mat4x2 a, mat4x2 b, float eps) { vec2 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec2(eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_MAT4X3])	stream << "bool isOk (mat4x3 a, mat4x3 b, float eps) { vec3 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec3(eps))); }\n";
	if (cmpTypeFound[TYPE_FLOAT_MAT4])		stream << "bool isOk (mat4 a, mat4 b, float eps) { vec4 diff = max(max(abs(a[0]-b[0]), abs(a[1]-b[1])), max(abs(a[2]-b[2]), abs(a[3]-b[3]))); return all(lessThanEqual(diff, vec4(eps))); }\n";
}

} // sl
} // glu
