1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef CONSTANT_EXPRESSION_H_
18 
19 #define CONSTANT_EXPRESSION_H_
20 
21 #include <android-base/macros.h>
22 #include <string>
23 #include "ScalarType.h"
24 
25 namespace android {
26 
27 /**
28  * A constant expression is represented by a tree.
29  */
30 struct ConstantExpression {
31 
32     enum ConstExprType {
33         kConstExprLiteral,
34         kConstExprUnary,
35         kConstExprBinary,
36         kConstExprTernary
37     };
38 
39     /* Default constructor. */
40     ConstantExpression();
41     /* Copy constructor. */
42     ConstantExpression(const ConstantExpression& other);
43     /* Copy constructor, with the expr overriden. */
44     ConstantExpression(const ConstantExpression& other, std::string expr);
45     /* Literals */
46     ConstantExpression(const char *value);
47     /* binary operations */
48     ConstantExpression(const ConstantExpression *value1,
49         const char *op, const ConstantExpression* value2);
50     /* unary operations */
51     ConstantExpression(const char *op, const ConstantExpression *value);
52     /* ternary ?: */
53     ConstantExpression(const ConstantExpression *cond,
54                        const ConstantExpression *trueVal,
55                        const ConstantExpression *falseVal);
56 
57     static ConstantExpression Zero(ScalarType::Kind kind);
58     static ConstantExpression One(ScalarType::Kind kind);
59     static ConstantExpression ValueOf(ScalarType::Kind kind, uint64_t value);
60 
61     /* Evaluated result in a string form. */
62     std::string value() const;
63     /* Evaluated result in a string form. */
64     std::string cppValue() const;
65     /* Evaluated result in a string form. */
66     std::string javaValue() const;
67     /* Evaluated result in a string form, with given contextual kind. */
68     std::string value(ScalarType::Kind castKind) const;
69     /* Evaluated result in a string form, with given contextual kind. */
70     std::string cppValue(ScalarType::Kind castKind) const;
71     /* Evaluated result in a string form, with given contextual kind. */
72     std::string javaValue(ScalarType::Kind castKind) const;
73     /* Original expression with type. */
74     const std::string &description() const;
75     /* See mTrivialDescription */
76     bool descriptionIsTrivial() const;
77     /* Return a ConstantExpression that is 1 plus the original. */
78     ConstantExpression addOne() const;
79     /* Assignment operator. */
80     ConstantExpression& operator=(const ConstantExpression& other);
81 
82     size_t castSizeT() const;
83 
84 private:
85     /* The formatted expression. */
86     std::string mExpr;
87     /* The type of the expression. Hints on its original form. */
88     ConstExprType mType;
89     /* The kind of the result value. */
90     ScalarType::Kind mValueKind;
91     /* The stored result value. */
92     uint64_t mValue;
93     /* true if description() does not offer more information than value(). */
94     bool mTrivialDescription = false;
95 
96     /*
97      * Helper function for all cpp/javaValue methods.
98      * Returns a plain string (without any prefixes or suffixes, just the
99      * digits) converted from mValue.
100      */
101     std::string rawValue(ScalarType::Kind castKind) const;
102     /* Trim unnecessary information. Only mValue and mValueKind is kept. */
103     ConstantExpression &toLiteral();
104 
105     /*
106      * Return the value casted to the given type.
107      * First cast it according to mValueKind, then cast it to T.
108      * Assumes !containsIdentifiers()
109      */
110     template <typename T> T cast() const;
111 };
112 
113 }  // namespace android
114 
115 #endif  // CONSTANT_EXPRESSION_H_
116