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
25namespace android {
26
27static const std::regex RE_S32("[^ul]$");
28static const std::regex RE_U32("[^ul]u$");
29static const std::regex RE_S64("[^ul](l|ll)$");
30static const std::regex RE_U64("[^ul](ul|ull)$");
31
32// static
33Expression::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
56Expression::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
84struct ParenthesizedExpression : Expression {
85    ParenthesizedExpression(Expression* inner)
86    : mInner(inner) {}
87    ~ParenthesizedExpression() {
88        delete mInner;
89    }
90
91    virtual Type getType(const AST &ast) {
92        return mInner->getType(ast);
93    }
94    virtual std::string toString(StringHelper::Case atomCase) {
95        return "(" + mInner->toString(atomCase) + ")";
96    }
97
98private:
99    Expression* mInner;
100
101    DISALLOW_COPY_AND_ASSIGN(ParenthesizedExpression);
102};
103
104struct AtomExpression : Expression {
105    AtomExpression(Type type, const std::string &value, bool isId)
106    : mType(type), mValue(value), mIsId(isId)
107    {}
108
109    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    }
122    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
127private:
128    Type mType;
129    std::string mValue;
130    bool mIsId;
131
132    DISALLOW_COPY_AND_ASSIGN(AtomExpression);
133};
134
135struct UnaryExpression : Expression {
136    UnaryExpression(std::string op, Expression* rhs)
137    : mOp(op), mRhs(rhs)
138    {}
139    ~UnaryExpression() {
140        delete mRhs;
141    }
142
143    virtual Type getType(const AST &ast) {
144        return mRhs->getType(ast);
145    }
146    virtual std::string toString(StringHelper::Case atomCase) {
147        return mOp + mRhs->toString(atomCase);
148    }
149
150private:
151    std::string mOp;
152    Expression* mRhs;
153
154    DISALLOW_COPY_AND_ASSIGN(UnaryExpression);
155};
156
157struct BinaryExpression : Expression {
158    BinaryExpression(Expression *lhs, std::string op, Expression* rhs)
159    : mLhs(lhs), mOp(op), mRhs(rhs)
160    {}
161    ~BinaryExpression() {
162        delete mLhs;
163        delete mRhs;
164    }
165
166    virtual Type getType(const AST &ast) {
167        return coalesceTypes(mLhs->getType(ast), mRhs->getType(ast));
168    }
169    virtual std::string toString(StringHelper::Case atomCase) {
170        return mLhs->toString(atomCase) + " " + mOp + " " + mRhs->toString(atomCase);
171    }
172
173private:
174    Expression* mLhs;
175    std::string mOp;
176    Expression* mRhs;
177
178    DISALLOW_COPY_AND_ASSIGN(BinaryExpression);
179};
180
181struct TernaryExpression : Expression {
182    TernaryExpression(Expression *lhs, Expression *mhs, Expression* rhs)
183    : mLhs(lhs), mMhs(mhs), mRhs(rhs)
184    {}
185    ~TernaryExpression() {
186        delete mLhs;
187        delete mMhs;
188        delete mRhs;
189    }
190
191    virtual Type getType(const AST &ast) {
192        return coalesceTypes(mMhs->getType(ast), mRhs->getType(ast));
193    }
194    virtual std::string toString(StringHelper::Case atomCase) {
195        return mLhs->toString(atomCase) + " ? " + mMhs->toString(atomCase) + " : " + mRhs->toString(atomCase);
196    }
197
198private:
199    Expression* mLhs;
200    Expression* mMhs;
201    Expression* mRhs;
202
203    DISALLOW_COPY_AND_ASSIGN(TernaryExpression);
204};
205
206struct ArraySubscript : Expression {
207    ArraySubscript(std::string id, Expression* subscript)
208    : mId(id), mSubscript(subscript)
209    {}
210    ~ArraySubscript() {
211        delete mSubscript;
212    }
213
214    virtual Type getType(const AST &) {
215        return Type::UNKNOWN;
216    }
217    virtual std::string toString(StringHelper::Case atomCase) {
218        return mId + "[" + mSubscript->toString(atomCase) + "]";
219    }
220
221private:
222    std::string mId;
223    Expression* mSubscript;
224
225    DISALLOW_COPY_AND_ASSIGN(ArraySubscript);
226};
227
228struct FunctionCall : Expression {
229    FunctionCall(std::string id, std::vector<Expression *> *args)
230    : mId(id), mArgs(args)
231    {}
232    ~FunctionCall() {
233        if(mArgs != NULL) {
234            for(auto* args : *mArgs) {
235                delete args;
236            }
237        }
238        delete mArgs;
239    }
240
241    virtual Type getType(const AST &) {
242        return Type::UNKNOWN;
243    }
244    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
260private:
261    std::string mId;
262    std::vector<Expression *> *mArgs;
263
264    DISALLOW_COPY_AND_ASSIGN(FunctionCall);
265};
266
267// static
268Expression *Expression::parenthesize(Expression *inner) {
269    return new ParenthesizedExpression(inner);
270}
271
272// static
273Expression *Expression::atom(Type type, const std::string &value, bool isId) {
274    return new AtomExpression(type, value, isId);
275}
276
277// static
278Expression *Expression::unary(std::string op, Expression *rhs) {
279    return new UnaryExpression(op, rhs);
280}
281
282// static
283Expression *Expression::binary(Expression *lhs, std::string op, Expression *rhs) {
284    return new BinaryExpression(lhs, op, rhs);
285}
286
287// static
288Expression *Expression::ternary(Expression *lhs, Expression *mhs, Expression *rhs) {
289    return new TernaryExpression(lhs, mhs, rhs);
290}
291
292// static
293Expression *Expression::arraySubscript(std::string id, Expression *subscript) {
294    return new ArraySubscript(id, subscript);
295}
296
297// static
298Expression *Expression::functionCall(std::string id, std::vector<Expression *> *args) {
299    return new FunctionCall(id, args);
300}
301
302
303} //namespace android
304