Changes in doc/papers/general/Paper.tex [4ada74e:b060aba]
- File:
-
- 1 edited
-
doc/papers/general/Paper.tex (modified) (30 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/papers/general/Paper.tex
r4ada74e rb060aba 7 7 \usepackage{listings} % format program code 8 8 \usepackage{enumitem} 9 \setlist[itemize]{topsep=3pt,itemsep=2pt,parsep=0pt}% global10 9 \usepackage[flushmargin]{footmisc} % support label/reference in footnote 11 10 \usepackage{rotating} … … 143 142 % replace/adjust listing characters that look bad in sanserif 144 143 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.1ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1 145 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {@}{\small{@}}1% {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1144 {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1 146 145 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex\textgreater}2, 147 146 moredelim=**[is][\color{red}]{`}{`}, … … 1073 1072 1074 1073 Both labelled @continue@ and @break@ are a @goto@ restricted in the following ways: 1075 \begin{itemize} 1074 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1076 1075 \item 1077 1076 They cannot create a loop, which means only the looping constructs cause looping. … … 1291 1290 The object is the implicit qualifier for the open structure-fields. 1292 1291 1293 All expressions in the expression list are open in parallelwithin the compound statement.1292 All expressions in the expression list are open in ``parallel'' within the compound statement. 1294 1293 This semantic is different from Pascal, which nests the openings from left to right. 1295 1294 The difference between parallel and nesting occurs for fields with the same name and type: … … 1337 1336 with ( (S)w ) { ... } $\C{// unambiguous, cast}$ 1338 1337 \end{cfa} 1339 and @with@ expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate:1338 and @with@ expressions may be pointers and references (see Section~\ref{s:References}) to aggregates: 1340 1339 \begin{cfa} 1341 1340 struct S { int i, j; } sv; 1342 with ( sv ) { $\C{ implicit reference}$1341 with ( sv ) { $\C{variable}$ 1343 1342 S & sr = sv; 1344 with ( sr ) { $\C{ explicitreference}$1343 with ( sr ) { $\C{reference}$ 1345 1344 S * sp = &sv; 1346 with ( *sp ) { $\C{ computed reference}$1345 with ( *sp ) { $\C{pointer}$ 1347 1346 i = 3; j = 4; $\C{\color{red}// sp-{\textgreater}i, sp-{\textgreater}j}$ 1348 1347 } 1349 i = 2; j = 3; $\C{\color{red}// sr.i, sr.j}$1348 i = 3; j = 4; $\C{\color{red}// sr.i, sr.j}$ 1350 1349 } 1351 i = 1; j = 2; $\C{\color{red}// sv.i, sv.j}$1350 i = 3; j = 4; $\C{\color{red}// sv.i, sv.j}$ 1352 1351 } 1353 1352 \end{cfa} … … 1356 1355 \subsection{Exception Handling} 1357 1356 1358 \CFA provides two forms of exception handling: \newterm{resumption} (fix-up) and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling}).1357 \CFA provides two forms of exception handling: \newterm{resumption} (fix-up) and \newterm{recovery}. 1359 1358 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}1366 1359 \begin{cquote} 1367 1360 \lstDeleteShortInline@% … … 1369 1362 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{Resumption}} & \multicolumn{1}{c}{\textbf{Recovery}} \\ 1370 1363 \begin{cfa} 1371 `_Exception R { int fix; };` 1364 _Exception E { int fix; }; 1372 1365 void f() { 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 1366 ... _Resume E; 1367 // control returns here after handler 1368 try { 1369 f(); 1370 } catchResume( E e ) { 1371 ... e.fix = ...; // return correction to raise 1380 1372 } // dynamic return to _Resume 1381 1373 \end{cfa} 1382 1374 & 1383 1375 \begin{cfa} 1384 `_Exception T {};` 1376 _Exception E {}; 1385 1377 void f() { 1386 1387 ... `throw( T{} );` ... 1378 ... _Throw E; 1388 1379 // control does NOT return here after handler 1389 `try`{1390 ... f(); ...1391 } `catch( T t )`{1380 try { 1381 f(); 1382 } catch( E e ) { 1392 1383 ... // recover and continue 1393 1384 } // static return to next statement … … 1396 1387 \lstMakeShortInline@% 1397 1388 \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 resumption1443 }1444 \end{cfa}1445 &1446 \begin{cfa}1447 disable $\emph{exception-type-list}$ {1448 // disallow non-local resumption1449 }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 clauses1463 } `finally` {1464 // house keeping1465 }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.1471 1389 1472 1390 1473 1391 \section{Declarations} 1474 1392 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. 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. 1481 1398 1482 1399 … … 1501 1418 For example, a routine returning a pointer to an array of integers is defined and used in the following way: 1502 1419 \begin{cfa} 1503 int `(*`f`())[`5`]` {...}; $\C{// definition}$1504 ... `(*`f`())[`3`]` += 1; $\C{// usage}$1420 int `(*`f`())[`5`]` {...}; $\C{// definition}$ 1421 ... `(*`f`())[`3`]` += 1; $\C{// usage}$ 1505 1422 \end{cfa} 1506 1423 Essentially, the return type is wrapped around the routine name in successive layers (like an onion). … … 1621 1538 \lstMakeShortInline@% 1622 1539 \end{cquote} 1623 Specifiers must appear at the start of a \CFA routine declaration\footnote{\label{StorageClassSpecifier}. 1540 All specifiers must appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier} 1624 1541 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}}. 1625 1542 … … 1645 1562 as well, parameter names are optional, \eg: 1646 1563 \begin{cfa} 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}$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}$ 1652 1569 \end{cfa} 1653 1570 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa). … … 1671 1588 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg: 1672 1589 \begin{cfa} 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}$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}$ 1677 1594 \end{cfa} 1678 1595 Note, \emph{a routine name cannot be specified}: 1679 1596 \begin{cfa} 1680 * [ int x ] f () fp; $\C{// routine name "f" is disallowed}$1597 * [ int x ] f () fp; $\C{// routine name "f" is disallowed}$ 1681 1598 \end{cfa} 1682 1599 … … 1704 1621 \begin{cfa} 1705 1622 int x = 1, y = 2, * p1, * p2, ** p3; 1706 p1 = &x; $\C{// p1 points to x}$1707 p2 = &y; $\C{// p2 points to y}$1708 p3 = &p1; $\C{// p3 points to p1}$1623 p1 = &x; $\C{// p1 points to x}$ 1624 p2 = &y; $\C{// p2 points to y}$ 1625 p3 = &p1; $\C{// p3 points to p1}$ 1709 1626 *p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15); 1710 1627 \end{cfa} … … 1718 1635 \begin{cfa} 1719 1636 int x = 1, y = 2, & r1, & r2, && r3; 1720 &r1 = &x; $\C{// r1 points to x}$1721 &r2 = &y; $\C{// r2 points to y}$1722 &&r3 = &&r1; $\C{// r3 points to r2}$1637 &r1 = &x; $\C{// r1 points to x}$ 1638 &r2 = &y; $\C{// r2 points to y}$ 1639 &&r3 = &&r1; $\C{// r3 points to r2}$ 1723 1640 r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); $\C{// implicit dereferencing}$ 1724 1641 \end{cfa} … … 1741 1658 \begin{cfa} 1742 1659 int & r = *new( int ); 1743 ... $\C{// non-null reference}$1660 ... 1744 1661 delete &r; 1745 r += 1; $\C{// undefined reference}$1662 r += 1; // undefined reference 1746 1663 \end{cfa} 1747 1664 \end{lrbox} 1748 1665 Rebinding allows \CFA references to be default-initialized (\eg to a null pointer\footnote{ 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: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: 1750 1667 \begin{cquote} 1751 1668 \usebox{\LstBox} … … 1762 1679 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@. 1763 1680 More precisely: 1764 \begin{itemize} 1681 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 1765 1682 \item 1766 1683 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). … … 1801 1718 1802 1719 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 \centering1811 \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 \hline1815 \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 qualification1866 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 1880 1720 \subsection{Constructors and Destructors} 1881 \label{s:ConstructorsDestructors}1882 1721 1883 1722 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. … … 1890 1729 1891 1730 In \CFA, a constructor is named @?{}@ and a destructor is named @^?{}@. 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.}.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. 1894 1733 Like other \CFA operators, these names represent the syntax used to call the constructor or destructor, \eg @?{}(x, ...)@ or @^{}(x, ...)@. 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.1734 The constructor and destructor have return type @void@ and a first parameter of reference to the object type to be constructed or destructs. 1896 1735 While the first parameter is informally called the @this@ parameter, as in object-oriented languages, any variable name may be used. 1897 1736 Both constructors and destructors allow additional parametes after the @this@ parameter for specifying values for initialization/de-initialization\footnote{ … … 1902 1741 }; 1903 1742 void ?{}( VLA & vla ) with ( vla ) { $\C{// default constructor}$ 1904 len = 10; data = alloc( len ); $\C{// shallow copy}$1743 len = 10; data = alloc( len ); 1905 1744 } 1906 1745 void ^?{}( VLA & vla ) with ( vla ) { $\C{// destructor}$ … … 1911 1750 } $\C{// implicit: ?\^{}\{\}( x );}$ 1912 1751 \end{cfa} 1913 (Note, the example is purposely kept simple by using shallow-copy semantics.)1914 1752 @VLA@ is a \newterm{managed type}\footnote{ 1915 1753 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. 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-generationplacement of implicit constructor and destructor calls among complex executable statements see~\cite[\S~2.2]{Schluntz17}.1754 A managed type is implicitly constructed upon allocation and destructed upon deallocation to ensure proper interaction with runtime resources, in this case the @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}. 1918 1756 1919 1757 \CFA also provides syntax for \newterm{initialization} and \newterm{copy}: … … 1966 1804 1967 1805 In some circumstance programmers may not wish to have constructor and destructor calls. 1968 In these cases, \CFA provides the initialization syntax \lstinline|S x @= {}|, and the object becomes unmanaged, so implicit constructor and destructorcalls are not generated.1806 In these cases, \CFA provides the initialization syntax \lstinline|S x @= {}|, and the object becomes unmanaged, so constructors and destructors calls are not generated. 1969 1807 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. 1970 1808 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. 1971 1809 1972 1810 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 \centering 1816 \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 \hline 1820 \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 qualification 1871 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 1973 1885 % \subsection{Default Parameters} 1974 1886 … … 1977 1889 1978 1890 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. 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@. 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. 1981 1892 1982 1893 … … 1995 1906 1996 1907 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 char2005 21_hhu // unsigned char2006 22_h // signed short int2007 23_uh // unsigned short int2008 24z // size_t2009 \end{cfa}2010 &2011 \begin{cfa}2012 20_L8 // int8_t2013 21_ul8 // uint8_t2014 22_l16 // int16_t2015 23_ul16 // uint16_t2016 24_l32 // int32_t2017 \end{cfa}2018 &2019 \begin{cfa}2020 25_ul32 // uint32_t2021 26_l64 // int64_t2022 27_l64u // uint64_t2023 26_L128 // int1282024 27_L128u // unsigned int1282025 \end{cfa}2026 \end{tabular}2027 \lstMakeShortInline@%2028 \end{cquote}2029 2030 2031 1908 \subsection{Units} 2032 1909 2033 1910 Alternative call syntax (literal argument before routine name) to convert basic literals into user literals. 2034 1911 2035 {\lstset{language=CFA, moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}1912 {\lstset{language=CFA,deletedelim=**[is][]{`}{`},moredelim=**[is][\color{red}]{@}{@}} 2036 1913 \begin{cfa} 2037 1914 struct Weight { double stones; }; 1915 2038 1916 void ?{}( Weight & w ) { w.stones = 0; } $\C{// operations}$ 2039 1917 void ?{}( Weight & w, double w ) { w.stones = w; } 2040 1918 Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; } 2041 1919 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}; }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}; } 2045 1923 2046 1924 int main() { 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; 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; 2052 1932 } 2053 1933 \end{cfa} … … 2152 2032 \end{cquote} 2153 2033 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). 2154 For example, it is impossible to overload @atan@ for both one and two arguments;2034 For example, it is not possible to overload @atan@ for both one and two arguments; 2155 2035 instead the names @atan@ and @atan2@ are required. 2156 2036 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. … … 2235 2115 ip = alloc( ip, 2 * dim ); 2236 2116 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 );2242 2117 \end{cfa} 2243 2118 & … … 2249 2124 ip = (int *)realloc( ip, 2 * dim * sizeof( int ) ); 2250 2125 ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) ); 2251 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} 2252 2137 ip = memalign( 16, sizeof( int ) ); 2253 2138 ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) ); … … 2366 2251 The implicit separator character (space/blank) is a separator not a terminator. 2367 2252 The rules for implicitly adding the separator are: 2368 \begin{itemize} 2253 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt] 2369 2254 \item 2370 2255 A separator does not appear at the start or end of a line. … … 2381 2266 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@ 2382 2267 }% 2268 \item 2269 There are routines to set and get the separator string, and manipulators to toggle separation on and off in the middle of output. 2383 2270 \end{itemize} 2384 There are routines to set and get the separator string, and manipulators to toggle separation on and off in the middle of output.2385 2271 2386 2272 … … 2401 2287 sout | "Factorial Numbers" | endl; 2402 2288 Int fact = 1; 2289 2403 2290 sout | 0 | fact | endl; 2404 2291 for ( unsigned int i = 1; i <= 40; i += 1 ) { … … 2413 2300 int main( void ) { 2414 2301 `gmp_printf`( "Factorial Numbers\n" ); 2415 `mpz_t` fact; `mpz_init_set_ui`( fact, 1 ); 2302 `mpz_t` fact; 2303 `mpz_init_set_ui`( fact, 1 ); 2416 2304 `gmp_printf`( "%d %Zd\n", 0, fact ); 2417 2305 for ( unsigned int i = 1; i <= 40; i += 1 ) {
Note:
See TracChangeset
for help on using the changeset viewer.