blob: 49d6facb63187429b6319fbd1d171733d4d73f1d [file] [log] [blame]
Brian Osman00185012021-02-04 16:07:11 -05001/*
2 * Copyright 2021 Google LLC
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_OPERATORS
9#define SKSL_OPERATORS
10
John Stiles45990502021-02-16 10:55:27 -050011#include "src/sksl/SkSLDefines.h"
Brian Osman00185012021-02-04 16:07:11 -050012#include "src/sksl/SkSLLexer.h"
13
14namespace SkSL {
John Stiles45990502021-02-16 10:55:27 -050015
John Stiles0b750f22021-02-26 20:13:07 -050016class Context;
17class Type;
18
John Stiles45990502021-02-16 10:55:27 -050019class Operator {
20public:
21 using Kind = Token::Kind;
22
23 // Allow implicit conversion from Token::Kind, since this is just a utility wrapper on top.
24 Operator(Token::Kind t) : fKind(t) {
25 SkASSERTF(this->isOperator(), "token-kind %d is not an operator", fKind);
26 }
Brian Osman00185012021-02-04 16:07:11 -050027
28 enum class Precedence {
29 kParentheses = 1,
30 kPostfix = 2,
31 kPrefix = 3,
32 kMultiplicative = 4,
33 kAdditive = 5,
34 kShift = 6,
35 kRelational = 7,
36 kEquality = 8,
37 kBitwiseAnd = 9,
38 kBitwiseXor = 10,
39 kBitwiseOr = 11,
40 kLogicalAnd = 12,
41 kLogicalXor = 13,
42 kLogicalOr = 14,
43 kTernary = 15,
44 kAssignment = 16,
45 kSequence = 17,
46 kTopLevel = kSequence
47 };
48
John Stiles45990502021-02-16 10:55:27 -050049 Token::Kind kind() const { return fKind; }
Brian Osman00185012021-02-04 16:07:11 -050050
John Stiles45990502021-02-16 10:55:27 -050051 Precedence getBinaryPrecedence() const;
52
53 const char* operatorName() const;
Brian Osman00185012021-02-04 16:07:11 -050054
55 // Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.)
John Stiles45990502021-02-16 10:55:27 -050056 bool isAssignment() const;
Brian Osman00185012021-02-04 16:07:11 -050057
58 // Given a compound assignment operator, returns the non-assignment version of the operator
59 // (e.g. '+=' becomes '+')
John Stiles45990502021-02-16 10:55:27 -050060 Operator removeAssignment() const;
Brian Osman00185012021-02-04 16:07:11 -050061
John Stiles45990502021-02-16 10:55:27 -050062 /**
63 * Defines the set of logical (comparison) operators:
64 * < <= > >=
65 */
66 bool isLogical() const;
67
68 /**
69 * Defines the set of operators which are only valid on integral types:
70 * << <<= >> >>= & &= | |= ^ ^= % %=
71 */
72 bool isOnlyValidForIntegralTypes() const;
73
74 /**
75 * Defines the set of operators which perform vector/matrix math.
76 * + += - -= * *= / /= % %= << <<= >> >>= & &= | |= ^ ^=
77 */
78 bool isValidForMatrixOrVector() const;
79
80 /*
81 * Defines the set of operators allowed by The OpenGL ES Shading Language 1.00, Section 5.1.
82 * The set of illegal (reserved) operators are the ones that only make sense with integral
83 * types. This is not a coincidence: It's because ES2 doesn't require 'int' to be anything but
84 * syntactic sugar for floats with truncation after each operation.
85 */
86 bool isAllowedInStrictES2Mode() const {
87 return !this->isOnlyValidForIntegralTypes();
88 }
89
John Stiles0b750f22021-02-26 20:13:07 -050090 /**
91 * Determines the operand and result types of a binary expression. Returns true if the
92 * expression is legal, false otherwise. If false, the values of the out parameters are
93 * undefined.
94 */
95 bool determineBinaryType(const Context& context,
96 const Type& left,
97 const Type& right,
98 const Type** outLeftType,
99 const Type** outRightType,
100 const Type** outResultType);
101
John Stiles45990502021-02-16 10:55:27 -0500102private:
103 bool isOperator() const;
John Stiles0b750f22021-02-26 20:13:07 -0500104 bool isMatrixMultiply(const Type& left, const Type& right);
John Stiles45990502021-02-16 10:55:27 -0500105
106 Kind fKind;
107};
108
Brian Osman00185012021-02-04 16:07:11 -0500109} // namespace SkSL
110
111#endif