Home | History | Annotate | Download | only in c2hal
      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 Expression::Type Expression::integralType(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 
     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 {
     83     ParenthesizedExpression(Expression* inner)
     84     : mInner(inner) {}
     85     ~ParenthesizedExpression() {
     86         delete mInner;
     87     }
     88 
     89     virtual Type getType(const AST &ast) {
     90         return mInner->getType(ast);
     91     }
     92     virtual std::string toString(StringHelper::Case atomCase) {
     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 {
    103     AtomExpression(Type type, const std::string &value, bool isId)
    104     : mType(type), mValue(value), mIsId(isId)
    105     {}
    106 
    107     virtual Type getType(const AST &ast) {
    108         if (mType != Type::UNKNOWN) {
    109             return mType;
    110         }
    111 
    112         Define *define = ast.getDefinesScope().lookup(mValue);
    113 
    114         if (define == NULL) {
    115             return Type::UNKNOWN;
    116         }
    117 
    118         return define->getExpressionType();
    119     }
    120     virtual std::string toString(StringHelper::Case atomCase) {
    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 {
    134     UnaryExpression(std::string op, Expression* rhs)
    135     : mOp(op), mRhs(rhs)
    136     {}
    137     ~UnaryExpression() {
    138         delete mRhs;
    139     }
    140 
    141     virtual Type getType(const AST &ast) {
    142         return mRhs->getType(ast);
    143     }
    144     virtual std::string toString(StringHelper::Case atomCase) {
    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 {
    156     BinaryExpression(Expression *lhs, std::string op, Expression* rhs)
    157     : mLhs(lhs), mOp(op), mRhs(rhs)
    158     {}
    159     ~BinaryExpression() {
    160         delete mLhs;
    161         delete mRhs;
    162     }
    163 
    164     virtual Type getType(const AST &ast) {
    165         return coalesceTypes(mLhs->getType(ast), mRhs->getType(ast));
    166     }
    167     virtual std::string toString(StringHelper::Case atomCase) {
    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 {
    180     TernaryExpression(Expression *lhs, Expression *mhs, Expression* rhs)
    181     : mLhs(lhs), mMhs(mhs), mRhs(rhs)
    182     {}
    183     ~TernaryExpression() {
    184         delete mLhs;
    185         delete mMhs;
    186         delete mRhs;
    187     }
    188 
    189     virtual Type getType(const AST &ast) {
    190         return coalesceTypes(mMhs->getType(ast), mRhs->getType(ast));
    191     }
    192     virtual std::string toString(StringHelper::Case atomCase) {
    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 {
    205     ArraySubscript(std::string id, Expression* subscript)
    206     : mId(id), mSubscript(subscript)
    207     {}
    208     ~ArraySubscript() {
    209         delete mSubscript;
    210     }
    211 
    212     virtual Type getType(const AST &) {
    213         return Type::UNKNOWN;
    214     }
    215     virtual std::string toString(StringHelper::Case atomCase) {
    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 {
    227     FunctionCall(std::string id, std::vector<Expression *> *args)
    228     : mId(id), mArgs(args)
    229     {}
    230     ~FunctionCall() {
    231         if(mArgs != NULL) {
    232             for(auto* args : *mArgs) {
    233                 delete args;
    234             }
    235         }
    236         delete mArgs;
    237     }
    238 
    239     virtual Type getType(const AST &) {
    240         return Type::UNKNOWN;
    241     }
    242     virtual std::string toString(StringHelper::Case atomCase) {
    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 
    265 Expression *Expression::parenthesize(Expression *inner) {
    266     return new ParenthesizedExpression(inner);
    267 }
    268 
    269 Expression *Expression::atom(Type type, const std::string &value, bool isId) {
    270     return new AtomExpression(type, value, isId);
    271 }
    272 
    273 Expression *Expression::unary(std::string op, Expression *rhs) {
    274     return new UnaryExpression(op, rhs);
    275 }
    276 
    277 Expression *Expression::binary(Expression *lhs, std::string op, Expression *rhs) {
    278     return new BinaryExpression(lhs, op, rhs);
    279 }
    280 
    281 Expression *Expression::ternary(Expression *lhs, Expression *mhs, Expression *rhs) {
    282     return new TernaryExpression(lhs, mhs, rhs);
    283 }
    284 
    285 Expression *Expression::arraySubscript(std::string id, Expression *subscript) {
    286     return new ArraySubscript(id, subscript);
    287 }
    288 
    289 Expression *Expression::functionCall(std::string id, std::vector<Expression *> *args) {
    290     return new FunctionCall(id, args);
    291 }
    292 
    293 
    294 } //namespace android
    295