Changes in / [32490deb:e71b09a]


Ignore:
Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Print.cpp

    r32490deb re71b09a  
    175175                }
    176176
     177                os << " " << (node->body ? "with" : "without") << " body";
     178
     179                if ( ! node->params.empty() ) {
     180                        os << endl << indent << "... with parameters" << endl;
     181                        ++indent;
     182                        printAll( node->params );
     183                        --indent;
     184                }
     185
     186                if ( ! short_mode && ! node->members.empty() ) {
     187                        os << endl << indent << "... with members" << endl;
     188                        ++indent;
     189                        printAll( node->members );
     190                        --indent;
     191                }
     192
     193                if ( ! short_mode && ! node->attributes.empty() ) {
     194                        os << endl << indent << "... with attributes" << endl;
     195                        ++indent;
     196                        printAll( node->attributes );
     197                        --indent;
     198                }
     199
    177200                auto ptrToEnum = dynamic_cast<const ast::EnumDecl *>(node);
    178201                if ( ! short_mode && ptrToEnum && ptrToEnum->base ) {
    179                         os << endl << indent << "... with base type" << endl;
    180                         ++indent;
    181                         os << indent;
     202                        os << endl << indent << ".. with (enum) base" << endl;
     203                        ++indent;
    182204                        ptrToEnum->base->accept( *this );
    183205                        --indent;
    184206                }
    185 
    186                 os << " " << (node->body ? "with" : "without") << " body";
    187 
    188                 if ( ! node->params.empty() ) {
    189                         os << endl << indent << "... with parameters" << endl;
    190                         ++indent;
    191                         printAll( node->params );
    192                         --indent;
    193                 }
    194 
    195                 if ( ! short_mode && ! node->members.empty() ) {
    196                         os << endl << indent << "... with members" << endl;
    197                         ++indent;
    198                         printAll( node->members );
    199                         --indent;
    200                 }
    201 
    202                 if ( ! short_mode && ! node->attributes.empty() ) {
    203                         os << endl << indent << "... with attributes" << endl;
    204                         ++indent;
    205                         printAll( node->attributes );
    206                         --indent;
    207                 }
    208 
    209 
    210207
    211208                os << endl;
  • src/CodeGen/CodeGenerator.cpp

    r32490deb re71b09a  
    331331        extension( decl );
    332332        auto members = decl->members;
    333         // if ( decl->base && !members.empty() ) {
    334         //      long long curVal = 0;
    335         //      for ( auto member : members ) {
    336         //              auto obj = member.strict_as<ast::ObjectDecl>();
    337         //              output << "static ";
    338         //              output << genType( decl->base, mangleName( obj ), options );
    339         //              genEnumInitializer( visitor, decl->base, output, obj->init, &curVal, options );
    340         //              output << ";" << endl;
    341         //      }
    342         // } else {
     333        if ( decl->base && !members.empty() ) {
     334                long long curVal = 0;
     335                for ( auto member : members ) {
     336                        auto obj = member.strict_as<ast::ObjectDecl>();
     337                        output << "static ";
     338                        output << genType( decl->base, mangleName( obj ), options );
     339                        genEnumInitializer( visitor, decl->base, output, obj->init, &curVal, options );
     340                        output << ";" << endl;
     341                }
     342        } else {
    343343                output << "enum ";
    344344                genAttributes( decl->attributes );
     
    353353                                auto obj = member.strict_as<ast::ObjectDecl>();
    354354                                output << indent << mangleName( obj );
    355                                 if ( !decl->base && obj->init ) {
     355                                if ( obj->init ) {
    356356                                        output << " = ";
    357357                                        obj->init->accept( *visitor );
     
    363363                        output << indent << "}";
    364364                }
    365         // }
     365        }
    366366}
    367367
  • src/CodeGen/GenType.cc

    r32490deb re71b09a  
    228228
    229229void GenType::postvisit( ast::EnumInstType const * type ) {
    230         // if ( type->base && type->base->base ) {
    231         //      result = genType( type->base->base, result, options );
    232         // } else {
     230        if ( type->base && type->base->base ) {
     231                result = genType( type->base->base, result, options );
     232        } else {
    233233                result = type->name + " " + result;
    234234                if ( options.genC ) {
    235235                        result = "enum " + result;
    236236                }
    237         // }
     237        }
    238238        handleQualifiers( type );
    239239}
  • src/GenPoly/Lvalue.cpp

    r32490deb re71b09a  
    133133                        return func->linkage == ast::Linkage::Intrinsic
    134134                                && lvalueFunctions.count( func->name );
    135                 }
    136         }
    137         return false;
    138 }
    139 
    140 bool isGeneratedInstrinct( ast::Expr const * expr ) {
    141         if ( auto app = dynamic_cast<ast::ApplicationExpr const *>( expr ) ) {
    142                 if ( app->args.size() == 2 && ast::getFunction( app )->name == "?[?]" ) {
    143                         auto param_1 = dynamic_cast<ast::VariableExpr const *>(app->args.front().get());
    144                         if ( param_1 ) {
    145                                 auto param_1_as_obj = param_1->var.as<ast::ObjectDecl>();
    146                                 return ( param_1_as_obj->name.find( "values_") != std::string::npos
    147                                         ||  param_1_as_obj->name.find( "labels_" ) != std::string::npos );
    148                         }
    149135                }
    150136        }
     
    175161ast::Expr const * FixIntrinsicResults::postvisit(
    176162                ast::ApplicationExpr const * expr ) {
    177 
    178         if ( skip == SkipInProgress || !isIntrinsicReference( expr ) || isGeneratedInstrinct( expr ) ) {
     163        if ( skip == SkipInProgress || !isIntrinsicReference( expr ) ) {
    179164                return expr;
    180165        }
  • src/ResolvExpr/CandidateFinder.cpp

    r32490deb re71b09a  
    891891                } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) {
    892892                        addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" );
    893                 } else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
    894                         // The Attribute Arrays are not yet generated, need to proxy them
    895                         // as attribute function call
    896                         const CodeLocation & location = cand->expr->location;
    897                         if ( enumInst->base && enumInst->base->base ) {
    898                                 auto valueName = new ast::NameExpr(location, "valueE");
    899                                 auto untypedValueCall = new ast::UntypedExpr(
    900                                         location, valueName, { aggrExpr } );
    901                                 auto result = ResolvExpr::findVoidExpression( untypedValueCall, context );
    902                                 assert( result.get() );
    903                                 CandidateRef newCand = std::make_shared<Candidate>(
    904                                         *cand, result, Cost::safe );
    905                                 candidates.emplace_back( std::move( newCand ) );
    906                         }
    907893                }
    908894        }
     
    975961
    976962                                        if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer);                                             
     963                                        // else if (const ast::EnumInstType * enumInst = argType.as<ast::EnumInstType>()) {
     964                                        //      const ast::EnumDecl * enumDecl = enumInst->base; // Here
     965                                        //      if ( const ast::Type* enumType = enumDecl->base ) {
     966                                        //              // instance of enum (T) is a instance of type (T)
     967                                        //              funcFinder.otypeKeys.insert(Mangle::mangle(enumType, Mangle::NoGenericParams | Mangle::Type));
     968                                        //      } else {
     969                                        //              // instance of an untyped enum is techically int
     970                                        //              funcFinder.otypeKeys.insert(Mangle::mangle(enumDecl, Mangle::NoGenericParams | Mangle::Type));
     971                                        //      }
     972                                        // }
    977973                                        else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type));
    978974                                }
     
    14031399                // not sufficient to just pass `variableExpr` here, type might have changed since
    14041400                // creation
    1405                 if ( auto obj =  dynamic_cast<const ast::ObjectDecl *>( variableExpr->var.get() )) {
    1406                         if ( auto enumInstType = dynamic_cast<const ast::EnumInstType *>( obj->type.get() ) ) {
    1407                                 if ( enumInstType->base && enumInstType->base->base ) {
    1408                                         const CodeLocation & location = variableExpr->location;
    1409                                         auto ids = symtab.lookupId( "valueE" );
    1410                                                 for ( ast::SymbolTable::IdData & id : ids ) {
    1411                                                         if ( auto func = id.id.as<ast::FunctionDecl>() ) {
    1412                                                                 if ( func->params.size() == 1 ) {
    1413                                                                         ast::ptr<ast::DeclWithType> valueEParam = func->params.front();
    1414                                                                         auto valueEParamType = valueEParam->get_type();
    1415                                                                         ast::OpenVarSet funcOpen;
    1416                                                                         ast::AssertionSet funcNeed, funcHave;
    1417                                                                         ast::TypeEnvironment funcEnv{ tenv };
    1418                                                                         ast::ptr<ast::Type> common;
    1419                                                                         if ( unifyInexact( valueEParamType, enumInstType, funcEnv, funcNeed, funcHave, funcOpen, WidenMode{ true, true }, common ) ) {
    1420                                                                                 auto appl = new ast::ApplicationExpr( location,
    1421                                                                                         ast::VariableExpr::functionPointer( location,  func), { variableExpr } );
    1422                                                                                 // addCandidate( appl, copy( tenv ),  );
    1423                                                                                 Candidate cand {appl, copy( tenv )};
    1424                                                                                 addCandidate( cand, appl, Cost::safe );
    1425                                                                         }
    1426                                                                 }
    1427                                                         }
    1428                                                 }
    1429                                 }
    1430                        
    1431                         }
    1432                 }
    1433                 addCandidate( variableExpr, tenv );
    1434                
     1401                addCandidate(
     1402                        new ast::VariableExpr{ variableExpr->location, variableExpr->var }, tenv );
    14351403        }
    14361404
  • src/ResolvExpr/ConversionCost.cc

    r32490deb re71b09a  
    279279                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    280280        } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    281                 auto enumDecl = enumInst->base;
    282                 if ( auto baseType = enumDecl->base.get() ) {
    283                         cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
    284                         cost.incUnsafe();
     281                const ast::EnumDecl * enumDecl = enumInst->base.get();
     282                if ( enumDecl->isTyped && !enumDecl->base.get() ) {
     283                        cost = Cost::infinity;
     284                } else if ( const ast::Type * enumType = enumDecl->base.get() ) {
     285                        if ( const ast::BasicType * enumTypeAsBasic = dynamic_cast<const ast::BasicType *>(enumType) ) {
     286                                conversionCostFromBasicToBasic( basicType, enumTypeAsBasic );
     287                        } else {
     288                                cost = Cost::infinity;
     289                        }
    285290                } else {
    286291            cost = Cost::unsafe;
     
    362367
    363368void ConversionCost::postvisit( const ast::EnumInstType * enumInstType ) {
    364         //      const ast::EnumDecl * baseEnum = enumInstType->base;
    365         // if ( const ast::Type * baseType = baseEnum->base ) {
    366         //      costCalc( baseType, dst, srcIsLvalue, symtab, env );
    367         // } else {
    368         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
    369         cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    370         // }
     369        const ast::EnumDecl * baseEnum = enumInstType->base;
     370        if ( const ast::Type * baseType = baseEnum->base ) {
     371                costCalc( baseType, dst, srcIsLvalue, symtab, env );
     372        } else {
     373                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
     374                cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     375        }
    371376        if ( cost < Cost::unsafe ) {
    372377                cost.incSafe();
  • src/ResolvExpr/Unify.cc

    r32490deb re71b09a  
    7373                ast::Type * newFirst  = shallowCopy( first  );
    7474                ast::Type * newSecond = shallowCopy( second );
     75                if ( auto temp = dynamic_cast<const ast::EnumInstType *>(first) ) {
     76                        if ( !dynamic_cast< const ast::EnumInstType * >( second ) ) {
     77                                const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get());
     78                                if ( auto t = baseEnum->base.get() ) {
     79                                        newFirst = ast::shallowCopy( t );
     80                                }
     81                        }
     82                } else if ( auto temp = dynamic_cast<const ast::EnumInstType *>(second) ) {
     83                        const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get());
     84                        if ( auto t = baseEnum->base.get() ) {
     85                                newSecond = ast::shallowCopy( t );
     86                        }
     87                }
    7588
    7689                newFirst ->qualifiers = {};
  • src/Validate/Autogen.cpp

    r32490deb re71b09a  
    197197
    198198        bool shouldAutogen() const final { return true; }
    199         void genAttrFuncForward();
    200         void __attribute__ ((unused)) genDualFuncs();
    201199private:
    202200        void genFuncBody( ast::FunctionDecl * decl ) final;
    203201        void genFieldCtors() final;
    204202        const ast::Decl * getDecl() const final { return decl; }
    205 
    206         ast::ObjectDecl * dualDstParam() const;
    207 
    208         ast::FunctionDecl * genPosProto() const;
    209         ast::FunctionDecl * genLabelProto() const;
    210         ast::FunctionDecl * genValueProto() const;
    211 
    212         ast::FunctionDecl * genCopyEnumToDualProto() const;
    213         ast::FunctionDecl * genAssignEnumToDualProto() const;
    214 
    215         void genDualBody( ast::FunctionDecl * decl );
    216203};
    217204
     
    251238// --------------------------------------------------------------------------
    252239void AutogenerateRoutines::previsit( const ast::EnumDecl * enumDecl ) {
     240        // Must visit children (enum constants) to add them to the symbol table.
    253241        if ( !enumDecl->body ) return;
     242
     243        // if ( auto enumBaseType = enumDecl->base ) {
     244        //      if ( auto enumBaseTypeAsStructInst = dynamic_cast<const ast::StructInstType *>(enumBaseType.get()) ) {
     245        //              const ast::StructDecl * structDecl = enumBaseTypeAsStructInst->base.get();
     246        //              this->previsit( structDecl );
     247        //      }
     248        // }
    254249
    255250        ast::EnumInstType enumInst( enumDecl->name );
    256251        enumInst.base = enumDecl;
    257252        EnumFuncGenerator gen( enumDecl, &enumInst, functionNesting );
    258         if ( enumDecl->base ) {
    259                 gen.genAttrFuncForward();
    260                 // gen.genDualFuncs();
    261         }
    262253        gen.generateAndAppendFunctions( declsToAddAfter );
    263254}
     
    751742                 * returns to zero.
    752743                 */
    753                 auto dstExpr = new ast::VariableExpr( location, dstParam );
    754                 const ast::Expr * srcExpr;
    755                 if ( decl->base ) {
    756                         srcExpr = new ast::ApplicationExpr( location,
    757                         ast::VariableExpr::functionPointer( location, genPosProto() ),
    758                         {
    759                                 new ast::VariableExpr( location, srcParam )
    760                         }
    761                         );
    762                 } else {
    763                         srcExpr = new ast::VariableExpr( location, srcParam );
    764                 }
    765 
    766744                auto callExpr = new ast::ApplicationExpr( location,
    767745                        ast::VariableExpr::functionPointer( location, functionDecl ),
    768746                        {
    769                                 dstExpr,
    770                                 srcExpr,
     747                                new ast::VariableExpr( location, dstParam ),
     748                                new ast::VariableExpr( location, srcParam ),
    771749                        }
    772750                );
    773 
     751                // auto fname = ast::getFunctionName( callExpr );
     752                // if (fname == "posE" ) {
     753                //      std::cerr << "Found posE autogen" << std::endl;
     754                // }
    774755                functionDecl->stmts = new ast::CompoundStmt( location,
    775756                        { new ast::ExprStmt( location, callExpr ) }
     
    787768                        forwards.back().get_and_mutate() );
    788769                addUnusedAttribute( fwd->params.front() );
    789         }
    790 }
    791 
    792 ast::FunctionDecl * EnumFuncGenerator::genPosProto() const {
    793         return genProto( "posE",
    794                 { new ast::ObjectDecl( getLocation(), "_i",
    795                 new ast::EnumInstType( decl ) )},
    796                 { new ast::ObjectDecl( getLocation(), "_ret",
    797                 new ast::BasicType{ ast::BasicType::UnsignedInt } )} );
    798 }
    799 
    800 ast::FunctionDecl * EnumFuncGenerator::genLabelProto() const {
    801         return genProto( "labelE",
    802                 { new ast::ObjectDecl( getLocation(), "_i",
    803                 new ast::EnumInstType( decl ) ) },
    804                 { new ast::ObjectDecl( getLocation(), "_ret",
    805                 new ast::PointerType( new ast::BasicType{ ast::BasicType::Char } ) ) } );
    806 }
    807 
    808 ast::FunctionDecl * EnumFuncGenerator::genValueProto() const {
    809         return genProto( "valueE",
    810                 { new ast::ObjectDecl( getLocation(), "_i", new ast::EnumInstType( decl ) )},
    811                 { new ast::ObjectDecl( getLocation(), "_ret", ast::deepCopy( decl->base ) ) } );
    812 }
    813 
    814 void EnumFuncGenerator::genAttrFuncForward() { 
    815         if ( decl->base ) {
    816                 ast::FunctionDecl *(EnumFuncGenerator::*attrProtos[3])() const = {
    817                         &EnumFuncGenerator::genPosProto, &EnumFuncGenerator::genLabelProto,
    818                         &EnumFuncGenerator::genValueProto };
    819                 for ( auto & generator : attrProtos ) {
    820                         produceForwardDecl( (this->*generator)() );
    821                 }
    822         }
    823 }
    824 
    825 ast::ObjectDecl * EnumFuncGenerator::dualDstParam() const {
    826         auto base = decl->base;
    827         assert( base );
    828         return new ast::ObjectDecl( getLocation(), "_dst",
    829                 new ast::ReferenceType( ast::deepCopy( base ) ) );
    830 }
    831 
    832 // void ?{}(T & _dst, enum E _src )
    833 ast::FunctionDecl * EnumFuncGenerator::genCopyEnumToDualProto() const {
    834         return genProto( "?{}", { dualDstParam(), srcParam() }, {} );
    835 }
    836 
    837 // T ?{}(T & _dst, enum E _src )
    838 ast::FunctionDecl * EnumFuncGenerator::genAssignEnumToDualProto() const {
    839         auto retval = dualDstParam();
    840         retval->name = "_ret";
    841         return genProto( "?=?", { dualDstParam(), srcParam() }, { retval });
    842 }
    843 
    844 void EnumFuncGenerator::genDualBody( ast::FunctionDecl * functionDecl ) {
    845         assert( decl->base );
    846         const CodeLocation& location = functionDecl->location;
    847         auto & params = functionDecl->params;
    848        
    849         assert( 2 == params.size() );
    850         auto dstParam = params.front().strict_as<ast::ObjectDecl>();
    851         auto srcParam = params.back().strict_as<ast::ObjectDecl>();
    852 
    853         auto dstExpr = new ast::VariableExpr( location, dstParam );
    854 
    855         auto srcExpr = new ast::ApplicationExpr( location,
    856                 ast::VariableExpr::functionPointer( location, genValueProto() ),
    857                 {
    858                         new ast::VariableExpr( location, srcParam )
    859                 });
    860         auto callExpr = new ast::ApplicationExpr( location,
    861                 ast::VariableExpr::functionPointer( location, functionDecl ),
    862                 { dstExpr, srcExpr } );
    863         functionDecl->stmts = new ast::CompoundStmt( location,
    864                 { new ast::ExprStmt( location, callExpr)} );
    865 }
    866 
    867 void EnumFuncGenerator::genDualFuncs() {
    868         assert( decl->base );
    869         ast::FunctionDecl *(EnumFuncGenerator::*dualProtos[2])() const = {
    870                         &EnumFuncGenerator::genCopyEnumToDualProto,
    871                         &EnumFuncGenerator::genAssignEnumToDualProto };
    872         for ( auto & generator : dualProtos ) {
    873                 ast::FunctionDecl * decl = (this->*generator)();
    874                 produceForwardDecl( decl );
    875                 genDualBody( decl );
    876                 if ( CodeGen::isAssignment( decl->name ) ) {
    877                         appendReturnThis( decl );
    878                 }
    879                 produceDecl( decl );
    880770        }
    881771}
  • src/Validate/ReplacePseudoFunc.cpp

    r32490deb re71b09a  
    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.