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 isConstant() const override {
29 return fOperator == Token::MINUS && fOperand->isConstant();
30 }
31
32 bool hasProperty(Property property) const override {
33 if (property == Property::kSideEffects && (fOperator == Token::PLUSPLUS ||
34 fOperator == Token::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::MINUS);
54 return -fOperand->getFVecComponent(index);
55 }
56
57 SKSL_INT getIVecComponent(int index) const override {
58 SkASSERT(fOperator == Token::Kind::MINUS);
59 return -fOperand->getIVecComponent(index);
60 }
61
62 SKSL_FLOAT getMatComponent(int col, int row) const override {
63 SkASSERT(fOperator == Token::Kind::MINUS);
64 return -fOperand->getMatComponent(col, row);
65 }
66
67 std::unique_ptr<Expression> clone() const override {
68 return std::unique_ptr<Expression>(new PrefixExpression(fOperator, fOperand->clone()));
69 }
70
71#ifdef SK_DEBUG
72 String description() const override {
73 return Compiler::OperatorName(fOperator) + fOperand->description();
74 }
75#endif
76
77 std::unique_ptr<Expression> fOperand;
78 const Token::Kind fOperator;
79
80 typedef Expression INHERITED;
81};
82
83} // namespace
84
85#endif
86