Changeset 5a806be4
- Timestamp:
- Feb 22, 2018, 11:13:27 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- df7a162
- Parents:
- a181494 (diff), 4ada74e (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/general/Paper.tex
ra181494 r5a806be4 7 7 \usepackage{listings} % format program code 8 8 \usepackage{enumitem} 9 \setlist[itemize]{topsep=3pt,itemsep=2pt,parsep=0pt}% global 9 10 \usepackage[flushmargin]{footmisc} % support label/reference in footnote 10 11 \usepackage{rotating} … … 142 143 % replace/adjust listing characters that look bad in sanserif 143 144 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1 144 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1145 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {@}{\small{@}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1 145 146 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex\textgreater}2, 146 147 moredelim=**[is][\color{red}]{`}{`}, … … 1072 1073 1073 1074 Both labelled @continue@ and @break@ are a @goto@ restricted in the following ways: 1074 \begin{itemize} [topsep=3pt,itemsep=2pt,parsep=0pt]1075 \begin{itemize} 1075 1076 \item 1076 1077 They cannot create a loop, which means only the looping constructs cause looping. … … 1290 1291 The object is the implicit qualifier for the open structure-fields. 1291 1292 1292 All expressions in the expression list are open in ``parallel''within the compound statement.1293 All expressions in the expression list are open in parallel within the compound statement. 1293 1294 This semantic is different from Pascal, which nests the openings from left to right. 1294 1295 The difference between parallel and nesting occurs for fields with the same name and type: … … 1336 1337 with ( (S)w ) { ... } $\C{// unambiguous, cast}$ 1337 1338 \end{cfa} 1338 and @with@ expressions may be pointers and references (see Section~\ref{s:References}) to aggregates:1339 and @with@ expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate: 1339 1340 \begin{cfa} 1340 1341 struct S { int i, j; } sv; 1341 with ( sv ) { $\C{ variable}$1342 with ( sv ) { $\C{implicit reference}$ 1342 1343 S & sr = sv; 1343 with ( sr ) { $\C{ reference}$1344 with ( sr ) { $\C{explicit reference}$ 1344 1345 S * sp = &sv; 1345 with ( *sp ) { $\C{ pointer}$1346 with ( *sp ) { $\C{computed reference}$ 1346 1347 i = 3; j = 4; $\C{\color{red}// sp-{\textgreater}i, sp-{\textgreater}j}$ 1347 1348 } 1348 i = 3; j = 4; $\C{\color{red}// sr.i, sr.j}$1349 i = 2; j = 3; $\C{\color{red}// sr.i, sr.j}$ 1349 1350 } 1350 i = 3; j = 4; $\C{\color{red}// sv.i, sv.j}$1351 i = 1; j = 2; $\C{\color{red}// sv.i, sv.j}$ 1351 1352 } 1352 1353 \end{cfa} … … 1355 1356 \subsection{Exception Handling} 1356 1357 1357 \CFA provides two forms of exception handling: \newterm{resumption} (fix-up) and \newterm{recovery} .1358 \CFA provides two forms of exception handling: \newterm{resumption} (fix-up) and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling}). 1358 1359 Both mechanisms provide dynamic call to a handler using dynamic name-lookup, where fix-up has dynamic return and recovery has static return from the handler. 1360 \CFA restricts exception types to those defined by aggregate type @_Exception@. 1361 The form of the raise dictates the set of handlers examined during propagation: \newterm{resumption propagation} (@resume@) only examines resumption handlers (@catchResume@); \newterm{terminating propagation} (@throw@) only examines termination handlers (@catch@). 1362 If @resume@ or @throw@ have no exception type, it is a reresume/rethrow, meaning the currently exception continues propagation. 1363 If there is no current exception, the reresume/rethrow results in an error. 1364 1365 \begin{figure} 1359 1366 \begin{cquote} 1360 1367 \lstDeleteShortInline@% … … 1362 1369 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{Resumption}} & \multicolumn{1}{c}{\textbf{Recovery}} \\ 1363 1370 \begin{cfa} 1364 _Exception E { int fix; }; 1371 `_Exception R { int fix; };` 1365 1372 void f() { 1366 ... _Resume E; 1367 // control returns here after handler 1368 try { 1369 f(); 1370 } catchResume( E e ) { 1371 ... e.fix = ...; // return correction to raise 1373 R r; 1374 ... `resume( r );` ... 1375 ... r.fix // control does return here after handler 1376 `try` { 1377 ... f(); ... 1378 } `catchResume( R r )` { 1379 ... r.fix = ...; // return correction to raise 1372 1380 } // dynamic return to _Resume 1373 1381 \end{cfa} 1374 1382 & 1375 1383 \begin{cfa} 1376 _Exception E {}; 1384 `_Exception T {};` 1377 1385 void f() { 1378 ... _Throw E; 1386 1387 ... `throw( T{} );` ... 1379 1388 // control does NOT return here after handler 1380 try{1381 f();1382 } catch( E e ){1389 `try` { 1390 ... f(); ... 1391 } `catch( T t )` { 1383 1392 ... // recover and continue 1384 1393 } // static return to next statement … … 1387 1396 \lstMakeShortInline@% 1388 1397 \end{cquote} 1398 \caption{\CFA Exception Handling} 1399 \label{f:CFAExceptionHandling} 1400 \end{figure} 1401 1402 The set of exception types in a list of catch clause may include both a resumption and termination handler: 1403 \begin{cfa} 1404 try { 1405 ... resume( `R{}` ); ... 1406 } catchResume( `R` r ) { ... throw( R{} ); ... } $\C{\color{red}// H1}$ 1407 catch( `R` r ) { ... } $\C{\color{red}// H2}$ 1408 1409 \end{cfa} 1410 The resumption propagation raises @R@ and the stack is not unwound; 1411 the exception is caught by the @catchResume@ clause and handler H1 is invoked. 1412 The termination propagation in handler H1 raises @R@ and the stack is unwound; 1413 the exception is caught by the @catch@ clause and handler H2 is invoked. 1414 The termination handler is available because the resumption propagation did not unwind the stack. 1415 1416 An additional feature is conditional matching in a catch clause: 1417 \begin{cfa} 1418 try { 1419 ... write( `datafile`, ... ); ... $\C{// may throw IOError}$ 1420 ... write( `logfile`, ... ); ... 1421 } catch ( IOError err; `err == datafile` ) { ... } $\C{// handle datafile error}$ 1422 catch ( IOError err; `err == logfile` ) { ... } $\C{// handle logfile error}$ 1423 catch ( IOError err ) { ... } $\C{// handler error from other files}$ 1424 \end{cfa} 1425 where the throw inserts the failing file-handle in the I/O exception. 1426 Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible.. 1427 1428 The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}: 1429 \begin{cfa} 1430 resume [ $\emph{exception-type}$ ] [ _At $\emph{alternate-stack}$ ] ; 1431 \end{cfa} 1432 The @_At@ clause raises the specified exception or the currently propagating exception (reresume) at another coroutine or task~\cite{Delisle18}. 1433 Nonlocal raise is restricted to resumption to provide the exception handler the greatest flexibility because processing the exception does not unwind its stack, allowing it to continue after the handle returns. 1434 1435 To facilitate nonlocal exception, \CFA provides dynamic enabling and disabling of nonlocal exception-propagation. 1436 The constructs for controlling propagation of nonlocal exceptions are the @enable@ and the @disable@ blocks: 1437 \begin{cquote} 1438 \lstDeleteShortInline@% 1439 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}} 1440 \begin{cfa} 1441 enable $\emph{exception-type-list}$ { 1442 // allow non-local resumption 1443 } 1444 \end{cfa} 1445 & 1446 \begin{cfa} 1447 disable $\emph{exception-type-list}$ { 1448 // disallow non-local resumption 1449 } 1450 \end{cfa} 1451 \end{tabular} 1452 \lstMakeShortInline@% 1453 \end{cquote} 1454 The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively. 1455 Specifying no exception type is shorthand for specifying all exception types. 1456 Both @enable@ and @disable@ blocks can be nested, turning propagation on/off on entry, and on exit, the specified exception types are restored to their prior state. 1457 1458 Finally, \CFA provides a Java like @finally@ clause after the catch clauses: 1459 \begin{cfa} 1460 try { 1461 ... f(); ... 1462 // catchResume or catch clauses 1463 } `finally` { 1464 // house keeping 1465 } 1466 \end{cfa} 1467 The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised. 1468 If an exception is raised and caught, the handler is run before the finally clause. 1469 Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated. 1470 Mimicking the @finally@ clause with mechanisms like RAII is non-trivially when there are multiple types and local accesses. 1389 1471 1390 1472 1391 1473 \section{Declarations} 1392 1474 1393 It is important that \CFA subjectively ``feel like'' C to programmers. 1394 An important part of this subjective feel is maintaining C's procedural paradigm, as opposed to the object-oriented paradigm of other systems languages such as \CC and Rust. 1395 Maintaining this procedural paradigm means that C coding-patterns remain not only functional but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development. 1396 Nonetheless, some features of object-oriented languages are undeniably convenient but are independent of object-oriented programming; 1397 \CFA adapts these features to a procedural paradigm. 1475 Declarations in C have weaknesses and omissions. 1476 \CFA attempts to correct and add to C declarations, while ensuring \CFA subjectively ``feels like'' C. 1477 An important part of this subjective feel is maintaining C's syntax and procedural paradigm, as opposed to functional and object-oriented approaches in other systems languages such as \CC and Rust. 1478 Maintaining the C approach means that C coding-patterns remain not only useable but idiomatic in \CFA, reducing the mental burden of retraining C programmers and switching between C and \CFA development. 1479 Nevertheless, some features from other approaches are undeniably convenient; 1480 \CFA attempts to adapt these features to the C paradigm. 1398 1481 1399 1482 … … 1418 1501 For example, a routine returning a pointer to an array of integers is defined and used in the following way: 1419 1502 \begin{cfa} 1420 int `(*`f`())[`5`]` {...}; $\C{// definition}$1421 ... `(*`f`())[`3`]` += 1; $\C{// usage}$1503 int `(*`f`())[`5`]` {...}; $\C{// definition}$ 1504 ... `(*`f`())[`3`]` += 1; $\C{// usage}$ 1422 1505 \end{cfa} 1423 1506 Essentially, the return type is wrapped around the routine name in successive layers (like an onion). … … 1538 1621 \lstMakeShortInline@% 1539 1622 \end{cquote} 1540 All specifiers must appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier} 1623 Specifiers must appear at the start of a \CFA routine declaration\footnote{\label{StorageClassSpecifier}. 1541 1624 The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}}. 1542 1625 … … 1562 1645 as well, parameter names are optional, \eg: 1563 1646 \begin{cfa} 1564 [ int x ] f ( /* void */ ); $\C{// returning int with no parameters}$1565 [ int x ] f (...); $\C{// returning int with unknown parameters}$1566 [ * int ] g ( int y ); $\C{// returning pointer to int with int parameter}$1567 [ void ] h ( int, char ); $\C{// returning no result with int and char parameters}$1568 [ * int, int ] j ( int ); $\C{// returning pointer to int and int, with int parameter}$1647 [ int x ] f ( /* void */ ); $\C{// returning int with no parameters}$ 1648 [ int x ] f (...); $\C{// returning int with unknown parameters}$ 1649 [ * int ] g ( int y ); $\C{// returning pointer to int with int parameter}$ 1650 [ void ] h ( int, char ); $\C{// returning no result with int and char parameters}$ 1651 [ * int, int ] j ( int ); $\C{// returning pointer to int and int, with int parameter}$ 1569 1652 \end{cfa} 1570 1653 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa). … … 1588 1671 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg: 1589 1672 \begin{cfa} 1590 * [ int x ] () fp; $\C{// pointer to routine returning int with no parameters}$1591 * [ * int ] ( int y ) gp; $\C{// pointer to routine returning pointer to int with int parameter}$1592 * [ ] ( int, char ) hp; $\C{// pointer to routine returning no result with int and char parameters}$1593 * [ * int, int ] ( int ) jp; $\C{// pointer to routine returning pointer to int and int, with int parameter}$1673 * [ int x ] () fp; $\C{// pointer to routine returning int with no parameters}$ 1674 * [ * int ] ( int y ) gp; $\C{// pointer to routine returning pointer to int with int parameter}$ 1675 * [ ] ( int, char ) hp; $\C{// pointer to routine returning no result with int and char parameters}$ 1676 * [ * int, int ] ( int ) jp; $\C{// pointer to routine returning pointer to int and int, with int parameter}$ 1594 1677 \end{cfa} 1595 1678 Note, \emph{a routine name cannot be specified}: 1596 1679 \begin{cfa} 1597 * [ int x ] f () fp; $\C{// routine name "f" is disallowed}$1680 * [ int x ] f () fp; $\C{// routine name "f" is disallowed}$ 1598 1681 \end{cfa} 1599 1682 … … 1621 1704 \begin{cfa} 1622 1705 int x = 1, y = 2, * p1, * p2, ** p3; 1623 p1 = &x; $\C{// p1 points to x}$1624 p2 = &y; $\C{// p2 points to y}$1625 p3 = &p1; $\C{// p3 points to p1}$1706 p1 = &x; $\C{// p1 points to x}$ 1707 p2 = &y; $\C{// p2 points to y}$ 1708 p3 = &p1; $\C{// p3 points to p1}$ 1626 1709 *p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15); 1627 1710 \end{cfa} … … 1635 1718 \begin{cfa} 1636 1719 int x = 1, y = 2, & r1, & r2, && r3; 1637 &r1 = &x; 1638 &r2 = &y; 1639 &&r3 = &&r1; 1720 &r1 = &x; $\C{// r1 points to x}$ 1721 &r2 = &y; $\C{// r2 points to y}$ 1722 &&r3 = &&r1; $\C{// r3 points to r2}$ 1640 1723 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); $\C{// implicit dereferencing}$ 1641 1724 \end{cfa} … … 1658 1741 \begin{cfa} 1659 1742 int & r = *new( int ); 1660 ... 1743 ... $\C{// non-null reference}$ 1661 1744 delete &r; 1662 r += 1; // undefined reference1745 r += 1; $\C{// undefined reference}$ 1663 1746 \end{cfa} 1664 1747 \end{lrbox} 1665 1748 Rebinding allows \CFA references to be default-initialized (\eg to a null pointer\footnote{ 1666 While effort has been put into non-null reference checking in \CC, the exercise seems moot for any non-managed languages, given that it only handles one of many different error situations:1749 While effort has been made into non-null reference checking in \CC and Java, the exercise seems moot for any non-managed languages (C/\CC), given that it only handles one of many different error situations: 1667 1750 \begin{cquote} 1668 1751 \usebox{\LstBox} … … 1679 1762 These explicit address-of operators can be thought of as ``cancelling out'' the implicit dereference operators, \eg @(&`*`)r1 = &x@ or @(&(&`*`)`*`)r3 = &(&`*`)r1@ or even @(&`*`)r2 = (&`*`)`*`r3@ for @&r2 = &r3@. 1680 1763 More precisely: 1681 \begin{itemize} [topsep=3pt,itemsep=2pt,parsep=0pt]1764 \begin{itemize} 1682 1765 \item 1683 1766 if @R@ is an rvalue of type {@T &@$_1 \cdots$@ &@$_r$} where $r \ge 1$ references (@&@ symbols) than @&R@ has type {@T `*`&@$_{\color{red}2} \cdots$@ &@$_{\color{red}r}$}, \\ \ie @T@ pointer with $r-1$ references (@&@ symbols). … … 1718 1801 1719 1802 1803 \subsection{Type Nesting} 1804 1805 Nested types provide a mechanism to organize associated types and refactor a subset of fields into a named aggregate (\eg sub-aggregates @name@, @address@, @department@, within aggregate @employe@). 1806 Java nested types are dynamic (apply to objects), \CC are static (apply to the \lstinline[language=C++]@class@), and C hoists (refactors) nested types into the enclosing scope, meaning there is no need for type qualification. 1807 Since \CFA in not object-oriented, adopting dynamic scoping does not make sense; 1808 instead \CFA adopts \CC static nesting, using the field-selection operator ``@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``@::@'' (see Figure~\ref{f:TypeNestingQualification}). 1809 \begin{figure} 1810 \centering 1811 \lstDeleteShortInline@% 1812 \begin{tabular}{@{}l@{\hspace{3em}}l|l@{}} 1813 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{C Type Nesting}} & \multicolumn{1}{c}{\textbf{C Implicit Hoisting}} & \multicolumn{1}{|c}{\textbf{\CFA}} \\ 1814 \hline 1815 \begin{cfa} 1816 struct S { 1817 enum C { R, G, B }; 1818 struct T { 1819 union U { int i, j; }; 1820 enum C c; 1821 short int i, j; 1822 }; 1823 struct T t; 1824 } s; 1825 1826 int rtn() { 1827 s.t.c = R; 1828 struct T t = { R, 1, 2 }; 1829 enum C c; 1830 union U u; 1831 } 1832 \end{cfa} 1833 & 1834 \begin{cfa} 1835 enum C { R, G, B }; 1836 union U { int i, j; }; 1837 struct T { 1838 enum C c; 1839 short int i, j; 1840 }; 1841 struct S { 1842 struct T t; 1843 } s; 1844 1845 1846 1847 1848 1849 1850 1851 \end{cfa} 1852 & 1853 \begin{cfa} 1854 struct S { 1855 enum C { R, G, B }; 1856 struct T { 1857 union U { int i, j; }; 1858 enum C c; 1859 short int i, j; 1860 }; 1861 struct T t; 1862 } s; 1863 1864 int rtn() { 1865 s.t.c = `S.`R; // type qualification 1866 struct `S.`T t = { `S.`R, 1, 2 }; 1867 enum `S.`C c; 1868 union `S.T.`U u; 1869 } 1870 \end{cfa} 1871 \end{tabular} 1872 \lstMakeShortInline@% 1873 \caption{Type Nesting / Qualification} 1874 \label{f:TypeNestingQualification} 1875 \end{figure} 1876 In the C left example, types @C@, @U@ and @T@ are implicitly hoisted outside of type @S@ into the containing block scope. 1877 In the \CFA right example, the types are not hoisted and accessible. 1878 1879 1720 1880 \subsection{Constructors and Destructors} 1881 \label{s:ConstructorsDestructors} 1721 1882 1722 1883 One of the strengths (and weaknesses) of C is memory-management control, allowing resource release to be precisely specified versus unknown release with garbage-collected memory-management. … … 1729 1890 1730 1891 In \CFA, a constructor is named @?{}@ and a destructor is named @^?{}@. 1731 The name @{}@ comes from the syntax for the initializer: @struct S { int i, j; } s = `{` 2, 3 `}`@ .1732 The symbol \lstinline+^+ is used because it was the last remaining binary operator that could be used in a unary context.1892 The name @{}@ comes from the syntax for the initializer: @struct S { int i, j; } s = `{` 2, 3 `}`@\footnote{% 1893 The symbol \lstinline+^+ is used for the destructor name because it was the last binary operator that could be used in a unary context.}. 1733 1894 Like other \CFA operators, these names represent the syntax used to call the constructor or destructor, \eg @?{}(x, ...)@ or @^{}(x, ...)@. 1734 The constructor and destructor have return type @void@ and a first parameter of reference to the object type to be constructed or destructs.1895 The constructor and destructor have return type @void@, and the first parameter is a reference to the object type to be constructed or destructed. 1735 1896 While the first parameter is informally called the @this@ parameter, as in object-oriented languages, any variable name may be used. 1736 1897 Both constructors and destructors allow additional parametes after the @this@ parameter for specifying values for initialization/de-initialization\footnote{ … … 1741 1902 }; 1742 1903 void ?{}( VLA & vla ) with ( vla ) { $\C{// default constructor}$ 1743 len = 10; data = alloc( len ); 1904 len = 10; data = alloc( len ); $\C{// shallow copy}$ 1744 1905 } 1745 1906 void ^?{}( VLA & vla ) with ( vla ) { $\C{// destructor}$ … … 1750 1911 } $\C{// implicit: ?\^{}\{\}( x );}$ 1751 1912 \end{cfa} 1913 (Note, the example is purposely kept simple by using shallow-copy semantics.) 1752 1914 @VLA@ is a \newterm{managed type}\footnote{ 1753 1915 A managed type affects the runtime environment versus a self-contained type.}: a type requiring a non-trivial constructor or destructor, or with a field of a managed type. 1754 A managed type is implicitly constructed upon allocation and destructed upon deallocation to ensure proper interaction with runtime resources, in this casethe @data@ array in the heap.1755 For details of the placement of implicit constructor and destructor calls among complex executable statements see~\cite[\S~2.2]{Schluntz17}.1916 A managed type is implicitly constructed at allocation and destructed at deallocation to ensure proper interaction with runtime resources, in this case, the @data@ array in the heap. 1917 For details of the code-generation placement of implicit constructor and destructor calls among complex executable statements see~\cite[\S~2.2]{Schluntz17}. 1756 1918 1757 1919 \CFA also provides syntax for \newterm{initialization} and \newterm{copy}: … … 1804 1966 1805 1967 In some circumstance programmers may not wish to have constructor and destructor calls. 1806 In these cases, \CFA provides the initialization syntax \lstinline|S x @= {}|, and the object becomes unmanaged, so constructors and destructorscalls are not generated.1968 In these cases, \CFA provides the initialization syntax \lstinline|S x @= {}|, and the object becomes unmanaged, so implicit constructor and destructor calls are not generated. 1807 1969 Any C initializer can be the right-hand side of an \lstinline|@=| initializer, \eg \lstinline|VLA a @= { 0, 0x0 }|, with the usual C initialization semantics. 1808 1970 The point of \lstinline|@=| is to provide a migration path from legacy C code to \CFA, by providing a mechanism to incrementally convert to implicit initialization. 1809 1971 1810 1972 1811 \subsection{Type Nesting}1812 1813 \CFA allows \newterm{type nesting}, and type qualification of the nested types (see Figure~\ref{f:TypeNestingQualification}), where as C hoists (refactors) nested types into the enclosing scope and has no type qualification.1814 \begin{figure}1815 \centering1816 \lstDeleteShortInline@%1817 \begin{tabular}{@{}l@{\hspace{3em}}l|l@{}}1818 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{C Type Nesting}} & \multicolumn{1}{c}{\textbf{C Implicit Hoisting}} & \multicolumn{1}{|c}{\textbf{\CFA}} \\1819 \hline1820 \begin{cfa}1821 struct S {1822 enum C { R, G, B };1823 struct T {1824 union U { int i, j; };1825 enum C c;1826 short int i, j;1827 };1828 struct T t;1829 } s;1830 1831 int rtn() {1832 s.t.c = R;1833 struct T t = { R, 1, 2 };1834 enum C c;1835 union U u;1836 }1837 \end{cfa}1838 &1839 \begin{cfa}1840 enum C { R, G, B };1841 union U { int i, j; };1842 struct T {1843 enum C c;1844 short int i, j;1845 };1846 struct S {1847 struct T t;1848 } s;1849 1850 1851 1852 1853 1854 1855 1856 \end{cfa}1857 &1858 \begin{cfa}1859 struct S {1860 enum C { R, G, B };1861 struct T {1862 union U { int i, j; };1863 enum C c;1864 short int i, j;1865 };1866 struct T t;1867 } s;1868 1869 int rtn() {1870 s.t.c = `S.`R; // type qualification1871 struct `S.`T t = { `S.`R, 1, 2 };1872 enum `S.`C c;1873 union `S.T.`U u;1874 }1875 \end{cfa}1876 \end{tabular}1877 \lstMakeShortInline@%1878 \caption{Type Nesting / Qualification}1879 \label{f:TypeNestingQualification}1880 \end{figure}1881 In the left example in C, types @C@, @U@ and @T@ are implicitly hoisted outside of type @S@ into the containing block scope.1882 In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``@::@''.1883 1884 1885 1973 % \subsection{Default Parameters} 1886 1974 … … 1889 1977 1890 1978 C already includes limited polymorphism for literals -- @0@ can be either an integer or a pointer literal, depending on context, while the syntactic forms of literals of the various integer and float types are very similar, differing from each other only in suffix. 1891 In keeping with the general \CFA approach of adding features while respecting ``the C way'' of doing things, we have extended both C's polymorphic zero and typed literal syntax to interoperate with user-defined types, while maintaining a backwards-compatible semantics. 1979 In keeping with the general \CFA approach of adding features while respecting the ``C-style'' of doing things, C's polymorphic constants and typed literal syntax are extended to interoperate with user-defined types, while maintaining a backwards-compatible semantics. 1980 A trivial example is allowing the underscore to separate prefixes, digits, and suffixes in all \CFA constants, as in Ada, \eg @0x`_`1.ffff`_`ffff`_`p`_`128`_`l@. 1892 1981 1893 1982 … … 1906 1995 1907 1996 1997 \subsection{Integral Suffixes} 1998 1999 Additional integral suffixes are added to cover all the integral types and lengths. 2000 \begin{cquote} 2001 \lstDeleteShortInline@% 2002 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}} 2003 \begin{cfa} 2004 20_hh // signed char 2005 21_hhu // unsigned char 2006 22_h // signed short int 2007 23_uh // unsigned short int 2008 24z // size_t 2009 \end{cfa} 2010 & 2011 \begin{cfa} 2012 20_L8 // int8_t 2013 21_ul8 // uint8_t 2014 22_l16 // int16_t 2015 23_ul16 // uint16_t 2016 24_l32 // int32_t 2017 \end{cfa} 2018 & 2019 \begin{cfa} 2020 25_ul32 // uint32_t 2021 26_l64 // int64_t 2022 27_l64u // uint64_t 2023 26_L128 // int128 2024 27_L128u // unsigned int128 2025 \end{cfa} 2026 \end{tabular} 2027 \lstMakeShortInline@% 2028 \end{cquote} 2029 2030 1908 2031 \subsection{Units} 1909 2032 1910 2033 Alternative call syntax (literal argument before routine name) to convert basic literals into user literals. 1911 2034 1912 {\lstset{language=CFA, deletedelim=**[is][]{`}{`},moredelim=**[is][\color{red}]{@}{@}}2035 {\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}} 1913 2036 \begin{cfa} 1914 2037 struct Weight { double stones; }; 1915 1916 2038 void ?{}( Weight & w ) { w.stones = 0; } $\C{// operations}$ 1917 2039 void ?{}( Weight & w, double w ) { w.stones = w; } 1918 2040 Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; } 1919 2041 1920 Weight @?`st@( double w ) { return (Weight){ w }; } $\C{// backquote for units}$1921 Weight @?`lb@( double w ) { return (Weight){ w / 14.0 }; }1922 Weight @?`kg@( double w ) { return (Weight) { w * 0.1575}; }2042 Weight |?`st|( double w ) { return (Weight){ w }; } $\C{// backquote for units}$ 2043 Weight |?`lb|( double w ) { return (Weight){ w / 14.0 }; } 2044 Weight |?`kg|( double w ) { return (Weight) { w * 0.1575}; } 1923 2045 1924 2046 int main() { 1925 Weight w, hw = { 14 }; $\C{// 14 stone}$ 1926 w = 11@`st@ + 1@`lb@; 1927 w = 70.3@`kg@; 1928 w = 155@`lb@; 1929 w = 0x_9b_u@`lb@; $\C{// hexadecimal unsigned weight (155)}$ 1930 w = 0_233@`lb@; $\C{// octal weight (155)}$ 1931 w = 5@`st@ + 8@`kg@ + 25@`lb@ + hw; 2047 Weight w, heavy = { 20 }; $\C{// 20 stone}$ 2048 w = 155|`lb|; 2049 w = 0x_9b_u|`lb|; $\C{// hexadecimal unsigned weight (155)}$ 2050 w = 0_233|`lb|; $\C{// octal weight (155)}$ 2051 w = 5|`st| + 8|`kg| + 25|`lb| + heavy; 1932 2052 } 1933 2053 \end{cfa} … … 2032 2152 \end{cquote} 2033 2153 While \Celeven has type-generic math~\cite[\S~7.25]{C11} in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a routine name with a single set of floating type(s). 2034 For example, it is notpossible to overload @atan@ for both one and two arguments;2154 For example, it is impossible to overload @atan@ for both one and two arguments; 2035 2155 instead the names @atan@ and @atan2@ are required. 2036 2156 The key observation is that only a restricted set of type-generic macros are provided for a limited set of routine names, which do not generalize across the type system, as in \CFA. … … 2115 2235 ip = alloc( ip, 2 * dim ); 2116 2236 ip = alloc( ip, 4 * dim, fill ); 2237 2238 ip = align_alloc( 16 ); 2239 ip = align_alloc( 16, fill ); 2240 ip = align_alloc( 16, dim ); 2241 ip = align_alloc( 16, dim, fill ); 2117 2242 \end{cfa} 2118 2243 & … … 2124 2249 ip = (int *)realloc( ip, 2 * dim * sizeof( int ) ); 2125 2250 ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) ); 2126 \end{cfa} 2127 \end{tabular} 2128 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}} 2129 \begin{cfa} 2130 ip = align_alloc( 16 ); 2131 ip = align_alloc( 16, fill ); 2132 ip = align_alloc( 16, dim ); 2133 ip = align_alloc( 16, dim, fill ); 2134 \end{cfa} 2135 & 2136 \begin{cfa} 2251 2137 2252 ip = memalign( 16, sizeof( int ) ); 2138 2253 ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) ); … … 2251 2366 The implicit separator character (space/blank) is a separator not a terminator. 2252 2367 The rules for implicitly adding the separator are: 2253 \begin{itemize} [topsep=3pt,itemsep=2pt,parsep=0pt]2368 \begin{itemize} 2254 2369 \item 2255 2370 A separator does not appear at the start or end of a line. … … 2266 2381 A separator does not appear before or after a C string beginning/ending with the quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]@`'": \t\v\f\r\n@ 2267 2382 }% 2268 \ item2383 \end{itemize} 2269 2384 There are routines to set and get the separator string, and manipulators to toggle separation on and off in the middle of output. 2270 \end{itemize}2271 2385 2272 2386 … … 2287 2401 sout | "Factorial Numbers" | endl; 2288 2402 Int fact = 1; 2289 2290 2403 sout | 0 | fact | endl; 2291 2404 for ( unsigned int i = 1; i <= 40; i += 1 ) { … … 2300 2413 int main( void ) { 2301 2414 `gmp_printf`( "Factorial Numbers\n" ); 2302 `mpz_t` fact; 2303 `mpz_init_set_ui`( fact, 1 ); 2415 `mpz_t` fact; `mpz_init_set_ui`( fact, 1 ); 2304 2416 `gmp_printf`( "%d %Zd\n", 0, fact ); 2305 2417 for ( unsigned int i = 1; i <= 40; i += 1 ) {
Note: See TracChangeset
for help on using the changeset viewer.