| Index: src/sksl/SkSLParser.cpp
|
| diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
|
| index b240e4501e98a1f4847cd8c00ca784d854ee9a31..29f1dbd1785d425ef638312560272f27c02394ba 100644
|
| --- a/src/sksl/SkSLParser.cpp
|
| +++ b/src/sksl/SkSLParser.cpp
|
| @@ -56,7 +56,9 @@
|
| #include "ast/SkSLASTIndexSuffix.h"
|
| #include "ast/SkSLASTInterfaceBlock.h"
|
| #include "ast/SkSLASTIntLiteral.h"
|
| +#include "ast/SkSLASTModifiersDeclaration.h"
|
| #include "ast/SkSLASTParameter.h"
|
| +#include "ast/SkSLASTPrecision.h"
|
| #include "ast/SkSLASTPrefixExpression.h"
|
| #include "ast/SkSLASTReturnStatement.h"
|
| #include "ast/SkSLASTStatement.h"
|
| @@ -97,9 +99,13 @@ std::vector<std::unique_ptr<ASTDeclaration>> Parser::file() {
|
| switch (this->peek().fKind) {
|
| case Token::END_OF_FILE:
|
| return result;
|
| - case Token::PRECISION:
|
| - this->precision();
|
| + case Token::PRECISION: {
|
| + std::unique_ptr<ASTDeclaration> precision = this->precision();
|
| + if (precision) {
|
| + result.push_back(std::move(precision));
|
| + }
|
| break;
|
| + }
|
| case Token::DIRECTIVE: {
|
| std::unique_ptr<ASTDeclaration> decl = this->directive();
|
| if (decl) {
|
| @@ -163,29 +169,37 @@ bool Parser::isType(std::string name) {
|
| }
|
|
|
| /* PRECISION (LOWP | MEDIUMP | HIGHP) type SEMICOLON */
|
| -void Parser::precision() {
|
| +std::unique_ptr<ASTDeclaration> Parser::precision() {
|
| if (!this->expect(Token::PRECISION, "'precision'")) {
|
| - return;
|
| + return nullptr;
|
| }
|
| + Modifiers::Flag result;
|
| Token p = this->nextToken();
|
| switch (p.fKind) {
|
| - case Token::LOWP: // fall through
|
| - case Token::MEDIUMP: // fall through
|
| + case Token::LOWP:
|
| + result = Modifiers::kLowp_Flag;
|
| + break;
|
| + case Token::MEDIUMP:
|
| + result = Modifiers::kMediump_Flag;
|
| + break;
|
| case Token::HIGHP:
|
| - // ignored for now
|
| + result = Modifiers::kHighp_Flag;
|
| break;
|
| default:
|
| this->error(p.fPosition, "expected 'lowp', 'mediump', or 'highp', but found '" +
|
| p.fText + "'");
|
| - return;
|
| + return nullptr;
|
| }
|
| + // FIXME handle the type
|
| if (!this->type()) {
|
| - return;
|
| + return nullptr;
|
| }
|
| this->expect(Token::SEMICOLON, "';'");
|
| + return std::unique_ptr<ASTDeclaration>(new ASTPrecision(p.fPosition, result));
|
| }
|
|
|
| -/* DIRECTIVE(#version) INT_LITERAL | DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */
|
| +/* DIRECTIVE(#version) INT_LITERAL ("es" | "compatibility")? |
|
| + DIRECTIVE(#extension) IDENTIFIER COLON IDENTIFIER */
|
| std::unique_ptr<ASTDeclaration> Parser::directive() {
|
| Token start;
|
| if (!this->expect(Token::DIRECTIVE, "a directive", &start)) {
|
| @@ -193,7 +207,12 @@ std::unique_ptr<ASTDeclaration> Parser::directive() {
|
| }
|
| if (start.fText == "#version") {
|
| this->expect(Token::INT_LITERAL, "a version number");
|
| - // ignored for now
|
| + Token next = this->peek();
|
| + if (next.fText == "es" || next.fText == "compatibility") {
|
| + this->nextToken();
|
| + }
|
| + // version is ignored for now; it will eventually become an error when we stop pretending
|
| + // to be GLSL
|
| return nullptr;
|
| } else if (start.fText == "#extension") {
|
| Token name;
|
| @@ -227,6 +246,10 @@ std::unique_ptr<ASTDeclaration> Parser::declaration() {
|
| if (lookahead.fKind == Token::STRUCT) {
|
| return this->structVarDeclaration(modifiers);
|
| }
|
| + if (lookahead.fKind == Token::SEMICOLON) {
|
| + this->nextToken();
|
| + return std::unique_ptr<ASTDeclaration>(new ASTModifiersDeclaration(modifiers));
|
| + }
|
| std::unique_ptr<ASTType> type(this->type());
|
| if (!type) {
|
| return nullptr;
|
| @@ -477,10 +500,13 @@ ASTLayout Parser::layout() {
|
| int set = -1;
|
| int builtin = -1;
|
| bool originUpperLeft = false;
|
| + bool overrideCoverage = false;
|
| + bool blendSupportAllEquations = false;
|
| if (this->peek().fKind == Token::LAYOUT) {
|
| this->nextToken();
|
| if (!this->expect(Token::LPAREN, "'('")) {
|
| - return ASTLayout(location, binding, index, set, builtin, originUpperLeft);
|
| + return ASTLayout(location, binding, index, set, builtin, originUpperLeft,
|
| + overrideCoverage, blendSupportAllEquations);
|
| }
|
| for (;;) {
|
| Token t = this->nextToken();
|
| @@ -496,6 +522,10 @@ ASTLayout Parser::layout() {
|
| builtin = this->layoutInt();
|
| } else if (t.fText == "origin_upper_left") {
|
| originUpperLeft = true;
|
| + } else if (t.fText == "override_coverage") {
|
| + overrideCoverage = true;
|
| + } else if (t.fText == "blend_support_all_equations") {
|
| + blendSupportAllEquations = true;
|
| } else {
|
| this->error(t.fPosition, ("'" + t.fText +
|
| "' is not a valid layout qualifier").c_str());
|
| @@ -509,7 +539,8 @@ ASTLayout Parser::layout() {
|
| }
|
| }
|
| }
|
| - return ASTLayout(location, binding, index, set, builtin, originUpperLeft);
|
| + return ASTLayout(location, binding, index, set, builtin, originUpperLeft, overrideCoverage,
|
| + blendSupportAllEquations);
|
| }
|
|
|
| /* layout? (UNIFORM | CONST | IN | OUT | INOUT | LOWP | MEDIUMP | HIGHP | FLAT | NOPERSPECTIVE)* */
|
| @@ -1211,10 +1242,11 @@ std::unique_ptr<ASTExpression> Parser::multiplicativeExpression() {
|
| /* postfixExpression | (PLUS | MINUS | NOT | PLUSPLUS | MINUSMINUS) unaryExpression */
|
| std::unique_ptr<ASTExpression> Parser::unaryExpression() {
|
| switch (this->peek().fKind) {
|
| - case Token::PLUS: // fall through
|
| - case Token::MINUS: // fall through
|
| - case Token::NOT: // fall through
|
| - case Token::PLUSPLUS: // fall through
|
| + case Token::PLUS: // fall through
|
| + case Token::MINUS: // fall through
|
| + case Token::LOGICALNOT: // fall through
|
| + case Token::BITWISENOT: // fall through
|
| + case Token::PLUSPLUS: // fall through
|
| case Token::MINUSMINUS: {
|
| Token t = this->nextToken();
|
| std::unique_ptr<ASTExpression> expr = this->unaryExpression();
|
| @@ -1254,12 +1286,16 @@ std::unique_ptr<ASTExpression> Parser::postfixExpression() {
|
| }
|
| }
|
|
|
| -/* LBRACKET expression RBRACKET | DOT IDENTIFIER | LPAREN parameters RPAREN |
|
| +/* LBRACKET expression? RBRACKET | DOT IDENTIFIER | LPAREN parameters RPAREN |
|
| PLUSPLUS | MINUSMINUS */
|
| std::unique_ptr<ASTSuffix> Parser::suffix() {
|
| Token next = this->nextToken();
|
| switch (next.fKind) {
|
| case Token::LBRACKET: {
|
| + if (this->peek().fKind == Token::RBRACKET) {
|
| + this->nextToken();
|
| + return std::unique_ptr<ASTSuffix>(new ASTIndexSuffix(next.fPosition));
|
| + }
|
| std::unique_ptr<ASTExpression> e = this->expression();
|
| if (!e) {
|
| return nullptr;
|
|
|