Changeset 6d2b3dc


Ignore:
Timestamp:
Jul 3, 2024, 5:32:06 PM (3 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
39cf5cc
Parents:
597f284
Message:

Change (enum) range loop so that it works on any type that define succ() and upperBound()

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/enum.cfa

    r597f284 r6d2b3dc  
    11#include "enum.hfa"
    22#include "fstream.hfa"
     3#include <string.h>
    34
    45#pragma GCC visibility push(default)
     
    1011        int args = fmt( is, "%255s", val );
    1112        if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
    12         // for ( s; E ) {
    13         //      if ( val == label( s ) ) { e = s; break; }
    14         // } else {
    15         //      fprintf( stderr, "invalid enumeration constant\n" );
    16         //      abort();                                                                        // cannot use abort stream
    17         // } // for
     13        for ( s; E ) {
     14                if ( strcmp(val, label( s )) == 0 ) { e = s; break; }
     15        } else {
     16                fprintf( stderr, "invalid enumeration constant\n" );
     17                abort();                                                                        // cannot use abort stream
     18        } // for
    1819        return is;
    1920}
  • src/ControlStruct/TranslateEnumRange.cpp

    r597f284 r6d2b3dc  
    2222        auto typeExpr = stmt->range_over.strict_as<ast::TypeExpr>();
    2323        auto type = typeExpr->type;
    24         auto inits = stmt->inits;
    25         auto enumInst = type.strict_as<ast::EnumInstType>();
    26         auto enumDecl = enumInst->base;
    2724
    2825        auto objInit = stmt->inits.front();
    29         auto initLocation = objInit->location;
    30         auto rangeLocation = stmt->range_over->location;
    3126        assert( stmt->inits.size() == 1 );
    3227
     
    4742const ast::Stmt* addInit::postvisit( const ast::ForStmt * stmt ) {
    4843    if ( stmt->range_over ) {
    49         auto typeExpr = stmt->range_over.strict_as<ast::TypeExpr>();
    50         auto type = typeExpr->type;
    5144        auto inits = stmt->inits;
    52         auto enumInst = type.strict_as<ast::EnumInstType>();
    53         auto enumDecl = enumInst->base;
    54 
    5545        auto init = stmt->inits.front();
    5646
     
    6050                if ( !objDecl->init ) {
    6151                    auto location = stmt->location;
    62                     // auto newInit = new ast::SingleInit( location, new ast::NameExpr( location, enumDecl->members.front()->name ) );
    6352                    ast::SingleInit * newInit = new ast::SingleInit( location,
    64                         new ast::NameExpr( location,
    65                            stmt->is_inc? enumDecl->members.front()->name: enumDecl->members.back()->name ) );
     53                        stmt->is_inc?
     54                        ast::UntypedExpr::createCall( location, "lowerBound", {} ):
     55                        ast::UntypedExpr::createCall( location, "upperBound", {} ),
     56                        ast::ConstructFlag::MaybeConstruct
     57                    );
    6658                    auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
    6759                    auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
     
    8072    auto initDecl = declStmt->decl.strict_as<ast::ObjectDecl>();
    8173    auto indexName = initDecl->name;
    82    
    83     auto typeExpr = stmt->range_over.strict_as<ast::TypeExpr>();
    84     auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>();
    85     auto enumDecl = enumInst->base;
    8674
    8775    // Both inc and dec check if the current posn less than the number of enumerator
     
    9078    ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
    9179        "?<=?",
    92         {new ast::CastExpr(location,
    93             new ast::NameExpr( location, indexName ),
    94             new ast::BasicType( ast::BasicKind::UnsignedInt
    95         ),ast::GeneratedFlag::ExplicitCast),
    96         ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 ) });
     80        {   new ast::NameExpr( location, indexName ),
     81            ast::UntypedExpr::createCall( location, "upperBound", {} )  });
    9782    auto increment = ast::UntypedExpr::createCall( location,
    98         stmt->is_inc? "succ": "pred",{
    99         new ast::NameExpr( location, indexName )
    100     });
     83        stmt->is_inc? "succ": "pred",
     84        { new ast::NameExpr( location, indexName ) });
    10185    auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
    10286    auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
     
    10690
    10791void translateEnumRange( ast::TranslationUnit & translationUnit ) {
    108     ast::Pass<addInitType>::run( translationUnit );
    10992    ast::Pass<addInit>::run( translationUnit );
    11093    ast::Pass<translateEnumRangeCore>::run( translationUnit );
  • src/Parser/StatementNode.cpp

    r597f284 r6d2b3dc  
    216216                return new ast::ForStmt( location,
    217217                        std::move( astinit ),
    218                         range_over, forctl->kind == OperKinds::LThan,
     218                        range_over, forctl->kind == OperKinds::LEThan,
    219219                        buildMoveSingle( stmt ),
    220220                        buildMoveOptional( else_ )
  • src/Parser/parser.yy

    r597f284 r6d2b3dc  
    275275} // forCtrl
    276276
    277 ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, __attribute__((unused)) OperKinds compop, ExpressionNode * range_over_expr ) {
     277ForCtrl * enumRangeCtrl( ExpressionNode * index_expr, OperKinds compop, ExpressionNode * range_over_expr, DeclarationNode * type ) {
     278        assert( compop == OperKinds::LEThan || compop == OperKinds::GEThan );
    278279        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index_expr->expr.get()) ) {
    279                 DeclarationNode * indexDecl = DeclarationNode::newName( new std::string(identifier->name) );
    280                 assert( range_over_expr );
     280                DeclarationNode * indexDecl =
     281                        DeclarationNode::newName( new std::string(identifier->name) )->addType( type );
    281282                return new ForCtrl( new StatementNode( indexDecl ), range_over_expr, compop );
    282283        } else {
     
    16051606                { SemanticError( yylloc, "illegal syntax, missing low/high value for ascending/descending range so index is uninitialized." ); $$ = nullptr; }
    16061607
    1607         | comma_expression ';' enum_key                                         // CFA, enum type
    1608                 {
    1609                         $$ = enumRangeCtrl( $1, OperKinds::LEThan, new ExpressionNode( new ast::TypeExpr( yylloc, $3->buildType() ) ) );
     1608        | comma_expression ';' type_type_specifier                                              // CFA, enum type
     1609                {
     1610                        $$ = enumRangeCtrl( $1, OperKinds::LEThan, new ExpressionNode( new ast::TypeExpr( yylloc, $3->clone()->buildType() ) ), $3 );
    16101611                }
    16111612        | comma_expression ';' downupdowneq enum_key            // CFA, enum type, reverse direction
     
    16151616                                $3 = OperKinds::GEThan;
    16161617                        } // if
    1617                         $$ = enumRangeCtrl( $1, $3, new ExpressionNode( new ast::TypeExpr( yylloc, $4->buildType() ) ) );
     1618                        $$ = enumRangeCtrl( $1, $3, new ExpressionNode( new ast::TypeExpr( yylloc, $4->clone()->buildType() ) ), $4 );
    16181619                }
    16191620        ;
     
    16211622enum_key:
    16221623        type_name
    1623                 { $$ = DeclarationNode::newEnum( $1->symbolic.name, nullptr, false, false ); }
     1624                {       typedefTable.makeTypedef( *$1->symbolic.name, "enum_type_nobody 1" );
     1625                        $$ = DeclarationNode::newEnum( $1->symbolic.name, nullptr, false, false ); }
    16241626        | ENUM identifier
    1625                 { $$ = DeclarationNode::newEnum( $2, nullptr, false, false ); }
     1627                {       typedefTable.makeTypedef( *$2, "enum_type_nobody 2" );
     1628                        $$ = DeclarationNode::newEnum( $2, nullptr, false, false ); }
    16261629        | ENUM type_name
    1627                 { $$ = DeclarationNode::newEnum( $2->symbolic.name, nullptr, false, false ); }
     1630                {       typedefTable.makeTypedef( *$2->symbolic.name, "enum_type_nobody 3" );
     1631                        $$ = DeclarationNode::newEnum( $2->symbolic.name, nullptr, false, false ); }
    16281632        ;
    16291633
Note: See TracChangeset for help on using the changeset viewer.