Changes in / [a4da45e:022bce0]


Ignore:
Files:
1 deleted
17 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Fwd.hpp

    ra4da45e r022bce0  
    133133class OneType;
    134134class GlobalScopeType;
    135 class EnumPosType;
    136135
    137136class Designation;
  • src/AST/Pass.hpp

    ra4da45e r022bce0  
    222222        const ast::Type *             visit( const ast::UnionInstType        * ) override final;
    223223        const ast::Type *             visit( const ast::EnumInstType         * ) override final;
    224         const ast::Type *             visit( const ast::EnumPosType          * ) override final;
    225224        const ast::Type *             visit( const ast::TraitInstType        * ) override final;
    226225        const ast::Type *             visit( const ast::TypeInstType         * ) override final;
  • src/AST/Pass.impl.hpp

    ra4da45e r022bce0  
    19861986
    19871987//--------------------------------------------------------------------------
    1988 // EnumPosType
    1989 template< typename core_t >
    1990 const ast::Type * ast::Pass< core_t >::visit( const ast::EnumPosType * node ) {
    1991         VISIT_START( node );
    1992 
    1993         VISIT_END( Type, node );
    1994 }
    1995 
    1996 //--------------------------------------------------------------------------
    19971988// TraitInstType
    19981989template< typename core_t >
  • src/AST/Print.cpp

    ra4da45e r022bce0  
    15761576        }
    15771577
    1578         virtual const ast::Type * visit( const ast::EnumPosType * node ) override final {
    1579                 preprint( node );
    1580                 os << "enum pos with ";
    1581                 (*(node->instance)).accept( *this );
    1582                 return node;
    1583         }
    1584 
    15851578        virtual const ast::Type * visit( const ast::TraitInstType * node ) override final {
    15861579                preprint( node );
  • src/AST/Type.hpp

    ra4da45e r022bce0  
    362362using EnumInstType = SueInstType<EnumDecl>;
    363363
    364 class EnumPosType final : public Type {
    365 public:
    366         readonly<EnumInstType> instance;
    367         const Type * accept( Visitor & v ) const override { return v.visit( this ); }
    368         EnumPosType( const EnumInstType * instance ): instance(instance) {}
    369        
    370 private:
    371         EnumPosType * clone() const override { return new EnumPosType{ *this }; }
    372         MUTATE_FRIEND
    373 };
    374 
    375364/// An instance of a trait type.
    376365class TraitInstType final : public BaseInstType {
  • src/AST/Visitor.hpp

    ra4da45e r022bce0  
    119119    virtual const ast::Type *             visit( const ast::OneType              * ) = 0;
    120120    virtual const ast::Type *             visit( const ast::GlobalScopeType      * ) = 0;
    121     virtual const ast::Type *             visit( const ast::EnumPosType          * ) = 0;
    122121    virtual const ast::Designation *      visit( const ast::Designation          * ) = 0;
    123122    virtual const ast::Init *             visit( const ast::SingleInit           * ) = 0;
  • src/CodeGen/GenType.cc

    ra4da45e r022bce0  
    4646        void postvisit( ast::UnionInstType const * type );
    4747        void postvisit( ast::EnumInstType const * type );
    48         void postvisit( ast::EnumPosType const * type );
    4948        void postvisit( ast::TypeInstType const * type );
    5049        void postvisit( ast::TupleType const * type );
     
    240239}
    241240
    242 void GenType::postvisit( ast::EnumPosType const * type ) {
    243         postvisit( type->instance );
    244 }
    245 
    246241void GenType::postvisit( ast::TypeInstType const * type ) {
    247242        assertf( !options.genC, "TypeInstType should not reach code generation." );
  • src/Common/CodeLocationTools.cpp

    ra4da45e r022bce0  
    188188    macro(UnionInstType, Type) \
    189189    macro(EnumInstType, Type) \
    190     macro(EnumPosType, Type) \
    191190    macro(TraitInstType, Type) \
    192191    macro(TypeInstType, Type) \
  • src/Parser/parser.yy

    ra4da45e r022bce0  
    30223022        | assertion_list
    30233023                { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    3024         | ENUM '(' identifier_or_type_name ')' identifier_or_type_name new_type_class type_initializer_opt assertion_list_opt
    3025                 {       
    3026                         typedefTable.addToScope( *$3, TYPEDIMname, "type_parameter 4" );
    3027                         typedefTable.addToScope( *$5, TYPEDIMname, "type_parameter 5" );
    3028                         $$ = DeclarationNode::newTypeParam( $6, $5 )->addTypeInitializer( $7 )->addAssertions( $8 );
    3029                 }
    30303024        ;
    30313025
  • src/ResolvExpr/CandidateFinder.cpp

    ra4da45e r022bce0  
    891891                } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) {
    892892                        addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" );
    893                 }
    894                 else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {
    895                         if (enumInst->base && enumInst->base->base) {
    896             const CodeLocation &location = cand->expr->location;
    897 
    898             CandidateFinder funcFinder(context, tenv);
    899             auto nameExpr = new ast::NameExpr(location, "valueE");
    900             ResolveMode mode = {true, false, selfFinder.candidates.empty()};
    901             funcFinder.find( nameExpr, mode );
    902 
    903             // make variableExpr itself the candidate for the value Call
    904             ExplodedArgs argExpansions;
    905             argExpansions.emplace_back();
    906             auto &argE = argExpansions.back();
    907 
    908             argE.emplace_back(*cand, symtab); // Use the typed name expr as param for value
    909 
    910             CandidateList found;
    911             SemanticErrorException errors;
    912 
    913             for (CandidateRef &func : funcFinder) {
    914                 try {
    915                     const ast::Type *funcResult =
    916                         func->expr->result->stripReferences();
    917                     if (auto pointer = dynamic_cast<const ast::PointerType *>(
    918                             funcResult)) {
    919                         if (auto function =
    920                                 pointer->base.as<ast::FunctionType>()) {
    921                             CandidateRef newFunc{new Candidate{*func}};
    922                             newFunc->expr = referenceToRvalueConversion(
    923                                 newFunc->expr, newFunc->cost);
    924                             makeFunctionCandidates( location,
    925                                                    newFunc, function,
    926                                                    argExpansions, found );
    927                         }
    928                     }
    929                 } catch (SemanticErrorException &e) {
    930                     std::cerr
    931                         << "Resolving value function should cause an error"
    932                         << std::endl;
    933                     errors.append(e);
    934                 }
    935             }
    936 
    937             if (found.empty()) {
    938                 std::cerr << "Resolve value function should always success"
    939                           << std::endl;
    940             }
    941 
    942             for (CandidateRef &withFunc : found) {
    943                 withFunc->cost.incSafe();
    944                 Cost cvtCost =
    945                     computeApplicationConversionCost(withFunc, symtab);
    946                 assert(cvtCost != Cost::infinity);
    947 
    948                 candidates.emplace_back(std::move(withFunc));
    949             }
    950         }
     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                        }
    951907                }
    952908        }
     
    14441400        }
    14451401
    1446     void Finder::postvisit(const ast::VariableExpr *variableExpr) {
    1447         // not sufficient to just pass `variableExpr` here, type might have changed
    1448 
    1449         auto cand = new Candidate(variableExpr, tenv);
    1450         candidates.emplace_back(cand);
    1451 
    1452         if (auto enumInst = dynamic_cast<const ast::EnumInstType *>(
    1453                 variableExpr->var->get_type())) {
    1454             if (enumInst->base && enumInst->base->base) {
    1455                 const CodeLocation &location = cand->expr->location;
    1456 
    1457                 CandidateFinder funcFinder(context, tenv);
    1458                 auto nameExpr = new ast::NameExpr(location, "valueE");
    1459                 ResolveMode mode = {true, false, selfFinder.candidates.empty()};
    1460                 funcFinder.find( nameExpr, mode );
    1461 
    1462                 // make variableExpr itself the candidate for the value Call
    1463                 ExplodedArgs argExpansions;
    1464                 argExpansions.emplace_back();
    1465                 auto &argE = argExpansions.back();
    1466 
    1467                 argE.emplace_back(*cand, symtab);
    1468 
    1469                 CandidateList found;
    1470                 SemanticErrorException errors;
    1471 
    1472                 for (CandidateRef &func : funcFinder) {
    1473                     try {
    1474                     const ast::Type *funcResult =
    1475                         func->expr->result->stripReferences();
    1476                     if (auto pointer = dynamic_cast<const ast::PointerType *>(
    1477                             funcResult)) {
    1478                         if (auto function =
    1479                                 pointer->base.as<ast::FunctionType>()) {
    1480                             CandidateRef newFunc{new Candidate{*func}};
    1481                             newFunc->expr = referenceToRvalueConversion(
    1482                                 newFunc->expr, newFunc->cost);
    1483                             makeFunctionCandidates(variableExpr->location,
    1484                                                    newFunc, function,
    1485                                                    argExpansions, found);
    1486                         }
    1487                     }
    1488                     } catch (SemanticErrorException &e) {
    1489                         std::cerr
    1490                             << "Resolving value function should cause an error"
    1491                             << std::endl;
    1492                         errors.append(e);
    1493                     }
    1494                 }
    1495 
    1496                 if (found.empty()) {
    1497                     std::cerr << "Resolve value function should always success"
    1498                             << std::endl;
    1499                 }
    1500 
    1501                 for (CandidateRef &withFunc : found) {
    1502                     withFunc->cost.incSafe();
    1503                     Cost cvtCost =
    1504                         computeApplicationConversionCost(withFunc, symtab);
    1505                     assert(cvtCost != Cost::infinity);
    1506 
    1507                     candidates.emplace_back(std::move(withFunc));
    1508                 }
    1509             }
    1510         }
    1511     }
     1402        void Finder::postvisit( const ast::VariableExpr * variableExpr ) {
     1403                // not sufficient to just pass `variableExpr` here, type might have changed since
     1404                addCandidate( variableExpr, tenv );
     1405        }
    15121406
    15131407        void Finder::postvisit( const ast::ConstantExpr * constantExpr ) {
  • src/ResolvExpr/CommonType.cc

    ra4da45e r022bce0  
    397397                                        result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
    398398                                }
    399                         }
    400                 } else if ( const ast::EnumPosType * pos = dynamic_cast< const ast::EnumPosType * >( type2 ) ) {
    401                         ast::BasicType::Kind kind = commonTypes[ basic->kind ][ ast::BasicType::SignedInt ];
    402                         if (
    403                                 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers )
    404                                         || widen.first )
    405                                 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers )
    406                                         || widen.second )
    407                         ) {
    408                                 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers };
    409399                        }
    410400                }
  • src/ResolvExpr/ConversionCost.cc

    ra4da45e r022bce0  
    278278        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    279279                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    280         }
    281         else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     280        } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    282281                auto enumDecl = enumInst->base;
    283                 if ( enumDecl->base.get() ) {
    284                         // cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
    285                         // cost.incUnsafe();
    286                         cost = Cost::infinity;
     282                if ( auto baseType = enumDecl->base.get() ) {
     283                        cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env );
     284                        cost.incUnsafe();
    287285                } else {
    288286            cost = Cost::unsafe;
     
    367365        cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    368366        // }
    369         if ( cost < Cost::unsafe ) {
    370                 cost.incSafe();
    371         }
    372 }
    373 
    374 void ConversionCost::postvisit( const ast::EnumPosType * ) {
    375         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
    376         cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    377367        if ( cost < Cost::unsafe ) {
    378368                cost.incSafe();
  • src/ResolvExpr/ConversionCost.h

    ra4da45e r022bce0  
    7272        void postvisit( const ast::ZeroType * zeroType );
    7373        void postvisit( const ast::OneType * oneType );
    74         void postvisit( const ast::EnumPosType * posType );
    7574private:
    7675        // refactor for code resue
  • src/ResolvExpr/Unify.cc

    ra4da45e r022bce0  
    517517                }
    518518
    519                 void postvisit( const ast::EnumPosType * posType ) {
    520                         // Does nothing for now. Handled in ReplacePseudoFunc
    521                         // Might move here in the future
    522                 }
    523 
    524519                void postvisit( const ast::TraitInstType * aggrType ) {
    525520                        handleRefType( aggrType, type2 );
  • src/SymTab/Mangler.cc

    ra4da45e r022bce0  
    5959        void postvisit( const ast::QualifiedType * qualType );
    6060
    61         void postvisit( const ast::EnumPosType * posType );
    62 
    6361        /// The result is the current constructed mangled name.
    6462        std::string result() const { return mangleName; }
     
    279277        assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
    280278        mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
    281 }
    282 
    283 void Mangler::postvisit( const ast::EnumPosType * pos ) {
    284         postvisit( pos->instance );
    285         mangleName += "_pos";
    286279}
    287280
  • src/Validate/Autogen.cpp

    ra4da45e r022bce0  
    205205        ast::FunctionDecl * genLabelProto() const;
    206206        ast::FunctionDecl * genValueProto() const;
    207         // ast::FunctionDecl * genValueProto2() const;
    208207};
    209208
     
    790789}
    791790
    792 // ast::FunctionDecl * EnumFuncGenerator::genValueProto2() const {
    793 //      return genProto( "valueE",
    794 //              { new ast::ObjectDecl( getLocation(), "_i", new ast::EnumPosType( new ast::EnumInstType( decl ) ) )},
    795 //              { new ast::ObjectDecl( getLocation(), "_ret", ast::deepCopy( decl->base ) ) } );
    796 // }
    797 
    798791void EnumFuncGenerator::genAttrFuncForward() { 
    799792        if ( decl->base ) {
    800793                ast::FunctionDecl *(EnumFuncGenerator::*attrProtos[3])() const = {
    801794                        &EnumFuncGenerator::genPosProto, &EnumFuncGenerator::genLabelProto,
    802                         &EnumFuncGenerator::genValueProto
    803                         // , &EnumFuncGenerator::genValueProto2
    804                         };
     795                        &EnumFuncGenerator::genValueProto };
    805796                for ( auto & generator : attrProtos ) {
    806797                        produceForwardDecl( (this->*generator)() );
  • src/Validate/ReplacePseudoFunc.cpp

    ra4da45e r022bce0  
    66#include "AST/Inspect.hpp"
    77#include "AST/Pass.hpp"
    8 #include "AST/Print.hpp"
    98#include "AST/Stmt.hpp"
    109#include "Common/utility.h"
    11 #include "ResolvExpr/CandidateFinder.hpp"
    1210#include "ResolvExpr/Resolver.h"
    1311#include "SymTab/Mangler.h"
    1412
     13#include "AST/Print.hpp"
     14
     15#include "ResolvExpr/CandidateFinder.hpp"
     16
    1517namespace Validate {
    1618
     
    1921std::set<std::string> queryLabels;
    2022std::set<std::string> queryValues;
    21 
    22 struct ReplaceEnumInstWithPos final : public ast::WithShortCircuiting {
    23     void previsit(const ast::ObjectDecl*) { visit_children = false; }
    24     const ast::ObjectDecl* postvisit(const ast::ObjectDecl* decl) {
    25         auto enumInst = decl->type.strict_as<ast::EnumInstType>();
    26         auto enumPos = new ast::EnumPosType(enumInst);
    27         auto ret = ast::mutate_field(decl, &ast::ObjectDecl::type, enumPos);
    28         ret = ast::mutate_field(ret, &ast::ObjectDecl::mangleName,
    29                                 Mangle::mangle(ret));
    30         return ret;
    31     }
    32 };
    33 
    34 const inline std::string getValueArrayName(std::string enumName) {
    35     return "values_" + enumName;
    36 }
    3723
    3824// struct AutoInit {
     
    4632    void previsit(const ast::ApplicationExpr* expr);
    4733    void previsit(const ast::CastExpr* expr);
    48     void previsit(const ast::VariableExpr*) { visit_children = false; }
     34    void previsit(const ast::VariableExpr* ) { visit_children = false; }
    4935
    5036    ast::Expr const* postvisit(const ast::VariableExpr* expr);
     
    8066    auto varExpr = expr->func.as<ast::VariableExpr>();
    8167    auto fname = ast::getFunctionName(expr);
    82     if (!varExpr || varExpr->var->linkage == ast::Linkage::Intrinsic) {
    83         if (fname == "?{}" || fname == "?=?") visit_children = false;
    84     }
     68        if ( !varExpr || varExpr->var->linkage == ast::Linkage::Intrinsic ) {
     69        if ( fname == "?{}" || fname == "?=?" )
     70                    visit_children = false;
     71        }
    8572
    8673    if (fname == "labelE" || fname == "valueE" || fname == "posE") {
     
    10794            auto untyped = new ast::UntypedExpr(
    10895                expr->location, new ast::NameExpr(expr->location, "valueE"),
    109                 {std::move(expr)});
     96                { std::move( expr ) });
    11097            ResolvExpr::ResolveContext context{symtab, transUnit().global};
    11198            auto result = ResolvExpr::findVoidExpression(untyped, context);
    11299            ast::ptr<ast::ApplicationExpr> ret =
    113                 result.strict_as<ast::ApplicationExpr>();
    114             return ast::deepCopy(ret);
     100                    result.strict_as<ast::ApplicationExpr>();
     101            return ast::deepCopy( ret );
    115102        }
    116103    }
     
    145132}
    146133
    147 const ast::Init* getAutoInit(const CodeLocation& location,
    148                              const ast::Type* type,
    149                              ResolvExpr::ResolveContext context,
    150                              const ast::Init* prev) {
    151     if (auto prevInit = dynamic_cast<const ast::SingleInit*>(prev)) {
     134const ast::Init * getAutoInit( const CodeLocation & location,
     135    const ast::Type * type, ResolvExpr::ResolveContext context, const ast::Init * prev ) {
     136    if ( auto prevInit = dynamic_cast< const ast::SingleInit * >( prev ) ) {
    152137        auto prevInitExpr = prevInit->value;
    153         if (auto constInit = prevInitExpr.as<ast::ConstantExpr>()) {
     138        if ( auto constInit = prevInitExpr.as< ast::ConstantExpr >() ) {
    154139            // Assume no string literal for now
    155140            return new ast::SingleInit(
    156                 location, ast::ConstantExpr::from_int(
    157                               location, constInit->intValue() + 1));
     141                location,
     142                ast::ConstantExpr::from_int(
     143                    location, constInit->intValue() + 1 )
     144            );
    158145        } else {
    159146            auto untypedThisInit = new ast::UntypedExpr(
    160                 location, new ast::NameExpr(location, "?++"), {prevInitExpr});
    161             auto typedInit = ResolvExpr::findSingleExpression(untypedThisInit,
    162                                                               type, context);
    163             return new ast::SingleInit(location, typedInit);
    164         }
    165     }
    166     SemanticError(prev, "Auto Init a List is not implemented");
     147                    location,
     148                    new ast::NameExpr( location, "?++" ),
     149                    { prevInitExpr }
     150                );
     151            auto typedInit = ResolvExpr::findSingleExpression(untypedThisInit, type,
     152                context );
     153            return new ast::SingleInit( location, typedInit );
     154        }
     155    }
     156    SemanticError( prev, "Auto Init a List is not implemented" );
    167157    return prev;
    168158}
     
    177167    auto type = enumDecl->base;
    178168
    179     for (size_t i = 0; i < enumDecl->members.size(); i++) {
    180         ast::ptr<ast::Decl> mem = enumDecl->members.at(i);
    181         auto memAsObjectDecl = mem.as<ast::ObjectDecl>();
    182         assert(memAsObjectDecl);
    183         if (memAsObjectDecl->init) {
    184             inits.emplace_back(memAsObjectDecl->init);
     169    for ( size_t i = 0; i < enumDecl->members.size(); i++ ) {
     170        ast::ptr<ast::Decl> mem = enumDecl->members.at( i );
     171        auto memAsObjectDecl = mem.as< ast::ObjectDecl >();
     172        assert( memAsObjectDecl );
     173        if ( memAsObjectDecl->init ) {
     174            inits.emplace_back( memAsObjectDecl->init );
    185175        } else {
    186             const CodeLocation& location = mem->location;
    187             if (i == 0) {
    188                 inits.emplace_back(new ast::SingleInit(
    189                     location, ast::ConstantExpr::from_int(mem->location, 0)));
     176            const CodeLocation & location = mem->location;
     177            if ( i == 0 ) {
     178                inits.emplace_back( new ast::SingleInit(
     179                    location,
     180                    ast::ConstantExpr::from_int( mem->location, 0 )
     181                ) );
    190182            } else {
    191                 inits.emplace_back(getAutoInit(
    192                     location, enumDecl->base,
    193                     ResolvExpr::ResolveContext{symtab, transUnit().global},
    194                     inits.at(i - 1).as<ast::SingleInit>()));
     183                inits.emplace_back( getAutoInit( location, enumDecl->base,
     184                    ResolvExpr::ResolveContext{symtab, transUnit().global},
     185                    inits.at( i - 1 ).as<ast::SingleInit>()) );
    195186            }
    196187        }
    197188        labels.emplace_back(new ast::SingleInit(
    198             location, ast::ConstantExpr::from_string(location, mem->name)));
    199     }
     189        location, ast::ConstantExpr::from_string(location, mem->name)));
     190    } 
    200191    if (queryValues.count(enumDecl->name)) {
    201192        auto init = new ast::ListInit(location, std::move(inits));
     
    228219ast::ApplicationExpr const* getPseudoFuncApplication(
    229220    const CodeLocation location, ResolvExpr::ResolveContext context,
    230     const ast::VariableExpr* arg, const ast::EnumDecl* base,
    231     const std::string& name) {
     221    const ast::VariableExpr* arg, const ast::EnumDecl* base, const std::string & name) {
    232222    ast::Expr* toResolve = new ast::NameExpr(location, name + base->name);
    233     // Find the request arrary
    234     auto arr = ResolvExpr::findVoidExpression(toResolve, context);
    235     assert(arr.get());
    236     auto arrAsVar = arr.strict_as<ast::VariableExpr>();
    237     // change EnumInstType to EnumPosType to avoid recursive resolution
    238     auto argAsDecl = arg->var.as<ast::ObjectDecl>();
    239     if (argAsDecl->type.as<ast::EnumInstType>()) {
    240         ast::Pass<ReplaceEnumInstWithPos> replacer;
    241         auto rep = argAsDecl->accept(replacer);
    242         auto mutatedArg = ast::mutate_field(arg, &ast::VariableExpr::var, rep);
    243         auto untyped =
    244             new ast::UntypedExpr(location, new ast::NameExpr(location, "?[?]"),
    245                                  {std::move(arrAsVar), mutatedArg});
    246         auto typedResult = ResolvExpr::findVoidExpression(untyped, context);
    247         ast::ptr<ast::ApplicationExpr> ret =
    248             typedResult.strict_as<ast::ApplicationExpr>();
    249         return ast::deepCopy(ret);
    250     } else {
    251         auto untyped =
    252             new ast::UntypedExpr(location, new ast::NameExpr(location, "?[?]"),
    253                                  {std::move(arrAsVar), arg});
    254         auto typedResult = ResolvExpr::findVoidExpression(untyped, context);
    255 
    256         ast::ptr<ast::ApplicationExpr> ret =
    257             typedResult.strict_as<ast::ApplicationExpr>();
    258         return ast::deepCopy(ret);
    259     }
     223    auto result = ResolvExpr::findVoidExpression(toResolve, context);
     224    assert(result.get());
     225    auto arrAsVar = result.strict_as<ast::VariableExpr>();
     226    auto untyped = new ast::UntypedExpr(
     227        location, new ast::NameExpr(location, "?[?]"),
     228        { std::move(arrAsVar), std::move(arg) });
     229    auto typedResult = ResolvExpr::findVoidExpression(untyped, context);
     230
     231    ast::ptr<ast::ApplicationExpr> ret =
     232        typedResult.strict_as<ast::ApplicationExpr>();
     233    return ast::deepCopy(ret);
    260234}
    261235
     
    276250        const ast::ObjectDecl* argAsVar = arg->var.as<const ast::ObjectDecl>();
    277251        const std::string referredName = argAsVar->name;
    278 
    279         if (const ast::EnumInstType* argTypeAsEnumInst =
    280                 argAsVar->type.as<const ast::EnumInstType>()) {
    281             const ast::EnumDecl* base = argTypeAsEnumInst->base;
    282             ResolvExpr::ResolveContext context{symtab, transUnit().global};
    283             // If resolvable as constant
    284             for (size_t i = 0; i < base->members.size(); i++) {
    285                 if (base->members[i]->name == referredName) {
    286                     if (fname == "posE")
    287                         return ast::ConstantExpr::from_int(expr->location, i);
    288                     else if (fname == "labelE")
    289                         return ast::ConstantExpr::from_string(expr->location,
    290                                                               referredName);
    291                     else {
    292                         return getPseudoFuncApplication(
    293                             location, context, arg.get(), base, "values_");
    294                     }
    295                 }
    296             }
    297 
    298             if (fname == "labelE") {
    299                 if (auto labelExpr = getPseudoFuncApplication(
    300                         location, context, arg.get(), base, "labels_")) {
    301                     return labelExpr;
    302                 }
    303             } else if (fname == "valueE") {
    304                 if (auto valueExpr = getPseudoFuncApplication(
    305                         location, context, arg.get(), base, "values_")) {
    306                     return valueExpr;
    307                 }
    308             } else {  // it is position; replace itself
    309                 return std::move(arg.get());
    310             }
    311         } else if (const ast::EnumPosType* argTypeAsPos =
    312                        argAsVar->type.as<const ast::EnumPosType>()) {
    313             const ast::EnumDecl* base = argTypeAsPos->instance->base;
    314             ResolvExpr::ResolveContext context{symtab, transUnit().global};
    315             if (fname == "labelE") {
    316                 if (auto labelExpr = getPseudoFuncApplication(
    317                         location, context, arg.get(), base, "labels_")) {
    318                     return labelExpr;
    319                 }
    320             } else if (fname == "valueE") {
    321                 if (auto valueExpr = getPseudoFuncApplication(
    322                         location, context, arg.get(), base, "values_")) {
    323                     return valueExpr;
    324                 }
    325             } else {  // it is position; replace itself
    326                 return std::move(arg.get());
    327             }
    328         } else {
     252        const ast::EnumInstType* argType =
     253            argAsVar->type.as<const ast::EnumInstType>();
     254        if (!argType) {
    329255            SemanticError(argAsVar,
    330256                          "Pseudo Enum Expression can only be used on an "
    331257                          "enumeration instance");
    332258        }
     259        const ast::EnumDecl* base = argType->base;
     260        ResolvExpr::ResolveContext context{symtab, transUnit().global};
     261        // If resolvable as constant
     262        for (size_t i = 0; i < base->members.size(); i++) {
     263            if (base->members[i]->name == referredName) {
     264                if (fname == "posE")
     265                    return ast::ConstantExpr::from_int(expr->location, i);
     266                else if (fname == "labelE")
     267                    return ast::ConstantExpr::from_string(expr->location,
     268                                                          referredName);
     269                else {
     270                    return getPseudoFuncApplication(location, context, arg.get(),
     271                                               base, "values_");                   
     272                }
     273
     274            }
     275        }
     276
     277        if (fname == "labelE") {
     278            if (auto labelExpr =
     279                    getPseudoFuncApplication(location, context, arg.get(), base, "labels_")) {
     280                return labelExpr;
     281            }
     282        } else if (fname == "valueE") {
     283            if (auto valueExpr =
     284                    getPseudoFuncApplication(location, context, arg.get(), base, "values_")) {
     285                return valueExpr;
     286            }
     287        } else { // it is position; replace itself
     288            return std::move( arg.get() );
     289        }
    333290    }
    334291    return expr;
    335292}
    336 
    337 ast::ptr<ast::Expr> reduceCastExpr(ast::ptr<ast::Expr> expr) {
    338     if (auto castExpr = expr.as<ast::CastExpr>()) {
    339         return reduceCastExpr(castExpr->arg);
    340     }
    341     return expr;
    342 }
    343 
    344 struct ReplaceEnumInst final {
    345     const ast::Expr* postvisit(const ast::ApplicationExpr* expr) {
    346         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;
    379     }
    380 };
    381293
    382294}  // namespace
     
    387299    ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
    388300    ast::Pass<ReplacePseudoFuncCore>::run(translationUnit);
    389     ast::Pass<ReplaceEnumInst>::run(translationUnit);
    390301}
    391302}  // namespace Validate
Note: See TracChangeset for help on using the changeset viewer.