/*-------------------------------------------------------------------------
 * 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 (spec.fullGLSLES100Required)
	{
		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;
}

// 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 == '.');
}

struct CaseRequirement
{
	enum Type
	{
		TYPE_EXTENSION = 0,
		TYPE_FULL_GLSL_ES_100_SUPPORT,
		TYPE_IMPLEMENTATION_LIMIT,

		TYPE_LAST
	};

	Type					type;

	// TYPE_EXTENSION:
	RequiredExtension		extension;

	// TYPE_IMPLEMENTATION_LIMIT
	RequiredCapability		requiredCap;

	CaseRequirement (void) : type(TYPE_LAST) {}

	static CaseRequirement createFullGLSLES100SpecificationRequirement (void)
	{
		CaseRequirement req;
		req.type		= TYPE_FULL_GLSL_ES_100_SUPPORT;
		return req;
	}

	static CaseRequirement createAnyExtensionRequirement (const vector<string>& alternatives, deUint32 effectiveStages)
	{
		CaseRequirement req;
		req.type		= TYPE_EXTENSION;
		req.extension	= RequiredExtension(alternatives, effectiveStages);
		return req;
	}

	static CaseRequirement createLimitRequirement (deUint32 enumName, int referenceValue)
	{
		CaseRequirement req;
		req.type		= TYPE_IMPLEMENTATION_LIMIT;
		req.requiredCap	= RequiredCapability(enumName, referenceValue);
		return req;
	}
};

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_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			(CaseRequirement& valueBlock);
	void						parseExpectResult			(ExpectResult& expectResult);
	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						},
			{ "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 (CaseRequirement& valueBlock)
{
	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();
		}

		valueBlock = CaseRequirement::createAnyExtensionRequirement(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();

		valueBlock = CaseRequirement::createLimitRequirement(limitEnum, limitValue);
	}
	else if (m_curTokenStr == "full_glsl_es_100_support")
	{
		advanceToken();

		valueBlock = CaseRequirement::createFullGLSLES100SpecificationRequirement();
	}
	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::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 == 14);

	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
		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)
		{
			CaseRequirement requirement;
			parseRequirement(requirement);

			if (requirement.type == CaseRequirement::TYPE_EXTENSION)
				program.requiredExtensions.push_back(requirement.extension);
			else
				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;
	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<CaseRequirement>			requirements;
	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_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)
		{
			CaseRequirement requirement;
			parseRequirement(requirement);
			requirements.push_back(requirement);
		}
		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

	// \todo [pyry] Clean up
	vector<RequiredCapability>	requiredCaps;
	vector<RequiredExtension>	requiredExts;
	bool						fullGLSLES100Required	= false;

	for (size_t reqNdx = 0; reqNdx < requirements.size(); ++reqNdx)
	{
		const CaseRequirement&	requirement	= requirements[reqNdx];

		if (requirement.type == CaseRequirement::TYPE_EXTENSION)
			requiredExts.push_back(requirement.extension);
		else if (requirement.type == CaseRequirement::TYPE_IMPLEMENTATION_LIMIT)
			requiredCaps.push_back(requirement.requiredCap);
		else if (requirement.type == CaseRequirement::TYPE_FULL_GLSL_ES_100_SUPPORT)
			fullGLSLES100Required = true;
		else
			DE_ASSERT(false);
	}

	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.fullGLSLES100Required	= fullGLSLES100Required;
			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.fullGLSLES100Required	= fullGLSLES100Required;
			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.targetVersion			= version;
		spec.fullGLSLES100Required	= fullGLSLES100Required;
		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.fullGLSLES100Required	= fullGLSLES100Required;
			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
