Expression* old = (*iter)->expression()->get();
do {
if ((*iter) == fNodes.begin()) {
- ABORT("couldn't find %s before %s\n", e->description().c_str(),
- old->description().c_str());
+ return false;
}
--(*iter);
} while ((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
Statement* old = (*iter)->statement()->get();
do {
if ((*iter) == fNodes.begin()) {
- ABORT("couldn't find %s before %s\n", e->description().c_str(),
- old->description().c_str());
+ return false;
}
--(*iter);
} while ((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
this->addExpression(cfg, &b->fRight, constantPropagate);
cfg.newBlock();
cfg.addExit(start, cfg.fCurrent);
+ cfg.fBlocks[cfg.fCurrent].fNodes.push_back({
+ BasicBlock::Node::kExpression_Kind,
+ constantPropagate,
+ e,
+ nullptr
+ });
break;
}
case Token::EQ: {
BinaryExpression& bin = (BinaryExpression&) **target;
bool result;
if (bin.fOperator == Token::EQ) {
- result = !b->tryRemoveLValueBefore(iter, bin.fLeft.get());
+ result = b->tryRemoveLValueBefore(iter, bin.fLeft.get());
} else {
- result = !b->tryRemoveExpressionBefore(iter, bin.fLeft.get());
+ result = b->tryRemoveExpressionBefore(iter, bin.fLeft.get());
}
+ *target = std::move(bin.fRight);
if (!result) {
- *target = std::move(bin.fRight);
+ *outNeedsRescan = true;
+ return;
+ }
+ if (*iter == b->fNodes.begin()) {
*outNeedsRescan = true;
return;
}
--(*iter);
- ASSERT((*iter)->expression() == &bin.fRight);
+ if ((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
+ (*iter)->expression() != &bin.fRight) {
+ *outNeedsRescan = true;
+ return;
+ }
*iter = b->fNodes.erase(*iter);
ASSERT((*iter)->expression() == target);
- *target = std::move(bin.fRight);
}
/**
*outNeedsRescan = true;
return;
}
+ *target = std::move(bin.fLeft);
+ if (*iter == b->fNodes.begin()) {
+ *outNeedsRescan = true;
+ return;
+ }
--(*iter);
- ASSERT((*iter)->expression() == &bin.fLeft);
+ if (((*iter)->fKind != BasicBlock::Node::kExpression_Kind ||
+ (*iter)->expression() != &bin.fLeft)) {
+ *outNeedsRescan = true;
+ return;
+ }
*iter = b->fNodes.erase(*iter);
ASSERT((*iter)->expression() == target);
- *target = std::move(bin.fLeft);
}
/**
if ((*iter)->fConstantPropagation) {
std::unique_ptr<Expression> optimized = expr->constantPropagate(*fIRGenerator, definitions);
if (optimized) {
+ *outUpdated = true;
if (!try_replace_expression(&b, iter, &optimized)) {
*outNeedsRescan = true;
+ return;
}
ASSERT((*iter)->fKind == BasicBlock::Node::kExpression_Kind);
expr = (*iter)->expression()->get();
- *outUpdated = true;
}
}
switch (expr->fKind) {
this->simplifyStatement(definitions, b, &iter, &undefinedVariables, &updated,
&needsRescan);
}
+ if (needsRescan) {
+ break;
+ }
this->addDefinitions(*iter, &definitions);
}
}
case Token::BITWISEANDEQ: // fall through
case Token::BITWISEXOREQ: // fall through
case Token::BITWISEOREQ: return GLSLCodeGenerator::kAssignment_Precedence;
+ case Token::COMMA: return GLSLCodeGenerator::kSequence_Precedence;
default: ABORT("unsupported binary operator");
}
}
kTernary_Precedence = 15,
kAssignment_Precedence = 16,
kSequence_Precedence = 17,
- kTopLevel_Precedence = 18
+ kTopLevel_Precedence = kSequence_Precedence
};
GLSLCodeGenerator(const Context* context, const Program* program, ErrorReporter* errors,
case Token::MINUS: // fall through
case Token::MINUSEQ: // fall through
case Token::SLASH: // fall through
- case Token::SLASHEQ:
+ case Token::SLASHEQ: // fall through
isLogical = false;
validMatrixOrVectorOp = true;
break;
+ case Token::COMMA:
+ *outLeftType = &left;
+ *outRightType = &right;
+ *outResultType = &right;
+ return true;
default:
isLogical = false;
validMatrixOrVectorOp = false;
return nullptr;
}
-/* (LBRACKET expression? RBRACKET)* (EQ expression)? (COMMA IDENTIFER
- (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
+/* (LBRACKET expression? RBRACKET)* (EQ assignmentExpression)? (COMMA IDENTIFER
+ (LBRACKET expression? RBRACKET)* (EQ assignmentExpression)?)* SEMICOLON */
std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(Modifiers mods,
std::unique_ptr<ASTType> type,
String name) {
}
std::unique_ptr<ASTExpression> value;
if (this->checkNext(Token::EQ)) {
- value = this->expression();
+ value = this->assignmentExpression();
if (!value) {
return nullptr;
}
}
}
if (this->checkNext(Token::EQ)) {
- value = this->expression();
+ value = this->assignmentExpression();
if (!value) {
return nullptr;
}
if (!depth.checkValid()) {
return nullptr;
}
- return this->assignmentExpression();
+ return this->commaExpression();
+}
+
+/* assignmentExpression (COMMA assignmentExpression)* */
+std::unique_ptr<ASTExpression> Parser::commaExpression() {
+ std::unique_ptr<ASTExpression> result = this->assignmentExpression();
+ if (!result) {
+ return nullptr;
+ }
+ Token t;
+ while (this->checkNext(Token::COMMA, &t)) {
+ std::unique_ptr<ASTExpression> right = this->commaExpression();
+ if (!right) {
+ return nullptr;
+ }
+ result.reset(new ASTBinaryExpression(std::move(result), t, std::move(right)));
+ }
+ return result;
}
/* ternaryExpression ((EQEQ | STAREQ | SLASHEQ | PERCENTEQ | PLUSEQ | MINUSEQ | SHLEQ | SHREQ |
std::vector<std::unique_ptr<ASTExpression>> parameters;
if (this->peek().fKind != Token::RPAREN) {
for (;;) {
- std::unique_ptr<ASTExpression> expr = this->expression();
+ std::unique_ptr<ASTExpression> expr = this->assignmentExpression();
if (!expr) {
return nullptr;
}
parameters.push_back(std::move(expr));
- if (this->peek().fKind != Token::COMMA) {
+ if (!this->checkNext(Token::COMMA)) {
break;
}
- this->nextToken();
}
}
this->expect(Token::RPAREN, "')' to complete function parameters");
std::unique_ptr<ASTExpression> expression();
+ std::unique_ptr<ASTExpression> commaExpression();
+
std::unique_ptr<ASTExpression> assignmentExpression();
std::unique_ptr<ASTExpression> ternaryExpression();
case Token::BITWISEXOREQ: return String("^=");
case Token::PLUSPLUS: return String("++");
case Token::MINUSMINUS: return String("--");
+ case Token::COMMA: return String(",");
default:
ABORT("unsupported operator: %d\n", kind);
}
"z >>= 2;"
"z <<= 4;"
"z %= 5;"
+ "x = (vec2(sqrt(1)) , 6);"
+ "z = (vec2(sqrt(1)) , 6);"
"}",
*SkSL::ShaderCapsFactory::Default(),
"#version 400\n"
" z >>= 2;\n"
" z <<= 4;\n"
" z %= 5;\n"
+ " x = float((vec2(sqrt(1.0)) , 6));\n"
+ " z = (vec2(sqrt(1.0)) , 6);\n"
"}\n");
}
"}\n");
}
+DEF_TEST(SkSLComplexDelete, r) {
+ test(r,
+ "uniform mat4 colorXform;"
+ "uniform sampler2D sampler;"
+ "void main() {"
+ "vec4 tmpColor;"
+ "sk_FragColor = vec4(1.0) * (tmpColor = texture(sampler, vec2(1)) , "
+ "colorXform != mat4(1.0) ? vec4(clamp((mat4(colorXform) * vec4(tmpColor.xyz, 1.0)).xyz, "
+ "0.0, tmpColor.w), tmpColor.w) : tmpColor);"
+ "}",
+ *SkSL::ShaderCapsFactory::Default(),
+ "#version 400\n"
+ "out vec4 sk_FragColor;\n"
+ "uniform mat4 colorXform;\n"
+ "uniform sampler2D sampler;\n"
+ "void main() {\n"
+ " vec4 tmpColor;\n"
+ " sk_FragColor = (tmpColor = texture(sampler, vec2(1.0)) , colorXform != mat4(1.0) ? "
+ "vec4(clamp((colorXform * vec4(tmpColor.xyz, 1.0)).xyz, 0.0, tmpColor.w), tmpColor.w) : "
+ "tmpColor);\n"
+ "}\n");
+}
#endif