Changeset c298079
- Timestamp:
- Oct 16, 2023, 1:16:42 PM (9 months ago)
- Branches:
- master
- Children:
- 6bd9f9e
- Parents:
- bab2917 (diff), 61e5d99 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/uC++toCFA/uC++toCFA.tex
rbab2917 rc298079 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Sep 17 09:10:12202314 %% Update Count : 5 88313 %% Last Modified On : Sun Oct 15 23:09:58 2023 14 %% Update Count : 5926 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 119 119 120 120 \title{\vspace*{-0.5in} 121 \ CC/\uC to \CFA Cheat Sheet}121 \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 \CC/\uC and the right example is \CFA. 197 In subsequent code examples, the left example is \uC and the right example is \CFA. 198 199 200 \section{Stream I/O} 201 202 \CFA output streams automatically separate values and insert a newline at the end of the print. 203 204 \begin{cquote} 205 \begin{tabular}{l|l} 206 \begin{uC++} 207 #include <@iostream@> 208 using namespace std; 209 int i; double d; char c; 210 cin >> i >> d >> c; 211 cout << i << ' ' << d << ' ' << c | endl; 212 \end{uC++} 213 & 214 \begin{cfa} 215 #include <@fstream.hfa@> 216 217 int i; double d; char c; 218 sin | i | d | c; 219 sout | i | d | c 220 \end{cfa} 221 \end{tabular} 222 \end{cquote} 198 223 199 224 … … 203 228 \begin{tabular}{l|l} 204 229 \begin{uC++} 205 for ( ;; ) { ... } / while ( true ) { ... } 206 for ( int i = 0; i < 10; i += 1 ) { ... } 207 for ( int i = 5; i < 15; i += 2 ) { ... } 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++} 208 247 int i = 0 209 248 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 ) { ... } 249 @if ( i == 10 )@ { ... } 250 \end{uC++} 251 & 252 \begin{cfa} 217 253 218 254 for ( i; 10 ) { ... } 219 else { ... } // i == 10 220 \end{cfa} 221 \end{tabular} 222 \end{cquote} 223 224 225 \section{Exceptions} 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} 226 279 227 280 Currently, \CFA uses macros @ExceptionDecl@ and @ExceptionInst@ to declare and instantiate an exception. … … 230 283 \begin{uC++} 231 284 232 struct E {// local or global scope285 @_Exception@ E { // local or global scope 233 286 ... // exception fields 234 287 }; 235 288 try { 236 289 ... 237 if ( ... ) _ResumeE( /* initialization */ );238 if ( ... ) _ThrowE( /* initialization */ );239 ...240 } _CatchResume( E & ) { // should be reference290 if ( ... ) @_Resume@ E( /* initialization */ ); 291 if ( ... ) @_Throw@ E( /* initialization */ ); 292 ... 293 } @_CatchResume@( E & ) { // should be reference 241 294 ... 242 295 } catch( E & ) { … … 252 305 try { 253 306 ... 254 if ( ... ) throwResume@ExceptionInst@( E, /* intialization */ );255 if ( ... ) throw@ExceptionInst@( E, /* intialization */ );307 if ( ... ) @throwResume@ @ExceptionInst@( E, /* intialization */ ); 308 if ( ... ) @throw@ @ExceptionInst@( E, /* intialization */ ); 256 309 ... 257 } catchResume( E * ) { // must be pointer310 } @catchResume@( E * ) { // must be pointer 258 311 ... 259 312 } catch( E * ) { … … 265 318 266 319 267 \section{Stream I/O} 268 269 \CFA output streams automatically separate values and insert a newline at the end of the print. 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} 270 360 271 361 \begin{cquote} 272 362 \begin{tabular}{l|l} 273 363 \begin{uC++} 274 #include <@iostream@> 275 using namespace std; 276 int i; double d; char c; 277 cin >> i >> d >> c; 278 cout << i << ' ' << d << ' ' << c | endl;279 \end{uC++} 280 & 281 \begin{cfa} 282 #include <@fstream.hfa@> 283 284 int i; double d; char c;285 sin | i | d | c; 286 sout | i | d | c 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@ ) { ... } 287 377 \end{cfa} 288 378 \end{tabular} … … 332 422 333 423 334 \section{Constructor / Destructor}335 336 \begin{cquote}337 \begin{tabular}{l|l}338 \begin{uC++}339 struct S {340 ... // fields341 @S@(...) { ... }342 @~S@(...) { ... }343 };344 \end{uC++}345 &346 \begin{cfa}347 struct S {348 ... // fields349 };350 @?{}@( @S & s,@ ...) { ... }351 @^?{}@( @S & s@ ) { ... }352 \end{cfa}353 \end{tabular}354 \end{cquote}355 356 357 424 \section{\texorpdfstring{Structures (object-oriented \protect\vs routine style)}{Structures (object-oriented vs. routine style)}} 358 425 -
src/GenPoly/BoxNew.cpp
rbab2917 rc298079 386 386 // return value. 387 387 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. 388 /// Passes extra layout arguments for sized polymorphic type parameters. 395 389 ast::vector<ast::Expr>::iterator passTypeVars( 396 390 ast::ApplicationExpr * expr, 397 ast::Type const * polyRetType, 398 ast::FunctionType const * funcType, 399 const TypeVarMap & exprTyVars ); 391 ast::FunctionType const * funcType ); 400 392 /// Wraps a function application with a new temporary for the 401 393 /// out-parameter return value. … … 700 692 // the concrete type's parameters, not the formal type's). 701 693 ast::vector<ast::Expr>::iterator argIt = 702 passTypeVars( mutExpr, concRetType, function, exprTypeVars);694 passTypeVars( mutExpr, function ); 703 695 addInferredParams( mutExpr, argIt, function, exprTypeVars ); 704 696 … … 812 804 } 813 805 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 pass844 // 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 859 806 ast::vector<ast::Expr>::iterator CallAdapter::passTypeVars( 860 807 ast::ApplicationExpr * expr, 861 ast::Type const * polyRetType, 862 ast::FunctionType const * function, 863 const TypeVarMap & exprTypeVars ) { 808 ast::FunctionType const * function ) { 864 809 assert( typeSubs ); 865 810 ast::vector<ast::Expr>::iterator arg = expr->args.begin(); … … 880 825 new ast::AlignofExpr( expr->location, ast::deepCopy( concrete ) ) ); 881 826 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 the909 // 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 < argsToPass916 ; ++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 );924 827 } 925 828 return arg; … … 1523 1426 } 1524 1427 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 1532 1428 ast::FunctionDecl const * DeclAdapter::previsit( ast::FunctionDecl const * decl ) { 1533 1429 TypeVarMap localTypeVars = { ast::TypeData() }; … … 1584 1480 mutDecl->assertions.clear(); 1585 1481 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 no1605 // 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 1614 1482 // Prepend each argument group. From last group to first. addAdapters 1615 1483 // does do the same, it just does it itself and see all other parameters. 1616 1484 spliceBegin( mutDecl->params, inferredParams ); 1617 spliceBegin( mutDecl->params, otypeParams );1618 1485 spliceBegin( mutDecl->params, layoutParams ); 1619 1486 addAdapters( mutDecl, localTypeVars ); … … 1815 1682 beginGenericScope(); 1816 1683 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 }1826 1684 } 1827 1685 … … 1898 1756 // don't mark them as known in this scope. 1899 1757 expect_func_type = false; 1900 1901 // Make sure that any type information passed into the function is1902 // 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 }1910 1758 } 1911 1759
Note: See TracChangeset
for help on using the changeset viewer.