Changeset d3aa55e9 for src


Ignore:
Timestamp:
Jun 27, 2024, 4:42:01 PM (6 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
7552fde
Parents:
d5efcb7
Message:
  1. Disallow implicit conversion from cfa enum to int during on the function call site; 2. implement the reverse enum loop
Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Stmt.hpp

    rd5efcb7 rd3aa55e9  
    238238        ptr<Expr> inc;
    239239        ptr<Expr> range_over;
     240        bool is_inc;
    240241        ptr<Stmt> body;
    241242        ptr<Stmt> else_;
     
    251252                        range_over(nullptr), body(body), else_(else_) {}
    252253
    253         ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over,
     254        ForStmt( const CodeLocation & loc, const std::vector<ptr<Stmt>> && inits, const Expr * range_over, bool is_inc,
    254255                         const Stmt * body, const Stmt * else_ )
    255                 : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), body(body), else_(else_) {}
     256                : Stmt(loc, std::move(labels)), inits(std::move(inits)), range_over(range_over), is_inc(is_inc),
     257                body(body), else_(else_) {}
    256258
    257259        const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
  • src/ControlStruct/TranslateEnumRange.cpp

    rd5efcb7 rd3aa55e9  
    2626        auto enumDecl = enumInst->base;
    2727
    28         auto init = stmt->inits.front();
     28        auto objInit = stmt->inits.front();
    2929
    30         if (auto declStmt = init.as<ast::DeclStmt>()) {
     30        auto initLocation = objInit->location;
     31        auto rangeLocation = stmt->range_over->location;
     32        assert( stmt->inits.size() == 1 );
     33
     34        if (auto declStmt = objInit.as<ast::DeclStmt>()) {
    3135            auto decl = declStmt->decl;
    3236            if ( auto objDecl = decl.as<ast::ObjectDecl>()) {
     
    5761                if ( !objDecl->init ) {
    5862                    auto location = stmt->location;
    59                     auto newInit = new ast::SingleInit( location, new ast::NameExpr( location, enumDecl->members.front()->name ) );
     63                    ast::SingleInit * newInit;
     64                    newInit = new ast::SingleInit( location,
     65                        new ast::NameExpr( location,
     66                        stmt->is_inc? enumDecl->members.front()->name: enumDecl->members.back()->name ) );
    6067                    auto objDeclWithInit = ast::mutate_field( objDecl, &ast::ObjectDecl::init, newInit );
    6168                    auto declWithInit = ast::mutate_field( declStmt, &ast::DeclStmt::decl, objDeclWithInit );
     
    7885    auto enumInst = typeExpr->type.strict_as<ast::EnumInstType>();
    7986    auto enumDecl = enumInst->base;
    80 
    81     auto condition = ast::UntypedExpr::createCall( location, "?<=?", {
    82         new ast::NameExpr( location, indexName ),
    83         // ast::ConstantExpr::from_ulong( location, enumDecl->members.size() )
    84         new ast::NameExpr( location, enumDecl->members.back()->name )
    85     });
    86     auto increment = ast::UntypedExpr::createCall( location, "succ", {
    87         new ast::NameExpr( location, indexName )
    88     });
     87   
     88    // Both inc and dec check if the current posn less than the number of enumerator
     89    // for dec, it keeps call pred until it passes 0 (the first enumerator) and underflow,
     90    // it wraps around and become unsigned max
     91    ast::UntypedExpr * condition = ast::UntypedExpr::createCall( location,
     92        "?<=?",
     93        {
     94            ast::UntypedExpr::createCall(location, "posn", { new ast::NameExpr( location, indexName ) } ),
     95            ast::ConstantExpr::from_ulong( location, enumDecl->members.size()-1 )
     96        });
     97    auto increment = ast::UntypedExpr::createCall( location,
     98        stmt->is_inc? "succ": "pred",
     99        { new ast::NameExpr( location, indexName ) });
    89100    auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
    90101    auto mut = ast::mutate_field( stmt, &ast::ForStmt::cond, condition );
  • src/Parser/StatementNode.cpp

    rd5efcb7 rd3aa55e9  
    216216                return new ast::ForStmt( location,
    217217                        std::move( astinit ),
    218                         range_over,
     218                        range_over, forctl->kind == OperKinds::LThan,
    219219                        buildMoveSingle( stmt ),
    220220                        buildMoveOptional( else_ )
  • src/Parser/StatementNode.hpp

    rd5efcb7 rd3aa55e9  
    6464        ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :
    6565                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 ) {}
     66        ForCtrl( StatementNode * decl, ExpressionNode * range_over, OperKinds kind ) :
     67                init( decl ), condition( nullptr ), change( nullptr ),  range_over( range_over ), kind( kind ) {}
    6868
    6969        StatementNode * init;
     
    7171        ExpressionNode * change;
    7272        ExpressionNode * range_over;
     73        OperKinds kind;
    7374};
    7475
  • src/Parser/parser.yy

    rd5efcb7 rd3aa55e9  
    279279                DeclarationNode * indexDecl = DeclarationNode::newName( new std::string(identifier->name) );
    280280                assert( range_over_expr );
    281                 return new ForCtrl( new StatementNode( indexDecl ), range_over_expr );
     281                return new ForCtrl( new StatementNode( indexDecl ), range_over_expr, compop );
    282282        } else {
    283283                SemanticError( yylloc, MISSING_LOOP_INDEX ); return nullptr;
  • src/ResolvExpr/CandidateFinder.cpp

    rd5efcb7 rd3aa55e9  
    698698                void postvisit( const ast::CountExpr * countExpr );
    699699
    700                 const ast::Expr * makeEnumOffsetCast( const ast::EnumInstType * src,
    701                         const ast::EnumInstType * dst
    702                         , const ast::Expr * expr, Cost minCost );
    703 
    704700                void postvisit( const ast::InitExpr * ) {
    705701                        assertf( false, "CandidateFinder should never see a resolved InitExpr." );
     
    12131209        }
    12141210
    1215         // src is a subset of dst
    1216         const ast::Expr * Finder::makeEnumOffsetCast( const ast::EnumInstType * src,
    1217                 const ast::EnumInstType * dst,
    1218                 const ast::Expr * expr,
    1219                 Cost minCost ) {
    1220                
    1221                 auto srcDecl = src->base;
    1222                 auto dstDecl = dst->base;
    1223 
    1224                 if (srcDecl->name == dstDecl->name) return expr;
    1225 
    1226                 for (auto& dstChild: dstDecl->inlinedDecl) {
    1227                         Cost c = castCost(src, dstChild, false, symtab, tenv);
    1228                         ast::CastExpr * castToDst;
    1229                         if (c<minCost) {
    1230                                 unsigned offset = dstDecl->calChildOffset(dstChild.get());
    1231                                 if (offset > 0) {
    1232                                         auto untyped = ast::UntypedExpr::createCall(
    1233                                                 expr->location,
    1234                                                 "?+?",
    1235                                                 { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
    1236                                                 ast::ConstantExpr::from_int(expr->location, offset)});
    1237                                         CandidateFinder finder(context, tenv);
    1238                                         finder.find( untyped );
    1239                                         CandidateList winners = findMinCost( finder.candidates );
    1240                                         CandidateRef & choice = winners.front();
    1241                                         // choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
    1242                                         choice->expr = new ast::CastExpr(expr->location, choice->expr, dstChild, ast::GeneratedFlag::ExplicitCast);
    1243                                         // castToDst = new ast::CastExpr(choice->expr, dstChild);
    1244                                         castToDst = new ast::CastExpr(
    1245                                                 makeEnumOffsetCast( src, dstChild, choice->expr, minCost ),
    1246                                          dst);
    1247 
    1248                                 } else {
    1249                                         castToDst = new ast::CastExpr( expr, dst );
    1250                                 }
    1251                                 return castToDst;
    1252                         }
    1253                 }
    1254                 SemanticError(expr, src->base->name + " is not a subtype of " + dst->base->name);
    1255                 return nullptr;
    1256         }
    1257 
    12581211        void Finder::postvisit( const ast::CastExpr * castExpr ) {
    12591212                ast::ptr< ast::Type > toType = castExpr->result;
     
    13091262                        auto argAsEnum = cand->expr->result.as<ast::EnumInstType>();
    13101263                        auto toAsEnum = toType.as<ast::EnumInstType>();
    1311                         if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {     
    1312                                 ast::ptr<ast::Expr> offsetExpr = makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
     1264                        if ( argAsEnum && toAsEnum && argAsEnum->name != toAsEnum->name ) {
     1265                                CandidateFinder subFinder(context, tenv);
     1266                                ast::ptr<ast::Expr> offsetExpr = subFinder.makeEnumOffsetCast(argAsEnum, toAsEnum, cand->expr, thisCost);
    13131267                                cand->expr = offsetExpr;
    13141268                        }
     
    21932147                                        expr->location,
    21942148                                        "?+?",
    2195                                         { new ast::CastExpr( expr, new ast::BasicType(ast::BasicKind::SignedInt) ),
    2196                                         ast::ConstantExpr::from_int(expr->location, offset)});
     2149                                        { new ast::CastExpr( expr->location,
     2150                                                expr,
     2151                                                new ast::BasicType(ast::BasicKind::SignedInt),
     2152                                                ast::GeneratedFlag::ExplicitCast ),
     2153                                                ast::ConstantExpr::from_int(expr->location, offset)} );
    21972154                                CandidateFinder finder(context, env);
    21982155                                finder.find( untyped );
  • src/ResolvExpr/CastCost.cpp

    rd5efcb7 rd3aa55e9  
    5353                void postvisit( const ast::EnumInstType * enumInst ) {
    5454                        cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env );
     55
     56                        if (Cost::unsafe < cost) {
     57                                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
     58                                Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     59                                cost = intCost < cost? intCost: cost;
     60                        }
     61                        if ( enumInst->base->isTyped && enumInst->base->base ) {
     62                                auto baseConversionCost =
     63                                        castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env );
     64                                cost = baseConversionCost < cost? baseConversionCost: cost;
     65                        }
    5566                }
    5667
  • src/ResolvExpr/ConversionCost.cpp

    rd5efcb7 rd3aa55e9  
    162162Cost conversionCost(
    163163        const ast::Type * src, const ast::Type * dst, bool srcIsLvalue,
    164         const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
     164const ast::SymbolTable & symtab, const ast::TypeEnvironment & env
    165165) {
    166166        if ( const ast::TypeInstType * inst = dynamic_cast< const ast::TypeInstType * >( dst ) ) {
     
    284284        if ( const ast::BasicType * dstAsBasic = dynamic_cast< const ast::BasicType * >( dst ) ) {
    285285                conversionCostFromBasicToBasic( basicType, dstAsBasic );
    286         }       else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
     286        } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) {
    287287                if ( dstAsEnumInst->base && !dstAsEnumInst->base->isTyped ) {
    288288                        cost = Cost::unsafe;
     
    368368                return;
    369369        }
    370         static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
    371         cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
     370
    372371        if ( !inst->base->isTyped ) {
     372                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) };
     373                cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
    373374                if ( cost < Cost::unsafe ) {
    374375                        cost.incSafe();
     
    376377                return;
    377378        }
    378         cost.incUnsafe();
     379        // cost.incUnsafe();
    379380}
    380381
  • src/ResolvExpr/Unify.cpp

    rd5efcb7 rd3aa55e9  
    276276        void postvisit( const ast::VoidType * ) {
    277277                result = dynamic_cast< const ast::VoidType * >( type2 );
    278                         // || tryToUnifyWithEnumValue(vt, type2, tenv, need, have, open, noWiden());
    279                 ;
    280278        }
    281279
     
    284282                        result = basic->kind == basic2->kind;
    285283                }
    286                 // result = result || tryToUnifyWithEnumValue(basic, type2, tenv, need, have, open, noWiden());
    287284        }
    288285
     
    293290                                noWiden());
    294291                }
    295                 // result = result || tryToUnifyWithEnumValue(pointer, type2, tenv, need, have, open, noWiden());
    296292        }
    297293
     
    312308                result = unifyExact(
    313309                        array->base, array2->base, tenv, need, have, open, noWiden());
    314                         // || tryToUnifyWithEnumValue(array, type2, tenv, need, have, open, noWiden());
    315310        }
    316311
     
    607602
    608603                result = unifyList( types, types2, tenv, need, have, open );
    609                         // || tryToUnifyWithEnumValue(tuple, type2, tenv, need, have, open, noWiden());
    610604        }
    611605
    612606        void postvisit( const ast::VarArgsType * ) {
    613607                result = dynamic_cast< const ast::VarArgsType * >( type2 );
    614                         // || tryToUnifyWithEnumValue(vat, type2, tenv, need, have, open, noWiden());
    615608        }
    616609
    617610        void postvisit( const ast::ZeroType * ) {
    618611                result = dynamic_cast< const ast::ZeroType * >( type2 );
    619                         // || tryToUnifyWithEnumValue(zt, type2, tenv, need, have, open, noWiden());
    620612        }
    621613
    622614        void postvisit( const ast::OneType * ) {
    623615                result = dynamic_cast< const ast::OneType * >( type2 );
    624                         // || tryToUnifyWithEnumValue(ot, type2, tenv, need, have, open, noWiden());
    625616        }
    626617};
Note: See TracChangeset for help on using the changeset viewer.