/*-------------------------------------------------------------------------
 * 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> dummyCaps;
			size_t size = program.requiredExtensions.size();
			parseRequirement(dummyCaps, 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:
					parseError(DE_FALSE);
			}
		}
		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:
					parseError(DE_FALSE);
			}
		}
		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
