1e5c31af7Sopenharmony_ci/*-------------------------------------------------------------------------
2e5c31af7Sopenharmony_ci * drawElements Quality Program Random Shader Generator
3e5c31af7Sopenharmony_ci * ----------------------------------------------------
4e5c31af7Sopenharmony_ci *
5e5c31af7Sopenharmony_ci * Copyright 2014 The Android Open Source Project
6e5c31af7Sopenharmony_ci *
7e5c31af7Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
8e5c31af7Sopenharmony_ci * you may not use this file except in compliance with the License.
9e5c31af7Sopenharmony_ci * You may obtain a copy of the License at
10e5c31af7Sopenharmony_ci *
11e5c31af7Sopenharmony_ci *      http://www.apache.org/licenses/LICENSE-2.0
12e5c31af7Sopenharmony_ci *
13e5c31af7Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
14e5c31af7Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
15e5c31af7Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16e5c31af7Sopenharmony_ci * See the License for the specific language governing permissions and
17e5c31af7Sopenharmony_ci * limitations under the License.
18e5c31af7Sopenharmony_ci *
19e5c31af7Sopenharmony_ci *//*!
20e5c31af7Sopenharmony_ci * \file
21e5c31af7Sopenharmony_ci * \brief Shader Source Formatter.
22e5c31af7Sopenharmony_ci *//*--------------------------------------------------------------------*/
23e5c31af7Sopenharmony_ci
24e5c31af7Sopenharmony_ci#include "rsgPrettyPrinter.hpp"
25e5c31af7Sopenharmony_ci#include "deStringUtil.hpp"
26e5c31af7Sopenharmony_ci
27e5c31af7Sopenharmony_cinamespace rsg
28e5c31af7Sopenharmony_ci{
29e5c31af7Sopenharmony_ci
30e5c31af7Sopenharmony_cistatic const char* s_tokenStr[] =
31e5c31af7Sopenharmony_ci{
32e5c31af7Sopenharmony_ci	DE_NULL,		// IDENTIFIER,
33e5c31af7Sopenharmony_ci	"struct",		// STRUCT,
34e5c31af7Sopenharmony_ci	"invariant",	// INVARIANT,
35e5c31af7Sopenharmony_ci	"precision",	// PRECISION,
36e5c31af7Sopenharmony_ci	"void",			// VOID,
37e5c31af7Sopenharmony_ci	"break",		// BREAK,
38e5c31af7Sopenharmony_ci	"continue",		// CONTINUE,
39e5c31af7Sopenharmony_ci	"do ",			// DO,
40e5c31af7Sopenharmony_ci	"while ",		// WHILE,
41e5c31af7Sopenharmony_ci	"else ",		// ELSE,
42e5c31af7Sopenharmony_ci	"for ",			// FOR,
43e5c31af7Sopenharmony_ci	"if ",			// IF,
44e5c31af7Sopenharmony_ci	"discard",		// DISCARD,
45e5c31af7Sopenharmony_ci	"return ",		// RETURN,
46e5c31af7Sopenharmony_ci	"++",			// INC_OP,
47e5c31af7Sopenharmony_ci	"--",			// DEC_OP,
48e5c31af7Sopenharmony_ci	"(",			// LEFT_PAREN,
49e5c31af7Sopenharmony_ci	")",			// RIGHT_PAREN,
50e5c31af7Sopenharmony_ci	"[",			// LEFT_BRACKET,
51e5c31af7Sopenharmony_ci	"]",			// RIGHT_BRACKET,
52e5c31af7Sopenharmony_ci	"{",			// LEFT_BRACE,
53e5c31af7Sopenharmony_ci	"}",			// RIGHT_BRACE,
54e5c31af7Sopenharmony_ci	".",			// DOT,
55e5c31af7Sopenharmony_ci	", ",			// COMMA,
56e5c31af7Sopenharmony_ci	" : ",			// COLON,
57e5c31af7Sopenharmony_ci	";",			// SEMICOLON,
58e5c31af7Sopenharmony_ci	" - ",			// MINUS,
59e5c31af7Sopenharmony_ci	" + ",			// PLUS,
60e5c31af7Sopenharmony_ci	" * ",			// MUL,
61e5c31af7Sopenharmony_ci	" / ",			// DIV,
62e5c31af7Sopenharmony_ci	" % ",			// MOD,
63e5c31af7Sopenharmony_ci	" ? ",			// QUESTION,
64e5c31af7Sopenharmony_ci	"bool",			// BOOL,
65e5c31af7Sopenharmony_ci	"bvec2",		// BVEC2,
66e5c31af7Sopenharmony_ci	"bvec3",		// BVEC3,
67e5c31af7Sopenharmony_ci	"bvec4",		// BVEC4,
68e5c31af7Sopenharmony_ci	"int",			// INT,
69e5c31af7Sopenharmony_ci	"ivec2",		// IVEC2,
70e5c31af7Sopenharmony_ci	"ivec3",		// IVEC3,
71e5c31af7Sopenharmony_ci	"ivec4",		// IVEC4,
72e5c31af7Sopenharmony_ci	"float",		// FLOAT,
73e5c31af7Sopenharmony_ci	"vec2",			// VEC2,
74e5c31af7Sopenharmony_ci	"vec3",			// VEC3,
75e5c31af7Sopenharmony_ci	"vec4",			// VEC4,
76e5c31af7Sopenharmony_ci	"mat2",			// MAT2,
77e5c31af7Sopenharmony_ci	"mat3",			// MAT3,
78e5c31af7Sopenharmony_ci	"mat4",			// MAT4,
79e5c31af7Sopenharmony_ci	"sampler2D",	// SAMPLER2D,
80e5c31af7Sopenharmony_ci	"samplerCube",	// SAMPLERCUBE,
81e5c31af7Sopenharmony_ci	DE_NULL,		// FLOAT_LITERAL,
82e5c31af7Sopenharmony_ci	DE_NULL,		// INT_LITERAL,
83e5c31af7Sopenharmony_ci	DE_NULL,		// BOOL_LITERAL,
84e5c31af7Sopenharmony_ci	" = ",			// EQUAL,
85e5c31af7Sopenharmony_ci	" *= ",			// MUL_ASSIGN,
86e5c31af7Sopenharmony_ci	" /= ",			// DIV_ASSIGN,
87e5c31af7Sopenharmony_ci	" += ",			// ADD_ASSIGN,
88e5c31af7Sopenharmony_ci	" -= ",			// SUB_ASSIGN,
89e5c31af7Sopenharmony_ci	" < ",			// CMP_LT,
90e5c31af7Sopenharmony_ci	" > ",			// CMP_GT,
91e5c31af7Sopenharmony_ci	" <= ",			// CMP_LE,
92e5c31af7Sopenharmony_ci	" >= ",			// CMP_GE,
93e5c31af7Sopenharmony_ci	" == ",			// CMP_EQ,
94e5c31af7Sopenharmony_ci	" != ",			// CMP_NE,
95e5c31af7Sopenharmony_ci	" && ",			// LOGICAL_AND,
96e5c31af7Sopenharmony_ci	" || ",			// LOGICAL_OR,
97e5c31af7Sopenharmony_ci	"!",			// LOGICAL_NOT,
98e5c31af7Sopenharmony_ci	" ^^ ",			// LOGICAL_XOR,
99e5c31af7Sopenharmony_ci	"attribute",	// ATTRIBUTE,
100e5c31af7Sopenharmony_ci	"uniform",		// UNIFORM,
101e5c31af7Sopenharmony_ci	"varying",		// VARYING,
102e5c31af7Sopenharmony_ci	"const",		// CONST,
103e5c31af7Sopenharmony_ci	"flat",			// FLAT,
104e5c31af7Sopenharmony_ci	"highp",		// HIGH_PRECISION,
105e5c31af7Sopenharmony_ci	"mediump",		// MEDIUM_PRECISION,
106e5c31af7Sopenharmony_ci	"lowp",			// LOW_PRECISION,
107e5c31af7Sopenharmony_ci	"in",			// IN,
108e5c31af7Sopenharmony_ci	"out",			// OUT,
109e5c31af7Sopenharmony_ci	"inout",		// INOUT,
110e5c31af7Sopenharmony_ci	"layout",		// LAYOUT,
111e5c31af7Sopenharmony_ci	"location",		// LOCATION,
112e5c31af7Sopenharmony_ci	DE_NULL,		// INDENT_INC,
113e5c31af7Sopenharmony_ci	DE_NULL,		// INDENT_DEC,
114e5c31af7Sopenharmony_ci	"\n"			// NEWLINE,
115e5c31af7Sopenharmony_ci};
116e5c31af7Sopenharmony_ci
117e5c31af7Sopenharmony_ciPrettyPrinter::PrettyPrinter (std::ostringstream& str)
118e5c31af7Sopenharmony_ci	: m_str			(str)
119e5c31af7Sopenharmony_ci	, m_indentDepth	(0)
120e5c31af7Sopenharmony_ci{
121e5c31af7Sopenharmony_ci}
122e5c31af7Sopenharmony_ci
123e5c31af7Sopenharmony_ciinline const char* PrettyPrinter::getSimpleTokenStr (Token::Type token)
124e5c31af7Sopenharmony_ci{
125e5c31af7Sopenharmony_ci	DE_ASSERT(de::inBounds<int>(token, 0, (int)DE_LENGTH_OF_ARRAY(s_tokenStr)));
126e5c31af7Sopenharmony_ci	return s_tokenStr[token];
127e5c31af7Sopenharmony_ci}
128e5c31af7Sopenharmony_ci
129e5c31af7Sopenharmony_civoid PrettyPrinter::append (const TokenStream& tokens)
130e5c31af7Sopenharmony_ci{
131e5c31af7Sopenharmony_ci	for (int ndx = 0; ndx < tokens.getSize(); ndx++)
132e5c31af7Sopenharmony_ci		processToken(tokens[ndx]);
133e5c31af7Sopenharmony_ci}
134e5c31af7Sopenharmony_ci
135e5c31af7Sopenharmony_ciinline bool isIdentifierChar (char c)
136e5c31af7Sopenharmony_ci{
137e5c31af7Sopenharmony_ci	return de::inRange(c, 'a', 'z') || de::inRange(c, 'A', 'Z') || de::inRange(c, '0', '9') || c == '_';
138e5c31af7Sopenharmony_ci}
139e5c31af7Sopenharmony_ci
140e5c31af7Sopenharmony_civoid PrettyPrinter::processToken (const Token& token)
141e5c31af7Sopenharmony_ci{
142e5c31af7Sopenharmony_ci	bool prevIsIdentifierChar = m_line.length() > 0 && isIdentifierChar(m_line[m_line.length()-1]);
143e5c31af7Sopenharmony_ci
144e5c31af7Sopenharmony_ci	switch (token.getType())
145e5c31af7Sopenharmony_ci	{
146e5c31af7Sopenharmony_ci		case Token::IDENTIFIER:
147e5c31af7Sopenharmony_ci			if (prevIsIdentifierChar)
148e5c31af7Sopenharmony_ci				m_line += " ";
149e5c31af7Sopenharmony_ci			m_line += token.getIdentifier();
150e5c31af7Sopenharmony_ci			break;
151e5c31af7Sopenharmony_ci
152e5c31af7Sopenharmony_ci		case Token::FLOAT_LITERAL:
153e5c31af7Sopenharmony_ci		{
154e5c31af7Sopenharmony_ci			std::string f = de::toString(token.getFloat());
155e5c31af7Sopenharmony_ci			if (f.find('.') == std::string::npos)
156e5c31af7Sopenharmony_ci				f += ".0"; // Make sure value parses as float
157e5c31af7Sopenharmony_ci			m_line += f;
158e5c31af7Sopenharmony_ci			break;
159e5c31af7Sopenharmony_ci		}
160e5c31af7Sopenharmony_ci
161e5c31af7Sopenharmony_ci		case Token::INT_LITERAL:
162e5c31af7Sopenharmony_ci			m_line += de::toString(token.getInt());
163e5c31af7Sopenharmony_ci			break;
164e5c31af7Sopenharmony_ci
165e5c31af7Sopenharmony_ci		case Token::BOOL_LITERAL:
166e5c31af7Sopenharmony_ci			m_line += (token.getBool() ? "true" : "false");
167e5c31af7Sopenharmony_ci			break;
168e5c31af7Sopenharmony_ci
169e5c31af7Sopenharmony_ci		case Token::INDENT_INC:
170e5c31af7Sopenharmony_ci			m_indentDepth += 1;
171e5c31af7Sopenharmony_ci			break;
172e5c31af7Sopenharmony_ci
173e5c31af7Sopenharmony_ci		case Token::INDENT_DEC:
174e5c31af7Sopenharmony_ci			m_indentDepth -= 1;
175e5c31af7Sopenharmony_ci			break;
176e5c31af7Sopenharmony_ci
177e5c31af7Sopenharmony_ci		case Token::NEWLINE:
178e5c31af7Sopenharmony_ci			// Indent
179e5c31af7Sopenharmony_ci			for (int i = 0; i < m_indentDepth; i++)
180e5c31af7Sopenharmony_ci				m_str << "\t";
181e5c31af7Sopenharmony_ci
182e5c31af7Sopenharmony_ci			// Flush line to source
183e5c31af7Sopenharmony_ci			m_str << m_line + "\n";
184e5c31af7Sopenharmony_ci			m_line = "";
185e5c31af7Sopenharmony_ci			break;
186e5c31af7Sopenharmony_ci
187e5c31af7Sopenharmony_ci		default:
188e5c31af7Sopenharmony_ci		{
189e5c31af7Sopenharmony_ci			const char* tokenStr = getSimpleTokenStr(token.getType());
190e5c31af7Sopenharmony_ci			if (prevIsIdentifierChar && isIdentifierChar(tokenStr[0]))
191e5c31af7Sopenharmony_ci				m_line += " ";
192e5c31af7Sopenharmony_ci			m_line += tokenStr;
193e5c31af7Sopenharmony_ci			break;
194e5c31af7Sopenharmony_ci		}
195e5c31af7Sopenharmony_ci	}
196e5c31af7Sopenharmony_ci}
197e5c31af7Sopenharmony_ci
198e5c31af7Sopenharmony_ci} // rsg
199