Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Validate/Autogen.cpp

    raf746cc rbbf2cb1  
    196196
    197197        bool shouldAutogen() const final { return true; }
     198        void genAttrFuncForward();
     199        void genPosFunctions();
    198200private:
    199201        void genFuncBody( ast::FunctionDecl * decl ) final;
    200202        void genFieldCtors() final;
    201203        const ast::Decl * getDecl() const final { return decl; }
     204
     205        ast::FunctionDecl * genPosProto() const;
     206        ast::FunctionDecl * genLabelProto() const;
     207        ast::FunctionDecl * genValueProto() const;
     208        ast::FunctionDecl * genSuccProto() const;
     209        ast::FunctionDecl * genPredProto() const;
     210
     211        ast::FunctionDecl * genSuccPosProto() const;
     212        ast::FunctionDecl * genPredPosProto() const;
     213
     214        ast::FunctionDecl * genSuccPredFunc( bool succ );
     215        // ast::FunctionDecl * genPredFunc();
    202216};
    203217
     
    242256        enumInst.base = enumDecl;
    243257        EnumFuncGenerator gen( enumDecl, &enumInst, functionNesting );
     258        if ( enumDecl->base ) {
     259                gen.genAttrFuncForward();
     260                gen.genPosFunctions();
     261        }
    244262        gen.generateAndAppendFunctions( declsToAddAfter );
    245263}
     
    400418}
    401419
    402 /// Use the current type T to create `void ^?{}(T & _dst)`.
     420/// Use the current type T to create `void ?{}(T & _dst)`.
    403421ast::FunctionDecl * FuncGenerator::genDtorProto() const {
    404422        // The destructor must be mutex on a concurrent type.
     
    759777}
    760778
     779ast::FunctionDecl * EnumFuncGenerator::genPosProto() const {
     780        return genProto( "posE",
     781                { new ast::ObjectDecl( getLocation(), "_i",
     782                new ast::EnumInstType( decl ) )},
     783                { new ast::ObjectDecl( getLocation(), "_ret",
     784                new ast::BasicType{ ast::BasicType::UnsignedInt } )} );
     785}
     786
     787ast::FunctionDecl * EnumFuncGenerator::genLabelProto() const {
     788        return genProto( "labelE",
     789                { new ast::ObjectDecl( getLocation(), "_i",
     790                new ast::EnumInstType( decl ) ) },
     791                { new ast::ObjectDecl( getLocation(), "_ret",
     792                new ast::PointerType( new ast::BasicType{ ast::BasicType::Char } ) ) } );
     793}
     794
     795ast::FunctionDecl * EnumFuncGenerator::genValueProto() const {
     796        return genProto( "valueE",
     797                { new ast::ObjectDecl( getLocation(), "_i", new ast::EnumInstType( decl ) )},
     798                { new ast::ObjectDecl( getLocation(), "_ret", ast::deepCopy( decl->base ) ) } );
     799}
     800
     801ast::FunctionDecl * EnumFuncGenerator::genSuccProto() const {
     802        return genProto( "succ",
     803                { new ast::ObjectDecl( getLocation(), "_i", new ast::EnumInstType( decl ) )},
     804                { new ast::ObjectDecl( getLocation(), "_ret", new ast::EnumInstType( decl ))} );
     805}
     806
     807ast::FunctionDecl * EnumFuncGenerator::genPredProto() const {
     808        return genProto( "pred",
     809                { new ast::ObjectDecl( getLocation(), "_i", new ast::EnumInstType( decl ))},
     810                { new ast::ObjectDecl( getLocation(), "_ret", new ast::EnumInstType( decl ))} );
     811}
     812
     813ast::FunctionDecl * EnumFuncGenerator::genSuccPosProto() const {
     814        return genProto( "_successor_",
     815                { new ast::ObjectDecl( getLocation(), "_i",
     816                        new ast::EnumPosType( new ast::EnumInstType( decl ) ) )},
     817                {
     818                        new ast::ObjectDecl( getLocation(), "_ret",
     819                        new ast::EnumPosType( new ast::EnumInstType( decl ) ) )
     820                } );
     821}
     822
     823ast::FunctionDecl * EnumFuncGenerator::genPredPosProto() const {
     824        return genProto( "_predessor_",
     825                { new ast::ObjectDecl( getLocation(), "_i",
     826                        new ast::EnumPosType( new ast::EnumInstType( decl ) ) )},
     827                {
     828                        new ast::ObjectDecl( getLocation(), "_ret",
     829                        new ast::EnumPosType( new ast::EnumInstType( decl ) ) )
     830                } );
     831}
     832
     833ast::FunctionDecl * EnumFuncGenerator::genSuccPredFunc( bool succ ) {
     834        ast::FunctionDecl * decl = succ? genSuccPosProto(): genPredPosProto();
     835        produceForwardDecl( decl );
     836
     837        const CodeLocation& location = getLocation();
     838
     839        auto & params = decl->params;
     840        assert( params.size() == 1 );
     841        auto param = params.front().strict_as<ast::ObjectDecl>();
     842
     843        auto newReturn = new ast::ObjectDecl( location, "_returns",
     844                new ast::BasicType{ ast::BasicType::SignedInt} );
     845       
     846
     847        ast::UntypedExpr * addOneExpr = new ast::UntypedExpr( location,
     848                new ast::NameExpr( location, succ? "?+?": "?-?" )
     849        );
     850        addOneExpr->args.push_back(
     851                new ast::CastExpr( location,
     852                        new ast::VariableExpr( location, param ),
     853                        new ast::BasicType{ ast::BasicType::SignedInt }
     854                )
     855        );
     856        addOneExpr->args.push_back(
     857                ast::ConstantExpr::from_int( location, 1 )
     858        );
     859
     860        ast::UntypedExpr * assignExpr = new ast::UntypedExpr( location,
     861                new ast::NameExpr( location, "?=?" )
     862        );
     863        assignExpr->args.push_back(     
     864                new ast::VariableExpr( location, newReturn )
     865        );
     866        assignExpr->args.push_back(
     867                addOneExpr
     868        );
     869
     870        decl->stmts = new ast::CompoundStmt( location,
     871                {
     872                        new ast::DeclStmt( location, newReturn ),
     873                        new ast::ExprStmt( location, assignExpr ),
     874                        new ast::ReturnStmt( location,
     875                                new ast::VariableExpr( location, newReturn ))
     876                } );
     877       
     878        return decl;
     879}
     880
     881void EnumFuncGenerator::genAttrFuncForward() { 
     882        if ( decl->base ) {
     883                ast::FunctionDecl *(EnumFuncGenerator::*attrProtos[5])() const = {
     884                        &EnumFuncGenerator::genPosProto, &EnumFuncGenerator::genLabelProto,
     885                        &EnumFuncGenerator::genValueProto, &EnumFuncGenerator::genSuccProto,
     886                        &EnumFuncGenerator::genPredProto
     887                        // ,&EnumFuncGenerator::genSuccPosProto,
     888                        // &EnumFuncGenerator::genPredPosProto
     889                };
     890                for ( auto & generator : attrProtos ) {
     891                        produceForwardDecl( (this->*generator)() );
     892                }
     893        }
     894}
     895
     896void EnumFuncGenerator::genPosFunctions() {
     897        if ( decl->base ) {
     898                ast::FunctionDecl * succ = genSuccPredFunc( true );
     899                ast::FunctionDecl * pred = genSuccPredFunc( false );
     900                produceDecl( succ );
     901                produceDecl( pred );
     902        }
     903
     904}
     905
    761906void TypeFuncGenerator::genFieldCtors() {
    762907        // Opaque types do not have field constructors.
Note: See TracChangeset for help on using the changeset viewer.