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; |