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
17namespace SkSL {
18
19/**
20 * An expression modified by a unary operator appearing before it, such as '!flag'.
21 */
22struct PrefixExpression : public Expression {
23 PrefixExpression(Token::Kind op, std::unique_ptr<Expression> operand)
24 : INHERITED(operand->fOffset, kPrefix_Kind, operand->fType)
25 , fOperand(std::move(operand))
26 , fOperator(op) {}
27
28 bool isCompileTimeConstant() const override {
29 return fOperator == Token::Kind::TK_MINUS && fOperand->isCompileTimeConstant();
30 }
31
32 bool hasProperty(Property property) const override {
33 if (property == Property::kSideEffects && (fOperator == Token::Kind::TK_PLUSPLUS ||
34 fOperator == Token::Kind::TK_MINUSMINUS)) {
35 return true;
36 }
37 return fOperand->hasProperty(property);
38 }
39
40 std::unique_ptr<Expression> constantPropagate(const IRGenerator& irGenerator,
41 const DefinitionMap& definitions) override {
42 if (fOperand->fKind == Expression::kFloatLiteral_Kind) {
43 return std::unique_ptr<Expression>(new FloatLiteral(
44 irGenerator.fContext,
45 fOffset,
46 -((FloatLiteral&) *fOperand).fValue));
47
48 }
49 return nullptr;
50 }
51
52 SKSL_FLOAT getFVecComponent(int index) const override {
53 SkASSERT(fOperator == Token::Kind::TK_MINUS);
54 return -fOperand->getFVecComponent(index);
55 }
56
57 SKSL_INT getIVecComponent(int index) const override {
58 SkASSERT(fOperator == Token::Kind::TK_MINUS);
59 return -fOperand->getIVecComponent(index);
60 }
61
62 SKSL_FLOAT getMatComponent(int col, int row) const override {
63 SkASSERT(fOperator == Token::Kind::TK_MINUS);
64 return -fOperand->getMatComponent(col, row);
65 }
66
67 int nodeCount() const override {
68 return 1 + fOperand->nodeCount();
69 }
70
71 std::unique_ptr<Expression> clone() const override {
72 return std::unique_ptr<Expression>(new PrefixExpression(fOperator, fOperand->clone()));
73 }
74
75 String description() const override {
76 return Compiler::OperatorName(fOperator) + fOperand->description();
77 }
78
79 std::unique_ptr<Expression> fOperand;
80 const Token::Kind fOperator;
81
82 typedef Expression INHERITED;
83};
84
85} // namespace SkSL
86
87#endif
88