1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef SKSL_PREFIXEXPRESSION
9 #define SKSL_PREFIXEXPRESSION
10 
11 #include "src/sksl/SkSLCompiler.h"
12 #include "src/sksl/SkSLIRGenerator.h"
13 #include "src/sksl/SkSLLexer.h"
14 #include "src/sksl/ir/SkSLExpression.h"
15 #include "src/sksl/ir/SkSLFloatLiteral.h"
16 
17 namespace SkSL {
18 
19 /**
20  * An expression modified by a unary operator appearing before it, such as '!flag'.
21  */
22 class PrefixExpression final : public Expression {
23 public:
24     static constexpr Kind kExpressionKind = Kind::kPrefix;
25 
PrefixExpression(Token::Kind op,std::unique_ptr<Expression> operand)26     PrefixExpression(Token::Kind op, std::unique_ptr<Expression> operand)
27         : INHERITED(operand->fOffset, kExpressionKind, &operand->type())
28         , fOperator(op)
29         , fOperand(std::move(operand)) {}
30 
getOperator()31     Token::Kind getOperator() const {
32         return fOperator;
33     }
34 
operand()35     std::unique_ptr<Expression>& operand() {
36         return fOperand;
37     }
38 
operand()39     const std::unique_ptr<Expression>& operand() const {
40         return fOperand;
41     }
42 
isNegationOfCompileTimeConstant()43     bool isNegationOfCompileTimeConstant() const {
44         return this->getOperator() == Token::Kind::TK_MINUS &&
45                this->operand()->isCompileTimeConstant();
46     }
47 
isCompileTimeConstant()48     bool isCompileTimeConstant() const override {
49         return this->isNegationOfCompileTimeConstant();
50     }
51 
hasProperty(Property property)52     bool hasProperty(Property property) const override {
53         if (property == Property::kSideEffects &&
54             (this->getOperator() == Token::Kind::TK_PLUSPLUS ||
55              this->getOperator() == Token::Kind::TK_MINUSMINUS)) {
56             return true;
57         }
58         return this->operand()->hasProperty(property);
59     }
60 
61     std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
62                                                   const DefinitionMap& definitions) override;
63 
getFVecComponent(int index)64     SKSL_FLOAT getFVecComponent(int index) const override {
65         SkASSERT(this->getOperator() == Token::Kind::TK_MINUS);
66         return -this->operand()->getFVecComponent(index);
67     }
68 
getIVecComponent(int index)69     SKSL_INT getIVecComponent(int index) const override {
70         SkASSERT(this->getOperator() == Token::Kind::TK_MINUS);
71         return -this->operand()->getIVecComponent(index);
72     }
73 
getMatComponent(int col,int row)74     SKSL_FLOAT getMatComponent(int col, int row) const override {
75         SkASSERT(this->getOperator() == Token::Kind::TK_MINUS);
76         return -this->operand()->getMatComponent(col, row);
77     }
78 
clone()79     std::unique_ptr<Expression> clone() const override {
80         return std::unique_ptr<Expression>(new PrefixExpression(this->getOperator(),
81                                                                 this->operand()->clone()));
82     }
83 
description()84     String description() const override {
85         return Compiler::OperatorName(this->getOperator()) + this->operand()->description();
86     }
87 
88 private:
89     Token::Kind fOperator;
90     std::unique_ptr<Expression> fOperand;
91 
92     using INHERITED = Expression;
93 };
94 
95 }  // namespace SkSL
96 
97 #endif
98