Changeset bbf2cb1


Ignore:
Timestamp:
Mar 6, 2024, 6:06:30 AM (3 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
f6e8c67
Parents:
00eaeb8
Message:

Add the Working support to succ() and pred() pseudo function to Enum

Location:
src
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CommonType.cc

    r00eaeb8 rbbf2cb1  
    672672
    673673        void postvisit( const ast::EnumInstType * enumInst ) {
    674                 if (!dynamic_cast<const ast::EnumInstType *>(type2))
     674                // if ( dynamic_cast<const ast::EnumPosType *>(enumInst) ) {
     675                //      result = enumInst;
     676                // } else
     677                if (!dynamic_cast<const ast::EnumInstType *>(type2)) {
    675678                        result = commonType( type2, enumInst, tenv, need, have, open, widen);
    676679                }
     680        }
     681
     682        void postvisit( const ast::EnumPosType * enumPos ) {
     683                if ( auto type2AsPos = dynamic_cast<const ast::EnumPosType *>(type2) ) {
     684                        // result = commonType( type2AsPos->instance, enumPos->instance, tenv, need, have, open, widen );
     685                        result = enumPos;
     686                } else if (  auto typeAsBasic = dynamic_cast<const ast::BasicType *>(type2) ) {
     687                        result = type2;
     688                }
     689        }
    677690
    678691        void postvisit( const ast::TraitInstType * ) {}
  • src/ResolvExpr/ConversionCost.cc

    r00eaeb8 rbbf2cb1  
    366366}
    367367
    368 void ConversionCost::postvisit( const ast::EnumInstType * ) {
     368void ConversionCost::postvisit( const ast::EnumInstType * inst ) {
    369369        static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
    370370        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     
    374374}
    375375
    376 void ConversionCost::postvisit( const ast::EnumPosType * ) {
    377         if ( dynamic_cast<const ast::EnumPosType *>( dst ) ) {
    378                 // Tempoarary
    379                 cost = Cost::zero;
    380         } else {
     376void ConversionCost::postvisit( const ast::EnumPosType * src ) {
     377        if ( auto dstBase = dynamic_cast<const ast::EnumPosType *>( dst ) ) {
     378                // cost = costCalc( src->instance, dstBase->instance, srcIsLvalue, symtab, env );
     379                // if ( cost < Cost::unsafe ) cost.incSafe();
     380                cost = Cost::zero;
     381        }
     382        // if ( auto dstBase = dynamic_cast<const ast::EnumInstType *>( dst ) ) {
     383        //      cost = costCalc( src->instance, dstBase, srcIsLvalue, symtab, env );
     384        //      if ( cost < Cost::unsafe ) cost.incSafe();
     385        // }
     386        else {
    381387                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
    382388                cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
  • src/ResolvExpr/Unify.cc

    r00eaeb8 rbbf2cb1  
    518518
    519519                void postvisit( const ast::EnumPosType * ) {
    520                         // Does nothing for now. Handled in ReplacePseudoFunc
    521                         // Might move here in the future
     520                        // Lazy approach for now
     521                        auto otherPos = dynamic_cast< const ast::EnumPosType *>(type2);
     522                        if (otherPos) this->result = otherPos;
    522523                }
    523524
  • src/Validate/Autogen.cpp

    r00eaeb8 rbbf2cb1  
    212212        ast::FunctionDecl * genPredPosProto() const;
    213213
    214         void genSuccFunc(ast::FunctionDecl *);
     214        ast::FunctionDecl * genSuccPredFunc( bool succ );
     215        // ast::FunctionDecl * genPredFunc();
    215216};
    216217
     
    811812
    812813ast::FunctionDecl * EnumFuncGenerator::genSuccPosProto() const {
    813         return genProto( "succ",
     814        return genProto( "_successor_",
    814815                { new ast::ObjectDecl( getLocation(), "_i",
    815816                        new ast::EnumPosType( new ast::EnumInstType( decl ) ) )},
     
    821822
    822823ast::FunctionDecl * EnumFuncGenerator::genPredPosProto() const {
    823         return genProto( "pred",
     824        return genProto( "_predessor_",
    824825                { new ast::ObjectDecl( getLocation(), "_i",
    825826                        new ast::EnumPosType( new ast::EnumInstType( decl ) ) )},
     
    830831}
    831832
    832 void EnumFuncGenerator::genSuccFunc(ast::FunctionDecl * succDecl) {
     833ast::FunctionDecl * EnumFuncGenerator::genSuccPredFunc( bool succ ) {
     834        ast::FunctionDecl * decl = succ? genSuccPosProto(): genPredPosProto();
     835        produceForwardDecl( decl );
     836
    833837        const CodeLocation& location = getLocation();
    834838
    835         auto & params = succDecl->params;
     839        auto & params = decl->params;
    836840        assert( params.size() == 1 );
    837841        auto param = params.front().strict_as<ast::ObjectDecl>();
    838 
    839         // auto & returns = succDecl->returns;
    840         // assert( returns.size() == 1 );
    841         // auto oldRet = returns.front().strict_as<ast::ObjectDecl>();
    842 
    843         // auto param = new ast::ObjectDecl( getLocation(), "_i",
    844         //              new ast::EnumPosType( new ast::EnumInstType( decl ) ) );
    845842
    846843        auto newReturn = new ast::ObjectDecl( location, "_returns",
     
    849846
    850847        ast::UntypedExpr * addOneExpr = new ast::UntypedExpr( location,
    851                 new ast::NameExpr( location, "?+?" )
     848                new ast::NameExpr( location, succ? "?+?": "?-?" )
    852849        );
    853850        addOneExpr->args.push_back(
     
    871868        );
    872869
    873         succDecl->stmts = new ast::CompoundStmt( location,
     870        decl->stmts = new ast::CompoundStmt( location,
    874871                {
    875872                        new ast::DeclStmt( location, newReturn ),
     
    878875                                new ast::VariableExpr( location, newReturn ))
    879876                } );
     877       
     878        return decl;
    880879}
    881880
     
    886885                        &EnumFuncGenerator::genValueProto, &EnumFuncGenerator::genSuccProto,
    887886                        &EnumFuncGenerator::genPredProto
     887                        // ,&EnumFuncGenerator::genSuccPosProto,
     888                        // &EnumFuncGenerator::genPredPosProto
    888889                };
    889890                for ( auto & generator : attrProtos ) {
     
    895896void EnumFuncGenerator::genPosFunctions() {
    896897        if ( decl->base ) {
    897                 ast::FunctionDecl * decl = genSuccPosProto();
    898                 produceForwardDecl( decl );
    899                 genSuccFunc (decl );
    900                 produceDecl( decl );
     898                ast::FunctionDecl * succ = genSuccPredFunc( true );
     899                ast::FunctionDecl * pred = genSuccPredFunc( false );
     900                produceDecl( succ );
     901                produceDecl( pred );
    901902        }
    902903
  • src/Validate/ReplacePseudoFunc.cpp

    r00eaeb8 rbbf2cb1  
    2121
    2222struct ReplaceEnumInstWithPos final : public ast::WithShortCircuiting {
    23     void previsit(const ast::ObjectDecl*) { visit_children = false; }
    2423    const ast::ObjectDecl* postvisit(const ast::ObjectDecl* decl) {
    2524        auto enumInst = decl->type.strict_as<ast::EnumInstType>();
     
    8483    }
    8584
    86     if (fname == "labelE" || fname == "valueE" || fname == "posE") {
     85    if (fname == "labelE" || fname == "valueE" || fname == "posE" ||
     86        fname == "pred" || fname == "succ") {
    8787        visit_children = false;
    8888    }
     
    226226}
    227227
    228 ast::ApplicationExpr const* getPseudoFuncApplication(
     228ast::ApplicationExpr const* resolveAttributeFunctions(
    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());
    243245        auto untyped =
    244246            new ast::UntypedExpr(location, new ast::NameExpr(location, "?[?]"),
     
    290292                                                              referredName);
    291293                    else {
    292                         return getPseudoFuncApplication(
     294                        return resolveAttributeFunctions(
    293295                            location, context, arg.get(), base, "values_");
    294296                    }
     
    297299
    298300            if (fname == "labelE") {
    299                 if (auto labelExpr = getPseudoFuncApplication(
     301                if (auto labelExpr = resolveAttributeFunctions(
    300302                        location, context, arg.get(), base, "labels_")) {
    301303                    return labelExpr;
    302304                }
    303305            } else if (fname == "valueE") {
    304                 if (auto valueExpr = getPseudoFuncApplication(
     306                if (auto valueExpr = resolveAttributeFunctions(
    305307                        location, context, arg.get(), base, "values_")) {
    306308                    return valueExpr;
     
    314316            ResolvExpr::ResolveContext context{symtab, transUnit().global};
    315317            if (fname == "labelE") {
    316                 if (auto labelExpr = getPseudoFuncApplication(
     318                if (auto labelExpr = resolveAttributeFunctions(
    317319                        location, context, arg.get(), base, "labels_")) {
    318320                    return labelExpr;
    319321                }
    320322            } else if (fname == "valueE") {
    321                 if (auto valueExpr = getPseudoFuncApplication(
     323                if (auto valueExpr = resolveAttributeFunctions(
    322324                        location, context, arg.get(), base, "values_")) {
    323325                    return valueExpr;
     
    345347    const ast::Expr* postvisit(const ast::ApplicationExpr* expr) {
    346348        auto fname = ast::getFunctionName(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;
     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
     410struct 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;
    379516    }
    380517};
     
    385522    ast::Pass<WrapEnumValueExpr>::run(translationUnit);
    386523    ast::Pass<FindGenEnumArray>::run(translationUnit);
     524
    387525    ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
    388526    ast::Pass<ReplacePseudoFuncCore>::run(translationUnit);
    389527    ast::Pass<ReplaceEnumInst>::run(translationUnit);
     528
     529    ast::Pass<ReplaceSuccAndPred>::run(translationUnit);
    390530}
    391531}  // namespace Validate
Note: See TracChangeset for help on using the changeset viewer.