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 #include "Expression.h"
18 #include "Define.h"
19 #include "AST.h"
20 #include "Scope.h"
21 
22 #include <vector>
23 #include <regex>
24 
25 namespace android {
26 
27 static const std::regex RE_S32("[^ul]$");
28 static const std::regex RE_U32("[^ul]u$");
29 static const std::regex RE_S64("[^ul](l|ll)$");
30 static const std::regex RE_U64("[^ul](ul|ull)$");
31 
integralType(const std::string & integer)32 Expression::Type Expression::integralType(const std::string& integer) {
33     if (std::regex_search(integer, RE_S32)) {
34         return Type::S32;
35     }
36 
37     if (std::regex_search(integer, RE_U32)) {
38         return Type::U32;
39     }
40 
41     if (std::regex_search(integer, RE_S64)) {
42         return Type::S64;
43     }
44 
45     if (std::regex_search(integer, RE_U64)) {
46         return Type::U64;
47     }
48 
49     LOG(WARNING) << "UNKNOWN INTEGER LITERAL: " << integer;
50 
51     return Type::UNKNOWN;
52 }
53 
coalesceTypes(Type lhs,Type rhs)54 Expression::Type Expression::coalesceTypes(Type lhs, Type rhs) {
55     // because we are reducing everything to two ranks, we can heavily simplify
56     // conversion rules
57 
58 #define SIGNED(i) ((i) & 2) // i & 0b10
59 #define MAX_RANK(i) ((i) | 1) // i | 0b01
60 
61     if (lhs == rhs) {
62         return lhs;
63     }
64 
65     // lhs != rhs
66     if (SIGNED(lhs) == SIGNED(rhs)) {
67         return (Type)MAX_RANK(lhs);
68     }
69 
70     // lhs != rhs && SIGNED(lhs) != SIGNED(rhs)
71     if (lhs == U32 || rhs == U32) {
72         return S64;
73     }
74 
75     return Type::UNKNOWN;
76 
77 #undef SIGNED
78 #undef MAX_RANK
79 
80 }
81 
82 struct ParenthesizedExpression : Expression {
ParenthesizedExpressionandroid::ParenthesizedExpression83     ParenthesizedExpression(Expression* inner)
84     : mInner(inner) {}
~ParenthesizedExpressionandroid::ParenthesizedExpression85     ~ParenthesizedExpression() override {
86         delete mInner;
87     }
88 
getTypeandroid::ParenthesizedExpression89     Type getType(const AST &ast) override {
90         return mInner->getType(ast);
91     }
toStringandroid::ParenthesizedExpression92     std::string toString(StringHelper::Case atomCase) override {
93         return "(" + mInner->toString(atomCase) + ")";
94     }
95 
96 private:
97     Expression* mInner;
98 
99     DISALLOW_COPY_AND_ASSIGN(ParenthesizedExpression);
100 };
101 
102 struct AtomExpression : Expression {
AtomExpressionandroid::AtomExpression103     AtomExpression(Type type, const std::string &value, bool isId)
104     : mType(type), mValue(value), mIsId(isId)
105     {}
106 
getTypeandroid::AtomExpression107     Type getType(const AST &ast) override {
108         if (mType != Type::UNKNOWN) {
109             return mType;
110         }
111 
112         Define *define = ast.getDefinesScope().lookup(mValue);
113 
114         if (define == nullptr) {
115             return Type::UNKNOWN;
116         }
117 
118         return define->getExpressionType();
119     }
toStringandroid::AtomExpression120     std::string toString(StringHelper::Case atomCase) override {
121         // do not enforce case if it is not an identifier.
122         return mIsId ? StringHelper::ToCase(atomCase, mValue) : mValue;
123     }
124 
125 private:
126     Type mType;
127     std::string mValue;
128     bool mIsId;
129 
130     DISALLOW_COPY_AND_ASSIGN(AtomExpression);
131 };
132 
133 struct UnaryExpression : Expression {
UnaryExpressionandroid::UnaryExpression134     UnaryExpression(std::string op, Expression* rhs)
135     : mOp(op), mRhs(rhs)
136     {}
~UnaryExpressionandroid::UnaryExpression137     ~UnaryExpression() override {
138         delete mRhs;
139     }
140 
getTypeandroid::UnaryExpression141     Type getType(const AST &ast) override {
142         return mRhs->getType(ast);
143     }
toStringandroid::UnaryExpression144     std::string toString(StringHelper::Case atomCase) override {
145         return mOp + mRhs->toString(atomCase);
146     }
147 
148 private:
149     std::string mOp;
150     Expression* mRhs;
151 
152     DISALLOW_COPY_AND_ASSIGN(UnaryExpression);
153 };
154 
155 struct BinaryExpression : Expression {
BinaryExpressionandroid::BinaryExpression156     BinaryExpression(Expression *lhs, std::string op, Expression* rhs)
157     : mLhs(lhs), mOp(op), mRhs(rhs)
158     {}
~BinaryExpressionandroid::BinaryExpression159     ~BinaryExpression() override {
160         delete mLhs;
161         delete mRhs;
162     }
163 
getTypeandroid::BinaryExpression164     Type getType(const AST &ast) override {
165         return coalesceTypes(mLhs->getType(ast), mRhs->getType(ast));
166     }
toStringandroid::BinaryExpression167     std::string toString(StringHelper::Case atomCase) override {
168         return mLhs->toString(atomCase) + " " + mOp + " " + mRhs->toString(atomCase);
169     }
170 
171 private:
172     Expression* mLhs;
173     std::string mOp;
174     Expression* mRhs;
175 
176     DISALLOW_COPY_AND_ASSIGN(BinaryExpression);
177 };
178 
179 struct TernaryExpression : Expression {
TernaryExpressionandroid::TernaryExpression180     TernaryExpression(Expression *lhs, Expression *mhs, Expression* rhs)
181     : mLhs(lhs), mMhs(mhs), mRhs(rhs)
182     {}
~TernaryExpressionandroid::TernaryExpression183     ~TernaryExpression() override {
184         delete mLhs;
185         delete mMhs;
186         delete mRhs;
187     }
188 
getTypeandroid::TernaryExpression189     Type getType(const AST &ast) override {
190         return coalesceTypes(mMhs->getType(ast), mRhs->getType(ast));
191     }
toStringandroid::TernaryExpression192     std::string toString(StringHelper::Case atomCase) override {
193         return mLhs->toString(atomCase) + " ? " + mMhs->toString(atomCase) + " : " + mRhs->toString(atomCase);
194     }
195 
196 private:
197     Expression* mLhs;
198     Expression* mMhs;
199     Expression* mRhs;
200 
201     DISALLOW_COPY_AND_ASSIGN(TernaryExpression);
202 };
203 
204 struct ArraySubscript : Expression {
ArraySubscriptandroid::ArraySubscript205     ArraySubscript(std::string id, Expression* subscript)
206     : mId(id), mSubscript(subscript)
207     {}
~ArraySubscriptandroid::ArraySubscript208     ~ArraySubscript() override {
209         delete mSubscript;
210     }
211 
getTypeandroid::ArraySubscript212     Type getType(const AST &) override {
213         return Type::UNKNOWN;
214     }
toStringandroid::ArraySubscript215     std::string toString(StringHelper::Case atomCase) override {
216         return mId + "[" + mSubscript->toString(atomCase) + "]";
217     }
218 
219 private:
220     std::string mId;
221     Expression* mSubscript;
222 
223     DISALLOW_COPY_AND_ASSIGN(ArraySubscript);
224 };
225 
226 struct FunctionCall : Expression {
FunctionCallandroid::FunctionCall227     FunctionCall(std::string id, std::vector<Expression *> *args)
228     : mId(id), mArgs(args)
229     {}
~FunctionCallandroid::FunctionCall230     ~FunctionCall() override {
231         if(mArgs != nullptr) {
232             for(auto* args : *mArgs) {
233                 delete args;
234             }
235         }
236         delete mArgs;
237     }
238 
getTypeandroid::FunctionCall239     Type getType(const AST &) override {
240         return Type::UNKNOWN;
241     }
toStringandroid::FunctionCall242     std::string toString(StringHelper::Case atomCase) override {
243         std::string out = mId + "(";
244 
245         for (auto it = mArgs->begin(); it != mArgs->end(); ++it) {
246             if (it != mArgs->begin()) {
247                 out += ", ";
248             }
249 
250             out += (*it)->toString(atomCase);
251         }
252 
253         out += ")";
254 
255         return out;
256     }
257 
258 private:
259     std::string mId;
260     std::vector<Expression *> *mArgs;
261 
262     DISALLOW_COPY_AND_ASSIGN(FunctionCall);
263 };
264 
parenthesize(Expression * inner)265 Expression *Expression::parenthesize(Expression *inner) {
266     return new ParenthesizedExpression(inner);
267 }
268 
atom(Type type,const std::string & value,bool isId)269 Expression *Expression::atom(Type type, const std::string &value, bool isId) {
270     return new AtomExpression(type, value, isId);
271 }
272 
unary(std::string op,Expression * rhs)273 Expression *Expression::unary(std::string op, Expression *rhs) {
274     return new UnaryExpression(op, rhs);
275 }
276 
binary(Expression * lhs,std::string op,Expression * rhs)277 Expression *Expression::binary(Expression *lhs, std::string op, Expression *rhs) {
278     return new BinaryExpression(lhs, op, rhs);
279 }
280 
ternary(Expression * lhs,Expression * mhs,Expression * rhs)281 Expression *Expression::ternary(Expression *lhs, Expression *mhs, Expression *rhs) {
282     return new TernaryExpression(lhs, mhs, rhs);
283 }
284 
arraySubscript(std::string id,Expression * subscript)285 Expression *Expression::arraySubscript(std::string id, Expression *subscript) {
286     return new ArraySubscript(id, subscript);
287 }
288 
functionCall(std::string id,std::vector<Expression * > * args)289 Expression *Expression::functionCall(std::string id, std::vector<Expression *> *args) {
290     return new FunctionCall(id, args);
291 }
292 
293 
294 } //namespace android
295