Changeset 525f7ad


Ignore:
Timestamp:
Jun 19, 2024, 3:20:39 PM (5 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
57e43cd
Parents:
1725989
Message:
  1. Add count_e( enum_name ), a pseudo function that return the number of element in an enum; 2. Implementation of enum range loop.
Files:
1 added
18 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/enum.cfa

    r1725989 r525f7ad  
    1313    return os | type_name(e) | "." | labelE(e);
    1414}
     15
     16forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) {
     17    int ?==?(E l, E r) { return posE(l) == posE(r); }
     18    int ?<=?(E l, E r) { return posE(l) <= posE(r); }
     19    int ?>=?(E l, E r) { return posE(l) >= posE(r); }
     20    int ?<?(E l, E r) { return posE(l) < posE(r); }
     21    int ?>?(E l, E r) { return posE(l) > posE(r); }
     22}
  • libcfa/src/enum.hfa

    r1725989 r525f7ad  
    3838//     V valueE(E e);
    3939// };
     40
     41forall(ostype & | basic_ostream(ostype), E, V| CfaEnum(E, V)) {
     42    int ?==?(E, E);
     43    int ?<=?(E, E);
     44    int ?>=?(E, E);
     45    int ?<?(E, E);
     46    int ?>?(E, E);
     47
     48        // E ++?( E & lhs );
     49        // E ?++( E & lhs );
     50}
  • src/AST/Expr.cpp

    r1725989 r525f7ad  
    282282: Expr( loc, new BasicType{ BasicKind::LongUnsignedInt } ), expr( nullptr ), type( t ) {}
    283283
     284// --- CountExpr
     285
     286CountExpr::CountExpr( const CodeLocation & loc, const Type * t )
     287: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), type( t ) {}
     288
    284289// --- AlignofExpr
    285290
  • src/AST/Expr.hpp

    r1725989 r525f7ad  
    494494};
    495495
     496class CountExpr final : public Expr {
     497public:
     498        ptr<Type> type;
     499
     500        CountExpr( const CodeLocation & loc, const Type * t );
     501
     502        const Expr * accept( Visitor & v )const override { return v.visit( this ); }
     503private:
     504        CountExpr * clone() const override { return new CountExpr( *this ); }
     505        MUTATE_FRIEND
     506};
     507
    496508/// alignof expression, e.g. `alignof(int)`, `alignof 3+4`
    497509class AlignofExpr final : public Expr {
  • src/AST/Fwd.hpp

    r1725989 r525f7ad  
    8585class ConstantExpr;
    8686class SizeofExpr;
     87class CountExpr;
    8788class AlignofExpr;
    8889class UntypedOffsetofExpr;
  • src/AST/Pass.hpp

    r1725989 r525f7ad  
    172172        const ast::Expr *             visit( const ast::ConstantExpr         * ) override final;
    173173        const ast::Expr *             visit( const ast::SizeofExpr           * ) override final;
     174        const ast::Expr *             visit( const ast::CountExpr            * ) override final;
    174175        const ast::Expr *             visit( const ast::AlignofExpr          * ) override final;
    175176        const ast::Expr *             visit( const ast::UntypedOffsetofExpr  * ) override final;
  • src/AST/Pass.impl.hpp

    r1725989 r525f7ad  
    802802                maybe_accept_top( node, &ForStmt::cond  );
    803803                maybe_accept_top( node, &ForStmt::inc   );
     804                maybe_accept_top( node, &ForStmt::range_over );
    804805                maybe_accept_as_compound( node, &ForStmt::body  );
    805806        }
     
    13231324        }
    13241325
     1326        VISIT_END( Expr, node );
     1327}
     1328
     1329//--------------------------------------------------------------------------
     1330// CountExpr
     1331template< typename core_t >
     1332const ast::Expr * ast::Pass< core_t >::visit( const ast::CountExpr * node ) {
     1333        VISIT_START( node );
     1334        if ( __visit_children() ) {
     1335                {
     1336                        guard_symtab guard { *this };
     1337                        maybe_accept( node, &CountExpr::result );
     1338                }
     1339                maybe_accept( node, &CountExpr::type );
     1340        }
    13251341        VISIT_END( Expr, node );
    13261342}
  • src/AST/Print.cpp

    r1725989 r525f7ad  
    11431143        }
    11441144
     1145        virtual const ast::Expr * visit( const ast::CountExpr * node ) override final {
     1146                os << "Count Expression on: ";
     1147                ++indent;
     1148                node->type->accept( *this );
     1149                --indent;
     1150                postprint( node );
     1151                return node;
     1152        }
     1153
    11451154        virtual const ast::Expr * visit( const ast::AlignofExpr * node ) override final {
    11461155                os << "Alignof Expression on: ";
  • src/AST/Stmt.hpp

    r1725989 r525f7ad  
    237237        ptr<Expr> cond;
    238238        ptr<Expr> inc;
     239        ptr<Expr> range_over;
    239240        ptr<Stmt> body;
    240241        ptr<Stmt> else_;
     
    242243        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
    243244                         const Expr * inc, const Stmt * body, const std::vector<Label> && label = {} )
    244                 : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc), body(body), else_(nullptr) {}
     245                : Stmt(loc, std::move(label)), inits(std::move(inits)), cond(cond), inc(inc),
     246                        range_over(nullptr), body(body), else_(nullptr) {}
    245247
    246248        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * cond,
    247249                         const Expr * inc, const Stmt * body, const Stmt * else_, const std::vector<Label> && labels = {} )
    248                 : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc), body(body), else_(else_) {}
     250                : Stmt(loc, std::move(labels)), inits(std::move(inits)), cond(cond), inc(inc),
     251                        range_over(nullptr), body(body), else_(else_) {}
     252
     253        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over,
     254                         const Stmt * body, const Stmt * else_ )
     255                : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), body(body), else_(else_) {}
    249256
    250257        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/AST/Visitor.hpp

    r1725989 r525f7ad  
    7575    virtual const ast::Expr *             visit( const ast::ConstantExpr         * ) = 0;
    7676    virtual const ast::Expr *             visit( const ast::SizeofExpr           * ) = 0;
     77    virtual const ast::Expr *             visit( const ast::CountExpr            * ) = 0;
    7778    virtual const ast::Expr *             visit( const ast::AlignofExpr          * ) = 0;
    7879    virtual const ast::Expr *             visit( const ast::UntypedOffsetofExpr  * ) = 0;
  • src/Common/CodeLocationTools.cpp

    r1725989 r525f7ad  
    153153    macro(ConstantExpr, Expr) \
    154154    macro(SizeofExpr, Expr) \
     155    macro(CountExpr, Expr ) \
    155156    macro(AlignofExpr, Expr) \
    156157    macro(UntypedOffsetofExpr, Expr) \
  • src/ControlStruct/module.mk

    r1725989 r525f7ad  
    2727        ControlStruct/LabelGenerator.hpp \
    2828        ControlStruct/MultiLevelExit.cpp \
    29         ControlStruct/MultiLevelExit.hpp
     29        ControlStruct/MultiLevelExit.hpp \
     30        ControlStruct/TranslateEnumRange.cpp \
     31        ControlStruct/TranslateEnumRange.hpp
    3032
  • src/Parser/StatementNode.cpp

    r1725989 r525f7ad  
    211211        buildMoveList( forctl->init, astinit );
    212212
     213        if ( forctl->range_over ) {
     214                ast::Expr * range_over = maybeMoveBuild( forctl->range_over );
     215                delete forctl;
     216                return new ast::ForStmt( location,
     217                        std::move( astinit ),
     218                        range_over,
     219                        buildMoveSingle( stmt ),
     220                        buildMoveOptional( else_ )
     221                );
     222        }
     223
    213224        ast::Expr * astcond = nullptr;                                          // maybe empty
    214225        astcond = maybeMoveBuild( forctl->condition );
  • src/Parser/StatementNode.hpp

    r1725989 r525f7ad  
    6363struct ForCtrl {
    6464        ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
    65                 init( stmt ), condition( condition ), change( change ) {}
     65                init( stmt ), condition( condition ), change( change ), range_over( nullptr ) {}
     66        ForCtrl( StatementNode * decl, ExpressionNode * _range_over) :
     67                init( decl ), condition( nullptr ), change( nullptr ),  range_over( _range_over ) {}
    6668
    6769        StatementNode * init;
    6870        ExpressionNode * condition;
    6971        ExpressionNode * change;
     72        ExpressionNode * range_over;
    7073};
    7174
  • src/Parser/lex.ll

    r1725989 r525f7ad  
    321321__signed__              { KEYWORD_RETURN(SIGNED); }                             // GCC
    322322sizeof                  { KEYWORD_RETURN(SIZEOF); }
     323__count_e__             { KEYWORD_RETURN(COUNT); }                              // GCC
    323324static                  { KEYWORD_RETURN(STATIC); }
    324325_Static_assert  { KEYWORD_RETURN(STATICASSERT); }               // C11
  • src/Parser/parser.yy

    r1725989 r525f7ad  
    284284} // forCtrl
    285285
     286ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, ExpressionNode * range_over_expr ) {
     287        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index_expr->expr.get()) ) {
     288                DeclarationNode * indexDecl =
     289                        DeclarationNode::newName( new std::string(identifier->name) );
     290                assert( range_over_expr );
     291                auto node = new StatementNode( indexDecl ); // <- this cause this error
     292                return new ForCtrl( node, range_over_expr );
     293        } else if (auto commaExpr = dynamic_cast<ast::CommaExpr *>( index_expr->expr.get() )) {
     294                if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
     295                        assert( range_over_expr );
     296                        DeclarationNode * indexDecl = distAttr(
     297                                DeclarationNode::newTypeof( range_over_expr, true ),
     298                                DeclarationNode::newName( new std::string( identifier->name) ) );
     299                        return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
     300                } else {
     301                        SemanticError( yylloc, "syntax error, loop-index name missing. Expression disallowed." ); return nullptr;
     302                } // if
     303        } else {
     304                SemanticError( yylloc, "syntax error, loop-index name missing. Expression disallowed." ); return nullptr;
     305        } // if
     306} // enumRangeCtrl
     307
    286308static void IdentifierBeforeIdentifier( string & identifier1, string & identifier2, const char * kind ) {
    287309        SemanticError( yylloc, "syntax error, adjacent identifiers \"%s\" and \"%s\" are not meaningful in an %s.\n"
     
    368390%token DECIMAL32 DECIMAL64 DECIMAL128                                   // GCC
    369391%token ZERO_T ONE_T                                                                             // CFA
    370 %token SIZEOF TYPEOF VA_LIST VA_ARG AUTO_TYPE                   // GCC
     392%token SIZEOF TYPEOF VA_LIST VA_ARG AUTO_TYPE COUNT             // GCC
    371393%token OFFSETOF BASETYPEOF TYPEID                                               // CFA
    372394%token ENUM STRUCT UNION
     
    968990                        // $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) );
    969991                }
     992        | COUNT '(' type ')'
     993                {
     994                        // SemanticError( yylloc, "Count is currently unimplemented. "); $$ = nullptr;
     995                        $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuildType( $3 ) ) );
     996                }
    970997        ;
    971998
     
    15991626                { SemanticError( yylloc, "syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    16001627
    1601         | comma_expression ';' enum_key                                         // CFA, enum type
    1602                 {
    1603                         SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    1604                         //$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
    1605                 }
    1606         | comma_expression ';' downupdowneq enum_key            // CFA, enum type, reverse direction
     1628        | comma_expression ';' enum_type                                        // CFA, enum type
     1629                {
     1630                        $$ = enumRangeCtrl( $1, new ExpressionNode( new ast::TypeExpr(yylloc, $3->buildType() ) ) );
     1631                }
     1632        | comma_expression ';' downupdowneq enum_type           // CFA, enum type, reverse direction
    16071633                {
    16081634                        if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) {
     
    16111637                        SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    16121638                }
    1613         ;
    1614 
    1615 enum_key:
    1616         TYPEDEFname
    1617         | ENUM identifier_or_type_name
    16181639        ;
    16191640
  • src/ResolvExpr/CandidateFinder.cpp

    r1725989 r525f7ad  
    696696                void postvisit( const ast::UntypedInitExpr * initExpr );
    697697                void postvisit( const ast::QualifiedNameExpr * qualifiedExpr );
     698                void postvisit( const ast::CountExpr * countExpr );
    698699
    699700                const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src,
     
    15271528                        addCandidate( *choice, new ast::SizeofExpr{ sizeofExpr->location, choice->expr } );
    15281529                }
     1530        }
     1531
     1532        void Finder::postvisit( const ast::CountExpr * countExpr ) {
     1533                assert( countExpr->type );
     1534                auto enumInst = countExpr->type.as<ast::EnumInstType>();
     1535                if ( !enumInst ) {
     1536                        SemanticError( countExpr, "Count Expression only supports Enum Type as operand: ");
     1537                }
     1538                addCandidate( ast::ConstantExpr::from_ulong(countExpr->location, enumInst->base->members.size()), tenv );
    15291539        }
    15301540
  • src/main.cpp

    r1725989 r525f7ad  
    5353#include "ControlStruct/FixLabels.hpp"      // for fixLabels
    5454#include "ControlStruct/HoistControlDecls.hpp" //  hoistControlDecls
     55#include "ControlStruct/TrasnlateEnumRange.hpp" // translateEnumRange
    5556#include "GenPoly/Box.hpp"                  // for box
    5657#include "GenPoly/InstantiateGeneric.hpp"   // for instantiateGeneric
     
    323324                PASS( "Hoist Struct", Validate::hoistStruct, transUnit );
    324325                PASS( "Validate Generic Parameters", Validate::fillGenericParameters, transUnit );
     326                PASS( "Translate Enum Range Expression", ControlStruct::translateEnumRange, transUnit );
    325327                PASS( "Translate Dimensions", Validate::translateDimensionParameters, transUnit );
    326328                // Need to happen before fixing returns because implementEnumFunc has ReturnStmt
Note: See TracChangeset for help on using the changeset viewer.