Changes in / [c298079:bab2917]


Ignore:
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • doc/uC++toCFA/uC++toCFA.tex

    rc298079 rbab2917  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sun Oct 15 23:09:58 2023
    14 %% Update Count     : 5926
     13%% Last Modified On : Sun Sep 17 09:10:12 2023
     14%% Update Count     : 5883
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    119119
    120120\title{\vspace*{-0.5in}
    121 \uC to \CFA Cheat Sheet}
     121\CC/\uC to \CFA Cheat Sheet}
    122122%\author{Peter A. Buhr}
    123123\date{}
     
    195195\end{cfa}
    196196\noindent
    197 In subsequent code examples, the left example is \uC and the right example is \CFA.
     197In subsequent code examples, the left example is \CC/\uC and the right example is \CFA.
     198
     199
     200\section{Looping}
     201
     202\begin{cquote}
     203\begin{tabular}{l|l}
     204\begin{uC++}
     205for ( ;; ) { ... } / while ( true ) { ... }
     206for ( int i = 0; i < 10; i += 1 ) { ... }
     207for ( int i = 5; i < 15; i += 2 ) { ... }
     208int i = 0
     209for ( i = 0; i < 10; i += 1 ) { ... }
     210if ( i == 10 ) { ... }
     211\end{uC++}
     212&
     213\begin{cfa}
     214for () { ... } / while () { ... }
     215for ( 10 ) { ... } / for ( i; 10 ) { ... }
     216for ( i; 5~15~2 ) { ... }
     217
     218for ( i; 10 ) { ... }
     219else { ... } // i == 10
     220\end{cfa}
     221\end{tabular}
     222\end{cquote}
     223
     224
     225\section{Exceptions}
     226
     227Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception.
     228\begin{cquote}
     229\begin{tabular}{l|ll}
     230\begin{uC++}
     231
     232struct E {              // local or global scope
     233        ... // exception fields
     234};
     235try {
     236        ...
     237        if ( ... ) _Resume E( /* initialization */ );
     238        if ( ... ) _Throw E( /* initialization */ );
     239        ...
     240} _CatchResume( E & ) { // should be reference
     241        ...
     242} catch( E & ) {
     243        ...
     244}
     245\end{uC++}
     246&
     247\begin{cfa}
     248#include <Exception.hfa>
     249@ExceptionDecl@( E,             // must be global scope
     250        ... // exception fields
     251);
     252try {
     253        ...
     254        if ( ... ) throwResume @ExceptionInst@( E, /* intialization */ );
     255        if ( ... ) throw @ExceptionInst@( E, /* intialization */ );
     256        ...
     257} catchResume( E * ) { // must be pointer
     258        ...
     259} catch( E * ) {
     260        ...
     261}
     262\end{cfa}
     263\end{tabular}
     264\end{cquote}
    198265
    199266
     
    218285sin | i | d | c;
    219286sout | i | d | c
    220 \end{cfa}
    221 \end{tabular}
    222 \end{cquote}
    223 
    224 
    225 \section{Looping}
    226 
    227 \begin{cquote}
    228 \begin{tabular}{l|l}
    229 \begin{uC++}
    230 for ( @;;@ ) { ... }  /  while ( @true@ ) { ... }
    231 for ( int i = 0; i < @10@; i += 1 ) { ... }
    232 for ( int i = @5@; i < @15@; i += @2@ ) { ... }
    233 for ( int i = -1; i <@=@ 10; i += 3 ) { ... }
    234 for ( int i = 10; i > 0; i @-@= 1 ) { ... }
    235 \end{uC++}
    236 &
    237 \begin{cfa}
    238 for () { ... }  /  while () { ... }
    239 for ( @10@ ) { ... }  /  for ( i; @10@ ) { ... }
    240 for ( i; @5@ ~ @15@ ~ @2@ ) { ... }
    241 for ( i; -1 ~@=@ 10 ~ 3 ) { ... }
    242 for ( i; 0 @-@~ 10 ) { ... }
    243 \end{cfa}
    244 \\
    245 \hline
    246 \begin{uC++}
    247 int i = 0
    248 for ( i = 0; i < 10; i += 1 ) { ... }
    249 @if ( i == 10 )@ { ... }
    250 \end{uC++}
    251 &
    252 \begin{cfa}
    253 
    254 for ( i; 10 ) { ... }
    255 @else@ { ... } // i == 10
    256 \end{cfa}
    257 \\
    258 \hline
    259 \begin{uC++}
    260 L1: for ( ;; ) {
    261         L2: for ( ;; ) {
    262                 ... @break L1@; ... @break L2@; ...
    263         }
    264 }
    265 \end{uC++}
    266 &
    267 \begin{cfa}
    268 L1: for () {
    269         L2: for () {
    270                 ... @break L1@; ... @break L2@; ...
    271         }
    272 }
    273 \end{cfa}
    274 \end{tabular}
    275 \end{cquote}
    276 
    277 
    278 \section{Exception}
    279 
    280 Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception.
    281 \begin{cquote}
    282 \begin{tabular}{l|ll}
    283 \begin{uC++}
    284 
    285 @_Exception@ E {        // local or global scope
    286         ... // exception fields
    287 };
    288 try {
    289         ...
    290         if ( ... ) @_Resume@ E( /* initialization */ );
    291         if ( ... ) @_Throw@ E( /* initialization */ );
    292                 ...
    293 } @_CatchResume@( E & ) { // should be reference
    294         ...
    295 } catch( E & ) {
    296         ...
    297 }
    298 \end{uC++}
    299 &
    300 \begin{cfa}
    301 #include <Exception.hfa>
    302 @ExceptionDecl@( E,             // must be global scope
    303         ... // exception fields
    304 );
    305 try {
    306         ...
    307         if ( ... ) @throwResume@ @ExceptionInst@( E, /* intialization */ );
    308         if ( ... ) @throw@ @ExceptionInst@( E, /* intialization */ );
    309         ...
    310 } @catchResume@( E * ) { // must be pointer
    311         ...
    312 } catch( E * ) {
    313         ...
    314 }
    315 \end{cfa}
    316 \end{tabular}
    317 \end{cquote}
    318 
    319 
    320 \section{Non-local Exception}
    321 
    322 \begin{cquote}
    323 \begin{tabular}{l|ll}
    324 \begin{uC++}
    325 
    326 
    327 void main() {
    328         try {
    329                 _Enable {
    330                         ... suspend(); ...
    331                 }
    332         } @_CatchResume@( E & ) { // reference
    333                 ...
    334         } catch( E & ) {
    335                 ...
    336         }
    337 }
    338 \end{uC++}
    339 &
    340 \begin{cfa}
    341 #define resumePoll( coroutine ) resume( coroutine ); checked_poll()
    342 #define suspendPoll suspend; checked_poll()
    343 void main() {
    344         try {
    345                 enable_ehm();
    346                 ... suspendPoll ...
    347                 disable_ehm();
    348         } @catchResume@( E * ) { // pointer
    349                 ...
    350         } catch( E & ) {
    351                 ...
    352         }
    353 }
    354 \end{cfa}
    355 \end{tabular}
    356 \end{cquote}
    357 
    358 
    359 \section{Constructor / Destructor}
    360 
    361 \begin{cquote}
    362 \begin{tabular}{l|l}
    363 \begin{uC++}
    364 struct S {
    365         ... // fields
    366         @S@(...) { ... }
    367         @~S@(...) { ... }
    368 };
    369 \end{uC++}
    370 &
    371 \begin{cfa}
    372 struct S {
    373         ... // fields
    374 };
    375 @?{}@( @S & s,@ ...) { ... }
    376 @^?{}@( @S & s@ ) { ... }
    377287\end{cfa}
    378288\end{tabular}
     
    422332
    423333
     334\section{Constructor / Destructor}
     335
     336\begin{cquote}
     337\begin{tabular}{l|l}
     338\begin{uC++}
     339struct S {
     340        ... // fields
     341        @S@(...) { ... }
     342        @~S@(...) { ... }
     343};
     344\end{uC++}
     345&
     346\begin{cfa}
     347struct S {
     348        ... // fields
     349};
     350@?{}@( @S & s,@ ...) { ... }
     351@^?{}@( @S & s@ ) { ... }
     352\end{cfa}
     353\end{tabular}
     354\end{cquote}
     355
     356
    424357\section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}}
    425358
  • src/GenPoly/BoxNew.cpp

    rc298079 rbab2917  
    386386        // return value.
    387387
    388         /// Passes extra layout arguments for sized polymorphic type parameters.
     388        /// Pass the extra type parameters from polymorphic generic arguments or
     389        /// return types into a function application.
     390        ast::vector<ast::Expr>::iterator passArgTypeVars(
     391                ast::ApplicationExpr * expr, ast::Type const * parmType,
     392                ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,
     393                const TypeVarMap & exprTyVars, std::set<std::string> & seenTypes );
     394        /// Passes extra type parameters into a polymorphic function application.
    389395        ast::vector<ast::Expr>::iterator passTypeVars(
    390396                ast::ApplicationExpr * expr,
    391                 ast::FunctionType const * funcType );
     397                ast::Type const * polyRetType,
     398                ast::FunctionType const * funcType,
     399                const TypeVarMap & exprTyVars );
    392400        /// Wraps a function application with a new temporary for the
    393401        /// out-parameter return value.
     
    692700        // the concrete type's parameters, not the formal type's).
    693701        ast::vector<ast::Expr>::iterator argIt =
    694                 passTypeVars( mutExpr, function );
     702                passTypeVars( mutExpr, concRetType, function, exprTypeVars );
    695703        addInferredParams( mutExpr, argIt, function, exprTypeVars );
    696704
     
    804812}
    805813
     814// arg is an in/out parameter that matches the return value.
     815ast::vector<ast::Expr>::iterator CallAdapter::passArgTypeVars(
     816                ast::ApplicationExpr * expr, ast::Type const * paramType,
     817                ast::Type const * argBaseType, ast::vector<ast::Expr>::iterator arg,
     818                const TypeVarMap & exprTypeVars, std::set<std::string> & seenTypes ) {
     819        ast::Type const * polyType = isPolyType( paramType, exprTypeVars );
     820        if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
     821                return arg;
     822        }
     823
     824        std::string typeName = Mangle::mangleType( polyType );
     825        if ( seenTypes.count( typeName ) ) return arg;
     826
     827        arg = expr->args.insert( arg,
     828                new ast::SizeofExpr( expr->location, ast::deepCopy( argBaseType ) )
     829        );
     830        arg++;
     831        arg = expr->args.insert( arg,
     832                new ast::AlignofExpr( expr->location, ast::deepCopy( argBaseType ) )
     833        );
     834        arg++;
     835        if ( dynamic_cast<ast::StructInstType const *>( polyType ) ) {
     836                auto argBaseStructType =
     837                                dynamic_cast<ast::StructInstType const *>( argBaseType );
     838                if ( nullptr == argBaseStructType ) {
     839                        SemanticError( expr,
     840                                "Cannot pass non-structure type for generic struct: " );
     841                }
     842
     843                // Zero-length arrays are forbidden by C, so don't pass
     844                // offset for empty structure.
     845                if ( !argBaseStructType->base->members.empty() ) {
     846                        arg = expr->args.insert( arg,
     847                                new ast::OffsetPackExpr(
     848                                        expr->location,
     849                                        ast::deepCopy( argBaseStructType ) )
     850                        );
     851                        arg++;
     852                }
     853        }
     854
     855        seenTypes.insert( typeName );
     856        return arg;
     857}
     858
    806859ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars(
    807860                ast::ApplicationExpr * expr,
    808                 ast::FunctionType const * function ) {
     861                ast::Type const * polyRetType,
     862                ast::FunctionType const * function,
     863                const TypeVarMap & exprTypeVars ) {
    809864        assert( typeSubs );
    810865        ast::vector<ast::Expr>::iterator arg = expr->args.begin();
     
    825880                        new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) );
    826881                arg++;
     882        }
     883
     884        // Add size/align for generic types to parameter list.
     885        if ( !expr->func->result ) return arg;
     886        ast::FunctionType const * funcType = getFunctionType( expr->func->result );
     887        assert( funcType );
     888
     889        // This iterator points at first original argument.
     890        ast::vector<ast::Expr>::const_iterator funcArg;
     891        // Names for generic types we've seen.
     892        std::set<std::string> seenTypes;
     893
     894        // A polymorphic return type may need to be added to the argument list.
     895        if ( polyRetType ) {
     896                assert( typeSubs );
     897                auto concRetType = replaceWithConcrete( polyRetType, *typeSubs );
     898                // TODO: This write-back may not be correct.
     899                arg = passArgTypeVars( expr, polyRetType, concRetType,
     900                                arg, exprTypeVars, seenTypes );
     901                // Skip the return parameter in the argument list.
     902                funcArg = arg + 1;
     903        } else {
     904                funcArg = arg;
     905        }
     906
     907        // TODO:
     908        // I believe this is (starts as) the number of original arguments to the
     909        // function with the args before funcArg all being inserted.
     910        ptrdiff_t argsToPass = std::distance( funcArg, expr->args.cend() );
     911
     912        // Add type information args for presently unseen types in parameter list.
     913        ast::vector<ast::Type>::const_iterator funcParam = funcType->params.begin();
     914        // assert( funcType->params.size() == argsToPass );
     915        for ( ; funcParam != funcType->params.end() && 0 < argsToPass
     916                        ; ++funcParam, --argsToPass ) {
     917                assert( 0 < argsToPass );
     918                assert( argsToPass <= (ptrdiff_t)expr->args.size() );
     919                ptrdiff_t index = expr->args.size() - argsToPass;
     920                ast::Type const * argType = expr->args[index]->result;
     921                if ( nullptr == argType ) continue;
     922                arg = passArgTypeVars( expr, *funcParam, argType,
     923                                arg, exprTypeVars, seenTypes );
    827924        }
    828925        return arg;
     
    14261523}
    14271524
     1525ast::ObjectDecl * makePtr(
     1526                CodeLocation const & location, std::string const & name ) {
     1527        return new ast::ObjectDecl( location, name,
     1528                new ast::PointerType( makeSizeAlignType() ),
     1529                nullptr, ast::Storage::Classes(), ast::Linkage::C, nullptr );
     1530}
     1531
    14281532ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) {
    14291533        TypeVarMap localTypeVars = { ast::TypeData() };
     
    14801584        mutDecl->assertions.clear();
    14811585
     1586        // Add size/align for generic parameter types to parameter list.
     1587        std::set<std::string> seenTypes;
     1588        ast::vector<ast::DeclWithType> otypeParams;
     1589        for ( ast::ptr<ast::DeclWithType> & funcParam : mutDecl->params ) {
     1590                ast::Type const * polyType = isPolyType( funcParam->get_type(), localTypeVars );
     1591                if ( !polyType || dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
     1592                        continue;
     1593                }
     1594                std::string typeName = Mangle::mangleType( polyType );
     1595                if ( seenTypes.count( typeName ) ) continue;
     1596                seenTypes.insert( typeName );
     1597
     1598                auto sizeParam = makeObj( funcParam->location, sizeofName( typeName ) );
     1599                otypeParams.emplace_back( sizeParam );
     1600
     1601                auto alignParam = makeObj( funcParam->location, alignofName( typeName ) );
     1602                otypeParams.emplace_back( alignParam );
     1603
     1604                // Zero-length arrays are illegal in C, so empty structs have no
     1605                // offset array.
     1606                if ( auto * polyStruct =
     1607                                dynamic_cast<ast::StructInstType const *>( polyType ) ;
     1608                                polyStruct && !polyStruct->base->members.empty() ) {
     1609                        auto offsetParam = makePtr( funcParam->location, offsetofName( typeName ) );
     1610                        otypeParams.emplace_back( offsetParam );
     1611                }
     1612        }
     1613
    14821614        // Prepend each argument group. From last group to first. addAdapters
    14831615        // does do the same, it just does it itself and see all other parameters.
    14841616        spliceBegin( mutDecl->params, inferredParams );
     1617        spliceBegin( mutDecl->params, otypeParams );
    14851618        spliceBegin( mutDecl->params, layoutParams );
    14861619        addAdapters( mutDecl, localTypeVars );
     
    16821815        beginGenericScope();
    16831816        beginTypeScope( decl->type );
     1817
     1818        // TODO: Going though dec->params does not work for some reason.
     1819        for ( ast::ptr<ast::Type> const & funcParam : decl->type->params ) {
     1820                // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
     1821                ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );
     1822                if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
     1823                        knownLayouts.insert( Mangle::mangleType( polyType ) );
     1824                }
     1825        }
    16841826}
    16851827
     
    17561898        // don't mark them as known in this scope.
    17571899        expect_func_type = false;
     1900
     1901        // Make sure that any type information passed into the function is
     1902        // accounted for.
     1903        for ( ast::ptr<ast::Type> const & funcParam : type->params ) {
     1904                // Condition here duplicates that in `DeclAdapter::previsit( FunctionDecl const * )`
     1905                ast::Type const * polyType = isPolyType( funcParam, scopeTypeVars );
     1906                if ( polyType && !dynamic_cast<ast::TypeInstType const *>( polyType ) ) {
     1907                        knownLayouts.insert( Mangle::mangleType( polyType ) );
     1908                }
     1909        }
    17581910}
    17591911
Note: See TracChangeset for help on using the changeset viewer.