diff --git a/src/sksl/SkSLASTNode.cpp b/src/sksl/SkSLASTNode.cpp index ccfe25451a..e25bdf0af5 100644 --- a/src/sksl/SkSLASTNode.cpp +++ b/src/sksl/SkSLASTNode.cpp @@ -17,7 +17,7 @@ String ASTNode::description() const { case Kind::kNull: return ""; case Kind::kBinary: return "(" + this->begin()->description() + " " + - Operators::OperatorName(getToken().fKind) + " " + + getOperator().operatorName() + " " + (this->begin() + 1)->description() + ")"; case Kind::kBlock: { String result = "{\n"; @@ -162,9 +162,9 @@ String ASTNode::description() const { return result; } case Kind::kPostfix: - return this->begin()->description() + Operators::OperatorName(getToken().fKind); + return this->begin()->description() + getOperator().operatorName(); case Kind::kPrefix: - return Operators::OperatorName(getToken().fKind) + this->begin()->description(); + return getOperator().operatorName() + this->begin()->description(); case Kind::kReturn: if (this->begin() != this->end()) { return "return " + this->begin()->description() + ";"; diff --git a/src/sksl/SkSLASTNode.h b/src/sksl/SkSLASTNode.h index a9678d7d94..e6d3015d33 100644 --- a/src/sksl/SkSLASTNode.h +++ b/src/sksl/SkSLASTNode.h @@ -9,6 +9,7 @@ #define SKSL_ASTNODE #include "src/sksl/SkSLLexer.h" +#include "src/sksl/SkSLOperators.h" #include "src/sksl/SkSLString.h" #include "src/sksl/ir/SkSLModifiers.h" @@ -53,7 +54,7 @@ struct ASTNode { }; enum class Kind { - // data: operator(Token), children: left, right + // data: operator, children: left, right kBinary, // children: statements kBlock, @@ -97,9 +98,9 @@ struct ASTNode { kNull, // data: ParameterData, children: type, arraySize1, arraySize2, ..., value? kParameter, - // data: operator(Token), children: operand + // data: operator, children: operand kPostfix, - // data: operator(Token), children: operand + // data: operator, children: operand kPrefix, // children: value kReturn, @@ -250,7 +251,7 @@ struct ASTNode { }; struct NodeData { - char fBytes[std::max({sizeof(Token), + char fBytes[std::max({sizeof(Token::Kind), sizeof(StringFragment), sizeof(bool), sizeof(SKSL_INT), @@ -263,7 +264,7 @@ struct ASTNode { sizeof(SectionData)})]; enum class Kind { - kToken, + kOperator, kStringFragment, kBool, kInt, @@ -278,8 +279,9 @@ struct ASTNode { NodeData() = default; - NodeData(Token data) - : fKind(Kind::kToken) { + NodeData(Operator op) + : fKind(Kind::kOperator) { + Token::Kind data = op.kind(); memcpy(fBytes, &data, sizeof(data)); } @@ -341,12 +343,13 @@ struct ASTNode { ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind) : fNodes(nodes) , fOffset(offset) - , fKind(kind) { + , fKind(kind) { + switch (kind) { case Kind::kBinary: case Kind::kPostfix: case Kind::kPrefix: - fData.fKind = NodeData::Kind::kToken; + fData.fKind = NodeData::Kind::kOperator; break; case Kind::kBool: @@ -398,9 +401,9 @@ struct ASTNode { } } - ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, Token t) + ASTNode(std::vector<ASTNode>* nodes, int offset, Kind kind, Operator op) : fNodes(nodes) - , fData(t) + , fData(op) , fOffset(offset) , fKind(kind) {} @@ -450,11 +453,11 @@ struct ASTNode { return fKind != Kind::kNull; } - Token getToken() const { - SkASSERT(fData.fKind == NodeData::Kind::kToken); - Token result; - memcpy(&result, fData.fBytes, sizeof(result)); - return result; + Operator getOperator() const { + SkASSERT(fData.fKind == NodeData::Kind::kOperator); + Token::Kind tokenKind; + memcpy(&tokenKind, fData.fBytes, sizeof(tokenKind)); + return Operator{tokenKind}; } bool getBool() const { diff --git a/src/sksl/SkSLAnalysis.cpp b/src/sksl/SkSLAnalysis.cpp index fa19e7a923..cf9905fdf8 100644 --- a/src/sksl/SkSLAnalysis.cpp +++ b/src/sksl/SkSLAnalysis.cpp @@ -538,7 +538,7 @@ static const char* invalid_for_ES2(const ForStatement& loop, return "expected loop index on left hand side of condition"; } // relational_operator is one of: > >= < <= == or != - switch (cond.getOperator()) { + switch (cond.getOperator().kind()) { case Token::Kind::TK_GT: case Token::Kind::TK_GTEQ: case Token::Kind::TK_LT: @@ -575,7 +575,7 @@ static const char* invalid_for_ES2(const ForStatement& loop, if (!getConstant(next.right(), &loopInfo.fDelta)) { return "loop index must be modified by a constant expression"; } - switch (next.getOperator()) { + switch (next.getOperator().kind()) { case Token::Kind::TK_PLUSEQ: break; case Token::Kind::TK_MINUSEQ: loopInfo.fDelta = -loopInfo.fDelta; break; default: @@ -587,7 +587,7 @@ static const char* invalid_for_ES2(const ForStatement& loop, if (!is_loop_index(next.operand())) { return "expected loop index in loop expression"; } - switch (next.getOperator()) { + switch (next.getOperator().kind()) { case Token::Kind::TK_PLUSPLUS: loopInfo.fDelta = 1; break; case Token::Kind::TK_MINUSMINUS: loopInfo.fDelta = -1; break; default: @@ -599,7 +599,7 @@ static const char* invalid_for_ES2(const ForStatement& loop, if (!is_loop_index(next.operand())) { return "expected loop index in loop expression"; } - switch (next.getOperator()) { + switch (next.getOperator().kind()) { case Token::Kind::TK_PLUSPLUS: loopInfo.fDelta = 1; break; case Token::Kind::TK_MINUSMINUS: loopInfo.fDelta = -1; break; default: @@ -624,7 +624,7 @@ static const char* invalid_for_ES2(const ForStatement& loop, double val = loopInfo.fStart; auto evalCond = [&]() { - switch (cond.getOperator()) { + switch (cond.getOperator().kind()) { case Token::Kind::TK_GT: return val > loopEnd; case Token::Kind::TK_GTEQ: return val >= loopEnd; case Token::Kind::TK_LT: return val < loopEnd; diff --git a/src/sksl/SkSLCFGGenerator.cpp b/src/sksl/SkSLCFGGenerator.cpp index 45e6d7cf36..6932369214 100644 --- a/src/sksl/SkSLCFGGenerator.cpp +++ b/src/sksl/SkSLCFGGenerator.cpp @@ -197,7 +197,7 @@ bool BasicBlock::tryRemoveExpression(std::vector<BasicBlock::Node>::iterator* it switch (expr->kind()) { case Expression::Kind::kBinary: { BinaryExpression& b = expr->as<BinaryExpression>(); - if (b.getOperator() == Token::Kind::TK_EQ) { + if (b.getOperator().kind() == Token::Kind::TK_EQ) { if (!this->tryRemoveLValueBefore(iter, b.left().get())) { return false; } @@ -349,8 +349,8 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool switch ((*e)->kind()) { case Expression::Kind::kBinary: { BinaryExpression& b = e->get()->as<BinaryExpression>(); - Token::Kind op = b.getOperator(); - switch (op) { + Operator op = b.getOperator(); + switch (op.kind()) { case Token::Kind::TK_LOGICALAND: // fall through case Token::Kind::TK_LOGICALOR: { // this isn't as precise as it could be -- we don't bother to track that if we @@ -374,8 +374,7 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool break; } default: - this->addExpression(cfg, &b.left(), - !Operators::IsAssignment(b.getOperator())); + this->addExpression(cfg, &b.left(), !b.getOperator().isAssignment()); this->addExpression(cfg, &b.right(), constantPropagate); cfg.currentBlock().fNodes.push_back( BasicBlock::MakeExpression(e, constantPropagate)); @@ -421,9 +420,10 @@ void CFGGenerator::addExpression(CFG& cfg, std::unique_ptr<Expression>* e, bool } case Expression::Kind::kPrefix: { PrefixExpression& p = e->get()->as<PrefixExpression>(); - this->addExpression(cfg, &p.operand(), constantPropagate && - p.getOperator() != Token::Kind::TK_PLUSPLUS && - p.getOperator() != Token::Kind::TK_MINUSMINUS); + this->addExpression(cfg, &p.operand(), + constantPropagate && + p.getOperator().kind() != Token::Kind::TK_PLUSPLUS && + p.getOperator().kind() != Token::Kind::TK_MINUSMINUS); cfg.currentBlock().fNodes.push_back(BasicBlock::MakeExpression(e, constantPropagate)); break; } diff --git a/src/sksl/SkSLCPPCodeGenerator.cpp b/src/sksl/SkSLCPPCodeGenerator.cpp index 8f9fe6f17c..0c26b438f0 100644 --- a/src/sksl/SkSLCPPCodeGenerator.cpp +++ b/src/sksl/SkSLCPPCodeGenerator.cpp @@ -72,10 +72,10 @@ void CPPCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence) { const Expression& left = *b.left(); const Expression& right = *b.right(); - Token::Kind op = b.getOperator(); - if (op == Token::Kind::TK_PERCENT) { + Operator op = b.getOperator(); + if (op.kind() == Token::Kind::TK_PERCENT) { // need to use "%%" instead of "%" b/c the code will be inside of a printf - Precedence precedence = Operators::GetBinaryPrecedence(op); + Precedence precedence = op.getBinaryPrecedence(); if (precedence >= parentPrecedence) { this->write("("); } diff --git a/src/sksl/SkSLCPPCodeGenerator.h b/src/sksl/SkSLCPPCodeGenerator.h index 287352c59b..252f5b7e7f 100644 --- a/src/sksl/SkSLCPPCodeGenerator.h +++ b/src/sksl/SkSLCPPCodeGenerator.h @@ -25,7 +25,7 @@ public: bool generateCode() override; private: - using Precedence = Operators::Precedence; + using Precedence = Operator::Precedence; void writef(const char* s, va_list va) SK_PRINTF_LIKE(2, 0); diff --git a/src/sksl/SkSLCompiler.cpp b/src/sksl/SkSLCompiler.cpp index 137084e15a..b8a01c29b1 100644 --- a/src/sksl/SkSLCompiler.cpp +++ b/src/sksl/SkSLCompiler.cpp @@ -431,7 +431,7 @@ static bool is_dead(const Expression& lvalue, ProgramUsage* usage) { * to a dead target and lack of side effects on the left hand side. */ static bool dead_assignment(const BinaryExpression& b, ProgramUsage* usage) { - if (!Operators::IsAssignment(b.getOperator())) { + if (!b.getOperator().isAssignment()) { return false; } return is_dead(*b.left(), usage); @@ -477,7 +477,7 @@ static bool is_matching_expression_tree(const Expression& left, const Expression } static bool self_assignment(const BinaryExpression& b) { - return b.getOperator() == Token::Kind::TK_EQ && + return b.getOperator().kind() == Token::Kind::TK_EQ && is_matching_expression_tree(*b.left(), *b.right()); } @@ -576,7 +576,7 @@ static void delete_left(BasicBlock* b, std::unique_ptr<Expression>& rightPointer = bin.right(); SkASSERT(!left.hasSideEffects()); bool result; - if (bin.getOperator() == Token::Kind::TK_EQ) { + if (bin.getOperator().kind() == Token::Kind::TK_EQ) { result = b->tryRemoveLValueBefore(iter, &left); } else { result = b->tryRemoveExpressionBefore(iter, &left); @@ -764,7 +764,7 @@ void Compiler::simplifyExpression(DefinitionMap& definitions, (!rightType.isScalar() && !rightType.isVector())) { break; } - switch (bin->getOperator()) { + switch (bin->getOperator().kind()) { case Token::Kind::TK_STAR: if (is_constant(left, 1)) { if (leftType.isVector() && rightType.isScalar()) { diff --git a/src/sksl/SkSLConstantFolder.cpp b/src/sksl/SkSLConstantFolder.cpp index 137ab64373..7d05ffda13 100644 --- a/src/sksl/SkSLConstantFolder.cpp +++ b/src/sksl/SkSLConstantFolder.cpp @@ -24,17 +24,17 @@ namespace SkSL { static std::unique_ptr<Expression> eliminate_no_op_boolean(const Expression& left, - Token::Kind op, + Operator op, const Expression& right) { SkASSERT(right.is<BoolLiteral>()); bool rightVal = right.as<BoolLiteral>().value(); // Detect no-op Boolean expressions and optimize them away. - if ((op == Token::Kind::TK_LOGICALAND && rightVal) || // (expr && true) -> (expr) - (op == Token::Kind::TK_LOGICALOR && !rightVal) || // (expr || false) -> (expr) - (op == Token::Kind::TK_LOGICALXOR && !rightVal) || // (expr ^^ false) -> (expr) - (op == Token::Kind::TK_EQEQ && rightVal) || // (expr == true) -> (expr) - (op == Token::Kind::TK_NEQ && !rightVal)) { // (expr != false) -> (expr) + if ((op.kind() == Token::Kind::TK_LOGICALAND && rightVal) || // (expr && true) -> (expr) + (op.kind() == Token::Kind::TK_LOGICALOR && !rightVal) || // (expr || false) -> (expr) + (op.kind() == Token::Kind::TK_LOGICALXOR && !rightVal) || // (expr ^^ false) -> (expr) + (op.kind() == Token::Kind::TK_EQEQ && rightVal) || // (expr == true) -> (expr) + (op.kind() == Token::Kind::TK_NEQ && !rightVal)) { // (expr != false) -> (expr) return left.clone(); } @@ -43,14 +43,14 @@ static std::unique_ptr<Expression> eliminate_no_op_boolean(const Expression& lef } static std::unique_ptr<Expression> short_circuit_boolean(const Expression& left, - Token::Kind op, + Operator op, const Expression& right) { SkASSERT(left.is<BoolLiteral>()); bool leftVal = left.as<BoolLiteral>().value(); // When the literal is on the left, we can sometimes eliminate the other expression entirely. - if ((op == Token::Kind::TK_LOGICALAND && !leftVal) || // (false && expr) -> (false) - (op == Token::Kind::TK_LOGICALOR && leftVal)) { // (true || expr) -> (true) + if ((op.kind() == Token::Kind::TK_LOGICALAND && !leftVal) || // (false && expr) -> (false) + (op.kind() == Token::Kind::TK_LOGICALOR && leftVal)) { // (true || expr) -> (true) return left.clone(); } @@ -67,15 +67,15 @@ static std::unique_ptr<Expression> short_circuit_boolean(const Expression& left, template <typename T, typename U = T> static std::unique_ptr<Expression> simplify_vector(const Context& context, const Expression& left, - Token::Kind op, + Operator op, const Expression& right) { SkASSERT(left.type().isVector()); SkASSERT(left.type() == right.type()); const Type& type = left.type(); // Handle boolean operations: == != - if (op == Token::Kind::TK_EQEQ || op == Token::Kind::TK_NEQ) { - bool equality = (op == Token::Kind::TK_EQEQ); + if (op.kind() == Token::Kind::TK_EQEQ || op.kind() == Token::Kind::TK_NEQ) { + bool equality = (op.kind() == Token::Kind::TK_EQEQ); switch (left.compareConstant(right)) { case Expression::ComparisonResult::kNotEqual: @@ -102,7 +102,7 @@ static std::unique_ptr<Expression> simplify_vector(const Context& context, return std::make_unique<Constructor>(left.fOffset, &type, std::move(args)); }; - switch (op) { + switch (op.kind()) { case Token::Kind::TK_PLUS: return vectorComponentwiseFold([](U a, U b) { return a + b; }); case Token::Kind::TK_MINUS: return vectorComponentwiseFold([](U a, U b) { return a - b; }); case Token::Kind::TK_STAR: return vectorComponentwiseFold([](U a, U b) { return a * b; }); @@ -167,9 +167,9 @@ static bool contains_constant_zero(const Expression& expr) { (ConstantFolder::GetConstantFloat(expr, &floatValue) && floatValue == 0.0f); } -bool ConstantFolder::ErrorOnDivideByZero(const Context& context, int offset, Token::Kind op, +bool ConstantFolder::ErrorOnDivideByZero(const Context& context, int offset, Operator op, const Expression& right) { - switch (op) { + switch (op.kind()) { case Token::Kind::TK_SLASH: case Token::Kind::TK_SLASHEQ: case Token::Kind::TK_PERCENT: @@ -187,11 +187,11 @@ bool ConstantFolder::ErrorOnDivideByZero(const Context& context, int offset, Tok std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context, int offset, const Expression& left, - Token::Kind op, + Operator op, const Expression& right) { // If this is the comma operator, the left side is evaluated but not otherwise used in any way. // So if the left side has no side effects, it can just be eliminated entirely. - if (op == Token::Kind::TK_COMMA && !left.hasSideEffects()) { + if (op.kind() == Token::Kind::TK_COMMA && !left.hasSideEffects()) { return right.clone(); } @@ -200,7 +200,7 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context, bool leftVal = left.as<BoolLiteral>().value(); bool rightVal = right.as<BoolLiteral>().value(); bool result; - switch (op) { + switch (op.kind()) { case Token::Kind::TK_LOGICALAND: result = leftVal && rightVal; break; case Token::Kind::TK_LOGICALOR: result = leftVal || rightVal; break; case Token::Kind::TK_LOGICALXOR: result = leftVal ^ rightVal; break; @@ -249,7 +249,7 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context, if (left.is<IntLiteral>() && right.is<IntLiteral>()) { SKSL_INT leftVal = left.as<IntLiteral>().value(); SKSL_INT rightVal = right.as<IntLiteral>().value(); - switch (op) { + switch (op.kind()) { case Token::Kind::TK_PLUS: return URESULT(Int, +); case Token::Kind::TK_MINUS: return URESULT(Int, -); case Token::Kind::TK_STAR: return URESULT(Int, *); @@ -298,7 +298,7 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context, if (left.is<FloatLiteral>() && right.is<FloatLiteral>()) { SKSL_FLOAT leftVal = left.as<FloatLiteral>().value(); SKSL_FLOAT rightVal = right.as<FloatLiteral>().value(); - switch (op) { + switch (op.kind()) { case Token::Kind::TK_PLUS: return RESULT(Float, +); case Token::Kind::TK_MINUS: return RESULT(Float, -); case Token::Kind::TK_STAR: return RESULT(Float, *); @@ -354,7 +354,7 @@ std::unique_ptr<Expression> ConstantFolder::Simplify(const Context& context, // Perform constant folding on pairs of matrices. if (leftType.isMatrix() && rightType.isMatrix()) { bool equality; - switch (op) { + switch (op.kind()) { case Token::Kind::TK_EQEQ: equality = true; break; diff --git a/src/sksl/SkSLConstantFolder.h b/src/sksl/SkSLConstantFolder.h index 20c9a0c6db..bcc5bda168 100644 --- a/src/sksl/SkSLConstantFolder.h +++ b/src/sksl/SkSLConstantFolder.h @@ -11,7 +11,7 @@ #include <memory> #include "src/sksl/SkSLDefines.h" -#include "src/sksl/SkSLLexer.h" +#include "src/sksl/SkSLOperators.h" namespace SkSL { @@ -41,14 +41,14 @@ public: * Reports an error and returns true if op is a division / mod operator and right is zero or * contains a zero element. */ - static bool ErrorOnDivideByZero(const Context& context, int offset, Token::Kind op, + static bool ErrorOnDivideByZero(const Context& context, int offset, Operator op, const Expression& right); /** Simplifies the binary expression `left OP right`. Returns null if it can't be simplified. */ static std::unique_ptr<Expression> Simplify(const Context& context, int offset, const Expression& left, - Token::Kind op, + Operator op, const Expression& right); }; diff --git a/src/sksl/SkSLDefinitionMap.cpp b/src/sksl/SkSLDefinitionMap.cpp index 9cecef53d7..968d7655a6 100644 --- a/src/sksl/SkSLDefinitionMap.cpp +++ b/src/sksl/SkSLDefinitionMap.cpp @@ -119,9 +119,9 @@ void DefinitionMap::addDefinitions(const Context& context, const BasicBlock::Nod switch (expr->kind()) { case Expression::Kind::kBinary: { BinaryExpression* b = &expr->as<BinaryExpression>(); - if (b->getOperator() == Token::Kind::TK_EQ) { + if (b->getOperator().kind() == Token::Kind::TK_EQ) { this->addDefinition(context, b->left().get(), &b->right()); - } else if (Operators::IsAssignment(b->getOperator())) { + } else if (b->getOperator().isAssignment()) { this->addDefinition( context, b->left().get(), (std::unique_ptr<Expression>*)&context.fDefined_Expression); @@ -142,8 +142,8 @@ void DefinitionMap::addDefinitions(const Context& context, const BasicBlock::Nod } case Expression::Kind::kPrefix: { const PrefixExpression* p = &expr->as<PrefixExpression>(); - if (p->getOperator() == Token::Kind::TK_MINUSMINUS || - p->getOperator() == Token::Kind::TK_PLUSPLUS) { + if (p->getOperator().kind() == Token::Kind::TK_MINUSMINUS || + p->getOperator().kind() == Token::Kind::TK_PLUSPLUS) { this->addDefinition( context, p->operand().get(), (std::unique_ptr<Expression>*)&context.fDefined_Expression); @@ -152,8 +152,8 @@ void DefinitionMap::addDefinitions(const Context& context, const BasicBlock::Nod } case Expression::Kind::kPostfix: { const PostfixExpression* p = &expr->as<PostfixExpression>(); - if (p->getOperator() == Token::Kind::TK_MINUSMINUS || - p->getOperator() == Token::Kind::TK_PLUSPLUS) { + if (p->getOperator().kind() == Token::Kind::TK_MINUSMINUS || + p->getOperator().kind() == Token::Kind::TK_PLUSPLUS) { this->addDefinition( context, p->operand().get(), (std::unique_ptr<Expression>*)&context.fDefined_Expression); diff --git a/src/sksl/SkSLDehydrator.cpp b/src/sksl/SkSLDehydrator.cpp index e1e2cafbe8..d6d63ce635 100644 --- a/src/sksl/SkSLDehydrator.cpp +++ b/src/sksl/SkSLDehydrator.cpp @@ -262,7 +262,7 @@ void Dehydrator::write(const Expression* e) { const BinaryExpression& b = e->as<BinaryExpression>(); this->writeCommand(Rehydrator::kBinary_Command); this->write(b.left().get()); - this->writeU8((int) b.getOperator()); + this->writeU8((int) b.getOperator().kind()); this->write(b.right().get()); this->write(b.type()); break; @@ -332,14 +332,14 @@ void Dehydrator::write(const Expression* e) { case Expression::Kind::kPostfix: { const PostfixExpression& p = e->as<PostfixExpression>(); this->writeCommand(Rehydrator::kPostfix_Command); - this->writeU8((int) p.getOperator()); + this->writeU8((int) p.getOperator().kind()); this->write(p.operand().get()); break; } case Expression::Kind::kPrefix: { const PrefixExpression& p = e->as<PrefixExpression>(); this->writeCommand(Rehydrator::kPrefix_Command); - this->writeU8((int) p.getOperator()); + this->writeU8((int) p.getOperator().kind()); this->write(p.operand().get()); break; } diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp index 2b290c74c4..0712d4c075 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.cpp +++ b/src/sksl/SkSLGLSLCodeGenerator.cpp @@ -509,7 +509,7 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) { arguments.size() == 2 && arguments[1]->kind() == Expression::Kind::kPrefix) { const PrefixExpression& p = (PrefixExpression&) *arguments[1]; - if (p.getOperator() == Token::Kind::TK_MINUS) { + if (p.getOperator().kind() == Token::Kind::TK_MINUS) { this->write("atan("); this->writeExpression(*arguments[0], Precedence::kSequence); this->write(", -1.0 * "); @@ -862,21 +862,21 @@ void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Precedence parentPrecedence) { const Expression& left = *b.left(); const Expression& right = *b.right(); - Token::Kind op = b.getOperator(); + Operator op = b.getOperator(); if (fProgram.fCaps->unfoldShortCircuitAsTernary() && - (op == Token::Kind::TK_LOGICALAND || op == Token::Kind::TK_LOGICALOR)) { + (op.kind() == Token::Kind::TK_LOGICALAND || op.kind() == Token::Kind::TK_LOGICALOR)) { this->writeShortCircuitWorkaroundExpression(b, parentPrecedence); return; } - Precedence precedence = Operators::GetBinaryPrecedence(op); + Precedence precedence = op.getBinaryPrecedence(); if (precedence >= parentPrecedence) { this->write("("); } bool positionWorkaround = fProgramKind == Program::Kind::kVertex_Kind && - Operators::IsAssignment(op) && - left.kind() == Expression::Kind::kFieldAccess && - is_sk_position((FieldAccess&) left) && + op.isAssignment() && + left.is<FieldAccess>() && + is_sk_position(left.as<FieldAccess>()) && !right.containsRTAdjust() && !fProgram.fCaps->canUseFragCoord(); if (positionWorkaround) { @@ -884,7 +884,7 @@ void GLSLCodeGenerator::writeBinaryExpression(const BinaryExpression& b, } this->writeExpression(left, precedence); this->write(" "); - this->write(Operators::OperatorName(op)); + this->write(op.operatorName()); this->write(" "); this->writeExpression(right, precedence); if (positionWorkaround) { @@ -906,14 +906,14 @@ void GLSLCodeGenerator::writeShortCircuitWorkaroundExpression(const BinaryExpres // a || b => a ? true : b this->writeExpression(*b.left(), Precedence::kTernary); this->write(" ? "); - if (b.getOperator() == Token::Kind::TK_LOGICALAND) { + if (b.getOperator().kind() == Token::Kind::TK_LOGICALAND) { this->writeExpression(*b.right(), Precedence::kTernary); } else { BoolLiteral boolTrue(fContext, -1, true); this->writeBoolLiteral(boolTrue); } this->write(" : "); - if (b.getOperator() == Token::Kind::TK_LOGICALAND) { + if (b.getOperator().kind() == Token::Kind::TK_LOGICALAND) { BoolLiteral boolFalse(fContext, -1, false); this->writeBoolLiteral(boolFalse); } else { @@ -944,7 +944,7 @@ void GLSLCodeGenerator::writePrefixExpression(const PrefixExpression& p, if (Precedence::kPrefix >= parentPrecedence) { this->write("("); } - this->write(Operators::OperatorName(p.getOperator())); + this->write(p.getOperator().operatorName()); this->writeExpression(*p.operand(), Precedence::kPrefix); if (Precedence::kPrefix >= parentPrecedence) { this->write(")"); @@ -957,7 +957,7 @@ void GLSLCodeGenerator::writePostfixExpression(const PostfixExpression& p, this->write("("); } this->writeExpression(*p.operand(), Precedence::kPostfix); - this->write(Operators::OperatorName(p.getOperator())); + this->write(p.getOperator().operatorName()); if (Precedence::kPostfix >= parentPrecedence) { this->write(")"); } @@ -1332,7 +1332,7 @@ void GLSLCodeGenerator::writeForStatement(const ForStatement& f) { if (f.test()) { if (fProgram.fCaps->addAndTrueToLoopCondition()) { std::unique_ptr<Expression> and_true(new BinaryExpression( - -1, f.test()->clone(), Token::Kind::TK_LOGICALAND, + /*offset=*/-1, f.test()->clone(), Token::Kind::TK_LOGICALAND, std::make_unique<BoolLiteral>(fContext, -1, true), fContext.fTypes.fBool.get())); this->writeExpression(*and_true, Precedence::kTopLevel); diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h index b40a78c8e5..78bcabcdcf 100644 --- a/src/sksl/SkSLGLSLCodeGenerator.h +++ b/src/sksl/SkSLGLSLCodeGenerator.h @@ -61,7 +61,7 @@ public: bool generateCode() override; protected: - using Precedence = Operators::Precedence; + using Precedence = Operator::Precedence; void write(const char* s); diff --git a/src/sksl/SkSLIRGenerator.cpp b/src/sksl/SkSLIRGenerator.cpp index 9800dfdd2e..82dd7aafe3 100644 --- a/src/sksl/SkSLIRGenerator.cpp +++ b/src/sksl/SkSLIRGenerator.cpp @@ -934,10 +934,12 @@ std::unique_ptr<Statement> IRGenerator::getNormalizeSkPositionCode() { // sk_Position.w); SkASSERT(skPerVertex && fRTAdjust); auto Ref = [](const Variable* var) -> std::unique_ptr<Expression> { - return std::make_unique<VariableReference>(-1, var, VariableReference::RefKind::kRead); + return std::make_unique<VariableReference>(/*offset=*/-1, var, + VariableReference::RefKind::kRead); }; auto WRef = [](const Variable* var) -> std::unique_ptr<Expression> { - return std::make_unique<VariableReference>(-1, var, VariableReference::RefKind::kWrite); + return std::make_unique<VariableReference>(/*offset=*/-1, var, + VariableReference::RefKind::kWrite); }; auto Field = [&](const Variable* var, int idx) -> std::unique_ptr<Expression> { return std::make_unique<FieldAccess>(Ref(var), idx, @@ -957,8 +959,8 @@ std::unique_ptr<Statement> IRGenerator::getNormalizeSkPositionCode() { }; auto Op = [&](std::unique_ptr<Expression> left, Token::Kind op, std::unique_ptr<Expression> right) -> std::unique_ptr<Expression> { - return std::make_unique<BinaryExpression>(-1, std::move(left), op, std::move(right), - fContext.fTypes.fFloat2.get()); + return std::make_unique<BinaryExpression>(/*offset=*/-1, std::move(left), op, + std::move(right), fContext.fTypes.fFloat2.get()); }; static const ComponentArray kXYIndices{0, 1}; @@ -1720,8 +1722,8 @@ std::unique_ptr<Expression> IRGenerator::coerce(std::unique_ptr<Expression> expr return this->convertConstructor(offset, type.scalarTypeForLiteral(), std::move(args)); } -static bool is_matrix_multiply(const Type& left, Token::Kind op, const Type& right) { - if (op != Token::Kind::TK_STAR && op != Token::Kind::TK_STAREQ) { +static bool is_matrix_multiply(const Type& left, Operator op, const Type& right) { + if (op.kind() != Token::Kind::TK_STAR && op.kind() != Token::Kind::TK_STAREQ) { return false; } if (left.isMatrix()) { @@ -1730,98 +1732,19 @@ static bool is_matrix_multiply(const Type& left, Token::Kind op, const Type& rig return left.isVector() && right.isMatrix(); } -/** - * Defines the set of logical (comparison) operators. - */ -static bool op_is_logical(Token::Kind op) { - switch (op) { - case Token::Kind::TK_LT: - case Token::Kind::TK_GT: - case Token::Kind::TK_LTEQ: - case Token::Kind::TK_GTEQ: - return true; - default: - return false; - } -} - -/** - * Defines the set of operators which are only valid on integral types. - */ -static bool op_only_valid_for_integral_types(Token::Kind op) { - switch (op) { - case Token::Kind::TK_SHL: - case Token::Kind::TK_SHR: - case Token::Kind::TK_BITWISEAND: - case Token::Kind::TK_BITWISEOR: - case Token::Kind::TK_BITWISEXOR: - case Token::Kind::TK_PERCENT: - case Token::Kind::TK_SHLEQ: - case Token::Kind::TK_SHREQ: - case Token::Kind::TK_BITWISEANDEQ: - case Token::Kind::TK_BITWISEOREQ: - case Token::Kind::TK_BITWISEXOREQ: - case Token::Kind::TK_PERCENTEQ: - return true; - default: - return false; - } -} - -/** - * Defines the set of operators which perform vector/matrix math. - */ -static bool op_valid_for_matrix_or_vector(Token::Kind op) { - switch (op) { - case Token::Kind::TK_PLUS: - case Token::Kind::TK_MINUS: - case Token::Kind::TK_STAR: - case Token::Kind::TK_SLASH: - case Token::Kind::TK_PERCENT: - case Token::Kind::TK_SHL: - case Token::Kind::TK_SHR: - case Token::Kind::TK_BITWISEAND: - case Token::Kind::TK_BITWISEOR: - case Token::Kind::TK_BITWISEXOR: - case Token::Kind::TK_PLUSEQ: - case Token::Kind::TK_MINUSEQ: - case Token::Kind::TK_STAREQ: - case Token::Kind::TK_SLASHEQ: - case Token::Kind::TK_PERCENTEQ: - case Token::Kind::TK_SHLEQ: - case Token::Kind::TK_SHREQ: - case Token::Kind::TK_BITWISEANDEQ: - case Token::Kind::TK_BITWISEOREQ: - case Token::Kind::TK_BITWISEXOREQ: - return true; - default: - return false; - } -} - -/* - * Defines the set of operators allowed by The OpenGL ES Shading Language 1.00, Section 5.1. - * The set of illegal (reserved) operators are the ones that only make sense with integral types. - * This is not a coincidence: It's because ES2 doesn't require 'int' to be anything but syntactic - * sugar for floats with truncation after each operation). - */ -static bool op_allowed_in_strict_es2_mode(Token::Kind op) { - return !op_only_valid_for_integral_types(op); -} - /** * Determines the operand and result types of a binary expression. Returns true if the expression is * legal, false otherwise. If false, the values of the out parameters are undefined. */ static bool determine_binary_type(const Context& context, bool allowNarrowing, - Token::Kind op, + Operator op, const Type& left, const Type& right, const Type** outLeftType, const Type** outRightType, const Type** outResultType) { - switch (op) { + switch (op.kind()) { case Token::Kind::TK_EQ: // left = right *outLeftType = &left; *outRightType = &left; @@ -1876,7 +1799,7 @@ static bool determine_binary_type(const Context& context, return false; } - bool isAssignment = Operators::IsAssignment(op); + bool isAssignment = op.isAssignment(); if (is_matrix_multiply(left, op, right)) { // left * right // Determine final component type. if (!determine_binary_type(context, allowNarrowing, op, @@ -1907,13 +1830,13 @@ static bool determine_binary_type(const Context& context, } bool leftIsVectorOrMatrix = left.isVector() || left.isMatrix(); - bool validMatrixOrVectorOp = op_valid_for_matrix_or_vector(op); + bool validMatrixOrVectorOp = op.isValidForMatrixOrVector(); if (leftIsVectorOrMatrix && validMatrixOrVectorOp && right.isScalar()) { if (determine_binary_type(context, allowNarrowing, op, left.componentType(), right, outLeftType, outRightType, outResultType)) { *outLeftType = &(*outLeftType)->toCompound(context, left.columns(), left.rows()); - if (!op_is_logical(op)) { + if (!op.isLogical()) { *outResultType = &(*outResultType)->toCompound(context, left.columns(), left.rows()); } @@ -1928,7 +1851,7 @@ static bool determine_binary_type(const Context& context, if (determine_binary_type(context, allowNarrowing, op, left, right.componentType(), outLeftType, outRightType, outResultType)) { *outRightType = &(*outRightType)->toCompound(context, right.columns(), right.rows()); - if (!op_is_logical(op)) { + if (!op.isLogical()) { *outResultType = &(*outResultType)->toCompound(context, right.columns(), right.rows()); } @@ -1942,7 +1865,7 @@ static bool determine_binary_type(const Context& context, : left.coercionCost(right); if ((left.isScalar() && right.isScalar()) || (leftIsVectorOrMatrix && validMatrixOrVectorOp)) { - if (op_only_valid_for_integral_types(op)) { + if (op.isOnlyValidForIntegralTypes()) { if (!leftComponentType.isInteger() || !rightComponentType.isInteger()) { return false; } @@ -1960,7 +1883,7 @@ static bool determine_binary_type(const Context& context, } else { return false; } - if (op_is_logical(op)) { + if (op.isLogical()) { *outResultType = context.fTypes.fBool.get(); } return true; @@ -1975,17 +1898,17 @@ std::unique_ptr<Expression> IRGenerator::convertBinaryExpression(const ASTNode& if (!left) { return nullptr; } - Token::Kind op = expression.getToken().fKind; std::unique_ptr<Expression> right = this->convertExpression(*(iter++)); if (!right) { return nullptr; } - return this->convertBinaryExpression(std::move(left), op, std::move(right)); + return this->convertBinaryExpression(std::move(left), expression.getOperator(), + std::move(right)); } std::unique_ptr<Expression> IRGenerator::convertBinaryExpression( std::unique_ptr<Expression> left, - Token::Kind op, + Operator op, std::unique_ptr<Expression> right) { if (!left || !right) { return nullptr; @@ -2006,13 +1929,13 @@ std::unique_ptr<Expression> IRGenerator::convertBinaryExpression( } else { rawRightType = &right->type(); } - if (this->strictES2Mode() && !op_allowed_in_strict_es2_mode(op)) { - this->errorReporter().error( - offset, String("operator '") + Operators::OperatorName(op) + "' is not allowed"); + if (this->strictES2Mode() && !op.isAllowedInStrictES2Mode()) { + this->errorReporter().error(offset, + String("operator '") + op.operatorName() + "' is not allowed"); return nullptr; } - bool isAssignment = Operators::IsAssignment(op); - if (isAssignment && !this->setRefKind(*left, op != Token::Kind::TK_EQ + bool isAssignment = op.isAssignment(); + if (isAssignment && !this->setRefKind(*left, op.kind() != Token::Kind::TK_EQ ? VariableReference::RefKind::kReadWrite : VariableReference::RefKind::kWrite)) { return nullptr; @@ -2020,7 +1943,7 @@ std::unique_ptr<Expression> IRGenerator::convertBinaryExpression( if (!determine_binary_type(fContext, fSettings->fAllowNarrowingConversions, op, *rawLeftType, *rawRightType, &leftType, &rightType, &resultType)) { this->errorReporter().error( - offset, String("type mismatch: '") + Operators::OperatorName(op) + + offset, String("type mismatch: '") + op.operatorName() + "' cannot operate on '" + left->type().displayName() + "', '" + right->type().displayName() + "'"); return nullptr; @@ -2441,13 +2364,13 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(const ASTNode& if (!base) { return nullptr; } - return this->convertPrefixExpression(expression.getToken().fKind, std::move(base)); + return this->convertPrefixExpression(expression.getOperator(), std::move(base)); } -std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(Token::Kind op, +std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(Operator op, std::unique_ptr<Expression> base) { const Type& baseType = base->type(); - switch (op) { + switch (op.kind()) { case Token::Kind::TK_PLUS: if (!baseType.componentType().isNumber()) { this->errorReporter().error( @@ -2477,7 +2400,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(Token::Kind op, case Token::Kind::TK_PLUSPLUS: if (!baseType.isNumber()) { this->errorReporter().error(base->fOffset, - String("'") + Operators::OperatorName(op) + + String("'") + op.operatorName() + "' cannot operate on '" + baseType.displayName() + "'"); return nullptr; } @@ -2488,7 +2411,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(Token::Kind op, case Token::Kind::TK_MINUSMINUS: if (!baseType.isNumber()) { this->errorReporter().error(base->fOffset, - String("'") + Operators::OperatorName(op) + + String("'") + op.operatorName() + "' cannot operate on '" + baseType.displayName() + "'"); return nullptr; } @@ -2499,7 +2422,7 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(Token::Kind op, case Token::Kind::TK_LOGICALNOT: if (!baseType.isBoolean()) { this->errorReporter().error(base->fOffset, - String("'") + Operators::OperatorName(op) + + String("'") + op.operatorName() + "' cannot operate on '" + baseType.displayName() + "'"); return nullptr; } @@ -2512,14 +2435,14 @@ std::unique_ptr<Expression> IRGenerator::convertPrefixExpression(Token::Kind op, case Token::Kind::TK_BITWISENOT: if (this->strictES2Mode()) { // GLSL ES 1.00, Section 5.1 - this->errorReporter().error(base->fOffset, - String("operator '") + Operators::OperatorName(op) + - "' is not allowed"); + this->errorReporter().error( + base->fOffset, + String("operator '") + op.operatorName() + "' is not allowed"); return nullptr; } if (!baseType.isInteger()) { this->errorReporter().error(base->fOffset, - String("'") + Operators::OperatorName(op) + + String("'") + op.operatorName() + "' cannot operate on '" + baseType.displayName() + "'"); return nullptr; } @@ -2918,15 +2841,15 @@ std::unique_ptr<Expression> IRGenerator::convertPostfixExpression(const ASTNode& if (!base) { return nullptr; } - return this->convertPostfixExpression(std::move(base), expression.getToken().fKind); + return this->convertPostfixExpression(std::move(base), expression.getOperator()); } std::unique_ptr<Expression> IRGenerator::convertPostfixExpression(std::unique_ptr<Expression> base, - Token::Kind op) { + Operator op) { const Type& baseType = base->type(); if (!baseType.isNumber()) { this->errorReporter().error(base->fOffset, - "'" + String(Operators::OperatorName(op)) + + "'" + String(op.operatorName()) + "' cannot operate on '" + baseType.displayName() + "'"); return nullptr; } diff --git a/src/sksl/SkSLIRGenerator.h b/src/sksl/SkSLIRGenerator.h index 39561c25a6..1e2db9e681 100644 --- a/src/sksl/SkSLIRGenerator.h +++ b/src/sksl/SkSLIRGenerator.h @@ -14,6 +14,7 @@ #include "src/sksl/SkSLASTFile.h" #include "src/sksl/SkSLASTNode.h" #include "src/sksl/SkSLErrorReporter.h" +#include "src/sksl/SkSLOperators.h" #include "src/sksl/ir/SkSLBlock.h" #include "src/sksl/ir/SkSLExpression.h" #include "src/sksl/ir/SkSLExtension.h" @@ -185,9 +186,9 @@ private: int convertArraySize(const Type& type, int offset, const ASTNode& s); int convertArraySize(const Type& type, std::unique_ptr<Expression> s); bool containsConstantZero(Expression& expr); - bool dividesByZero(Token::Kind op, Expression& right); + bool dividesByZero(Operator op, Expression& right); std::unique_ptr<Expression> convertBinaryExpression(std::unique_ptr<Expression> left, - Token::Kind op, + Operator op, std::unique_ptr<Expression> right); std::unique_ptr<Block> convertBlock(const ASTNode& block); std::unique_ptr<Statement> convertBreak(const ASTNode& b); @@ -245,9 +246,9 @@ private: std::unique_ptr<Expression> convertIndex(std::unique_ptr<Expression> base, std::unique_ptr<Expression> index); std::unique_ptr<Expression> convertPostfixExpression(std::unique_ptr<Expression> base, - Token::Kind op); + Operator op); std::unique_ptr<Expression> convertPostfixExpression(const ASTNode& expression); - std::unique_ptr<Expression> convertPrefixExpression(Token::Kind op, + std::unique_ptr<Expression> convertPrefixExpression(Operator op, std::unique_ptr<Expression> base); std::unique_ptr<Expression> convertScopeExpression(const ASTNode& expression); std::unique_ptr<StructDefinition> convertStructDefinition(const ASTNode& expression); diff --git a/src/sksl/SkSLInliner.cpp b/src/sksl/SkSLInliner.cpp index 50b8268b99..0243d47161 100644 --- a/src/sksl/SkSLInliner.cpp +++ b/src/sksl/SkSLInliner.cpp @@ -1004,9 +1004,9 @@ public: // It is illegal for side-effects from x() or y() to occur. The simplest way to // enforce that rule is to avoid inlining the right side entirely. However, it is // safe for other types of binary expression to inline both sides. - Token::Kind op = binaryExpr.getOperator(); - bool shortCircuitable = (op == Token::Kind::TK_LOGICALAND || - op == Token::Kind::TK_LOGICALOR); + Operator op = binaryExpr.getOperator(); + bool shortCircuitable = (op.kind() == Token::Kind::TK_LOGICALAND || + op.kind() == Token::Kind::TK_LOGICALOR); if (!shortCircuitable) { this->visitExpression(&binaryExpr.right()); } diff --git a/src/sksl/SkSLMetalCodeGenerator.cpp b/src/sksl/SkSLMetalCodeGenerator.cpp index 88666b3302..f7e89e0863 100644 --- a/src/sksl/SkSLMetalCodeGenerator.cpp +++ b/src/sksl/SkSLMetalCodeGenerator.cpp @@ -22,10 +22,10 @@ namespace SkSL { -const char* MetalCodeGenerator::OperatorName(Token::Kind op) { - switch (op) { +const char* MetalCodeGenerator::OperatorName(Operator op) { + switch (op.kind()) { case Token::Kind::TK_LOGICALXOR: return "!="; - default: return Operators::OperatorName(op); + default: return op.operatorName(); } } @@ -1257,10 +1257,10 @@ void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b, const Expression& right = *b.right(); const Type& leftType = left.type(); const Type& rightType = right.type(); - Token::Kind op = b.getOperator(); - Precedence precedence = Operators::GetBinaryPrecedence(b.getOperator()); + Operator op = b.getOperator(); + Precedence precedence = op.getBinaryPrecedence(); bool needParens = precedence >= parentPrecedence; - switch (op) { + switch (op.kind()) { case Token::Kind::TK_EQEQ: if (leftType.isVector()) { this->write("all"); @@ -1280,16 +1280,16 @@ void MetalCodeGenerator::writeBinaryExpression(const BinaryExpression& b, this->write("("); } if (leftType.isMatrix() && rightType.isMatrix()) { - if (op == Token::Kind::TK_STAREQ) { + if (op.kind() == Token::Kind::TK_STAREQ) { this->writeMatrixTimesEqualHelper(leftType, rightType, b.type()); - } else if (op == Token::Kind::TK_EQEQ) { + } else if (op.kind() == Token::Kind::TK_EQEQ) { this->writeMatrixEqualityHelper(leftType, rightType); - } else if (op == Token::Kind::TK_NEQ) { + } else if (op.kind() == Token::Kind::TK_NEQ) { this->writeMatrixInequalityHelper(leftType, rightType); } } this->writeExpression(left, precedence); - if (op != Token::Kind::TK_EQ && Operators::IsAssignment(op) && + if (op.kind() != Token::Kind::TK_EQ && op.isAssignment() && left.kind() == Expression::Kind::kSwizzle && !left.hasSideEffects()) { // This doesn't compile in Metal: // float4 x = float4(1); diff --git a/src/sksl/SkSLMetalCodeGenerator.h b/src/sksl/SkSLMetalCodeGenerator.h index d446807f5b..02c4a7bc8f 100644 --- a/src/sksl/SkSLMetalCodeGenerator.h +++ b/src/sksl/SkSLMetalCodeGenerator.h @@ -68,7 +68,7 @@ public: bool generateCode() override; protected: - using Precedence = Operators::Precedence; + using Precedence = Operator::Precedence; typedef int Requirements; static constexpr Requirements kNo_Requirements = 0; @@ -109,7 +109,7 @@ protected: kTexture_IntrinsicKind, }; - static const char* OperatorName(Token::Kind op); + static const char* OperatorName(Operator op); class GlobalStructVisitor; void visitGlobalStruct(GlobalStructVisitor* visitor); diff --git a/src/sksl/SkSLOperators.cpp b/src/sksl/SkSLOperators.cpp index e6890d22d2..cddd9174ac 100644 --- a/src/sksl/SkSLOperators.cpp +++ b/src/sksl/SkSLOperators.cpp @@ -9,123 +9,222 @@ #include "src/sksl/SkSLOperators.h" namespace SkSL { -namespace Operators { -Precedence GetBinaryPrecedence(Token::Kind op) { - switch (op) { - case Token::Kind::TK_STAR: // fall through - case Token::Kind::TK_SLASH: // fall through - case Token::Kind::TK_PERCENT: return Precedence::kMultiplicative; - case Token::Kind::TK_PLUS: // fall through - case Token::Kind::TK_MINUS: return Precedence::kAdditive; - case Token::Kind::TK_SHL: // fall through - case Token::Kind::TK_SHR: return Precedence::kShift; - case Token::Kind::TK_LT: // fall through - case Token::Kind::TK_GT: // fall through - case Token::Kind::TK_LTEQ: // fall through - case Token::Kind::TK_GTEQ: return Precedence::kRelational; - case Token::Kind::TK_EQEQ: // fall through - case Token::Kind::TK_NEQ: return Precedence::kEquality; - case Token::Kind::TK_BITWISEAND: return Precedence::kBitwiseAnd; - case Token::Kind::TK_BITWISEXOR: return Precedence::kBitwiseXor; - case Token::Kind::TK_BITWISEOR: return Precedence::kBitwiseOr; - case Token::Kind::TK_LOGICALAND: return Precedence::kLogicalAnd; - case Token::Kind::TK_LOGICALXOR: return Precedence::kLogicalXor; - case Token::Kind::TK_LOGICALOR: return Precedence::kLogicalOr; - case Token::Kind::TK_EQ: // fall through - case Token::Kind::TK_PLUSEQ: // fall through - case Token::Kind::TK_MINUSEQ: // fall through - case Token::Kind::TK_STAREQ: // fall through - case Token::Kind::TK_SLASHEQ: // fall through - case Token::Kind::TK_PERCENTEQ: // fall through - case Token::Kind::TK_SHLEQ: // fall through - case Token::Kind::TK_SHREQ: // fall through - case Token::Kind::TK_BITWISEANDEQ: // fall through - case Token::Kind::TK_BITWISEXOREQ: // fall through - case Token::Kind::TK_BITWISEOREQ: return Precedence::kAssignment; - case Token::Kind::TK_COMMA: return Precedence::kSequence; +Operator::Precedence Operator::getBinaryPrecedence() const { + switch (fKind) { + case Kind::TK_STAR: // fall through + case Kind::TK_SLASH: // fall through + case Kind::TK_PERCENT: return Precedence::kMultiplicative; + case Kind::TK_PLUS: // fall through + case Kind::TK_MINUS: return Precedence::kAdditive; + case Kind::TK_SHL: // fall through + case Kind::TK_SHR: return Precedence::kShift; + case Kind::TK_LT: // fall through + case Kind::TK_GT: // fall through + case Kind::TK_LTEQ: // fall through + case Kind::TK_GTEQ: return Precedence::kRelational; + case Kind::TK_EQEQ: // fall through + case Kind::TK_NEQ: return Precedence::kEquality; + case Kind::TK_BITWISEAND: return Precedence::kBitwiseAnd; + case Kind::TK_BITWISEXOR: return Precedence::kBitwiseXor; + case Kind::TK_BITWISEOR: return Precedence::kBitwiseOr; + case Kind::TK_LOGICALAND: return Precedence::kLogicalAnd; + case Kind::TK_LOGICALXOR: return Precedence::kLogicalXor; + case Kind::TK_LOGICALOR: return Precedence::kLogicalOr; + case Kind::TK_EQ: // fall through + case Kind::TK_PLUSEQ: // fall through + case Kind::TK_MINUSEQ: // fall through + case Kind::TK_STAREQ: // fall through + case Kind::TK_SLASHEQ: // fall through + case Kind::TK_PERCENTEQ: // fall through + case Kind::TK_SHLEQ: // fall through + case Kind::TK_SHREQ: // fall through + case Kind::TK_BITWISEANDEQ: // fall through + case Kind::TK_BITWISEXOREQ: // fall through + case Kind::TK_BITWISEOREQ: return Precedence::kAssignment; + case Kind::TK_COMMA: return Precedence::kSequence; default: SK_ABORT("unsupported binary operator"); } } - -const char* OperatorName(Token::Kind op) { - switch (op) { - case Token::Kind::TK_PLUS: return "+"; - case Token::Kind::TK_MINUS: return "-"; - case Token::Kind::TK_STAR: return "*"; - case Token::Kind::TK_SLASH: return "/"; - case Token::Kind::TK_PERCENT: return "%"; - case Token::Kind::TK_SHL: return "<<"; - case Token::Kind::TK_SHR: return ">>"; - case Token::Kind::TK_LOGICALNOT: return "!"; - case Token::Kind::TK_LOGICALAND: return "&&"; - case Token::Kind::TK_LOGICALOR: return "||"; - case Token::Kind::TK_LOGICALXOR: return "^^"; - case Token::Kind::TK_BITWISENOT: return "~"; - case Token::Kind::TK_BITWISEAND: return "&"; - case Token::Kind::TK_BITWISEOR: return "|"; - case Token::Kind::TK_BITWISEXOR: return "^"; - case Token::Kind::TK_EQ: return "="; - case Token::Kind::TK_EQEQ: return "=="; - case Token::Kind::TK_NEQ: return "!="; - case Token::Kind::TK_LT: return "<"; - case Token::Kind::TK_GT: return ">"; - case Token::Kind::TK_LTEQ: return "<="; - case Token::Kind::TK_GTEQ: return ">="; - case Token::Kind::TK_PLUSEQ: return "+="; - case Token::Kind::TK_MINUSEQ: return "-="; - case Token::Kind::TK_STAREQ: return "*="; - case Token::Kind::TK_SLASHEQ: return "/="; - case Token::Kind::TK_PERCENTEQ: return "%="; - case Token::Kind::TK_SHLEQ: return "<<="; - case Token::Kind::TK_SHREQ: return ">>="; - case Token::Kind::TK_BITWISEANDEQ: return "&="; - case Token::Kind::TK_BITWISEOREQ: return "|="; - case Token::Kind::TK_BITWISEXOREQ: return "^="; - case Token::Kind::TK_PLUSPLUS: return "++"; - case Token::Kind::TK_MINUSMINUS: return "--"; - case Token::Kind::TK_COMMA: return ","; - default: - SK_ABORT("unsupported operator: %d\n", (int) op); - } -} - - -bool IsAssignment(Token::Kind op) { - switch (op) { - case Token::Kind::TK_EQ: // fall through - case Token::Kind::TK_PLUSEQ: // fall through - case Token::Kind::TK_MINUSEQ: // fall through - case Token::Kind::TK_STAREQ: // fall through - case Token::Kind::TK_SLASHEQ: // fall through - case Token::Kind::TK_PERCENTEQ: // fall through - case Token::Kind::TK_SHLEQ: // fall through - case Token::Kind::TK_SHREQ: // fall through - case Token::Kind::TK_BITWISEOREQ: // fall through - case Token::Kind::TK_BITWISEXOREQ: // fall through - case Token::Kind::TK_BITWISEANDEQ: +bool Operator::isOperator() const { + switch (this->kind()) { + case Kind::TK_PLUS: + case Kind::TK_MINUS: + case Kind::TK_STAR: + case Kind::TK_SLASH: + case Kind::TK_PERCENT: + case Kind::TK_SHL: + case Kind::TK_SHR: + case Kind::TK_LOGICALNOT: + case Kind::TK_LOGICALAND: + case Kind::TK_LOGICALOR: + case Kind::TK_LOGICALXOR: + case Kind::TK_BITWISENOT: + case Kind::TK_BITWISEAND: + case Kind::TK_BITWISEOR: + case Kind::TK_BITWISEXOR: + case Kind::TK_EQ: + case Kind::TK_EQEQ: + case Kind::TK_NEQ: + case Kind::TK_LT: + case Kind::TK_GT: + case Kind::TK_LTEQ: + case Kind::TK_GTEQ: + case Kind::TK_PLUSEQ: + case Kind::TK_MINUSEQ: + case Kind::TK_STAREQ: + case Kind::TK_SLASHEQ: + case Kind::TK_PERCENTEQ: + case Kind::TK_SHLEQ: + case Kind::TK_SHREQ: + case Kind::TK_BITWISEANDEQ: + case Kind::TK_BITWISEOREQ: + case Kind::TK_BITWISEXOREQ: + case Kind::TK_PLUSPLUS: + case Kind::TK_MINUSMINUS: + case Kind::TK_COMMA: return true; default: return false; } } -Token::Kind RemoveAssignment(Token::Kind op) { - switch (op) { - case Token::Kind::TK_PLUSEQ: return Token::Kind::TK_PLUS; - case Token::Kind::TK_MINUSEQ: return Token::Kind::TK_MINUS; - case Token::Kind::TK_STAREQ: return Token::Kind::TK_STAR; - case Token::Kind::TK_SLASHEQ: return Token::Kind::TK_SLASH; - case Token::Kind::TK_PERCENTEQ: return Token::Kind::TK_PERCENT; - case Token::Kind::TK_SHLEQ: return Token::Kind::TK_SHL; - case Token::Kind::TK_SHREQ: return Token::Kind::TK_SHR; - case Token::Kind::TK_BITWISEOREQ: return Token::Kind::TK_BITWISEOR; - case Token::Kind::TK_BITWISEXOREQ: return Token::Kind::TK_BITWISEXOR; - case Token::Kind::TK_BITWISEANDEQ: return Token::Kind::TK_BITWISEAND; - default: return op; +const char* Operator::operatorName() const { + switch (fKind) { + case Kind::TK_PLUS: return "+"; + case Kind::TK_MINUS: return "-"; + case Kind::TK_STAR: return "*"; + case Kind::TK_SLASH: return "/"; + case Kind::TK_PERCENT: return "%"; + case Kind::TK_SHL: return "<<"; + case Kind::TK_SHR: return ">>"; + case Kind::TK_LOGICALNOT: return "!"; + case Kind::TK_LOGICALAND: return "&&"; + case Kind::TK_LOGICALOR: return "||"; + case Kind::TK_LOGICALXOR: return "^^"; + case Kind::TK_BITWISENOT: return "~"; + case Kind::TK_BITWISEAND: return "&"; + case Kind::TK_BITWISEOR: return "|"; + case Kind::TK_BITWISEXOR: return "^"; + case Kind::TK_EQ: return "="; + case Kind::TK_EQEQ: return "=="; + case Kind::TK_NEQ: return "!="; + case Kind::TK_LT: return "<"; + case Kind::TK_GT: return ">"; + case Kind::TK_LTEQ: return "<="; + case Kind::TK_GTEQ: return ">="; + case Kind::TK_PLUSEQ: return "+="; + case Kind::TK_MINUSEQ: return "-="; + case Kind::TK_STAREQ: return "*="; + case Kind::TK_SLASHEQ: return "/="; + case Kind::TK_PERCENTEQ: return "%="; + case Kind::TK_SHLEQ: return "<<="; + case Kind::TK_SHREQ: return ">>="; + case Kind::TK_BITWISEANDEQ: return "&="; + case Kind::TK_BITWISEOREQ: return "|="; + case Kind::TK_BITWISEXOREQ: return "^="; + case Kind::TK_PLUSPLUS: return "++"; + case Kind::TK_MINUSMINUS: return "--"; + case Kind::TK_COMMA: return ","; + default: + SK_ABORT("unsupported operator: %d\n", (int) fKind); + } +} + +bool Operator::isAssignment() const { + switch (fKind) { + case Kind::TK_EQ: // fall through + case Kind::TK_PLUSEQ: // fall through + case Kind::TK_MINUSEQ: // fall through + case Kind::TK_STAREQ: // fall through + case Kind::TK_SLASHEQ: // fall through + case Kind::TK_PERCENTEQ: // fall through + case Kind::TK_SHLEQ: // fall through + case Kind::TK_SHREQ: // fall through + case Kind::TK_BITWISEOREQ: // fall through + case Kind::TK_BITWISEXOREQ: // fall through + case Kind::TK_BITWISEANDEQ: + return true; + default: + return false; + } +} + +Operator Operator::removeAssignment() const { + switch (fKind) { + case Kind::TK_PLUSEQ: return Operator{Kind::TK_PLUS}; + case Kind::TK_MINUSEQ: return Operator{Kind::TK_MINUS}; + case Kind::TK_STAREQ: return Operator{Kind::TK_STAR}; + case Kind::TK_SLASHEQ: return Operator{Kind::TK_SLASH}; + case Kind::TK_PERCENTEQ: return Operator{Kind::TK_PERCENT}; + case Kind::TK_SHLEQ: return Operator{Kind::TK_SHL}; + case Kind::TK_SHREQ: return Operator{Kind::TK_SHR}; + case Kind::TK_BITWISEOREQ: return Operator{Kind::TK_BITWISEOR}; + case Kind::TK_BITWISEXOREQ: return Operator{Kind::TK_BITWISEXOR}; + case Kind::TK_BITWISEANDEQ: return Operator{Kind::TK_BITWISEAND}; + default: return *this; + } +} + +bool Operator::isLogical() const { + switch (kind()) { + case Token::Kind::TK_LT: + case Token::Kind::TK_GT: + case Token::Kind::TK_LTEQ: + case Token::Kind::TK_GTEQ: + return true; + default: + return false; + } +} + +bool Operator::isOnlyValidForIntegralTypes() const { + switch (kind()) { + case Token::Kind::TK_SHL: + case Token::Kind::TK_SHR: + case Token::Kind::TK_BITWISEAND: + case Token::Kind::TK_BITWISEOR: + case Token::Kind::TK_BITWISEXOR: + case Token::Kind::TK_PERCENT: + case Token::Kind::TK_SHLEQ: + case Token::Kind::TK_SHREQ: + case Token::Kind::TK_BITWISEANDEQ: + case Token::Kind::TK_BITWISEOREQ: + case Token::Kind::TK_BITWISEXOREQ: + case Token::Kind::TK_PERCENTEQ: + return true; + default: + return false; + } +} + +bool Operator::isValidForMatrixOrVector() const { + switch (kind()) { + case Token::Kind::TK_PLUS: + case Token::Kind::TK_MINUS: + case Token::Kind::TK_STAR: + case Token::Kind::TK_SLASH: + case Token::Kind::TK_PERCENT: + case Token::Kind::TK_SHL: + case Token::Kind::TK_SHR: + case Token::Kind::TK_BITWISEAND: + case Token::Kind::TK_BITWISEOR: + case Token::Kind::TK_BITWISEXOR: + case Token::Kind::TK_PLUSEQ: + case Token::Kind::TK_MINUSEQ: + case Token::Kind::TK_STAREQ: + case Token::Kind::TK_SLASHEQ: + case Token::Kind::TK_PERCENTEQ: + case Token::Kind::TK_SHLEQ: + case Token::Kind::TK_SHREQ: + case Token::Kind::TK_BITWISEANDEQ: + case Token::Kind::TK_BITWISEOREQ: + case Token::Kind::TK_BITWISEXOREQ: + return true; + default: + return false; } } -} // namespace Operators } // namespace SkSL diff --git a/src/sksl/SkSLOperators.h b/src/sksl/SkSLOperators.h index a88de88600..c151485a04 100644 --- a/src/sksl/SkSLOperators.h +++ b/src/sksl/SkSLOperators.h @@ -8,10 +8,19 @@ #ifndef SKSL_OPERATORS #define SKSL_OPERATORS +#include "src/sksl/SkSLDefines.h" #include "src/sksl/SkSLLexer.h" namespace SkSL { -namespace Operators { + +class Operator { +public: + using Kind = Token::Kind; + + // Allow implicit conversion from Token::Kind, since this is just a utility wrapper on top. + Operator(Token::Kind t) : fKind(t) { + SkASSERTF(this->isOperator(), "token-kind %d is not an operator", fKind); + } enum class Precedence { kParentheses = 1, @@ -34,18 +43,53 @@ namespace Operators { kTopLevel = kSequence }; - Precedence GetBinaryPrecedence(Token::Kind op); + Token::Kind kind() const { return fKind; } - const char* OperatorName(Token::Kind op); + Precedence getBinaryPrecedence() const; + + const char* operatorName() const; // Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.) - bool IsAssignment(Token::Kind op); + bool isAssignment() const; // Given a compound assignment operator, returns the non-assignment version of the operator // (e.g. '+=' becomes '+') - Token::Kind RemoveAssignment(Token::Kind op); + Operator removeAssignment() const; + + /** + * Defines the set of logical (comparison) operators: + * < <= > >= + */ + bool isLogical() const; + + /** + * Defines the set of operators which are only valid on integral types: + * << <<= >> >>= & &= | |= ^ ^= % %= + */ + bool isOnlyValidForIntegralTypes() const; + + /** + * Defines the set of operators which perform vector/matrix math. + * + += - -= * *= / /= % %= << <<= >> >>= & &= | |= ^ ^= + */ + bool isValidForMatrixOrVector() const; + + /* + * Defines the set of operators allowed by The OpenGL ES Shading Language 1.00, Section 5.1. + * The set of illegal (reserved) operators are the ones that only make sense with integral + * types. This is not a coincidence: It's because ES2 doesn't require 'int' to be anything but + * syntactic sugar for floats with truncation after each operation. + */ + bool isAllowedInStrictES2Mode() const { + return !this->isOnlyValidForIntegralTypes(); + } + +private: + bool isOperator() const; + + Kind fKind; +}; -} // namespace Operators } // namespace SkSL #endif diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp index 3211e151dd..20fc7c10d9 100644 --- a/src/sksl/SkSLParser.cpp +++ b/src/sksl/SkSLParser.cpp @@ -1610,7 +1610,8 @@ ASTNode::ID Parser::expression() { if (!right) { return ASTNode::ID::Invalid(); } - ASTNode::ID newResult = this->createNode(t.fOffset, ASTNode::Kind::kBinary, std::move(t)); + ASTNode::ID newResult = this->createNode(t.fOffset, ASTNode::Kind::kBinary, + Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1650,7 +1651,7 @@ ASTNode::ID Parser::assignmentExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, - ASTNode::Kind::kBinary, std::move(t)); + ASTNode::Kind::kBinary, Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1710,7 +1711,7 @@ ASTNode::ID Parser::logicalOrExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, ASTNode::Kind::kBinary, - std::move(t)); + Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1735,7 +1736,7 @@ ASTNode::ID Parser::logicalXorExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, ASTNode::Kind::kBinary, - std::move(t)); + Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1760,7 +1761,7 @@ ASTNode::ID Parser::logicalAndExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, ASTNode::Kind::kBinary, - std::move(t)); + Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1784,8 +1785,8 @@ ASTNode::ID Parser::bitwiseOrExpression() { if (!right) { return ASTNode::ID::Invalid(); } - ASTNode::ID newResult = - this->createNode(getNode(result).fOffset, ASTNode::Kind::kBinary, std::move(t)); + ASTNode::ID newResult = this->createNode(getNode(result).fOffset, ASTNode::Kind::kBinary, + Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1809,7 +1810,8 @@ ASTNode::ID Parser::bitwiseXorExpression() { if (!right) { return ASTNode::ID::Invalid(); } - ASTNode::ID newResult = this->createNode(getNode(result).fOffset, ASTNode::Kind::kBinary, std::move(t)); + ASTNode::ID newResult = this->createNode(getNode(result).fOffset, ASTNode::Kind::kBinary, + Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1834,7 +1836,7 @@ ASTNode::ID Parser::bitwiseAndExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, ASTNode::Kind::kBinary, - std::move(t)); + Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1862,7 +1864,7 @@ ASTNode::ID Parser::equalityExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, - ASTNode::Kind::kBinary, std::move(t)); + ASTNode::Kind::kBinary, Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1896,7 +1898,7 @@ ASTNode::ID Parser::relationalExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, - ASTNode::Kind::kBinary, std::move(t)); + ASTNode::Kind::kBinary, Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1928,7 +1930,7 @@ ASTNode::ID Parser::shiftExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, - ASTNode::Kind::kBinary, std::move(t)); + ASTNode::Kind::kBinary, Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1960,7 +1962,7 @@ ASTNode::ID Parser::additiveExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, - ASTNode::Kind::kBinary, std::move(t)); + ASTNode::Kind::kBinary, Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -1993,7 +1995,7 @@ ASTNode::ID Parser::multiplicativeExpression() { return ASTNode::ID::Invalid(); } ASTNode::ID newResult = this->createNode(getNode(result).fOffset, - ASTNode::Kind::kBinary, std::move(t)); + ASTNode::Kind::kBinary, Operator(t.fKind)); getNode(newResult).addChild(result); getNode(newResult).addChild(right); result = newResult; @@ -2023,7 +2025,8 @@ ASTNode::ID Parser::unaryExpression() { if (!expr) { return ASTNode::ID::Invalid(); } - ASTNode::ID result = this->createNode(t.fOffset, ASTNode::Kind::kPrefix, std::move(t)); + ASTNode::ID result = this->createNode(t.fOffset, ASTNode::Kind::kPrefix, + Operator(t.fKind)); getNode(result).addChild(expr); return result; } @@ -2160,7 +2163,8 @@ ASTNode::ID Parser::suffix(ASTNode::ID base) { } case Token::Kind::TK_PLUSPLUS: // fall through case Token::Kind::TK_MINUSMINUS: { - ASTNode::ID result = this->createNode(next.fOffset, ASTNode::Kind::kPostfix, next); + ASTNode::ID result = this->createNode(next.fOffset, ASTNode::Kind::kPostfix, + Operator(next.fKind)); getNode(result).addChild(base); return result; } diff --git a/src/sksl/SkSLPipelineStageCodeGenerator.cpp b/src/sksl/SkSLPipelineStageCodeGenerator.cpp index 804ecd349c..d86b8c9baa 100644 --- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp +++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp @@ -50,7 +50,7 @@ public: void generateCode(); private: - using Precedence = Operators::Precedence; + using Precedence = Operator::Precedence; void write(const char* s); void writeLine(const char* s = nullptr); @@ -476,15 +476,15 @@ void PipelineStageCodeGenerator::writeBinaryExpression(const BinaryExpression& b Precedence parentPrecedence) { const Expression& left = *b.left(); const Expression& right = *b.right(); - Token::Kind op = b.getOperator(); + Operator op = b.getOperator(); - Precedence precedence = Operators::GetBinaryPrecedence(op); + Precedence precedence = op.getBinaryPrecedence(); if (precedence >= parentPrecedence) { this->write("("); } this->writeExpression(left, precedence); this->write(" "); - this->write(Operators::OperatorName(op)); + this->write(op.operatorName()); this->write(" "); this->writeExpression(right, precedence); if (precedence >= parentPrecedence) { @@ -512,7 +512,7 @@ void PipelineStageCodeGenerator::writePrefixExpression(const PrefixExpression& p if (Precedence::kPrefix >= parentPrecedence) { this->write("("); } - this->write(Operators::OperatorName(p.getOperator())); + this->write(p.getOperator().operatorName()); this->writeExpression(*p.operand(), Precedence::kPrefix); if (Precedence::kPrefix >= parentPrecedence) { this->write(")"); @@ -525,7 +525,7 @@ void PipelineStageCodeGenerator::writePostfixExpression(const PostfixExpression& this->write("("); } this->writeExpression(*p.operand(), Precedence::kPostfix); - this->write(Operators::OperatorName(p.getOperator())); + this->write(p.getOperator().operatorName()); if (Precedence::kPostfix >= parentPrecedence) { this->write(")"); } diff --git a/src/sksl/SkSLSPIRVCodeGenerator.cpp b/src/sksl/SkSLSPIRVCodeGenerator.cpp index 918fe50c59..2e774b9076 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.cpp +++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp @@ -2233,11 +2233,11 @@ static std::unique_ptr<Expression> create_literal_1(const Context& context, cons } } -SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs, Token::Kind op, +SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs, Operator op, const Type& rightType, SpvId rhs, const Type& resultType, OutputStream& out) { // The comma operator ignores the type of the left-hand side entirely. - if (op == Token::Kind::TK_COMMA) { + if (op.kind() == Token::Kind::TK_COMMA) { return rhs; } // overall type we are operating on: float2, int, uint4... @@ -2246,14 +2246,14 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs, // handling in SPIR-V if (this->getActualType(leftType) != this->getActualType(rightType)) { if (leftType.isVector() && rightType.isNumber()) { - if (op == Token::Kind::TK_SLASH) { + if (op.kind() == Token::Kind::TK_SLASH) { SpvId one = this->writeExpression(*create_literal_1(fContext, rightType), out); SpvId inverse = this->nextId(); this->writeInstruction(SpvOpFDiv, this->getType(rightType), inverse, one, rhs, out); rhs = inverse; op = Token::Kind::TK_STAR; } - if (op == Token::Kind::TK_STAR) { + if (op.kind() == Token::Kind::TK_STAR) { SpvId result = this->nextId(); this->writeInstruction(SpvOpVectorTimesScalar, this->getType(resultType), result, lhs, rhs, out); @@ -2271,7 +2271,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs, rhs = vec; operandType = &leftType; } else if (rightType.isVector() && leftType.isNumber()) { - if (op == Token::Kind::TK_STAR) { + if (op.kind() == Token::Kind::TK_STAR) { SpvId result = this->nextId(); this->writeInstruction(SpvOpVectorTimesScalar, this->getType(resultType), result, rhs, lhs, out); @@ -2320,7 +2320,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs, operandType = &this->getActualType(leftType); SkASSERT(*operandType == this->getActualType(rightType)); } - switch (op) { + switch (op.kind()) { case Token::Kind::TK_EQEQ: { if (operandType->isMatrix()) { return this->writeMatrixComparison(*operandType, lhs, rhs, SpvOpFOrdEqual, @@ -2438,9 +2438,9 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const Type& leftType, SpvId lhs, SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, OutputStream& out) { const Expression& left = *b.left(); const Expression& right = *b.right(); - Token::Kind op = b.getOperator(); + Operator op = b.getOperator(); // handle cases where we don't necessarily evaluate both LHS and RHS - switch (op) { + switch (op.kind()) { case Token::Kind::TK_EQ: { SpvId rhs = this->writeExpression(right, out); this->getLValue(left, out)->store(rhs, out); @@ -2456,7 +2456,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Outpu std::unique_ptr<LValue> lvalue; SpvId lhs; - if (Operators::IsAssignment(op)) { + if (op.isAssignment()) { lvalue = this->getLValue(left, out); lhs = lvalue->load(out); } else { @@ -2464,7 +2464,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Outpu lhs = this->writeExpression(left, out); } SpvId rhs = this->writeExpression(right, out); - SpvId result = this->writeBinaryExpression(left.type(), lhs, Operators::RemoveAssignment(op), + SpvId result = this->writeBinaryExpression(left.type(), lhs, op.removeAssignment(), right.type(), rhs, b.type(), out); if (lvalue) { lvalue->store(result, out); @@ -2473,7 +2473,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, Outpu } SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, OutputStream& out) { - SkASSERT(a.getOperator() == Token::Kind::TK_LOGICALAND); + SkASSERT(a.getOperator().kind() == Token::Kind::TK_LOGICALAND); BoolLiteral falseLiteral(fContext, -1, false); SpvId falseConstant = this->writeBoolLiteral(falseLiteral); SpvId lhs = this->writeExpression(*a.left(), out); @@ -2494,7 +2494,7 @@ SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, OutputStrea } SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, OutputStream& out) { - SkASSERT(o.getOperator() == Token::Kind::TK_LOGICALOR); + SkASSERT(o.getOperator().kind() == Token::Kind::TK_LOGICALOR); BoolLiteral trueLiteral(fContext, -1, true); SpvId trueConstant = this->writeBoolLiteral(trueLiteral); SpvId lhs = this->writeExpression(*o.left(), out); @@ -2553,7 +2553,7 @@ SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, Out SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, OutputStream& out) { const Type& type = p.type(); - if (p.getOperator() == Token::Kind::TK_MINUS) { + if (p.getOperator().kind() == Token::Kind::TK_MINUS) { SpvId result = this->nextId(); SpvId typeId = this->getType(type); SpvId expr = this->writeExpression(*p.operand(), out); @@ -2567,7 +2567,7 @@ SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, Outpu this->writePrecisionModifier(type, result); return result; } - switch (p.getOperator()) { + switch (p.getOperator().kind()) { case Token::Kind::TK_PLUS: return this->writeExpression(*p.operand(), out); case Token::Kind::TK_PLUSPLUS: { @@ -2611,7 +2611,7 @@ SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, Out std::unique_ptr<LValue> lv = this->getLValue(*p.operand(), out); SpvId result = lv->load(out); SpvId one = this->writeExpression(*create_literal_1(fContext, type), out); - switch (p.getOperator()) { + switch (p.getOperator().kind()) { case Token::Kind::TK_PLUSPLUS: { SpvId temp = this->writeBinaryOperation(type, type, result, one, SpvOpFAdd, SpvOpIAdd, SpvOpIAdd, SpvOpUndef, out); diff --git a/src/sksl/SkSLSPIRVCodeGenerator.h b/src/sksl/SkSLSPIRVCodeGenerator.h index eae99a7eab..4808118f87 100644 --- a/src/sksl/SkSLSPIRVCodeGenerator.h +++ b/src/sksl/SkSLSPIRVCodeGenerator.h @@ -307,7 +307,7 @@ private: SpvId writeBinaryOperation(const BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt, OutputStream& out); - SpvId writeBinaryExpression(const Type& leftType, SpvId lhs, Token::Kind op, + SpvId writeBinaryExpression(const Type& leftType, SpvId lhs, Operator op, const Type& rightType, SpvId rhs, const Type& resultType, OutputStream& out); diff --git a/src/sksl/SkSLVMGenerator.cpp b/src/sksl/SkSLVMGenerator.cpp index 1cf45b982f..c7bb702059 100644 --- a/src/sksl/SkSLVMGenerator.cpp +++ b/src/sksl/SkSLVMGenerator.cpp @@ -529,8 +529,8 @@ size_t SkVMGenerator::getSlot(const Variable& v) { Value SkVMGenerator::writeBinaryExpression(const BinaryExpression& b) { const Expression& left = *b.left(); const Expression& right = *b.right(); - Token::Kind op = b.getOperator(); - if (op == Token::Kind::TK_EQ) { + Operator op = b.getOperator(); + if (op.kind() == Token::Kind::TK_EQ) { return this->writeStore(left, this->writeExpression(right)); } @@ -538,14 +538,14 @@ Value SkVMGenerator::writeBinaryExpression(const BinaryExpression& b) { const Type& rType = right.type(); bool lVecOrMtx = (lType.isVector() || lType.isMatrix()); bool rVecOrMtx = (rType.isVector() || rType.isMatrix()); - bool isAssignment = Operators::IsAssignment(op); + bool isAssignment = op.isAssignment(); if (isAssignment) { - op = Operators::RemoveAssignment(op); + op = op.removeAssignment(); } Type::NumberKind nk = base_number_kind(lType); // A few ops require special treatment: - switch (op) { + switch (op.kind()) { case Token::Kind::TK_LOGICALAND: { SkASSERT(!isAssignment); SkASSERT(nk == Type::NumberKind::kBoolean); @@ -576,7 +576,7 @@ Value SkVMGenerator::writeBinaryExpression(const BinaryExpression& b) { rVal = this->writeExpression(right); // Special case for M*V, V*M, M*M (but not V*V!) - if (op == Token::Kind::TK_STAR + if (op.kind() == Token::Kind::TK_STAR && lVecOrMtx && rVecOrMtx && !(lType.isVector() && rType.isVector())) { int rCols = rType.columns(), rRows = rType.rows(), @@ -624,7 +624,7 @@ Value SkVMGenerator::writeBinaryExpression(const BinaryExpression& b) { return skvm::F32{}; }; - switch (op) { + switch (op.kind()) { case Token::Kind::TK_EQEQ: { SkASSERT(!isAssignment); Value cmp = binary([](skvm::F32 x, skvm::F32 y) { return x == y; }, @@ -1311,10 +1311,10 @@ Value SkVMGenerator::writeExternalFunctionCall(const ExternalFunctionCall& c) { Value SkVMGenerator::writePrefixExpression(const PrefixExpression& p) { Value val = this->writeExpression(*p.operand()); - switch (p.getOperator()) { + switch (p.getOperator().kind()) { case Token::Kind::TK_PLUSPLUS: case Token::Kind::TK_MINUSMINUS: { - bool incr = p.getOperator() == Token::Kind::TK_PLUSPLUS; + bool incr = p.getOperator().kind() == Token::Kind::TK_PLUSPLUS; switch (base_number_kind(p.type())) { case Type::NumberKind::kFloat: @@ -1350,13 +1350,13 @@ Value SkVMGenerator::writePrefixExpression(const PrefixExpression& p) { } Value SkVMGenerator::writePostfixExpression(const PostfixExpression& p) { - switch (p.getOperator()) { + switch (p.getOperator().kind()) { case Token::Kind::TK_PLUSPLUS: case Token::Kind::TK_MINUSMINUS: { Value old = this->writeExpression(*p.operand()), val = old; SkASSERT(val.slots() == 1); - bool incr = p.getOperator() == Token::Kind::TK_PLUSPLUS; + bool incr = p.getOperator().kind() == Token::Kind::TK_PLUSPLUS; switch (base_number_kind(p.type())) { case Type::NumberKind::kFloat: diff --git a/src/sksl/dsl/priv/DSLWriter.cpp b/src/sksl/dsl/priv/DSLWriter.cpp index abec397226..7e8015c034 100644 --- a/src/sksl/dsl/priv/DSLWriter.cpp +++ b/src/sksl/dsl/priv/DSLWriter.cpp @@ -104,7 +104,7 @@ DSLExpression DSLWriter::Construct(const SkSL::Type& type, std::vector<DSLExpres std::move(args))); } -DSLExpression DSLWriter::ConvertBinary(std::unique_ptr<Expression> left, Token::Kind op, +DSLExpression DSLWriter::ConvertBinary(std::unique_ptr<Expression> left, Operator op, std::unique_ptr<Expression> right) { return IRGenerator().convertBinaryExpression(std::move(left), op, std::move(right)); } @@ -118,11 +118,11 @@ DSLExpression DSLWriter::ConvertIndex(std::unique_ptr<Expression> base, return IRGenerator().convertIndex(std::move(base), std::move(index)); } -DSLExpression DSLWriter::ConvertPostfix(std::unique_ptr<Expression> expr, Token::Kind op) { +DSLExpression DSLWriter::ConvertPostfix(std::unique_ptr<Expression> expr, Operator op) { return IRGenerator().convertPostfixExpression(std::move(expr), op); } -DSLExpression DSLWriter::ConvertPrefix(Token::Kind op, std::unique_ptr<Expression> expr) { +DSLExpression DSLWriter::ConvertPrefix(Operator op, std::unique_ptr<Expression> expr) { return IRGenerator().convertPrefixExpression(op, std::move(expr)); } diff --git a/src/sksl/dsl/priv/DSLWriter.h b/src/sksl/dsl/priv/DSLWriter.h index dd3ec727bc..769350bd9b 100644 --- a/src/sksl/dsl/priv/DSLWriter.h +++ b/src/sksl/dsl/priv/DSLWriter.h @@ -9,6 +9,7 @@ #define SKSL_DSLWRITER #include "src/sksl/SkSLMangler.h" +#include "src/sksl/SkSLOperators.h" #include "src/sksl/dsl/DSLExpression.h" #include "src/sksl/dsl/DSLStatement.h" #include "src/sksl/ir/SkSLExpressionStatement.h" @@ -133,7 +134,7 @@ public: static DSLExpression Construct(const SkSL::Type& type, std::vector<DSLExpression> rawArgs); - static DSLExpression ConvertBinary(std::unique_ptr<Expression> left, Token::Kind op, + static DSLExpression ConvertBinary(std::unique_ptr<Expression> left, Operator op, std::unique_ptr<Expression> right); static DSLExpression ConvertField(std::unique_ptr<Expression> base, const char* name); @@ -141,9 +142,9 @@ public: static DSLExpression ConvertIndex(std::unique_ptr<Expression> base, std::unique_ptr<Expression> index); - static DSLExpression ConvertPostfix(std::unique_ptr<Expression> expr, Token::Kind op); + static DSLExpression ConvertPostfix(std::unique_ptr<Expression> expr, Operator op); - static DSLExpression ConvertPrefix(Token::Kind op, std::unique_ptr<Expression> expr); + static DSLExpression ConvertPrefix(Operator op, std::unique_ptr<Expression> expr); static DSLStatement ConvertSwitch(std::unique_ptr<Expression> value, ExpressionArray caseValues, diff --git a/src/sksl/ir/SkSLBinaryExpression.h b/src/sksl/ir/SkSLBinaryExpression.h index 1b51708141..5e7d657c23 100644 --- a/src/sksl/ir/SkSLBinaryExpression.h +++ b/src/sksl/ir/SkSLBinaryExpression.h @@ -49,14 +49,14 @@ class BinaryExpression final : public Expression { public: static constexpr Kind kExpressionKind = Kind::kBinary; - BinaryExpression(int offset, std::unique_ptr<Expression> left, Token::Kind op, + BinaryExpression(int offset, std::unique_ptr<Expression> left, Operator op, std::unique_ptr<Expression> right, const Type* type) : INHERITED(offset, kExpressionKind, type) , fLeft(std::move(left)) , fOperator(op) , fRight(std::move(right)) { // If we are assigning to a VariableReference, ensure that it is set to Write or ReadWrite - SkASSERT(!Operators::IsAssignment(op) || check_ref(*this->left())); + SkASSERT(!op.isAssignment() || check_ref(*this->left())); } std::unique_ptr<Expression>& left() { @@ -75,7 +75,7 @@ public: return fRight; } - Token::Kind getOperator() const { + Operator getOperator() const { return fOperator; } @@ -90,7 +90,7 @@ public: } bool hasProperty(Property property) const override { - if (property == Property::kSideEffects && Operators::IsAssignment(this->getOperator())) { + if (property == Property::kSideEffects && this->getOperator().isAssignment()) { return true; } return this->left()->hasProperty(property) || this->right()->hasProperty(property); @@ -106,13 +106,13 @@ public: String description() const override { return "(" + this->left()->description() + " " + - Operators::OperatorName(this->getOperator()) + " " + this->right()->description() + + this->getOperator().operatorName() + " " + this->right()->description() + ")"; } private: std::unique_ptr<Expression> fLeft; - Token::Kind fOperator; + Operator fOperator; std::unique_ptr<Expression> fRight; using INHERITED = Expression; diff --git a/src/sksl/ir/SkSLPostfixExpression.h b/src/sksl/ir/SkSLPostfixExpression.h index 8de89e272c..92b0cafe47 100644 --- a/src/sksl/ir/SkSLPostfixExpression.h +++ b/src/sksl/ir/SkSLPostfixExpression.h @@ -21,12 +21,12 @@ class PostfixExpression final : public Expression { public: static constexpr Kind kExpressionKind = Kind::kPostfix; - PostfixExpression(std::unique_ptr<Expression> operand, Token::Kind op) + PostfixExpression(std::unique_ptr<Expression> operand, Operator op) : INHERITED(operand->fOffset, kExpressionKind, &operand->type()) , fOperand(std::move(operand)) , fOperator(op) {} - Token::Kind getOperator() const { + Operator getOperator() const { return fOperator; } @@ -51,12 +51,12 @@ public: } String description() const override { - return this->operand()->description() + Operators::OperatorName(this->getOperator()); + return this->operand()->description() + this->getOperator().operatorName(); } private: std::unique_ptr<Expression> fOperand; - Token::Kind fOperator; + Operator fOperator; using INHERITED = Expression; }; diff --git a/src/sksl/ir/SkSLPrefixExpression.cpp b/src/sksl/ir/SkSLPrefixExpression.cpp index 336d23b85f..73270a0f43 100644 --- a/src/sksl/ir/SkSLPrefixExpression.cpp +++ b/src/sksl/ir/SkSLPrefixExpression.cpp @@ -38,7 +38,7 @@ static std::unique_ptr<Expression> negate_operand(const Expression& operand) { std::unique_ptr<Expression> PrefixExpression::constantPropagate(const IRGenerator& irGenerator, const DefinitionMap& definitions) { if (this->operand()->isCompileTimeConstant()) { - if (this->getOperator() == Token::Kind::TK_MINUS) { + if (this->getOperator().kind() == Token::Kind::TK_MINUS) { // Constant-propagate negation onto compile-time constants. switch (this->operand()->kind()) { case Expression::Kind::kFloatLiteral: @@ -66,7 +66,7 @@ std::unique_ptr<Expression> PrefixExpression::constantPropagate(const IRGenerato default: break; } - } else if (this->getOperator() == Token::Kind::TK_LOGICALNOT) { + } else if (this->getOperator().kind() == Token::Kind::TK_LOGICALNOT) { if (this->operand()->is<BoolLiteral>()) { // Convert !boolLiteral(true) to boolLiteral(false). const BoolLiteral& b = this->operand()->as<BoolLiteral>(); diff --git a/src/sksl/ir/SkSLPrefixExpression.h b/src/sksl/ir/SkSLPrefixExpression.h index 0cf046b6da..673c789dd6 100644 --- a/src/sksl/ir/SkSLPrefixExpression.h +++ b/src/sksl/ir/SkSLPrefixExpression.h @@ -22,12 +22,12 @@ class PrefixExpression final : public Expression { public: static constexpr Kind kExpressionKind = Kind::kPrefix; - PrefixExpression(Token::Kind op, std::unique_ptr<Expression> operand) + PrefixExpression(Operator op, std::unique_ptr<Expression> operand) : INHERITED(operand->fOffset, kExpressionKind, &operand->type()) , fOperator(op) , fOperand(std::move(operand)) {} - Token::Kind getOperator() const { + Operator getOperator() const { return fOperator; } @@ -41,8 +41,8 @@ public: bool hasProperty(Property property) const override { if (property == Property::kSideEffects && - (this->getOperator() == Token::Kind::TK_PLUSPLUS || - this->getOperator() == Token::Kind::TK_MINUSMINUS)) { + (this->getOperator().kind() == Token::Kind::TK_PLUSPLUS || + this->getOperator().kind() == Token::Kind::TK_MINUSMINUS)) { return true; } return this->operand()->hasProperty(property); @@ -57,11 +57,11 @@ public: } String description() const override { - return Operators::OperatorName(this->getOperator()) + this->operand()->description(); + return this->getOperator().operatorName() + this->operand()->description(); } private: - Token::Kind fOperator; + Operator fOperator; std::unique_ptr<Expression> fOperand; using INHERITED = Expression;