Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/ReplacePseudoFunc.cpp

    rbbf2cb1 r0522ebe  
    2121
    2222struct ReplaceEnumInstWithPos final : public ast::WithShortCircuiting {
     23    void previsit(const ast::ObjectDecl*) { visit_children = false; }
    2324    const ast::ObjectDecl* postvisit(const ast::ObjectDecl* decl) {
    2425        auto enumInst = decl->type.strict_as<ast::EnumInstType>();
     
    8384    }
    8485
    85     if (fname == "labelE" || fname == "valueE" || fname == "posE" ||
    86         fname == "pred" || fname == "succ") {
     86    if (fname == "labelE" || fname == "valueE" || fname == "posE") {
    8787        visit_children = false;
    8888    }
     
    226226}
    227227
    228 ast::ApplicationExpr const* resolveAttributeFunctions(
     228ast::ApplicationExpr const* getPseudoFuncApplication(
    229229    const CodeLocation location, ResolvExpr::ResolveContext context,
    230230    const ast::VariableExpr* arg, const ast::EnumDecl* base,
     
    241241        auto rep = argAsDecl->accept(replacer);
    242242        auto mutatedArg = ast::mutate_field(arg, &ast::VariableExpr::var, rep);
    243         mutatedArg = ast::mutate_field(mutatedArg, &ast::VariableExpr::result,
    244                                        mutatedArg->var->get_type());
    245243        auto untyped =
    246244            new ast::UntypedExpr(location, new ast::NameExpr(location, "?[?]"),
     
    292290                                                              referredName);
    293291                    else {
    294                         return resolveAttributeFunctions(
     292                        return getPseudoFuncApplication(
    295293                            location, context, arg.get(), base, "values_");
    296294                    }
     
    299297
    300298            if (fname == "labelE") {
    301                 if (auto labelExpr = resolveAttributeFunctions(
     299                if (auto labelExpr = getPseudoFuncApplication(
    302300                        location, context, arg.get(), base, "labels_")) {
    303301                    return labelExpr;
    304302                }
    305303            } else if (fname == "valueE") {
    306                 if (auto valueExpr = resolveAttributeFunctions(
     304                if (auto valueExpr = getPseudoFuncApplication(
    307305                        location, context, arg.get(), base, "values_")) {
    308306                    return valueExpr;
     
    316314            ResolvExpr::ResolveContext context{symtab, transUnit().global};
    317315            if (fname == "labelE") {
    318                 if (auto labelExpr = resolveAttributeFunctions(
     316                if (auto labelExpr = getPseudoFuncApplication(
    319317                        location, context, arg.get(), base, "labels_")) {
    320318                    return labelExpr;
    321319                }
    322320            } else if (fname == "valueE") {
    323                 if (auto valueExpr = resolveAttributeFunctions(
     321                if (auto valueExpr = getPseudoFuncApplication(
    324322                        location, context, arg.get(), base, "values_")) {
    325323                    return valueExpr;
     
    347345    const ast::Expr* postvisit(const ast::ApplicationExpr* expr) {
    348346        auto fname = ast::getFunctionName(expr);
    349         if (fname == "?[?]") {
    350             if (expr->args.size() != 2) return expr;
    351 
    352             auto arg1AsVar =
    353                 reduceCastExpr(expr->args.front()).as<ast::VariableExpr>();
    354             auto arg2AsVar =
    355                 reduceCastExpr(expr->args.back()).as<ast::VariableExpr>();
    356 
    357             if (!arg1AsVar || !arg2AsVar) return expr;
    358 
    359             auto arg1AsDecl = arg1AsVar->var.as<ast::ObjectDecl>();
    360             auto arg2AsDecl = arg2AsVar->var.as<ast::ObjectDecl>();
    361 
    362             if (!arg1AsDecl || !arg2AsDecl) return expr;
    363             auto arrInst = arg1AsDecl->type.as<ast::ArrayType>();
    364             auto pointerInst = arg1AsDecl->type.as<ast::PointerType>();
    365             if (!arrInst && !pointerInst) {
    366                 return expr;
    367             }
    368             auto enumInst = arg2AsDecl->type.as<ast::EnumInstType>();
    369             if (!enumInst) return expr;
    370 
    371             const std::string arrName = arg1AsDecl->name;
    372             if (arrName != getValueArrayName(enumInst->base->name)) return expr;
    373             ast::Pass<ReplaceEnumInstWithPos> replacer;
    374             auto rep = arg2AsDecl->accept(replacer);
    375             if (!rep) return expr;
    376             auto mutObj =
    377                 ast::mutate_field(arg2AsVar, &ast::VariableExpr::var, rep);
    378             mutObj = ast::mutate_field(mutObj, &ast::VariableExpr::result,
    379                                        mutObj->var->get_type());
    380             auto mut = ast::mutate_field_index(
    381                 expr, &ast::ApplicationExpr::args, 1, mutObj);
    382             return mut;
    383         }
    384         // else if (fname == "succ" || fname == "pred") {
    385         //     if (expr->args.size() != 1) return expr;
    386         //     auto argExpr = expr->args.front();
    387         //     auto argAsVar = reduceCastExpr(argExpr).as<ast::VariableExpr>();
    388 
    389         //     if (auto argAsDecl = argAsVar->var.as<ast::ObjectDecl>()) {
    390         //         if (auto enumInst = argAsDecl->type.as<ast::EnumInstType>())
    391         //         {
    392         //             auto enumPos = new ast::EnumPosType(enumInst);
    393         //             auto castExpr =
    394         //                 new ast::CastExpr(argExpr->location, argExpr,
    395         //                 enumPos);
    396         //             auto mut = ast::mutate_field_index(
    397         //                 expr, &ast::ApplicationExpr::args, 0, castExpr);
    398         //             return mut;
    399         //         } else if (auto enumPos =
    400         //                        argAsDecl->type.as<ast::EnumPosType>()) {
    401         //             //     std::cout << "pos" << std::endl;
    402         //             return expr;
    403         //         }
    404         //     }
    405         // }
    406         return expr;
    407     }
    408 };
    409 
    410 struct ReplaceSuccAndPred final : public ast::WithSymbolTable,
    411                                   public ast::WithConstTranslationUnit {
    412     const ast::Expr* postvisit(const ast::ApplicationExpr* expr) {
    413         auto fname = ast::getFunctionName(expr);
    414         if (fname == "succ" || fname == "pred") {
    415             const CodeLocation& location = expr->location;
    416             if (expr->args.size() != 1) return expr;
    417 
    418             // if (auto argAsVar = reduceCastExpr(expr->args.front())
    419             //                         .as<ast::VariableExpr>()) {
    420             //     if (auto argAsDecl = argAsVar->var.as<ast::ObjectDecl>()) {
    421             //         auto enumPos = argAsDecl->type.as<ast::EnumPosType>();
    422             //         if (!enumPos) return expr;
    423             //         // ast::Pass<ReplaceEnumInstWithPos> replacer;
    424             //         // auto posObj = argAsDecl->accept(replacer);
    425             //         // if (!posObj) return expr;
    426 
    427             //         // auto newParam = new ast::VariableExpr( location,
    428             //         posObj
    429             //         // );
    430 
    431             //         auto untyped = new ast::UntypedExpr(
    432             //             location,
    433             //             new ast::NameExpr(location, fname == "succ"
    434             //                                             ? "_successor_"
    435             //                                             : "_predessor_"),
    436             //             {argAsVar});
    437 
    438             //         ResolvExpr::ResolveContext context{symtab,
    439             //                                            transUnit().global};
    440 
    441             //         auto typedResult =
    442             //             ResolvExpr::findVoidExpression(untyped, context);
    443 
    444             //         ast::ptr<ast::ApplicationExpr> ret =
    445             //             typedResult.strict_as<ast::ApplicationExpr>();
    446 
    447             //         return ast::deepCopy(ret);
    448             //     }
    449             // }
    450             auto param = expr->args.front();
    451             if (auto argAsVar = reduceCastExpr(param).as<ast::VariableExpr>()) {
    452                 if (auto argAsDecl = argAsVar->var.as<ast::ObjectDecl>()) {
    453                     if (auto enumInst =
    454                             argAsDecl->type.as<ast::EnumInstType>()) {
    455                         auto castTo = new ast::EnumPosType(enumInst);
    456                         auto castExpr =
    457                             new ast::CastExpr(param->location, param, castTo);
    458 
    459                         auto untyped = new ast::UntypedExpr(
    460                             expr->location,
    461                             new ast::NameExpr(location, fname == "succ"
    462                                                             ? "_successor_"
    463                                                             : "_predessor_"),
    464                             {castExpr});
    465                         ResolvExpr::ResolveContext context{symtab,
    466                                                            transUnit().global};
    467                         auto typedResult =
    468                             ResolvExpr::findVoidExpression(untyped, context);
    469                         ast::ptr<ast::ApplicationExpr> ret =
    470                             typedResult.strict_as<ast::ApplicationExpr>();
    471                         return ast::deepCopy(ret);
    472                     } else if (auto posType =
    473                                    argAsDecl->type.as<ast::EnumPosType>()) {
    474                         // Very nasty fix. Must be revisit
    475                         if (auto paramAsVar = param.as<ast::VariableExpr>()) {
    476                             if (paramAsVar->result.as<ast::EnumInstType>()) {
    477                                 auto paramToUse = ast::mutate_field(
    478                                     paramAsVar, &ast::VariableExpr::result,
    479                                     posType);
    480                                 auto untyped = new ast::UntypedExpr(
    481                                     expr->location,
    482                                     new ast::NameExpr(location,
    483                                                       fname == "succ"
    484                                                           ? "_successor_"
    485                                                           : "_predessor_"),
    486                                     {paramToUse});
    487                                 ResolvExpr::ResolveContext context{
    488                                     symtab, transUnit().global};
    489                                 auto typedResult =
    490                                     ResolvExpr::findVoidExpression(untyped,
    491                                                                    context);
    492                                 ast::ptr<ast::ApplicationExpr> ret =
    493                                     typedResult
    494                                         .strict_as<ast::ApplicationExpr>();
    495                                 return ast::deepCopy(ret);
    496                             }
    497                         }
    498                         auto untyped = new ast::UntypedExpr(
    499                             expr->location,
    500                             new ast::NameExpr(location, fname == "succ"
    501                                                             ? "_successor_"
    502                                                             : "_predessor_"),
    503                             {param});
    504                         ResolvExpr::ResolveContext context{symtab,
    505                                                            transUnit().global};
    506                         auto typedResult =
    507                             ResolvExpr::findVoidExpression(untyped, context);
    508                         ast::ptr<ast::ApplicationExpr> ret =
    509                             typedResult.strict_as<ast::ApplicationExpr>();
    510                         return ast::deepCopy(ret);
    511                     }
    512                 }
    513             }
    514         }
    515         return expr;
     347        if (fname != "?[?]") return expr;
     348        if (expr->args.size() != 2) return expr;
     349
     350        auto arg1AsVar =
     351            reduceCastExpr(expr->args.front()).as<ast::VariableExpr>();
     352        auto arg2AsVar =
     353            reduceCastExpr(expr->args.back()).as<ast::VariableExpr>();
     354
     355        if (!arg1AsVar || !arg2AsVar) return expr;
     356
     357        auto arg1Asecl = arg1AsVar->var.as<ast::ObjectDecl>();
     358        auto arg2Asecl = arg2AsVar->var.as<ast::ObjectDecl>();
     359
     360        if (!arg1Asecl || !arg2Asecl) return expr;
     361        auto arrInst = arg1Asecl->type.as<ast::ArrayType>();
     362        auto pointerInst = arg1Asecl->type.as<ast::PointerType>();
     363        if (!arrInst && !pointerInst) {
     364            return expr;
     365        }
     366        auto enumInst = arg2Asecl->type.as<ast::EnumInstType>();
     367        if (!enumInst) return expr;
     368
     369        const std::string arrName = arg1Asecl->name;
     370        if (arrName != getValueArrayName(enumInst->base->name)) return expr;
     371        ast::Pass<ReplaceEnumInstWithPos> replacer;
     372        auto rep = arg2Asecl->accept(replacer);
     373        if (!rep) return expr;
     374        auto mutObj =
     375            ast::mutate_field(arg2AsVar, &ast::VariableExpr::var, rep);
     376        auto mut = ast::mutate_field_index(expr, &ast::ApplicationExpr::args, 1,
     377                                           mutObj);
     378        return mut;
    516379    }
    517380};
     
    522385    ast::Pass<WrapEnumValueExpr>::run(translationUnit);
    523386    ast::Pass<FindGenEnumArray>::run(translationUnit);
    524 
    525387    ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
    526388    ast::Pass<ReplacePseudoFuncCore>::run(translationUnit);
    527389    ast::Pass<ReplaceEnumInst>::run(translationUnit);
    528 
    529     ast::Pass<ReplaceSuccAndPred>::run(translationUnit);
    530390}
    531391}  // namespace Validate
Note: See TracChangeset for help on using the changeset viewer.