| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 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 #include "stdio.h" | 8 #include "stdio.h" |
| 9 #include "SkSLParser.h" | 9 #include "SkSLParser.h" |
| 10 #include "SkSLToken.h" | 10 #include "SkSLToken.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 49 #include "ast/SkSLASTExtension.h" | 49 #include "ast/SkSLASTExtension.h" |
| 50 #include "ast/SkSLASTFieldSuffix.h" | 50 #include "ast/SkSLASTFieldSuffix.h" |
| 51 #include "ast/SkSLASTFloatLiteral.h" | 51 #include "ast/SkSLASTFloatLiteral.h" |
| 52 #include "ast/SkSLASTForStatement.h" | 52 #include "ast/SkSLASTForStatement.h" |
| 53 #include "ast/SkSLASTFunction.h" | 53 #include "ast/SkSLASTFunction.h" |
| 54 #include "ast/SkSLASTIdentifier.h" | 54 #include "ast/SkSLASTIdentifier.h" |
| 55 #include "ast/SkSLASTIfStatement.h" | 55 #include "ast/SkSLASTIfStatement.h" |
| 56 #include "ast/SkSLASTIndexSuffix.h" | 56 #include "ast/SkSLASTIndexSuffix.h" |
| 57 #include "ast/SkSLASTInterfaceBlock.h" | 57 #include "ast/SkSLASTInterfaceBlock.h" |
| 58 #include "ast/SkSLASTIntLiteral.h" | 58 #include "ast/SkSLASTIntLiteral.h" |
| 59 #include "ast/SkSLASTModifiersDeclaration.h" | |
| 60 #include "ast/SkSLASTParameter.h" | 59 #include "ast/SkSLASTParameter.h" |
| 61 #include "ast/SkSLASTPrefixExpression.h" | 60 #include "ast/SkSLASTPrefixExpression.h" |
| 62 #include "ast/SkSLASTReturnStatement.h" | 61 #include "ast/SkSLASTReturnStatement.h" |
| 63 #include "ast/SkSLASTStatement.h" | 62 #include "ast/SkSLASTStatement.h" |
| 64 #include "ast/SkSLASTSuffixExpression.h" | 63 #include "ast/SkSLASTSuffixExpression.h" |
| 65 #include "ast/SkSLASTTernaryExpression.h" | 64 #include "ast/SkSLASTTernaryExpression.h" |
| 66 #include "ast/SkSLASTType.h" | 65 #include "ast/SkSLASTType.h" |
| 67 #include "ast/SkSLASTVarDeclaration.h" | 66 #include "ast/SkSLASTVarDeclaration.h" |
| 68 #include "ast/SkSLASTVarDeclarationStatement.h" | 67 #include "ast/SkSLASTVarDeclarationStatement.h" |
| 69 #include "ast/SkSLASTWhileStatement.h" | 68 #include "ast/SkSLASTWhileStatement.h" |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 179 this->error(p.fPosition, "expected 'lowp', 'mediump', or 'highp', bu
t found '" + | 178 this->error(p.fPosition, "expected 'lowp', 'mediump', or 'highp', bu
t found '" + |
| 180 p.fText + "'"); | 179 p.fText + "'"); |
| 181 return; | 180 return; |
| 182 } | 181 } |
| 183 if (!this->type()) { | 182 if (!this->type()) { |
| 184 return; | 183 return; |
| 185 } | 184 } |
| 186 this->expect(Token::SEMICOLON, "';'"); | 185 this->expect(Token::SEMICOLON, "';'"); |
| 187 } | 186 } |
| 188 | 187 |
| 189 /* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? | | 188 /* DIRECTIVE(#version) INT_LITERAL | DIRECTIVE(#extension) IDENTIFIER COLON IDEN
TIFIER */ |
| 190 DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */ | |
| 191 std::unique_ptr<ASTDeclaration> Parser::directive() { | 189 std::unique_ptr<ASTDeclaration> Parser::directive() { |
| 192 Token start; | 190 Token start; |
| 193 if (!this->expect(Token::DIRECTIVE, "a directive", &start)) { | 191 if (!this->expect(Token::DIRECTIVE, "a directive", &start)) { |
| 194 return nullptr; | 192 return nullptr; |
| 195 } | 193 } |
| 196 if (start.fText == "#version") { | 194 if (start.fText == "#version") { |
| 197 this->expect(Token::INT_LITERAL, "a version number"); | 195 this->expect(Token::INT_LITERAL, "a version number"); |
| 198 Token next = this->peek(); | 196 // ignored for now |
| 199 if (next.fText == "es" || next.fText == "compatibility") { | |
| 200 this->nextToken(); | |
| 201 } | |
| 202 // version is ignored for now; it will eventually become an error when w
e stop pretending | |
| 203 // to be GLSL | |
| 204 return nullptr; | 197 return nullptr; |
| 205 } else if (start.fText == "#extension") { | 198 } else if (start.fText == "#extension") { |
| 206 Token name; | 199 Token name; |
| 207 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { | 200 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { |
| 208 return nullptr; | 201 return nullptr; |
| 209 } | 202 } |
| 210 if (!this->expect(Token::COLON, "':'")) { | 203 if (!this->expect(Token::COLON, "':'")) { |
| 211 return nullptr; | 204 return nullptr; |
| 212 } | 205 } |
| 213 // FIXME: need to start paying attention to this token | 206 // FIXME: need to start paying attention to this token |
| (...skipping 13 matching lines...) Expand all Loading... |
| 227 std::unique_ptr<ASTDeclaration> Parser::declaration() { | 220 std::unique_ptr<ASTDeclaration> Parser::declaration() { |
| 228 ASTModifiers modifiers = this->modifiers(); | 221 ASTModifiers modifiers = this->modifiers(); |
| 229 Token lookahead = this->peek(); | 222 Token lookahead = this->peek(); |
| 230 if (lookahead.fKind == Token::IDENTIFIER && !this->isType(lookahead.fText))
{ | 223 if (lookahead.fKind == Token::IDENTIFIER && !this->isType(lookahead.fText))
{ |
| 231 // we have an identifier that's not a type, could be the start of an int
erface block | 224 // we have an identifier that's not a type, could be the start of an int
erface block |
| 232 return this->interfaceBlock(modifiers); | 225 return this->interfaceBlock(modifiers); |
| 233 } | 226 } |
| 234 if (lookahead.fKind == Token::STRUCT) { | 227 if (lookahead.fKind == Token::STRUCT) { |
| 235 return this->structVarDeclaration(modifiers); | 228 return this->structVarDeclaration(modifiers); |
| 236 } | 229 } |
| 237 if (lookahead.fKind == Token::SEMICOLON) { | |
| 238 this->nextToken(); | |
| 239 return std::unique_ptr<ASTDeclaration>(new ASTModifiersDeclaration(modif
iers)); | |
| 240 } | |
| 241 std::unique_ptr<ASTType> type(this->type()); | 230 std::unique_ptr<ASTType> type(this->type()); |
| 242 if (!type) { | 231 if (!type) { |
| 243 return nullptr; | 232 return nullptr; |
| 244 } | 233 } |
| 245 if (type->fKind == ASTType::kStruct_Kind && peek().fKind == Token::SEMICOLON
) { | 234 if (type->fKind == ASTType::kStruct_Kind && peek().fKind == Token::SEMICOLON
) { |
| 246 this->nextToken(); | 235 this->nextToken(); |
| 247 return nullptr; | 236 return nullptr; |
| 248 } | 237 } |
| 249 Token name; | 238 Token name; |
| 250 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { | 239 if (!this->expect(Token::IDENTIFIER, "an identifier", &name)) { |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 | 470 |
| 482 /* LAYOUT LPAREN IDENTIFIER EQ INT_LITERAL (COMMA IDENTIFIER EQ INT_LITERAL)* | 471 /* LAYOUT LPAREN IDENTIFIER EQ INT_LITERAL (COMMA IDENTIFIER EQ INT_LITERAL)* |
| 483 RPAREN */ | 472 RPAREN */ |
| 484 ASTLayout Parser::layout() { | 473 ASTLayout Parser::layout() { |
| 485 int location = -1; | 474 int location = -1; |
| 486 int binding = -1; | 475 int binding = -1; |
| 487 int index = -1; | 476 int index = -1; |
| 488 int set = -1; | 477 int set = -1; |
| 489 int builtin = -1; | 478 int builtin = -1; |
| 490 bool originUpperLeft = false; | 479 bool originUpperLeft = false; |
| 491 bool overrideCoverage = false; | |
| 492 bool blendSupportAllEquations = false; | |
| 493 if (this->peek().fKind == Token::LAYOUT) { | 480 if (this->peek().fKind == Token::LAYOUT) { |
| 494 this->nextToken(); | 481 this->nextToken(); |
| 495 if (!this->expect(Token::LPAREN, "'('")) { | 482 if (!this->expect(Token::LPAREN, "'('")) { |
| 496 return ASTLayout(location, binding, index, set, builtin, originUpper
Left, | 483 return ASTLayout(location, binding, index, set, builtin, originUpper
Left); |
| 497 overrideCoverage, blendSupportAllEquations); | |
| 498 } | 484 } |
| 499 for (;;) { | 485 for (;;) { |
| 500 Token t = this->nextToken(); | 486 Token t = this->nextToken(); |
| 501 if (t.fText == "location") { | 487 if (t.fText == "location") { |
| 502 location = this->layoutInt(); | 488 location = this->layoutInt(); |
| 503 } else if (t.fText == "binding") { | 489 } else if (t.fText == "binding") { |
| 504 binding = this->layoutInt(); | 490 binding = this->layoutInt(); |
| 505 } else if (t.fText == "index") { | 491 } else if (t.fText == "index") { |
| 506 index = this->layoutInt(); | 492 index = this->layoutInt(); |
| 507 } else if (t.fText == "set") { | 493 } else if (t.fText == "set") { |
| 508 set = this->layoutInt(); | 494 set = this->layoutInt(); |
| 509 } else if (t.fText == "builtin") { | 495 } else if (t.fText == "builtin") { |
| 510 builtin = this->layoutInt(); | 496 builtin = this->layoutInt(); |
| 511 } else if (t.fText == "origin_upper_left") { | 497 } else if (t.fText == "origin_upper_left") { |
| 512 originUpperLeft = true; | 498 originUpperLeft = true; |
| 513 } else if (t.fText == "override_coverage") { | |
| 514 overrideCoverage = true; | |
| 515 } else if (t.fText == "blend_support_all_equations") { | |
| 516 blendSupportAllEquations = true; | |
| 517 } else { | 499 } else { |
| 518 this->error(t.fPosition, ("'" + t.fText + | 500 this->error(t.fPosition, ("'" + t.fText + |
| 519 "' is not a valid layout qualifier").c
_str()); | 501 "' is not a valid layout qualifier").c
_str()); |
| 520 } | 502 } |
| 521 if (this->peek().fKind == Token::RPAREN) { | 503 if (this->peek().fKind == Token::RPAREN) { |
| 522 this->nextToken(); | 504 this->nextToken(); |
| 523 break; | 505 break; |
| 524 } | 506 } |
| 525 if (!this->expect(Token::COMMA, "','")) { | 507 if (!this->expect(Token::COMMA, "','")) { |
| 526 break; | 508 break; |
| 527 } | 509 } |
| 528 } | 510 } |
| 529 } | 511 } |
| 530 return ASTLayout(location, binding, index, set, builtin, originUpperLeft, ov
errideCoverage, | 512 return ASTLayout(location, binding, index, set, builtin, originUpperLeft); |
| 531 blendSupportAllEquations); | |
| 532 } | 513 } |
| 533 | 514 |
| 534 /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT |
NOPERSPECTIVE)* */ | 515 /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT |
NOPERSPECTIVE)* */ |
| 535 ASTModifiers Parser::modifiers() { | 516 ASTModifiers Parser::modifiers() { |
| 536 ASTLayout layout = this->layout(); | 517 ASTLayout layout = this->layout(); |
| 537 int flags = 0; | 518 int flags = 0; |
| 538 for (;;) { | 519 for (;;) { |
| 539 // TODO: handle duplicate / incompatible flags | 520 // TODO: handle duplicate / incompatible flags |
| 540 switch (peek().fKind) { | 521 switch (peek().fKind) { |
| 541 case Token::UNIFORM: | 522 case Token::UNIFORM: |
| (...skipping 724 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1266 } | 1247 } |
| 1267 result.reset(new ASTSuffixExpression(std::move(result), std::mov
e(s))); | 1248 result.reset(new ASTSuffixExpression(std::move(result), std::mov
e(s))); |
| 1268 break; | 1249 break; |
| 1269 } | 1250 } |
| 1270 default: | 1251 default: |
| 1271 return result; | 1252 return result; |
| 1272 } | 1253 } |
| 1273 } | 1254 } |
| 1274 } | 1255 } |
| 1275 | 1256 |
| 1276 /* LBRACKET expression? RBRACKET | DOT IDENTIFIER | LPAREN parameters RPAREN | | 1257 /* LBRACKET expression RBRACKET | DOT IDENTIFIER | LPAREN parameters RPAREN | |
| 1277 PLUSPLUS | MINUSMINUS */ | 1258 PLUSPLUS | MINUSMINUS */ |
| 1278 std::unique_ptr<ASTSuffix> Parser::suffix() { | 1259 std::unique_ptr<ASTSuffix> Parser::suffix() { |
| 1279 Token next = this->nextToken(); | 1260 Token next = this->nextToken(); |
| 1280 switch (next.fKind) { | 1261 switch (next.fKind) { |
| 1281 case Token::LBRACKET: { | 1262 case Token::LBRACKET: { |
| 1282 if (this->peek().fKind == Token::RBRACKET) { | |
| 1283 this->nextToken(); | |
| 1284 return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(next.fPosit
ion)); | |
| 1285 } | |
| 1286 std::unique_ptr<ASTExpression> e = this->expression(); | 1263 std::unique_ptr<ASTExpression> e = this->expression(); |
| 1287 if (!e) { | 1264 if (!e) { |
| 1288 return nullptr; | 1265 return nullptr; |
| 1289 } | 1266 } |
| 1290 this->expect(Token::RBRACKET, "']' to complete array access expressi
on"); | 1267 this->expect(Token::RBRACKET, "']' to complete array access expressi
on"); |
| 1291 return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(std::move(e))); | 1268 return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(std::move(e))); |
| 1292 } | 1269 } |
| 1293 case Token::DOT: { | 1270 case Token::DOT: { |
| 1294 Position pos = this->peek().fPosition; | 1271 Position pos = this->peek().fPosition; |
| 1295 std::string text; | 1272 std::string text; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1421 bool Parser::identifier(std::string* dest) { | 1398 bool Parser::identifier(std::string* dest) { |
| 1422 Token t; | 1399 Token t; |
| 1423 if (this->expect(Token::IDENTIFIER, "identifier", &t)) { | 1400 if (this->expect(Token::IDENTIFIER, "identifier", &t)) { |
| 1424 *dest = t.fText; | 1401 *dest = t.fText; |
| 1425 return true; | 1402 return true; |
| 1426 } | 1403 } |
| 1427 return false; | 1404 return false; |
| 1428 } | 1405 } |
| 1429 | 1406 |
| 1430 } // namespace | 1407 } // namespace |
| OLD | NEW |