Convert Operators namespace to first-class Operator object.
This lets us write `op.isAssignment()` instead of
`Operators::IsAssignment(op)`.
Change-Id: If35f2ac500b6ccabc364f9104faaad6e62564667
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/369958
Commit-Queue: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/src/sksl/SkSLASTNode.cpp b/src/sksl/SkSLASTNode.cpp
index ccfe254..e25bdf0 100644
--- a/src/sksl/SkSLASTNode.cpp
+++ b/src/sksl/SkSLASTNode.cpp
@@ -17,7 +17,7 @@
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 @@
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 a9678d7..e6d3015 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 @@
};
enum class Kind {
- // data: operator(Token), children: left, right
+ // data: operator, children: left, right
kBinary,
// children: statements
kBlock,
@@ -97,9 +98,9 @@
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 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 @@
sizeof(SectionData)})];
enum class Kind {
- kToken,
+ kOperator,
kStringFragment,
kBool,
kInt,
@@ -278,8 +279,9 @@
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 @@
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 @@
}
}
- 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 @@
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 fa19e7a..cf9905f 100644
--- a/src/sksl/SkSLAnalysis.cpp
+++ b/src/sksl/SkSLAnalysis.cpp
@@ -538,7 +538,7 @@
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 @@
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 @@
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 @@
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 @@
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 45e6d7c..6932369 100644
--- a/src/sksl/SkSLCFGGenerator.cpp
+++ b/src/sksl/SkSLCFGGenerator.cpp
@@ -197,7 +197,7 @@
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 @@
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 @@
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 @@
}
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 8f9fe6f..0c26b43 100644
--- a/src/sksl/SkSLCPPCodeGenerator.cpp
+++ b/src/sksl/SkSLCPPCodeGenerator.cpp
@@ -72,10 +72,10 @@
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 287352c..252f5b7 100644
--- a/src/sksl/SkSLCPPCodeGenerator.h
+++ b/src/sksl/SkSLCPPCodeGenerator.h
@@ -25,7 +25,7 @@
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 137084e..b8a01c2 100644
--- a/src/sksl/SkSLCompiler.cpp
+++ b/src/sksl/SkSLCompiler.cpp
@@ -431,7 +431,7 @@
* 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 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 @@
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 @@
(!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 137ab64..7d05ffd 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> 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 @@
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 @@
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 @@
(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 @@
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 @@
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 @@
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 @@
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 @@
// 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 20c9a0c..bcc5bda 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 @@
* 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 9cecef5..968d765 100644
--- a/src/sksl/SkSLDefinitionMap.cpp
+++ b/src/sksl/SkSLDefinitionMap.cpp
@@ -119,9 +119,9 @@
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 @@
}
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 @@
}
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 e1e2caf..d6d63ce 100644
--- a/src/sksl/SkSLDehydrator.cpp
+++ b/src/sksl/SkSLDehydrator.cpp
@@ -262,7 +262,7 @@
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 @@
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 2b290c7..0712d4c 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -509,7 +509,7 @@
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 @@
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 @@
}
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 @@
// 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 @@
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 @@
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 @@
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 b40a78c..78bcabc 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -61,7 +61,7 @@
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 9800dfd..82dd7aa 100644
--- a/src/sksl/SkSLIRGenerator.cpp
+++ b/src/sksl/SkSLIRGenerator.cpp
@@ -934,10 +934,12 @@
// 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 @@
};
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 @@
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()) {
@@ -1731,97 +1733,18 @@
}
/**
- * 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 @@
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 @@
}
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 @@
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 @@
: 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 @@
} else {
return false;
}
- if (op_is_logical(op)) {
+ if (op.isLogical()) {
*outResultType = context.fTypes.fBool.get();
}
return true;
@@ -1975,17 +1898,17 @@
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 @@
} 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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 39561c2..1e2db9e 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 @@
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 @@
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 50b8268..0243d47 100644
--- a/src/sksl/SkSLInliner.cpp
+++ b/src/sksl/SkSLInliner.cpp
@@ -1004,9 +1004,9 @@
// 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 88666b3..f7e89e0 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 @@
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 @@
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 d446807..02c4a7b 100644
--- a/src/sksl/SkSLMetalCodeGenerator.h
+++ b/src/sksl/SkSLMetalCodeGenerator.h
@@ -68,7 +68,7 @@
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 @@
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 e6890d2..cddd917 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);
}
}
-} // namespace Operators
+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 SkSL
diff --git a/src/sksl/SkSLOperators.h b/src/sksl/SkSLOperators.h
index a88de88..c151485 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 @@
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;
-} // namespace Operators
+ /**
+ * 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 SkSL
#endif
diff --git a/src/sksl/SkSLParser.cpp b/src/sksl/SkSLParser.cpp
index 3211e15..20fc7c1 100644
--- a/src/sksl/SkSLParser.cpp
+++ b/src/sksl/SkSLParser.cpp
@@ -1610,7 +1610,8 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
}
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 804ecd3..d86b8c9 100644
--- a/src/sksl/SkSLPipelineStageCodeGenerator.cpp
+++ b/src/sksl/SkSLPipelineStageCodeGenerator.cpp
@@ -50,7 +50,7 @@
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 @@
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 @@
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 @@
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 918fe50..2e774b9 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.cpp
+++ b/src/sksl/SkSLSPIRVCodeGenerator.cpp
@@ -2233,11 +2233,11 @@
}
}
-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 @@
// 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 @@
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 @@
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 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 @@
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 @@
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::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::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::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 @@
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 @@
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 eae99a7..4808118 100644
--- a/src/sksl/SkSLSPIRVCodeGenerator.h
+++ b/src/sksl/SkSLSPIRVCodeGenerator.h
@@ -307,7 +307,7 @@
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 1cf45b9..c7bb702 100644
--- a/src/sksl/SkSLVMGenerator.cpp
+++ b/src/sksl/SkSLVMGenerator.cpp
@@ -529,8 +529,8 @@
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 @@
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 @@
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 @@
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::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::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 abec397..7e8015c 100644
--- a/src/sksl/dsl/priv/DSLWriter.cpp
+++ b/src/sksl/dsl/priv/DSLWriter.cpp
@@ -104,7 +104,7 @@
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 @@
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 dd3ec72..769350b 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 @@
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 @@
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 1b51708..5e7d657 100644
--- a/src/sksl/ir/SkSLBinaryExpression.h
+++ b/src/sksl/ir/SkSLBinaryExpression.h
@@ -49,14 +49,14 @@
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 @@
return fRight;
}
- Token::Kind getOperator() const {
+ Operator getOperator() const {
return fOperator;
}
@@ -90,7 +90,7 @@
}
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 @@
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 8de89e2..92b0caf 100644
--- a/src/sksl/ir/SkSLPostfixExpression.h
+++ b/src/sksl/ir/SkSLPostfixExpression.h
@@ -21,12 +21,12 @@
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 @@
}
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 336d23b..73270a0 100644
--- a/src/sksl/ir/SkSLPrefixExpression.cpp
+++ b/src/sksl/ir/SkSLPrefixExpression.cpp
@@ -38,7 +38,7 @@
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 @@
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 0cf046b..673c789 100644
--- a/src/sksl/ir/SkSLPrefixExpression.h
+++ b/src/sksl/ir/SkSLPrefixExpression.h
@@ -22,12 +22,12 @@
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 @@
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 @@
}
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;