Changeset 0c327ce for src


Ignore:
Timestamp:
Jul 12, 2024, 3:30:06 PM (4 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
76b507d
Parents:
9c447e2
Message:
  1. Add bound check to Serial function: now compiler generates the unchecked functions in ImplementEnumFunc?, and enum.hfa implements the bound check on top. Todo: Wrapped the checked version into a trait; 2. countof is now works on any type that implement Countof(). Because Countof() is implemented in enum.hfa for all CfaEnum?, we can call countof on { T | CfaEnum?(T) }
Location:
src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    r9c447e2 r0c327ce  
    284284// --- CountExpr
    285285
     286CountExpr::CountExpr( const CodeLocation & loc, const Expr * e )
     287: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), expr(e), type( nullptr ) {}
     288
    286289CountExpr::CountExpr( const CodeLocation & loc, const Type * t )
    287 : Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), type( t ) {}
     290: Expr( loc, new BasicType( BasicKind::LongUnsignedInt) ), expr(nullptr), type( t ) {}
    288291
    289292// --- AlignofExpr
  • src/AST/Expr.hpp

    r9c447e2 r0c327ce  
    496496class CountExpr final : public Expr {
    497497public:
     498        ptr<Expr> expr;
    498499        ptr<Type> type;
    499500
     501        CountExpr( const CodeLocation & loc, const Expr * t );
    500502        CountExpr( const CodeLocation & loc, const Type * t );
    501503
  • src/AST/Pass.impl.hpp

    r9c447e2 r0c327ce  
    13391339                        maybe_accept( node, &CountExpr::result );
    13401340                }
    1341                 maybe_accept( node, &CountExpr::type );
     1341                if ( node->type ) {
     1342                        maybe_accept( node, &CountExpr::type );
     1343                } else {
     1344                        maybe_accept( node, &CountExpr::expr );
     1345                }
    13421346        }
    13431347        VISIT_END( Expr, node );
  • src/AST/Print.cpp

    r9c447e2 r0c327ce  
    11461146                os << "Count Expression on: ";
    11471147                ++indent;
    1148                 node->type->accept( *this );
     1148                if ( node->type ) node->type->accept( *this );
     1149                else safe_print( node->expr );
    11491150                --indent;
    11501151                postprint( node );
  • src/ControlStruct/TranslateEnumRange.cpp

    r9c447e2 r0c327ce  
    8181            ast::UntypedExpr::createCall( location, "upperBound", {} )  });
    8282    auto increment = ast::UntypedExpr::createCall( location,
    83         stmt->is_inc? "succ": "pred",
     83        stmt->is_inc? "succ_unsafe": "pred_unsafe",
    8484        { new ast::NameExpr( location, indexName ) });
    8585    auto assig = ast::UntypedExpr::createAssign( location, new ast::NameExpr( location, indexName ), increment );
  • src/Parser/parser.yy

    r9c447e2 r0c327ce  
    970970                        // $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) );
    971971                }
     972        | COUNTOF unary_expression
     973                {  $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    972974        | COUNTOF '(' type_no_function ')'
    973975                { $$ = new ExpressionNode( new ast::CountExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    974         | COUNTOF unary_expression
    975                 { SemanticError( yylloc, "countof for expressions is currently unimplemented. "); $$ = nullptr; }
    976976        ;
    977977
  • src/ResolvExpr/CandidateFinder.cpp

    r9c447e2 r0c327ce  
    14851485
    14861486        void Finder::postvisit( const ast::CountExpr * countExpr ) {
    1487                 assert( countExpr->type );
    1488                 auto enumInst = countExpr->type.as<ast::EnumInstType>();
    1489                 if ( !enumInst ) {
    1490                         SemanticError( countExpr, "Count Expression only supports Enum Type as operand: ");
    1491                 }
    1492                 addCandidate( ast::ConstantExpr::from_ulong(countExpr->location, enumInst->base->members.size()), tenv );
     1487                const ast::UntypedExpr * untyped;
     1488                if ( countExpr->type ) {
     1489                        auto enumInst = countExpr->type.as<ast::EnumInstType>();
     1490                        if ( enumInst ) {
     1491                                addCandidate( ast::ConstantExpr::from_ulong(countExpr->location, enumInst->base->members.size()), tenv );
     1492                                return;
     1493                        }
     1494                        auto untypedFirst = ast::UntypedExpr::createCall( countExpr->location, "lowerBound", {} );
     1495                        auto castFirst = new ast::CastExpr( countExpr->location, untypedFirst , countExpr->type );
     1496                        untyped = ast::UntypedExpr::createCall(
     1497                                countExpr->location, "Countof", { castFirst }
     1498                        );
     1499                }
     1500                if (!untyped) untyped = ast::UntypedExpr::createCall(
     1501                                countExpr->location, "Countof", { countExpr->expr }
     1502                );
     1503                CandidateFinder finder( context, tenv );
     1504                finder.find( untyped );
     1505                CandidateList winners = findMinCost( finder.candidates );
     1506                if ( winners.size() == 0 ) {
     1507                        SemanticError( countExpr->expr, "Countof is not implemented for operand: " );
     1508                }
     1509                if ( winners.size() !=  1 ) {
     1510                        SemanticError( countExpr->expr, "Ambiguous expression in countof operand: " );
     1511                }
     1512                CandidateRef & choice = winners.front();
     1513                choice->expr = referenceToRvalueConversion( choice->expr, choice->cost );
     1514                addCandidate( *choice, choice->expr );
    14931515        }
    14941516
  • src/Validate/ImplementEnumFunc.cpp

    r9c447e2 r0c327ce  
    228228ast::FunctionDecl* EnumAttrFuncGenerator::genFromIntProto() const {
    229229        return genProto(
    230                 "fromInt",
     230                "fromInt_unsafe",
    231231                {new ast::ObjectDecl(getLocation(), "_i", new ast::BasicType(ast::BasicKind::UnsignedInt))},
    232232                {new ast::ObjectDecl(getLocation(), "_ret", new ast::EnumInstType(decl))}
     
    313313                genFromIntProto(),
    314314                genFromInstanceProto(),
    315                 genInstToInstFuncProto("succ"),
    316                 genInstToInstFuncProto("pred")
     315                genInstToInstFuncProto("succ_unsafe"),
     316                genInstToInstFuncProto("pred_unsafe")
    317317        };
    318318        for (auto& proto: protos) produceForwardDecl(proto);
Note: See TracChangeset for help on using the changeset viewer.