Ignore:
Timestamp:
Jan 31, 2024, 6:25:02 PM (4 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
32490deb
Parents:
16afb2a
Message:

Introduce posE, valueE, labelE pseudo language to the language. Rework the internal representation of enumeration.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/Autogen.cpp

    r16afb2a rc75b30a  
    197197
    198198        bool shouldAutogen() const final { return true; }
     199        void genAttrFuncForward();
     200        void __attribute__ ((unused)) genDualFuncs();
    199201private:
    200202        void genFuncBody( ast::FunctionDecl * decl ) final;
    201203        void genFieldCtors() final;
    202204        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 );
    203216};
    204217
     
    238251// --------------------------------------------------------------------------
    239252void AutogenerateRoutines::previsit( const ast::EnumDecl * enumDecl ) {
    240         // Must visit children (enum constants) to add them to the symbol table.
    241253        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         // }
    249254
    250255        ast::EnumInstType enumInst( enumDecl->name );
    251256        enumInst.base = enumDecl;
    252257        EnumFuncGenerator gen( enumDecl, &enumInst, functionNesting );
     258        if ( enumDecl->base ) {
     259                gen.genAttrFuncForward();
     260                // gen.genDualFuncs();
     261        }
    253262        gen.generateAndAppendFunctions( declsToAddAfter );
    254263}
     
    742751                 * returns to zero.
    743752                 */
     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
    744766                auto callExpr = new ast::ApplicationExpr( location,
    745767                        ast::VariableExpr::functionPointer( location, functionDecl ),
    746768                        {
    747                                 new ast::VariableExpr( location, dstParam ),
    748                                 new ast::VariableExpr( location, srcParam ),
     769                                dstExpr,
     770                                srcExpr,
    749771                        }
    750772                );
    751                 // auto fname = ast::getFunctionName( callExpr );
    752                 // if (fname == "posE" ) {
    753                 //      std::cerr << "Found posE autogen" << std::endl;
    754                 // }
     773
    755774                functionDecl->stmts = new ast::CompoundStmt( location,
    756775                        { new ast::ExprStmt( location, callExpr ) }
     
    768787                        forwards.back().get_and_mutate() );
    769788                addUnusedAttribute( fwd->params.front() );
     789        }
     790}
     791
     792ast::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
     800ast::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
     808ast::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
     814void 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
     825ast::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 )
     833ast::FunctionDecl * EnumFuncGenerator::genCopyEnumToDualProto() const {
     834        return genProto( "?{}", { dualDstParam(), srcParam() }, {} );
     835}
     836
     837// T ?{}(T & _dst, enum E _src )
     838ast::FunctionDecl * EnumFuncGenerator::genAssignEnumToDualProto() const {
     839        auto retval = dualDstParam();
     840        retval->name = "_ret";
     841        return genProto( "?=?", { dualDstParam(), srcParam() }, { retval });
     842}
     843
     844void 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
     867void 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 );
    770880        }
    771881}
Note: See TracChangeset for help on using the changeset viewer.