OLD | NEW |
1 /* | 1 /* |
2 // | 2 // |
3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. | 3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. |
4 // Use of this source code is governed by a BSD-style license that can be | 4 // Use of this source code is governed by a BSD-style license that can be |
5 // found in the LICENSE file. | 5 // found in the LICENSE file. |
6 // | 6 // |
7 | 7 |
8 This file contains the Yacc grammar for GLSL ES. | 8 This file contains the Yacc grammar for GLSL ES. |
9 Based on ANSI C Yacc grammar: | 9 Based on ANSI C Yacc grammar: |
10 http://www.lysator.liu.se/c/ANSI-C-grammar-y.html | 10 http://www.lysator.liu.se/c/ANSI-C-grammar-y.html |
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 $$ = $1; | 260 $$ = $1; |
261 } | 261 } |
262 | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { | 262 | postfix_expression LEFT_BRACKET integer_expression RIGHT_BRACKET { |
263 if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { | 263 if (!$1->isArray() && !$1->isMatrix() && !$1->isVector()) { |
264 if ($1->getAsSymbolNode()) | 264 if ($1->getAsSymbolNode()) |
265 context->error(@2, " left of '[' is not of type array, matrix, o
r vector ", $1->getAsSymbolNode()->getSymbol().c_str()); | 265 context->error(@2, " left of '[' is not of type array, matrix, o
r vector ", $1->getAsSymbolNode()->getSymbol().c_str()); |
266 else | 266 else |
267 context->error(@2, " left of '[' is not of type array, matrix, o
r vector ", "expression"); | 267 context->error(@2, " left of '[' is not of type array, matrix, o
r vector ", "expression"); |
268 context->recover(); | 268 context->recover(); |
269 } | 269 } |
270 if ($1->getType().getQualifier() == EvqConst && $3->getQualifier() == Ev
qConst) { | 270 if ($3->getQualifier() == EvqConst) { |
271 if ($1->isArray()) { // constant folding for arrays | 271 int index = $3->getAsConstantUnion()->getIConst(0); |
272 $$ = context->addConstArrayNode($3->getAsConstantUnion()->getICo
nst(0), $1, @2); | 272 if (index < 0) { |
273 } else if ($1->isVector()) { // constant folding for vectors | 273 std::stringstream infoStream; |
274 TVectorFields fields; | 274 infoStream << index; |
275 fields.num = 1; | 275 std::string info = infoStream.str(); |
276 fields.offsets[0] = $3->getAsConstantUnion()->getIConst(0); // n
eed to do it this way because v.xy sends fields integer array | 276 context->error(@3, "negative index", info.c_str()); |
277 $$ = context->addConstVectorNode(fields, $1, @2); | 277 context->recover(); |
278 } else if ($1->isMatrix()) { // constant folding for matrices | 278 index = 0; |
279 $$ = context->addConstMatrixNode($3->getAsConstantUnion()->getIC
onst(0), $1, @2); | |
280 } | 279 } |
281 } else { | 280 if ($1->getType().getQualifier() == EvqConst) { |
282 if ($3->getQualifier() == EvqConst) { | 281 if ($1->isArray()) { // constant folding for arrays |
283 if (($1->isVector() || $1->isMatrix()) && $1->getType().getNomin
alSize() <= $3->getAsConstantUnion()->getIConst(0) && !$1->isArray() ) { | 282 $$ = context->addConstArrayNode(index, $1, @2); |
| 283 } else if ($1->isVector()) { // constant folding for vectors |
| 284 TVectorFields fields; |
| 285 fields.num = 1; |
| 286 fields.offsets[0] = index; // need to do it this way because
v.xy sends fields integer array |
| 287 $$ = context->addConstVectorNode(fields, $1, @2); |
| 288 } else if ($1->isMatrix()) { // constant folding for matrices |
| 289 $$ = context->addConstMatrixNode(index, $1, @2); |
| 290 } |
| 291 } else { |
| 292 if ($1->isArray()) { |
| 293 if ($1->getType().getArraySize() == 0) { |
| 294 if ($1->getType().getMaxArraySize() <= index) { |
| 295 if (context->arraySetMaxSize($1->getAsSymbolNode(),
$1->getTypePointer(), index, true, @2)) |
| 296 context->recover(); |
| 297 } else { |
| 298 if (context->arraySetMaxSize($1->getAsSymbolNode(),
$1->getTypePointer(), 0, false, @2)) |
| 299 context->recover(); |
| 300 } |
| 301 } else if (index >= $1->getType().getArraySize()) { |
| 302 std::stringstream extraInfoStream; |
| 303 extraInfoStream << "array index out of range '" << index
<< "'"; |
| 304 std::string extraInfo = extraInfoStream.str(); |
| 305 context->error(@2, "", "[", extraInfo.c_str()); |
| 306 context->recover(); |
| 307 index = $1->getType().getArraySize() - 1; |
| 308 } |
| 309 } else if (($1->isVector() || $1->isMatrix()) && $1->getType().g
etNominalSize() <= index) { |
284 std::stringstream extraInfoStream; | 310 std::stringstream extraInfoStream; |
285 extraInfoStream << "field selection out of range '" << $3->g
etAsConstantUnion()->getIConst(0) << "'"; | 311 extraInfoStream << "field selection out of range '" << index
<< "'"; |
286 std::string extraInfo = extraInfoStream.str(); | 312 std::string extraInfo = extraInfoStream.str(); |
287 context->error(@2, "", "[", extraInfo.c_str()); | 313 context->error(@2, "", "[", extraInfo.c_str()); |
288 context->recover(); | 314 context->recover(); |
289 } else { | 315 index = $1->getType().getNominalSize() - 1; |
290 if ($1->isArray()) { | |
291 if ($1->getType().getArraySize() == 0) { | |
292 if ($1->getType().getMaxArraySize() <= $3->getAsCons
tantUnion()->getIConst(0)) { | |
293 if (context->arraySetMaxSize($1->getAsSymbolNode
(), $1->getTypePointer(), $3->getAsConstantUnion()->getIConst(0), true, @2)) | |
294 context->recover(); | |
295 } else { | |
296 if (context->arraySetMaxSize($1->getAsSymbolNode
(), $1->getTypePointer(), 0, false, @2)) | |
297 context->recover(); | |
298 } | |
299 } else if ( $3->getAsConstantUnion()->getIConst(0) >= $1
->getType().getArraySize()) { | |
300 std::stringstream extraInfoStream; | |
301 extraInfoStream << "array index out of range '" << $
3->getAsConstantUnion()->getIConst(0) << "'"; | |
302 std::string extraInfo = extraInfoStream.str(); | |
303 context->error(@2, "", "[", extraInfo.c_str()); | |
304 context->recover(); | |
305 } | |
306 } | |
307 $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3,
@2); | |
308 } | 316 } |
309 } else { | 317 $3->getAsConstantUnion()->getUnionArrayPointer()->setIConst(inde
x); |
310 if ($1->isArray() && $1->getType().getArraySize() == 0) { | 318 $$ = context->intermediate.addIndex(EOpIndexDirect, $1, $3, @2); |
311 context->error(@2, "", "[", "array must be redeclared with a
size before being indexed with a variable"); | |
312 context->recover(); | |
313 } | |
314 | |
315 $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, @2
); | |
316 } | 319 } |
| 320 } else { |
| 321 if ($1->isArray() && $1->getType().getArraySize() == 0) { |
| 322 context->error(@2, "", "[", "array must be redeclared with a siz
e before being indexed with a variable"); |
| 323 context->recover(); |
| 324 } |
| 325 $$ = context->intermediate.addIndex(EOpIndexIndirect, $1, $3, @2); |
317 } | 326 } |
318 if ($$ == 0) { | 327 if ($$ == 0) { |
319 ConstantUnion *unionArray = new ConstantUnion[1]; | 328 ConstantUnion *unionArray = new ConstantUnion[1]; |
320 unionArray->setFConst(0.0f); | 329 unionArray->setFConst(0.0f); |
321 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFlo
at, EbpHigh, EvqConst), @2); | 330 $$ = context->intermediate.addConstantUnion(unionArray, TType(EbtFlo
at, EbpHigh, EvqConst), @2); |
322 } else if ($1->isArray()) { | 331 } else if ($1->isArray()) { |
323 if ($1->getType().getStruct()) | 332 if ($1->getType().getStruct()) |
324 $$->setType(TType($1->getType().getStruct(), $1->getType().getTy
peName())); | 333 $$->setType(TType($1->getType().getStruct(), $1->getType().getTy
peName())); |
325 else | 334 else |
326 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTem
porary, $1->getNominalSize(), $1->isMatrix())); | 335 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTem
porary, $1->getNominalSize(), $1->isMatrix())); |
327 | 336 |
328 if ($1->getType().getQualifier() == EvqConst) | 337 if ($1->getType().getQualifier() == EvqConst) |
329 $$->getTypePointer()->setQualifier(EvqConst); | 338 $$->getTypePointer()->setQualifier(EvqConst); |
330 } else if ($1->isMatrix() && $1->getType().getQualifier() == EvqConst) | 339 } else if ($1->isMatrix()) { |
331 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst,
$1->getNominalSize())); | 340 TQualifier qualifier = $1->getType().getQualifier() == EvqConst ? Ev
qConst : EvqTemporary; |
332 else if ($1->isMatrix()) | 341 $$->setType(TType($1->getBasicType(), $1->getPrecision(), qualifier,
$1->getNominalSize())); |
333 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTempora
ry, $1->getNominalSize())); | 342 } else if ($1->isVector()) { |
334 else if ($1->isVector() && $1->getType().getQualifier() == EvqConst) | 343 TQualifier qualifier = $1->getType().getQualifier() == EvqConst ? Ev
qConst : EvqTemporary; |
335 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqConst))
; | 344 $$->setType(TType($1->getBasicType(), $1->getPrecision(), qualifier)
); |
336 else if ($1->isVector()) | 345 } else { |
337 $$->setType(TType($1->getBasicType(), $1->getPrecision(), EvqTempora
ry)); | |
338 else | |
339 $$->setType($1->getType()); | 346 $$->setType($1->getType()); |
| 347 } |
340 } | 348 } |
341 | function_call { | 349 | function_call { |
342 $$ = $1; | 350 $$ = $1; |
343 } | 351 } |
344 | postfix_expression DOT identifier { | 352 | postfix_expression DOT identifier { |
345 if ($1->isArray()) { | 353 if ($1->isArray()) { |
346 context->error(@3, "cannot apply dot operator to an array", "."); | 354 context->error(@3, "cannot apply dot operator to an array", "."); |
347 context->recover(); | 355 context->recover(); |
348 } | 356 } |
349 | 357 |
(...skipping 1806 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2156 %% | 2164 %% |
2157 | 2165 |
2158 void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) { | 2166 void yyerror(YYLTYPE* yylloc, TParseContext* context, const char* reason) { |
2159 context->error(*yylloc, reason, ""); | 2167 context->error(*yylloc, reason, ""); |
2160 context->recover(); | 2168 context->recover(); |
2161 } | 2169 } |
2162 | 2170 |
2163 int glslang_parse(TParseContext* context) { | 2171 int glslang_parse(TParseContext* context) { |
2164 return yyparse(context); | 2172 return yyparse(context); |
2165 } | 2173 } |
OLD | NEW |