Changeset 5a806be4


Ignore:
Timestamp:
Feb 22, 2018, 11:13:27 AM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, 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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:/u/cforall/software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • doc/papers/general/Paper.tex

    ra181494 r5a806be4  
    77\usepackage{listings}                                           % format program code
    88\usepackage{enumitem}
     9\setlist[itemize]{topsep=3pt,itemsep=2pt,parsep=0pt}% global
    910\usepackage[flushmargin]{footmisc}                      % support label/reference in footnote
    1011\usepackage{rotating}
     
    142143% replace/adjust listing characters that look bad in sanserif
    143144literate={-}{\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}`}1
     145        {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {@}{\small{@}}1 % {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1
    145146        {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex\textgreater}2,
    146147moredelim=**[is][\color{red}]{`}{`},
     
    10721073
    10731074Both labelled @continue@ and @break@ are a @goto@ restricted in the following ways:
    1074 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt]
     1075\begin{itemize}
    10751076\item
    10761077They cannot create a loop, which means only the looping constructs cause looping.
     
    12901291The object is the implicit qualifier for the open structure-fields.
    12911292
    1292 All expressions in the expression list are open in ``parallel'' within the compound statement.
     1293All expressions in the expression list are open in parallel within the compound statement.
    12931294This semantic is different from Pascal, which nests the openings from left to right.
    12941295The difference between parallel and nesting occurs for fields with the same name and type:
     
    13361337with ( (S)w ) { ... }                                           $\C{// unambiguous, cast}$
    13371338\end{cfa}
    1338 and @with@ expressions may be pointers and references (see Section~\ref{s:References}) to aggregates:
     1339and @with@ expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate:
    13391340\begin{cfa}
    13401341struct S { int i, j; } sv;
    1341 with ( sv ) {                                                           $\C{variable}$
     1342with ( sv ) {                                                           $\C{implicit reference}$
    13421343        S & sr = sv;
    1343         with ( sr ) {                                                   $\C{reference}$
     1344        with ( sr ) {                                                   $\C{explicit reference}$
    13441345                S * sp = &sv;
    1345                 with ( *sp ) {                                          $\C{pointer}$
     1346                with ( *sp ) {                                          $\C{computed reference}$
    13461347                        i = 3; j = 4;                                   $\C{\color{red}// sp-{\textgreater}i, sp-{\textgreater}j}$
    13471348                }
    1348                 i = 3; j = 4;                                           $\C{\color{red}// sr.i, sr.j}$
     1349                i = 2; j = 3;                                           $\C{\color{red}// sr.i, sr.j}$
    13491350        }
    1350         i = 3; j = 4;                                                   $\C{\color{red}// sv.i, sv.j}$
     1351        i = 1; j = 2;                                                   $\C{\color{red}// sv.i, sv.j}$
    13511352}
    13521353\end{cfa}
     
    13551356\subsection{Exception Handling}
    13561357
    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}).
    13581359Both 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@.
     1361The 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@).
     1362If @resume@ or @throw@ have no exception type, it is a reresume/rethrow, meaning the currently exception continues propagation.
     1363If there is no current exception, the reresume/rethrow results in an error.
     1364
     1365\begin{figure}
    13591366\begin{cquote}
    13601367\lstDeleteShortInline@%
     
    13621369\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{Resumption}}       & \multicolumn{1}{c}{\textbf{Recovery}} \\
    13631370\begin{cfa}
    1364 _Exception E { int fix; };
     1371`_Exception R { int fix; };`
    13651372void 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
    13721380} // dynamic return to _Resume
    13731381\end{cfa}
    13741382&
    13751383\begin{cfa}
    1376 _Exception E {};
     1384`_Exception T {};`
    13771385void f() {
    1378         ... _Throw E;
     1386
     1387        ... `throw( T{} );` ...
    13791388        // control does NOT return here after handler
    1380 try {
    1381         f();
    1382 } catch( E e ) {
     1389`try` {
     1390        ... f(); ...
     1391} `catch( T t )` {
    13831392        ... // recover and continue
    13841393} // static return to next statement
     
    13871396\lstMakeShortInline@%
    13881397\end{cquote}
     1398\caption{\CFA Exception Handling}
     1399\label{f:CFAExceptionHandling}
     1400\end{figure}
     1401
     1402The set of exception types in a list of catch clause may include both a resumption and termination handler:
     1403\begin{cfa}
     1404try {
     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}
     1410The resumption propagation raises @R@ and the stack is not unwound;
     1411the exception is caught by the @catchResume@ clause and handler H1 is invoked.
     1412The termination propagation in handler H1 raises @R@ and the stack is unwound;
     1413the exception is caught by the @catch@ clause and handler H2 is invoked.
     1414The termination handler is available because the resumption propagation did not unwind the stack.
     1415
     1416An additional feature is conditional matching in a catch clause:
     1417\begin{cfa}
     1418try {
     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}
     1425where the throw inserts the failing file-handle in the I/O exception.
     1426Conditional 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
     1428The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}:
     1429\begin{cfa}
     1430resume [ $\emph{exception-type}$ ] [ _At $\emph{alternate-stack}$ ] ;
     1431\end{cfa}
     1432The @_At@ clause raises the specified exception or the currently propagating exception (reresume) at another coroutine or task~\cite{Delisle18}.
     1433Nonlocal 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
     1435To facilitate nonlocal exception, \CFA provides dynamic enabling and disabling of nonlocal exception-propagation.
     1436The 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}
     1441enable $\emph{exception-type-list}$ {
     1442        // allow non-local resumption
     1443}
     1444\end{cfa}
     1445&
     1446\begin{cfa}
     1447disable $\emph{exception-type-list}$ {
     1448        // disallow non-local resumption
     1449}
     1450\end{cfa}
     1451\end{tabular}
     1452\lstMakeShortInline@%
     1453\end{cquote}
     1454The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively.
     1455Specifying no exception type is shorthand for specifying all exception types.
     1456Both @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
     1458Finally, \CFA provides a Java like  @finally@ clause after the catch clauses:
     1459\begin{cfa}
     1460try {
     1461        ... f(); ...
     1462// catchResume or catch clauses
     1463} `finally` {
     1464        // house keeping
     1465}
     1466\end{cfa}
     1467The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised.
     1468If an exception is raised and caught, the handler is run before the finally clause.
     1469Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated.
     1470Mimicking the @finally@ clause with mechanisms like RAII is non-trivially when there are multiple types and local accesses.
    13891471
    13901472
    13911473\section{Declarations}
    13921474
    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.
     1475Declarations in C have weaknesses and omissions.
     1476\CFA attempts to correct and add to C declarations, while ensuring \CFA subjectively ``feels like'' C.
     1477An 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.
     1478Maintaining 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.
     1479Nevertheless, some features from other approaches are undeniably convenient;
     1480\CFA attempts to adapt these features to the C paradigm.
    13981481
    13991482
     
    14181501For example, a routine returning a pointer to an array of integers is defined and used in the following way:
    14191502\begin{cfa}
    1420 int `(*`f`())[`5`]` {...};                              $\C{// definition}$
    1421  ... `(*`f`())[`3`]` += 1;                              $\C{// usage}$
     1503int `(*`f`())[`5`]` {...};                                      $\C{// definition}$
     1504 ... `(*`f`())[`3`]` += 1;                                      $\C{// usage}$
    14221505\end{cfa}
    14231506Essentially, the return type is wrapped around the routine name in successive layers (like an onion).
     
    15381621\lstMakeShortInline@%
    15391622\end{cquote}
    1540 All specifiers must appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
     1623Specifiers must appear at the start of a \CFA routine declaration\footnote{\label{StorageClassSpecifier}.
    15411624The 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}}.
    15421625
     
    15621645as well, parameter names are optional, \eg:
    15631646\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}$
    15691652\end{cfa}
    15701653This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
     
    15881671The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    15891672\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}$
    15941677\end{cfa}
    15951678Note, \emph{a routine name cannot be specified}:
    15961679\begin{cfa}
    1597 * [ int x ] f () fp;                                    $\C{// routine name "f" is disallowed}$
     1680* [ int x ] f () fp;                                            $\C{// routine name "f" is disallowed}$
    15981681\end{cfa}
    15991682
     
    16211704\begin{cfa}
    16221705int 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}$
     1706p1 = &x;                                                                        $\C{// p1 points to x}$
     1707p2 = &y;                                                                        $\C{// p2 points to y}$
     1708p3 = &p1;                                                                       $\C{// p3 points to p1}$
    16261709*p2 = ((*p1 + *p2) * (**p3 - *p1)) / (**p3 - 15);
    16271710\end{cfa}
     
    16351718\begin{cfa}
    16361719int x = 1, y = 2, & r1, & r2, && r3;
    1637 &r1 = &x;  $\C{// r1 points to x}$
    1638 &r2 = &y;  $\C{// r2 points to y}$
    1639 &&r3 = &&r1;  $\C{// r3 points to r2}$
     1720&r1 = &x;                                                                       $\C{// r1 points to x}$
     1721&r2 = &y;                                                                       $\C{// r2 points to y}$
     1722&&r3 = &&r1;                                                            $\C{// r3 points to r2}$
    16401723r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15);       $\C{// implicit dereferencing}$
    16411724\end{cfa}
     
    16581741\begin{cfa}
    16591742int & r = *new( int );
    1660 ...
     1743...                                                                                     $\C{// non-null reference}$
    16611744delete &r;
    1662 r += 1;                 // undefined reference
     1745r += 1;                                                                         $\C{// undefined reference}$
    16631746\end{cfa}
    16641747\end{lrbox}
    16651748Rebinding 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:
     1749While 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:
    16671750\begin{cquote}
    16681751\usebox{\LstBox}
     
    16791762These 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@.
    16801763More precisely:
    1681 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt]
     1764\begin{itemize}
    16821765\item
    16831766if @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).
     
    17181801
    17191802
     1803\subsection{Type Nesting}
     1804
     1805Nested 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@).
     1806Java 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.
     1807Since \CFA in not object-oriented, adopting dynamic scoping does not make sense;
     1808instead \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}
     1816struct 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
     1826int 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}
     1835enum C { R, G, B };
     1836union U { int i, j; };
     1837struct T {
     1838        enum C c;
     1839        short int i, j;
     1840};
     1841struct S {
     1842        struct T t;
     1843} s;
     1844       
     1845
     1846
     1847
     1848
     1849
     1850
     1851\end{cfa}
     1852&
     1853\begin{cfa}
     1854struct 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
     1864int 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}
     1876In the C left example, types @C@, @U@ and @T@ are implicitly hoisted outside of type @S@ into the containing block scope.
     1877In the \CFA right example, the types are not hoisted and accessible.
     1878
     1879
    17201880\subsection{Constructors and Destructors}
     1881\label{s:ConstructorsDestructors}
    17211882
    17221883One 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.
     
    17291890
    17301891In \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.
     1892The name @{}@ comes from the syntax for the initializer: @struct S { int i, j; } s = `{` 2, 3 `}`@\footnote{%
     1893The symbol \lstinline+^+ is used for the destructor name because it was the last binary operator that could be used in a unary context.}.
    17331894Like 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.
     1895The constructor and destructor have return type @void@, and the first parameter is a reference to the object type to be constructed or destructed.
    17351896While the first parameter is informally called the @this@ parameter, as in object-oriented languages, any variable name may be used.
    17361897Both constructors and destructors allow additional parametes after the @this@ parameter for specifying values for initialization/de-initialization\footnote{
     
    17411902};
    17421903void ?{}( VLA & vla ) with ( vla ) {            $\C{// default constructor}$
    1743         len = 10;  data = alloc( len );
     1904        len = 10;  data = alloc( len );                 $\C{// shallow copy}$
    17441905}
    17451906void ^?{}( VLA & vla ) with ( vla ) {           $\C{// destructor}$
     
    17501911}                                                                                       $\C{// implicit:  ?\^{}\{\}( x );}$
    17511912\end{cfa}
     1913(Note, the example is purposely kept simple by using shallow-copy semantics.)
    17521914@VLA@ is a \newterm{managed type}\footnote{
    17531915A 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 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}.
     1916A 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.
     1917For details of the code-generation placement of implicit constructor and destructor calls among complex executable statements see~\cite[\S~2.2]{Schluntz17}.
    17561918
    17571919\CFA also provides syntax for \newterm{initialization} and \newterm{copy}:
     
    18041966
    18051967In 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 destructors calls are not generated.
     1968In these cases, \CFA provides the initialization syntax \lstinline|S x @= {}|, and the object becomes unmanaged, so implicit constructor and destructor calls are not generated.
    18071969Any C initializer can be the right-hand side of an \lstinline|@=| initializer, \eg \lstinline|VLA a @= { 0, 0x0 }|, with the usual C initialization semantics.
    18081970The 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.
    18091971
    18101972
    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 
    18851973% \subsection{Default Parameters}
    18861974
     
    18891977
    18901978C 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.
     1979In 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.
     1980A 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@.
    18921981
    18931982
     
    19061995
    19071996
     1997\subsection{Integral Suffixes}
     1998
     1999Additional 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}
     200420_hh     // signed char
     200521_hhu   // unsigned char
     200622_h      // signed short int
     200723_uh    // unsigned short int
     200824z        // size_t
     2009\end{cfa}
     2010&
     2011\begin{cfa}
     201220_L8     // int8_t
     201321_ul8    // uint8_t
     201422_l16    // int16_t
     201523_ul16  // uint16_t
     201624_l32    // int32_t
     2017\end{cfa}
     2018&
     2019\begin{cfa}
     202025_ul32      // uint32_t
     202126_l64        // int64_t
     202227_l64u      // uint64_t
     202326_L128     // int128
     202427_L128u  // unsigned int128
     2025\end{cfa}
     2026\end{tabular}
     2027\lstMakeShortInline@%
     2028\end{cquote}
     2029
     2030
    19082031\subsection{Units}
    19092032
    19102033Alternative call syntax (literal argument before routine name) to convert basic literals into user literals.
    19112034
    1912 {\lstset{language=CFA,deletedelim=**[is][]{`}{`},moredelim=**[is][\color{red}]{@}{@}}
     2035{\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
    19132036\begin{cfa}
    19142037struct Weight { double stones; };
    1915 
    19162038void ?{}( Weight & w ) { w.stones = 0; }        $\C{// operations}$
    19172039void ?{}( Weight & w, double w ) { w.stones = w; }
    19182040Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; }
    19192041
    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}; }
     2042Weight |?`st|( double w ) { return (Weight){ w }; } $\C{// backquote for units}$
     2043Weight |?`lb|( double w ) { return (Weight){ w / 14.0 }; }
     2044Weight |?`kg|( double w ) { return (Weight) { w * 0.1575}; }
    19232045
    19242046int 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;
    19322052}
    19332053\end{cfa}
     
    20322152\end{cquote}
    20332153While \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 not possible to overload @atan@ for both one and two arguments;
     2154For example, it is impossible to overload @atan@ for both one and two arguments;
    20352155instead the names @atan@ and @atan2@ are required.
    20362156The 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.
     
    21152235ip = alloc( ip, 2 * dim );
    21162236ip = alloc( ip, 4 * dim, fill );
     2237
     2238ip = align_alloc( 16 );
     2239ip = align_alloc( 16, fill );
     2240ip = align_alloc( 16, dim );
     2241ip = align_alloc( 16, dim, fill );
    21172242\end{cfa}
    21182243&
     
    21242249ip = (int *)realloc( ip, 2 * dim * sizeof( int ) );
    21252250ip = (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
    21372252ip = memalign( 16, sizeof( int ) );
    21382253ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) );
     
    22512366The implicit separator character (space/blank) is a separator not a terminator.
    22522367The rules for implicitly adding the separator are:
    2253 \begin{itemize}[topsep=3pt,itemsep=2pt,parsep=0pt]
     2368\begin{itemize}
    22542369\item
    22552370A separator does not appear at the start or end of a line.
     
    22662381A 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@
    22672382}%
    2268 \item
     2383\end{itemize}
    22692384There 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}
    22712385
    22722386
     
    22872401        sout | "Factorial Numbers" | endl;
    22882402        Int fact = 1;
    2289 
    22902403        sout | 0 | fact | endl;
    22912404        for ( unsigned int i = 1; i <= 40; i += 1 ) {
     
    23002413int main( void ) {
    23012414        `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 );
    23042416        `gmp_printf`( "%d %Zd\n", 0, fact );
    23052417        for ( unsigned int i = 1; i <= 40; i += 1 ) {
Note: See TracChangeset for help on using the changeset viewer.