Changes in / [c298079:bab2917]
- Files:
-
- 2 edited
-
doc/uC++toCFA/uC++toCFA.tex (modified) (5 diffs)
-
src/GenPoly/BoxNew.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/uC++toCFA/uC++toCFA.tex
rc298079 rbab2917 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Oct 15 23:09:58202314 %% Update Count : 5 92613 %% Last Modified On : Sun Sep 17 09:10:12 2023 14 %% Update Count : 5883 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 119 119 120 120 \title{\vspace*{-0.5in} 121 \ uC to \CFA Cheat Sheet}121 \CC/\uC to \CFA Cheat Sheet} 122 122 %\author{Peter A. Buhr} 123 123 \date{} … … 195 195 \end{cfa} 196 196 \noindent 197 In subsequent code examples, the left example is \uC and the right example is \CFA. 197 In 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++} 205 for ( ;; ) { ... } / while ( true ) { ... } 206 for ( int i = 0; i < 10; i += 1 ) { ... } 207 for ( int i = 5; i < 15; i += 2 ) { ... } 208 int i = 0 209 for ( i = 0; i < 10; i += 1 ) { ... } 210 if ( i == 10 ) { ... } 211 \end{uC++} 212 & 213 \begin{cfa} 214 for () { ... } / while () { ... } 215 for ( 10 ) { ... } / for ( i; 10 ) { ... } 216 for ( i; 5~15~2 ) { ... } 217 218 for ( i; 10 ) { ... } 219 else { ... } // i == 10 220 \end{cfa} 221 \end{tabular} 222 \end{cquote} 223 224 225 \section{Exceptions} 226 227 Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception. 228 \begin{cquote} 229 \begin{tabular}{l|ll} 230 \begin{uC++} 231 232 struct E { // local or global scope 233 ... // exception fields 234 }; 235 try { 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 ); 252 try { 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} 198 265 199 266 … … 218 285 sin | i | d | c; 219 286 sout | 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 \hline246 \begin{uC++}247 int i = 0248 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 == 10256 \end{cfa}257 \\258 \hline259 \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 scope286 ... // exception fields287 };288 try {289 ...290 if ( ... ) @_Resume@ E( /* initialization */ );291 if ( ... ) @_Throw@ E( /* initialization */ );292 ...293 } @_CatchResume@( E & ) { // should be reference294 ...295 } catch( E & ) {296 ...297 }298 \end{uC++}299 &300 \begin{cfa}301 #include <Exception.hfa>302 @ExceptionDecl@( E, // must be global scope303 ... // exception fields304 );305 try {306 ...307 if ( ... ) @throwResume@ @ExceptionInst@( E, /* intialization */ );308 if ( ... ) @throw@ @ExceptionInst@( E, /* intialization */ );309 ...310 } @catchResume@( E * ) { // must be pointer311 ...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 & ) { // reference333 ...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 * ) { // pointer349 ...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 ... // fields366 @S@(...) { ... }367 @~S@(...) { ... }368 };369 \end{uC++}370 &371 \begin{cfa}372 struct S {373 ... // fields374 };375 @?{}@( @S & s,@ ...) { ... }376 @^?{}@( @S & s@ ) { ... }377 287 \end{cfa} 378 288 \end{tabular} … … 422 332 423 333 334 \section{Constructor / Destructor} 335 336 \begin{cquote} 337 \begin{tabular}{l|l} 338 \begin{uC++} 339 struct S { 340 ... // fields 341 @S@(...) { ... } 342 @~S@(...) { ... } 343 }; 344 \end{uC++} 345 & 346 \begin{cfa} 347 struct S { 348 ... // fields 349 }; 350 @?{}@( @S & s,@ ...) { ... } 351 @^?{}@( @S & s@ ) { ... } 352 \end{cfa} 353 \end{tabular} 354 \end{cquote} 355 356 424 357 \section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}} 425 358 -
src/GenPoly/BoxNew.cpp
rc298079 rbab2917 386 386 // return value. 387 387 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. 389 395 ast::vector<ast::Expr>::iterator passTypeVars( 390 396 ast::ApplicationExpr * expr, 391 ast::FunctionType const * funcType ); 397 ast::Type const * polyRetType, 398 ast::FunctionType const * funcType, 399 const TypeVarMap & exprTyVars ); 392 400 /// Wraps a function application with a new temporary for the 393 401 /// out-parameter return value. … … 692 700 // the concrete type's parameters, not the formal type's). 693 701 ast::vector<ast::Expr>::iterator argIt = 694 passTypeVars( mutExpr, function);702 passTypeVars( mutExpr, concRetType, function, exprTypeVars ); 695 703 addInferredParams( mutExpr, argIt, function, exprTypeVars ); 696 704 … … 804 812 } 805 813 814 // arg is an in/out parameter that matches the return value. 815 ast::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 806 859 ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars( 807 860 ast::ApplicationExpr * expr, 808 ast::FunctionType const * function ) { 861 ast::Type const * polyRetType, 862 ast::FunctionType const * function, 863 const TypeVarMap & exprTypeVars ) { 809 864 assert( typeSubs ); 810 865 ast::vector<ast::Expr>::iterator arg = expr->args.begin(); … … 825 880 new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) ); 826 881 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 ); 827 924 } 828 925 return arg; … … 1426 1523 } 1427 1524 1525 ast::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 1428 1532 ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) { 1429 1533 TypeVarMap localTypeVars = { ast::TypeData() }; … … 1480 1584 mutDecl->assertions.clear(); 1481 1585 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 1482 1614 // Prepend each argument group. From last group to first. addAdapters 1483 1615 // does do the same, it just does it itself and see all other parameters. 1484 1616 spliceBegin( mutDecl->params, inferredParams ); 1617 spliceBegin( mutDecl->params, otypeParams ); 1485 1618 spliceBegin( mutDecl->params, layoutParams ); 1486 1619 addAdapters( mutDecl, localTypeVars ); … … 1682 1815 beginGenericScope(); 1683 1816 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 } 1684 1826 } 1685 1827 … … 1756 1898 // don't mark them as known in this scope. 1757 1899 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 } 1758 1910 } 1759 1911
Note:
See TracChangeset
for help on using the changeset viewer.