Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/ReplacePseudoFunc.cpp

    rc75b30a r544deb9  
    1717std::set<std::string> queryValues;
    1818
    19 struct WrapEnumValueExpr final : public ast::WithShortCircuiting,
    20                                  public ast::WithSymbolTable,
    21                                  public ast::WithConstTranslationUnit {
    22     void previsit(const ast::DeclStmt* expr);
    23     void previsit(const ast::ApplicationExpr* expr);
    24     void previsit(const ast::CastExpr* expr);
    25 
    26     ast::Expr const* postvisit(const ast::VariableExpr* expr);
    27 };
    28 
    2919struct FindGenEnumArray final : public ast::WithShortCircuiting {
    3020    void previsit(const ast::ApplicationExpr* enumDecl);
    3121};
    32 
    33 struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>,
    34                                          public ast::WithSymbolTable,
    35                                          public ast::WithShortCircuiting {
    36     void previsit(const ast::EnumDecl* enumDecl);
    37 };
    38 
    39 struct ReplacePseudoFuncCore : public ast::WithShortCircuiting,
    40                                public ast::WithSymbolTable,
    41                                public ast::WithConstTranslationUnit {
    42     ast::Expr const* postvisit(ast::ApplicationExpr const* decl);
    43 };
    44 
    45 void WrapEnumValueExpr::previsit(const ast::ApplicationExpr* expr) {
    46 
    47     auto varExpr = expr->func.as<ast::VariableExpr>();
    48     auto fname = ast::getFunctionName(expr);
    49         if ( !varExpr || varExpr->var->linkage == ast::Linkage::Intrinsic ) {
    50         if ( fname == "?{}" || fname == "?=?" )
    51                     visit_children = false;
    52         }
    53 
    54     if (fname == "labelE" || fname == "valueE" || fname == "posE")
    55         visit_children = false;
    56 }
    57 
    58 void WrapEnumValueExpr::previsit(const ast::DeclStmt*) {
    59     visit_children = false;
    60 }
    61 
    62 void WrapEnumValueExpr::previsit(const ast::CastExpr* expr) {
    63     if (expr->result && expr->result.as<ast::ReferenceType>()) {
    64         visit_children = false;
    65     }
    66 }
    67 
    68 ast::Expr const* WrapEnumValueExpr::postvisit(const ast::VariableExpr* expr) {
    69     visit_children = false;
    70     if (!expr->result) {
    71         return expr;
    72     }
    73     if (auto enumInst = expr->result.as<ast::EnumInstType>()) {
    74         if (enumInst->base && enumInst->base->base) {
    75             auto untyped = new ast::UntypedExpr(
    76                 expr->location, new ast::NameExpr(expr->location, "valueE"),
    77                 {new ast::VariableExpr(*expr)});
    78             ResolvExpr::ResolveContext context{symtab, transUnit().global};
    79             auto result = ResolvExpr::findVoidExpression(untyped, context);
    80             if (result.get()) {
    81                 ast::ptr<ast::ApplicationExpr> ret =
    82                     result.strict_as<ast::ApplicationExpr>();
    83                 return new ast::ApplicationExpr(*ret);
    84             }
    85         }
    86     }
    87     return expr;
    88 }
    8922
    9023void FindGenEnumArray::previsit(const ast::ApplicationExpr* expr) {
     
    11548}
    11649
     50struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>,
     51                                         public ast::WithSymbolTable,
     52                                         public ast::WithShortCircuiting {
     53    void previsit(const ast::EnumDecl* enumDecl);
     54};
     55
    11756void PseudoFuncGenerateRoutine::previsit(const ast::EnumDecl* enumDecl) {
    11857    visit_children = false;
     
    12867            location, ast::ConstantExpr::from_string(location, mem->name)));
    12968    }
    130     // Values only
    13169    if (queryValues.count(enumDecl->name)) {
    13270        auto init = new ast::ListInit(location, std::move(inits));
    133         const ast::ArrayType* arrT = new ast::ArrayType(
    134             enumDecl->base,
    135             ast::ConstantExpr::from_int(location, enumDecl->members.size()),
    136             ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim);
    137         ast::ObjectDecl* values = new ast::ObjectDecl(
    138             location, "values_" + enumDecl->name, arrT, init,
    139             ast::Storage::Static, ast::Linkage::AutoGen);
     71        auto values = new ast::ObjectDecl(
     72            location, "values_" + enumDecl->name,
     73            new ast::ArrayType(
     74                enumDecl->base,
     75                ast::ConstantExpr::from_int(location, enumDecl->members.size()),
     76                ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim),
     77            init, ast::Storage::Static, ast::Linkage::AutoGen);
    14078        symtab.addId(values);
    14179        values->mangleName = Mangle::mangle(values);
     
    14482    if (queryLabels.count(enumDecl->name)) {
    14583        auto label_strings = new ast::ListInit(location, std::move(labels));
    146         auto labels = new ast::ObjectDecl(
     84        auto label_arr = new ast::ObjectDecl(
    14785            location, "labels_" + enumDecl->name,
    14886            new ast::ArrayType(
     
    15189                ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim),
    15290            label_strings, ast::Storage::Static, ast::Linkage::AutoGen);
    153         symtab.addId(labels);
    154         labels->mangleName = Mangle::mangle(labels);
    155         declsToAddAfter.push_back(labels);
     91        symtab.addId(label_arr);
     92        label_arr->mangleName = Mangle::mangle(label_arr);
     93        declsToAddAfter.push_back(label_arr);
    15694    }
    15795}
    15896
    159 ast::ApplicationExpr const* getPseudoFuncApplication(
    160     const CodeLocation location, ResolvExpr::ResolveContext context,
    161     const ast::VariableExpr* arg, const ast::EnumDecl* base, const std::string & name) {
    162     ast::Expr* toResolve = new ast::NameExpr(location, name + base->name);
    163     auto result = ResolvExpr::findVoidExpression(toResolve, context);
    164     assert(result.get());
    165     auto arrAsVar = result.strict_as<ast::VariableExpr>();
    166     auto untyped = new ast::UntypedExpr(
    167         location, new ast::NameExpr(location, "?[?]"),
    168         {new ast::VariableExpr(*arrAsVar), new ast::VariableExpr(*arg)});
    169     auto typedResult = ResolvExpr::findVoidExpression(untyped, context);
    170 
    171     ast::ptr<ast::ApplicationExpr> ret =
    172         typedResult.strict_as<ast::ApplicationExpr>();
    173     return ast::deepCopy(ret);
    174 }
     97struct ReplacePseudoFuncCore : public ast::WithShortCircuiting,
     98                               public ast::WithSymbolTable,
     99                               public ast::WithConstTranslationUnit {
     100    ast::Expr const* postvisit(ast::ApplicationExpr const* decl);
     101};
    175102
    176103ast::Expr const* ReplacePseudoFuncCore::postvisit(
     
    198125        }
    199126        const ast::EnumDecl* base = argType->base;
    200         ResolvExpr::ResolveContext context{symtab, transUnit().global};
    201         // If resolvable as constant
    202127        for (size_t i = 0; i < base->members.size(); i++) {
    203128            if (base->members[i]->name == referredName) {
     
    208133                                                          referredName);
    209134                else
    210                     return getPseudoFuncApplication(location, context, arg.get(),
    211                                                base, "values_");
     135                    return new ast::TypeExpr(expr->location, argType);
    212136            }
    213137        }
    214138
     139        ResolvExpr::ResolveContext context{symtab, transUnit().global};
     140
    215141        if (fname == "labelE") {
    216             if (auto labelExpr =
    217                     getPseudoFuncApplication(location, context, arg.get(), base, "labels_")) {
    218                 return labelExpr;
     142            ast::Expr* toResolve =
     143                new ast::NameExpr(expr->location, "labels_" + base->name);
     144            auto result = ResolvExpr::findVoidExpression(toResolve, context);
     145            if (result.get()) {
     146                auto arrAsVar = result.strict_as<ast::VariableExpr>();
     147                auto untyped = new ast::UntypedExpr(
     148                    location, new ast::NameExpr(location, "?[?]"),
     149                    {new ast::VariableExpr(*arrAsVar),
     150                     ast::ConstantExpr::from_int(
     151                         location,
     152                         0)});  /// TODO: dummy value.
     153                                /// To make it works need to change the unifier
     154
     155                auto typedResult =
     156                    ResolvExpr::findVoidExpression(untyped, context);
     157                if (result.get()) {
     158                    ast::ptr<ast::ApplicationExpr> ret =
     159                        typedResult.strict_as<ast::ApplicationExpr>();
     160                    return new ast::ApplicationExpr(*ret);
     161                }
    219162            }
    220         } else if (fname == "valueE") {
    221             if (auto valueExpr =
    222                     getPseudoFuncApplication(location, context, arg.get(), base, "values_")) {
    223                 return valueExpr;
     163        }
     164       
     165        if (fname == "valueE") {
     166            ast::Expr* toResolve =
     167                new ast::NameExpr(expr->location, "values_" + base->name);
     168            auto result = ResolvExpr::findVoidExpression(toResolve, context);
     169            if (result.get()) {
     170                auto arrAsVar = result.strict_as<ast::VariableExpr>();
     171                auto untyped = new ast::UntypedExpr(
     172                    location, new ast::NameExpr(location, "?[?]"),
     173                    {new ast::VariableExpr(*arrAsVar),
     174                     ast::ConstantExpr::from_int(
     175                         location,
     176                         0)});  /// TODO: dummy value.
     177                                /// To make it works need to change the unifier
     178
     179                auto typedResult =
     180                    ResolvExpr::findVoidExpression(untyped, context);
     181                if (result.get()) {
     182                    ast::ptr<ast::ApplicationExpr> ret =
     183                        typedResult.strict_as<ast::ApplicationExpr>();
     184                    return new ast::ApplicationExpr(*ret);
     185                }
    224186            }
    225         } else { // it is position; replace itself
    226             return std::move( arg.get() );
    227187        }
    228188    }
     
    233193
    234194void replacePseudoFunc(ast::TranslationUnit& translationUnit) {
    235     ast::Pass<WrapEnumValueExpr>::run(translationUnit);
    236195    ast::Pass<FindGenEnumArray>::run(translationUnit);
    237196    ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
Note: See TracChangeset for help on using the changeset viewer.