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 
32 // static
integralType(std::string integer)33 Expression::Type Expression::integralType(std::string integer) {
34     if (std::regex_search(integer, RE_S32)) {
35         return Type::S32;
36     }
37 
38     if (std::regex_search(integer, RE_U32)) {
39         return Type::U32;
40     }
41 
42     if (std::regex_search(integer, RE_S64)) {
43         return Type::S64;
44     }
45 
46     if (std::regex_search(integer, RE_U64)) {
47         return Type::U64;
48     }
49 
50     LOG(WARNING) << "UNKNOWN INTEGER LITERAL: " << integer;
51 
52     return Type::UNKNOWN;
53 }
54 
55 // static
coalesceTypes(Type lhs,Type rhs)56 Expression::Type Expression::coalesceTypes(Type lhs, Type rhs) {
57     // because we are reducing everything to two ranks, we can heavily simplify
58     // conversion rules
59 
60 #define SIGNED(i) (i & 2) // i & 0b10
61 #define MAX_RANK(i) (i | 1) // i | 0b01
62 
63     if (lhs == rhs) {
64         return lhs;
65     }
66 
67     // lhs != rhs
68     if (SIGNED(lhs) == SIGNED(rhs)) {
69         return (Type)MAX_RANK(lhs);
70     }
71 
72     // lhs != rhs && SIGNED(lhs) != SIGNED(rhs)
73     if (lhs == U32 || rhs == U32) {
74         return S64;
75     }
76 
77     return Type::UNKNOWN;
78 
79 #undef SIGNED
80 #undef MAX_RANK
81 
82 }
83 
84 struct ParenthesizedExpression : Expression {
ParenthesizedExpressionandroid::ParenthesizedExpression85     ParenthesizedExpression(Expression* inner)
86     : mInner(inner) {}
~ParenthesizedExpressionandroid::ParenthesizedExpression87     ~ParenthesizedExpression() {
88         delete mInner;
89     }
90 
getTypeandroid::ParenthesizedExpression91     virtual Type getType(const AST &ast) {
92         return mInner->getType(ast);
93     }
toStringandroid::ParenthesizedExpression94     virtual std::string toString(StringHelper::Case atomCase) {
95         return "(" + mInner->toString(atomCase) + ")";
96     }
97 
98 private:
99     Expression* mInner;
100 
101     DISALLOW_COPY_AND_ASSIGN(ParenthesizedExpression);
102 };
103 
104 struct AtomExpression : Expression {
AtomExpressionandroid::AtomExpression105     AtomExpression(Type type, const std::string &value, bool isId)
106     : mType(type), mValue(value), mIsId(isId)
107     {}
108 
getTypeandroid::AtomExpression109     virtual Type getType(const AST &ast) {
110         if (mType != Type::UNKNOWN) {
111             return mType;
112         }
113 
114         Define *define = ast.getDefinesScope().lookup(mValue);
115 
116         if (define == NULL) {
117             return Type::UNKNOWN;
118         }
119 
120         return define->getExpressionType();
121     }
toStringandroid::AtomExpression122     virtual std::string toString(StringHelper::Case atomCase) {
123         // do not enforce case if it is not an identifier.
124         return mIsId ? StringHelper::ToCase(atomCase, mValue) : mValue;
125     }
126 
127 private:
128     Type mType;
129     std::string mValue;
130     bool mIsId;
131 
132     DISALLOW_COPY_AND_ASSIGN(AtomExpression);
133 };
134 
135 struct UnaryExpression : Expression {
UnaryExpressionandroid::UnaryExpression136     UnaryExpression(std::string op, Expression* rhs)
137     : mOp(op), mRhs(rhs)
138     {}
~UnaryExpressionandroid::UnaryExpression139     ~UnaryExpression() {
140         delete mRhs;
141     }
142 
getTypeandroid::UnaryExpression143     virtual Type getType(const AST &ast) {
144         return mRhs->getType(ast);
145     }
toStringandroid::UnaryExpression146     virtual std::string toString(StringHelper::Case atomCase) {
147         return mOp + mRhs->toString(atomCase);
148     }
149 
150 private:
151     std::string mOp;
152     Expression* mRhs;
153 
154     DISALLOW_COPY_AND_ASSIGN(UnaryExpression);
155 };
156 
157 struct BinaryExpression : Expression {
BinaryExpressionandroid::BinaryExpression158     BinaryExpression(Expression *lhs, std::string op, Expression* rhs)
159     : mLhs(lhs), mOp(op), mRhs(rhs)
160     {}
~BinaryExpressionandroid::BinaryExpression161     ~BinaryExpression() {
162         delete mLhs;
163         delete mRhs;
164     }
165 
getTypeandroid::BinaryExpression166     virtual Type getType(const AST &ast) {
167         return coalesceTypes(mLhs->getType(ast), mRhs->getType(ast));
168     }
toStringandroid::BinaryExpression169     virtual std::string toString(StringHelper::Case atomCase) {
170         return mLhs->toString(atomCase) + " " + mOp + " " + mRhs->toString(atomCase);
171     }
172 
173 private:
174     Expression* mLhs;
175     std::string mOp;
176     Expression* mRhs;
177 
178     DISALLOW_COPY_AND_ASSIGN(BinaryExpression);
179 };
180 
181 struct TernaryExpression : Expression {
TernaryExpressionandroid::TernaryExpression182     TernaryExpression(Expression *lhs, Expression *mhs, Expression* rhs)
183     : mLhs(lhs), mMhs(mhs), mRhs(rhs)
184     {}
~TernaryExpressionandroid::TernaryExpression185     ~TernaryExpression() {
186         delete mLhs;
187         delete mMhs;
188         delete mRhs;
189     }
190 
getTypeandroid::TernaryExpression191     virtual Type getType(const AST &ast) {
192         return coalesceTypes(mMhs->getType(ast), mRhs->getType(ast));
193     }
toStringandroid::TernaryExpression194     virtual std::string toString(StringHelper::Case atomCase) {
195         return mLhs->toString(atomCase) + " ? " + mMhs->toString(atomCase) + " : " + mRhs->toString(atomCase);
196     }
197 
198 private:
199     Expression* mLhs;
200     Expression* mMhs;
201     Expression* mRhs;
202 
203     DISALLOW_COPY_AND_ASSIGN(TernaryExpression);
204 };
205 
206 struct ArraySubscript : Expression {
ArraySubscriptandroid::ArraySubscript207     ArraySubscript(std::string id, Expression* subscript)
208     : mId(id), mSubscript(subscript)
209     {}
~ArraySubscriptandroid::ArraySubscript210     ~ArraySubscript() {
211         delete mSubscript;
212     }
213 
getTypeandroid::ArraySubscript214     virtual Type getType(const AST &) {
215         return Type::UNKNOWN;
216     }
toStringandroid::ArraySubscript217     virtual std::string toString(StringHelper::Case atomCase) {
218         return mId + "[" + mSubscript->toString(atomCase) + "]";
219     }
220 
221 private:
222     std::string mId;
223     Expression* mSubscript;
224 
225     DISALLOW_COPY_AND_ASSIGN(ArraySubscript);
226 };
227 
228 struct FunctionCall : Expression {
FunctionCallandroid::FunctionCall229     FunctionCall(std::string id, std::vector<Expression *> *args)
230     : mId(id), mArgs(args)
231     {}
~FunctionCallandroid::FunctionCall232     ~FunctionCall() {
233         if(mArgs != NULL) {
234             for(auto* args : *mArgs) {
235                 delete args;
236             }
237         }
238         delete mArgs;
239     }
240 
getTypeandroid::FunctionCall241     virtual Type getType(const AST &) {
242         return Type::UNKNOWN;
243     }
toStringandroid::FunctionCall244     virtual std::string toString(StringHelper::Case atomCase) {
245         std::string out = mId + "(";
246 
247         for (auto it = mArgs->begin(); it != mArgs->end(); ++it) {
248             if (it != mArgs->begin()) {
249                 out += ", ";
250             }
251 
252             out += (*it)->toString(atomCase);
253         }
254 
255         out += ")";
256 
257         return out;
258     }
259 
260 private:
261     std::string mId;
262     std::vector<Expression *> *mArgs;
263 
264     DISALLOW_COPY_AND_ASSIGN(FunctionCall);
265 };
266 
267 // static
parenthesize(Expression * inner)268 Expression *Expression::parenthesize(Expression *inner) {
269     return new ParenthesizedExpression(inner);
270 }
271 
272 // static
atom(Type type,const std::string & value,bool isId)273 Expression *Expression::atom(Type type, const std::string &value, bool isId) {
274     return new AtomExpression(type, value, isId);
275 }
276 
277 // static
unary(std::string op,Expression * rhs)278 Expression *Expression::unary(std::string op, Expression *rhs) {
279     return new UnaryExpression(op, rhs);
280 }
281 
282 // static
binary(Expression * lhs,std::string op,Expression * rhs)283 Expression *Expression::binary(Expression *lhs, std::string op, Expression *rhs) {
284     return new BinaryExpression(lhs, op, rhs);
285 }
286 
287 // static
ternary(Expression * lhs,Expression * mhs,Expression * rhs)288 Expression *Expression::ternary(Expression *lhs, Expression *mhs, Expression *rhs) {
289     return new TernaryExpression(lhs, mhs, rhs);
290 }
291 
292 // static
arraySubscript(std::string id,Expression * subscript)293 Expression *Expression::arraySubscript(std::string id, Expression *subscript) {
294     return new ArraySubscript(id, subscript);
295 }
296 
297 // static
functionCall(std::string id,std::vector<Expression * > * args)298 Expression *Expression::functionCall(std::string id, std::vector<Expression *> *args) {
299     return new FunctionCall(id, args);
300 }
301 
302 
303 } //namespace android
304