Changeset adaee12


Ignore:
Timestamp:
Apr 28, 2021, 1:06:13 PM (6 months ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
b7fd2db
Parents:
e9c0b4c (diff), c7015e6b (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:software/cfa/cfa-cc

Files:
16 edited

Legend:

Unmodified
Added
Removed
  • doc/user/user.tex

    re9c0b4c radaee12  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue Apr 20 23:25:56 2021
    14 %% Update Count     : 4888
     13%% Last Modified On : Sun Apr 25 19:03:03 2021
     14%% Update Count     : 4951
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    7070\lstset{language=CFA}                                                                   % CFA default lnaguage
    7171\lstnewenvironment{C++}[1][]                            % use C++ style
    72 {\lstset{language=C++,moredelim=**[is][\protect\color{red}]{@}{@},#1}}
     72{\lstset{language=C++,moredelim=**[is][\protect\color{red}]{®}{®},#1}}
    7373{}
    7474
     
    8282\newcommand{\Textbf}[2][red]{{\color{#1}{\textbf{#2}}}}
    8383\newcommand{\Emph}[2][red]{{\color{#1}\textbf{\emph{#2}}}}
    84 \newcommand{\R}[1]{\Textbf{#1}}
    85 \newcommand{\RC}[1]{\Textbf{\LstBasicStyle{#1}}}
     84\newcommand{\R}[1]{{\color{red}#1}}
     85\newcommand{\RB}[1]{\Textbf{#1}}
    8686\newcommand{\B}[1]{{\Textbf[blue]{#1}}}
    8787\newcommand{\G}[1]{{\Textbf[OliveGreen]{#1}}}
     
    177177int main( void ) {
    178178        int x = 0, y = 1, z = 2;
    179         @printf( "%d %d %d\n", x, y, z );@
     179        ®printf( "%d %d %d\n", x, y, z );®
    180180}
    181181\end{cfa}
     
    186186int main( void ) {
    187187        int x = 0, y = 1, z = 2;
    188         @sout | x | y | z;@$\indexc{sout}$
     188        ®sout | x | y | z;®$\indexc{sout}$
    189189}
    190190\end{cfa}
     
    195195int main() {
    196196        int x = 0, y = 1, z = 2;
    197         @cout<<x<<" "<<y<<" "<<z<<endl;@
     197        ®cout<<x<<" "<<y<<" "<<z<<endl;®
    198198}
    199199\end{cfa}
     
    225225\begin{tabular}{@{}rcccccccc@{}}
    226226                & 2021  & 2016  & 2011  & 2006  & 2001  & 1996  & 1991  & 1986  \\ \hline
    227 \R{C}   & \R{1} & \R{2} & \R{2} & \R{1} & \R{1} & \R{1} & \R{1} & \R{1} \\
     227\RB{C}  & \RB{1}& \RB{2}& \RB{2}& \RB{1}& \RB{1}& \RB{1}& \RB{1}& \RB{1}\\
    228228Java    & 2             & 1             & 1             & 2             & 3             & 28    & -             & -             \\
    229229Python  & 3             & 5             & 6             & 7             & 23    & 13    & -             & -             \\
     
    259259The signature feature of \CFA is \emph{\Index{overload}able} \Index{parametric-polymorphic} functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name):
    260260\begin{cfa}
    261 @forall( otype T )@ T identity( T val ) { return val; }
     261®forall( otype T )® T identity( T val ) { return val; }
    262262int forty_two = identity( 42 ); $\C{// T is bound to int, forty\_two == 42}$
    263263\end{cfa}
     
    323323Whereas, \CFA wraps each of these routines into one overloaded name ©abs©:
    324324\begin{cfa}
    325 char @abs@( char );
    326 extern "C" { int @abs@( int ); } $\C{// use default C routine for int}$
    327 long int @abs@( long int );
    328 long long int @abs@( long long int );
    329 float @abs@( float );
    330 double @abs@( double );
    331 long double @abs@( long double );
    332 float _Complex @abs@( float _Complex );
    333 double _Complex @abs@( double _Complex );
    334 long double _Complex @abs@( long double _Complex );
     325char ®abs®( char );
     326extern "C" { int ®abs®( int ); } $\C{// use default C routine for int}$
     327long int ®abs®( long int );
     328long long int ®abs®( long long int );
     329float ®abs®( float );
     330double ®abs®( double );
     331long double ®abs®( long double );
     332float _Complex ®abs®( float _Complex );
     333double _Complex ®abs®( double _Complex );
     334long double _Complex ®abs®( long double _Complex );
    335335\end{cfa}
    336336The problem is \Index{name clash} between the C name ©abs© and the \CFA names ©abs©, resulting in two name linkages\index{C linkage}: ©extern "C"© and ©extern "Cforall"© (default).
     
    359359The 2011 C standard plus GNU extensions.
    360360\item
    361 \Indexc[deletekeywords=inline]{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{\lstinline[deletekeywords=inline]$-fgnu89-inline$}}
     361\Indexc[deletekeywords=inline]{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{\lstinline[deletekeywords=inline]{-fgnu89-inline}}}
    362362Use the traditional GNU semantics for inline routines in C11 mode, which allows inline routines in header files.
    363363\end{description}
     
    531531Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism:
    532532\begin{cfa}
    533 int @``@otype = 3; $\C{// make keyword an identifier}$
    534 double @``@forall = 3.5;
     533int ®``®otype = 3; $\C{// make keyword an identifier}$
     534double ®``®forall = 3.5;
    535535\end{cfa}
    536536
     
    543543// include file uses the CFA keyword "with".
    544544#if ! defined( with )                                                   $\C{// nesting ?}$
    545 #define with @``@with                                                   $\C{// make keyword an identifier}$
     545#define with ®``®with                                                   $\C{// make keyword an identifier}$
    546546#define __CFA_BFD_H__
    547547#endif
     
    561561Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore} as a separator, \eg:
    562562\begin{cfa}
    563 2@_@147@_@483@_@648; $\C{// decimal constant}$
    564 56@_@ul; $\C{// decimal unsigned long constant}$
    565 0@_@377; $\C{// octal constant}$
    566 0x@_@ff@_@ff; $\C{// hexadecimal constant}$
    567 0x@_@ef3d@_@aa5c; $\C{// hexadecimal constant}$
    568 3.141@_@592@_@654; $\C{// floating constant}$
    569 10@_@e@_@+1@_@00; $\C{// floating constant}$
    570 0x@_@ff@_@ff@_@p@_@3; $\C{// hexadecimal floating}$
    571 0x@_@1.ffff@_@ffff@_@p@_@128@_@l; $\C{// hexadecimal floating long constant}$
    572 L@_@$"\texttt{\textbackslash{x}}$@_@$\texttt{ff}$@_@$\texttt{ee}"$; $\C{// wide character constant}$
     5632®_®147®_®483®_®648; $\C{// decimal constant}$
     56456®_®ul; $\C{// decimal unsigned long constant}$
     5650®_®377; $\C{// octal constant}$
     5660x®_®ff®_®ff; $\C{// hexadecimal constant}$
     5670x®_®ef3d®_®aa5c; $\C{// hexadecimal constant}$
     5683.141®_®592®_®654; $\C{// floating constant}$
     56910®_®e®_®+1®_®00; $\C{// floating constant}$
     5700x®_®ff®_®ff®_®p®_®3; $\C{// hexadecimal floating}$
     5710x®_®1.ffff®_®ffff®_®p®_®128®_®l; $\C{// hexadecimal floating long constant}$
     572L®_®$"\texttt{\textbackslash{x}}$®_®$\texttt{ff}$®_®$\texttt{ee}"$; $\C{// wide character constant}$
    573573\end{cfa}
    574574The rules for placement of underscores are:
     
    603603Floating exponentiation\index{exponentiation!floating} is performed using \Index{logarithm}s\index{exponentiation!logarithm}, so the exponent cannot be negative.
    604604\begin{cfa}
    605 sout | 1 @\@ 0 | 1 @\@ 1 | 2 @\@ 8 | -4 @\@ 3 | 5 @\@ 3 | 5 @\@ 32 | 5L @\@ 32 | 5L @\@ 64 | -4 @\@ -3 | -4.0 @\@ -3 | 4.0 @\@ 2.1
    606            | (1.0f+2.0fi) @\@ (3.0f+2.0fi);
    607 1 1 256 -64 125 @0@ 3273344365508751233 @0@ @0@ -0.015625 18.3791736799526 0.264715-1.1922i
     605sout | 1 ®\® 0 | 1 ®\® 1 | 2 ®\® 8 | -4 ®\® 3 | 5 ®\® 3 | 5 ®\® 32 | 5L ®\® 32 | 5L ®\® 64 | -4 ®\® -3 | -4.0 ®\® -3 | 4.0 ®\® 2.1
     606           | (1.0f+2.0fi) ®\® (3.0f+2.0fi);
     6071 1 256 -64 125 ®0® 3273344365508751233 ®0® ®0® -0.015625 18.3791736799526 0.264715-1.1922i
    608608\end{cfa}
    609609Note, ©5 \ 32© and ©5L \ 64© overflow, and ©-4 \ -3© is a fraction but stored in an integer so all three computations generate an integral zero.
     
    613613\begin{cfa}
    614614forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); } )
    615 T ?@\@?( T ep, unsigned int y );
     615T ?®\®?( T ep, unsigned int y );
    616616forall( otype T | { void ?{}( T & this, one_t ); T ?*?( T, T ); } )
    617 T ?@\@?( T ep, unsigned long int y );
     617T ?®\®?( T ep, unsigned long int y );
    618618\end{cfa}
    619619The user type ©T© must define multiplication, one (©1©), and ©*©.
     
    625625
    626626
    627 %\subsection{\texorpdfstring{\protect\lstinline@if@/\protect\lstinline@while@ Statement}{if Statement}}
     627%\subsection{\texorpdfstring{\protect\lstinline{if}/\protect\lstinline{while} Statement}{if Statement}}
    628628\subsection{\texorpdfstring{\LstKeywordStyle{if} / \LstKeywordStyle{while} Statement}{if / while Statement}}
    629629
     
    631631Declarations in the ©do©-©while© condition are not useful because they appear after the loop body.}
    632632\begin{cfa}
    633 if ( @int x = f()@ ) ... $\C{// x != 0}$
    634 if ( @int x = f(), y = g()@ ) ... $\C{// x != 0 \&\& y != 0}$
    635 if ( @int x = f(), y = g(); x < y@ ) ... $\C{// relational expression}$
    636 if ( @struct S { int i; } x = { f() }; x.i < 4@ ) $\C{// relational expression}$
    637 
    638 while ( @int x = f()@ ) ... $\C{// x != 0}$
    639 while ( @int x = f(), y = g()@ ) ... $\C{// x != 0 \&\& y != 0}$
    640 while ( @int x = f(), y = g(); x < y@ ) ... $\C{// relational expression}$
    641 while ( @struct S { int i; } x = { f() }; x.i < 4@ ) ... $\C{// relational expression}$
     633if ( ®int x = f()® ) ... $\C{// x != 0}$
     634if ( ®int x = f(), y = g()® ) ... $\C{// x != 0 \&\& y != 0}$
     635if ( ®int x = f(), y = g(); x < y® ) ... $\C{// relational expression}$
     636if ( ®struct S { int i; } x = { f() }; x.i < 4® ) $\C{// relational expression}$
     637
     638while ( ®int x = f()® ) ... $\C{// x != 0}$
     639while ( ®int x = f(), y = g()® ) ... $\C{// x != 0 \&\& y != 0}$
     640while ( ®int x = f(), y = g(); x < y® ) ... $\C{// relational expression}$
     641while ( ®struct S { int i; } x = { f() }; x.i < 4® ) ... $\C{// relational expression}$
    642642\end{cfa}
    643643Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the ©if©/©while© expression, and the results are combined using the logical ©&&© operator.
     
    646646
    647647
    648 %\section{\texorpdfstring{\protect\lstinline@case@ Clause}{case Clause}}
     648%\section{\texorpdfstring{\protect\lstinline{case} Clause}{case Clause}}
    649649\subsection{\texorpdfstring{\LstKeywordStyle{case} Clause}{case Clause}}
    650650\label{s:caseClause}
     
    659659\begin{cfa}
    660660switch ( i ) {
    661   case @1, 3, 5@:
     661  case ®1, 3, 5®:
    662662        ...
    663   case @2, 4, 6@:
     663  case ®2, 4, 6®:
    664664        ...
    665665}
     
    686686\end{cquote}
    687687In addition, subranges are allowed to specify case values.\footnote{
    688 gcc has the same mechanism but awkward syntax, \lstinline@2 ...42@, because a space is required after a number, otherwise the period is a decimal point.}
     688gcc has the same mechanism but awkward syntax, \lstinline{2 ...42}, because a space is required after a number, otherwise the period is a decimal point.}
    689689\begin{cfa}
    690690switch ( i ) {
    691   case @1~5:@ $\C{// 1, 2, 3, 4, 5}$
     691  case ®1~5:® $\C{// 1, 2, 3, 4, 5}$
    692692        ...
    693   case @10~15:@ $\C{// 10, 11, 12, 13, 14, 15}$
     693  case ®10~15:® $\C{// 10, 11, 12, 13, 14, 15}$
    694694        ...
    695695}
     
    697697Lists of subranges are also allowed.
    698698\begin{cfa}
    699 case @1~5, 12~21, 35~42@:
    700 \end{cfa}
    701 
    702 
    703 %\section{\texorpdfstring{\protect\lstinline@switch@ Statement}{switch Statement}}
     699case ®1~5, 12~21, 35~42®:
     700\end{cfa}
     701
     702
     703%\section{\texorpdfstring{\protect\lstinline{switch} Statement}{switch Statement}}
    704704\subsection{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}
    705705
     
    741741if ( argc == 3 ) {
    742742        // open output file
    743         @// open input file
    744 @} else if ( argc == 2 ) {
    745         @// open input file (duplicate)
    746 
    747 @} else {
     743        ®// open input file
     744®} else if ( argc == 2 ) {
     745        ®// open input file (duplicate)
     746
     747®} else {
    748748        // usage message
    749749}
     
    756756\begin{cfa}
    757757switch ( i ) {
    758   @case 1: case 3: case 5:@     // odd values
     758  ®case 1: case 3: case 5:®     // odd values
    759759        // odd action
    760760        break;
    761   @case 2: case 4: case 6:@     // even values
     761  ®case 2: case 4: case 6:®     // even values
    762762        // even action
    763763        break;
     
    775775        if ( j < k ) {
    776776                ...
    777           @case 1:@             // transfer into "if" statement
     777          ®case 1:®             // transfer into "if" statement
    778778                ...
    779779        } // if
     
    781781        while ( j < 5 ) {
    782782                ...
    783           @case 3:@             // transfer into "while" statement
     783          ®case 3:®             // transfer into "while" statement
    784784                ...
    785785        } // while
     
    822822\begin{cfa}
    823823switch ( x ) {
    824         @int y = 1;@ $\C{// unreachable initialization}$
    825         @x = 7;@ $\C{// unreachable code without label/branch}$
     824        ®int y = 1;® $\C{// unreachable initialization}$
     825        ®x = 7;® $\C{// unreachable code without label/branch}$
    826826  case 0: ...
    827827        ...
    828         @int z = 0;@ $\C{// unreachable initialization, cannot appear after case}$
     828        ®int z = 0;® $\C{// unreachable initialization, cannot appear after case}$
    829829        z = 2;
    830830  case 1:
    831         @x = z;@ $\C{// without fall through, z is uninitialized}$
     831        ®x = z;® $\C{// without fall through, z is uninitialized}$
    832832}
    833833\end{cfa}
     
    861861Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, \eg:
    862862\begin{cfa}
    863 @choose@ ( i ) {
     863®choose® ( i ) {
    864864  case 1:  case 2:  case 3:
    865865        ...
    866         @// implicit end of switch (break)
    867   @case 5:
     866        ®// implicit end of switch (break)
     867  ®case 5:
    868868        ...
    869         @fallthru@; $\C{// explicit fall through}$
     869        ®fallthru®; $\C{// explicit fall through}$
    870870  case 7:
    871871        ...
    872         @break@ $\C{// explicit end of switch (redundant)}$
     872        ®break® $\C{// explicit end of switch (redundant)}$
    873873  default:
    874874        j = 3;
     
    891891\begin{cfa}
    892892switch ( x ) {
    893         @int i = 0;@ $\C{// allowed only at start}$
     893        ®int i = 0;® $\C{// allowed only at start}$
    894894  case 0:
    895895        ...
    896         @int j = 0;@ $\C{// disallowed}$
     896        ®int j = 0;® $\C{// disallowed}$
    897897  case 1:
    898898        {
    899                 @int k = 0;@ $\C{// allowed at different nesting levels}$
     899                ®int k = 0;® $\C{// allowed at different nesting levels}$
    900900                ...
    901           @case 2:@ $\C{// disallow case in nested statements}$
     901          ®case 2:® $\C{// disallow case in nested statements}$
    902902        }
    903903  ...
     
    916916  case 3:
    917917        if ( ... ) {
    918                 ... @fallthru;@ // goto case 4
     918                ... ®fallthru;® // goto case 4
    919919        } else {
    920920                ...
     
    931931choose ( ... ) {
    932932  case 3:
    933         ... @fallthrough common;@
     933        ... ®fallthrough common;®
    934934  case 4:
    935         ... @fallthrough common;@
    936 
    937   @common:@ // below fallthrough
     935        ... ®fallthrough common;®
     936
     937  ®common:® // below fallthrough
    938938                          // at case-clause level
    939939        ...     // common code for cases 3/4
     
    951951                for ( ... ) {
    952952                        // multi-level transfer
    953                         ... @fallthru common;@
     953                        ... ®fallthru common;®
    954954                }
    955955                ...
    956956        }
    957957        ...
    958   @common:@ // below fallthrough
     958  ®common:® // below fallthrough
    959959                          // at case-clause level
    960960\end{cfa}
     
    971971\hline
    972972\begin{cfa}
    973 while @($\,$)@ { sout | "empty"; break; }
    974 do { sout | "empty"; break; } while @($\,$)@;
    975 for @($\,$)@ { sout | "empty"; break; }
    976 for ( @0@ ) { sout | "A"; } sout | "zero";
    977 for ( @1@ ) { sout | "A"; }
    978 for ( @10@ ) { sout | "A"; }
    979 for ( @= 10@ ) { sout | "A"; }
    980 for ( @1 ~= 10 ~ 2@ ) { sout | "B"; }
    981 for ( @10 -~= 1 ~ 2@ ) { sout | "C"; }
    982 for ( @0.5 ~ 5.5@ ) { sout | "D"; }
    983 for ( @5.5 -~ 0.5@ ) { sout | "E"; }
    984 for ( @i; 10@ ) { sout | i; }
    985 for ( @i; = 10@ ) { sout | i; }
    986 for ( @i; 1 ~= 10 ~ 2@ ) { sout | i; }
    987 for ( @i; 10 -~= 1 ~ 2@ ) { sout | i; }
    988 for ( @i; 0.5 ~ 5.5@ ) { sout | i; }
    989 for ( @i; 5.5 -~ 0.5@ ) { sout | i; }
    990 for ( @ui; 2u ~= 10u ~ 2u@ ) { sout | ui; }
    991 for ( @ui; 10u -~= 2u ~ 2u@ ) { sout | ui; }
     973while ®($\,$)® { sout | "empty"; break; }
     974do { sout | "empty"; break; } while ®($\,$)®;
     975for ®($\,$)® { sout | "empty"; break; }
     976for ( ®0® ) { sout | "A"; } sout | "zero";
     977for ( ®1® ) { sout | "A"; }
     978for ( ®10® ) { sout | "A"; }
     979for ( ®= 10® ) { sout | "A"; }
     980for ( ®1 ~= 10 ~ 2® ) { sout | "B"; }
     981for ( ®10 -~= 1 ~ 2® ) { sout | "C"; }
     982for ( ®0.5 ~ 5.5® ) { sout | "D"; }
     983for ( ®5.5 -~ 0.5® ) { sout | "E"; }
     984for ( ®i; 10® ) { sout | i; }
     985for ( ®i; = 10® ) { sout | i; }
     986for ( ®i; 1 ~= 10 ~ 2® ) { sout | i; }
     987for ( ®i; 10 -~= 1 ~ 2® ) { sout | i; }
     988for ( ®i; 0.5 ~ 5.5® ) { sout | i; }
     989for ( ®i; 5.5 -~ 0.5® ) { sout | i; }
     990for ( ®ui; 2u ~= 10u ~ 2u® ) { sout | ui; }
     991for ( ®ui; 10u -~= 2u ~ 2u® ) { sout | ui; }
    992992enum { N = 10 };
    993 for ( @N@ ) { sout | "N"; }
    994 for ( @i; N@ ) { sout | i; }
    995 for ( @i; N -~ 0@ ) { sout | i; }
     993for ( ®N® ) { sout | "N"; }
     994for ( ®i; N® ) { sout | i; }
     995for ( ®i; N -~ 0® ) { sout | i; }
    996996const int start = 3, comp = 10, inc = 2;
    997 for ( @i; start ~ comp ~ inc + 1@ ) { sout | i; }
    998 for ( i; 1 ~ $\R{@}$ ) { if ( i > 10 ) break; sout | i; }
    999 for ( i; 10 -~ $\R{@}$ ) { if ( i < 0 ) break; sout | i; }
    1000 for ( i; 2 ~ $\R{@}$ ~ 2 ) { if ( i > 10 ) break; sout | i; }
    1001 for ( i; 2.1 ~ $\R{@}$ ~ $\R{@}$ ) { if ( i > 10.5 ) break; sout | i; i += 1.7; }
    1002 for ( i; 10 -~ $\R{@}$ ~ 2 ) { if ( i < 0 ) break; sout | i; }
    1003 for ( i; 12.1 ~ $\R{@}$ ~ $\R{@}$ ) { if ( i < 2.5 ) break; sout | i; i -= 1.7; }
    1004 for ( i; 5 @:@ j; -5 ~ $@$ ) { sout | i | j; }
    1005 for ( i; 5 @:@ j; -5 -~ $@$ ) { sout | i | j; }
    1006 for ( i; 5 @:@ j; -5 ~ $@$ ~ 2 ) { sout | i | j; }
    1007 for ( i; 5 @:@ j; -5 -~ $@$ ~ 2 ) { sout | i | j; }
    1008 for ( i; 5 @:@ j; -5 ~ $@$ ) { sout | i | j; }
    1009 for ( i; 5 @:@ j; -5 -~ $@$ ) { sout | i | j; }
    1010 for ( i; 5 @:@ j; -5 ~ $@$ ~ 2 ) { sout | i | j; }
    1011 for ( i; 5 @:@ j; -5 -~ $@$ ~ 2 ) { sout | i | j; }
    1012 for ( i; 5 @:@ j; -5 -~ $@$ ~ 2 @:@ k; 1.5 ~ $@$ ) { sout | i | j | k; }
    1013 for ( i; 5 @:@ j; -5 -~ $@$ ~ 2 @:@ k; 1.5 ~ $@$ ) { sout | i | j | k; }
    1014 for ( i; 5 @:@ k; 1.5 ~ $@$ @:@ j; -5 -~ $@$ ~ 2 ) { sout | i | j | k; }
     997for ( ®i; start ~ comp ~ inc + 1® ) { sout | i; }
     998for ( i; 1 ~ ®@® ) { if ( i > 10 ) break; sout | i; }
     999for ( i; 10 -~ ®@® ) { if ( i < 0 ) break; sout | i; }
     1000for ( i; 2 ~ ®@® ~ 2 ) { if ( i > 10 ) break; sout | i; }
     1001for ( i; 2.1 ~ ®@® ~ ®@® ) { if ( i > 10.5 ) break; sout | i; i += 1.7; }
     1002for ( i; 10 -~ ®@® ~ 2 ) { if ( i < 0 ) break; sout | i; }
     1003for ( i; 12.1 ~ ®@® ~ ®@® ) { if ( i < 2.5 ) break; sout | i; i -= 1.7; }
     1004for ( i; 5 ®:® j; -5 ~ @ ) { sout | i | j; }
     1005for ( i; 5 ®:® j; -5 -~ @ ) { sout | i | j; }
     1006for ( i; 5 ®:® j; -5 ~ @ ~ 2 ) { sout | i | j; }
     1007for ( i; 5 ®:® j; -5 -~ @ ~ 2 ) { sout | i | j; }
     1008for ( i; 5 ®:® j; -5 ~ @ ) { sout | i | j; }
     1009for ( i; 5 ®:® j; -5 -~ @ ) { sout | i | j; }
     1010for ( i; 5 ®:® j; -5 ~ @ ~ 2 ) { sout | i | j; }
     1011for ( i; 5 ®:® j; -5 -~ @ ~ 2 ) { sout | i | j; }
     1012for ( i; 5 ®:® j; -5 -~ @ ~ 2 ®:® k; 1.5 ~ @ ) { sout | i | j | k; }
     1013for ( i; 5 ®:® j; -5 -~ @ ~ 2 ®:® k; 1.5 ~ @ ) { sout | i | j | k; }
     1014for ( i; 5 ®:® k; 1.5 ~ @ ®:® j; -5 -~ @ ~ 2 ) { sout | i | j | k; }
    10151015\end{cfa}
    10161016&
     
    10901090The loop index is polymorphic in the type of the comparison value N (when the start value is implicit) or the start value M.
    10911091\begin{cfa}
    1092 for ( i; @5@ )                                  $\C[2.5in]{// typeof(5) i; 5 is comparison value}$
    1093 for ( i; @1.5@~5.5~0.5 )                $\C{// typeof(1.5) i; 1.5 is start value}$
     1092for ( i; ®5® )                                  $\C[2.5in]{// typeof(5) i; 5 is comparison value}$
     1093for ( i; ®1.5®~5.5~0.5 )                $\C{// typeof(1.5) i; 1.5 is start value}$
    10941094\end{cfa}
    10951095\item
    10961096An empty conditional implies comparison value of ©1© (true).
    10971097\begin{cfa}
    1098 while ( $\R{/*empty*/}$ )               $\C{// while ( true )}$
    1099 for ( $\R{/*empty*/}$ )                 $\C{// for ( ; true; )}$
    1100 do ... while ( $\R{/*empty*/}$ ) $\C{// do ... while ( true )}$
     1098while ( ®/*empty*/®  )                  $\C{// while ( true )}$
     1099for ( ®/*empty*/® )                    $\C{// for ( ; true; )}$
     1100do ... while ( ®/*empty*/®  )    $\C{// do ... while ( true )}$
    11011101\end{cfa}
    11021102\item
    11031103A comparison N is implicit up-to exclusive range [0,N\R{)}.
    11041104\begin{cfa}
    1105 for ( @5@ )                                             $\C{// for ( typeof(5) i; i < 5; i += 1 )}$
     1105for ( ®5® )                                             $\C{// for ( typeof(5) i; i < 5; i += 1 )}$
    11061106\end{cfa}
    11071107\item
    11081108A comparison ©=© N is implicit up-to inclusive range [0,N\R{]}.
    11091109\begin{cfa}
    1110 for ( @=@5 )                                    $\C{// for ( typeof(5) i; i <= 5; i += 1 )}$
     1110for ( ®=®5 )                                    $\C{// for ( typeof(5) i; i <= 5; i += 1 )}$
    11111111\end{cfa}
    11121112\item
    11131113The up-to range M ©~©\index{~@©~©} N means exclusive range [M,N\R{)}.
    11141114\begin{cfa}
    1115 for ( 1@~@5 )                                   $\C{// for ( typeof(1) i = 1; i < 5; i += 1 )}$
     1115for ( 1®~®5 )                                   $\C{// for ( typeof(1) i = 1; i < 5; i += 1 )}$
    11161116\end{cfa}
    11171117\item
    11181118The up-to range M ©~=©\index{~=@©~=©} N means inclusive range [M,N\R{]}.
    11191119\begin{cfa}
    1120 for ( 1@~=@5 )                                  $\C{// for ( typeof(1) i = 1; i <= 5; i += 1 )}$
     1120for ( 1®~=®5 )                                  $\C{// for ( typeof(1) i = 1; i <= 5; i += 1 )}$
    11211121\end{cfa}
    11221122\item
    11231123The down-to range M ©-~©\index{-~@©-~©} N means exclusive range [N,M\R{)}.
    11241124\begin{cfa}
    1125 for ( 1@-~@5 )                                  $\C{// for ( typeof(1) i = 5; i > 0; i -= 1 )}$
     1125for ( 1®-~®5 )                                  $\C{// for ( typeof(1) i = 5; i > 0; i -= 1 )}$
    11261126\end{cfa}
    11271127\item
    11281128The down-to range M ©-~=©\index{-~=@©-~=©} N means inclusive range [N,M\R{]}.
    11291129\begin{cfa}
    1130 for ( 1@-~=@5 )                                 $\C{// for ( typeof(1) i = 5; i >= 0; i -= 1 )}$
     1130for ( 1®-~=®5 )                                 $\C{// for ( typeof(1) i = 5; i >= 0; i -= 1 )}$
    11311131\end{cfa}
    11321132\item
    11331133©@© means put nothing in this field.
    11341134\begin{cfa}
    1135 for ( 1~$\R{@}$~2 )                             $\C{// for ( typeof(1) i = 1; /*empty*/; i += 2 )}$
     1135for ( 1~®@®~2 )                                 $\C{// for ( typeof(1) i = 1; /*empty*/; i += 2 )}$
    11361136\end{cfa}
    11371137\item
    11381138©:© means start another index.
    11391139\begin{cfa}
    1140 for ( i; 5 @:@ j; 2~12~3 )              $\C{// for ( typeof(i) i = 1, j = 2; i < 5 \&\& j < 12; i += 1, j += 3 )}\CRT$
     1140for ( i; 5 ®:® j; 2~12~3 )              $\C{// for ( typeof(i) i = 1, j = 2; i < 5 \&\& j < 12; i += 1, j += 3 )}\CRT$
    11411141\end{cfa}
    11421142\end{itemize}
    11431143
    11441144
    1145 %\subsection{\texorpdfstring{Labelled \protect\lstinline@continue@ / \protect\lstinline@break@}{Labelled continue / break}}
     1145%\subsection{\texorpdfstring{Labelled \protect\lstinline{continue} / \protect\lstinline{break}}{Labelled continue / break}}
    11461146\subsection{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break} Statement}{Labelled continue / break Statement}}
    11471147
     
    11581158\begin{lrbox}{\myboxA}
    11591159\begin{cfa}[tabsize=3]
    1160 @Compound:@ {
    1161         @Try:@ try {
    1162                 @For:@ for ( ... ) {
    1163                         @While:@ while ( ... ) {
    1164                                 @Do:@ do {
    1165                                         @If:@ if ( ... ) {
    1166                                                 @Switch:@ switch ( ... ) {
     1160®Compound:® {
     1161        ®Try:® try {
     1162                ®For:® for ( ... ) {
     1163                        ®While:® while ( ... ) {
     1164                                ®Do:® do {
     1165                                        ®If:® if ( ... ) {
     1166                                                ®Switch:® switch ( ... ) {
    11671167                                                        case 3:
    1168                                                                 @break Compound@;
    1169                                                                 @break Try@;
    1170                                                                 @break For@;      /* or */  @continue For@;
    1171                                                                 @break While@;  /* or */  @continue While@;
    1172                                                                 @break Do@;      /* or */  @continue Do@;
    1173                                                                 @break If@;
    1174                                                                 @break Switch@;
     1168                                                                ®break Compound®;
     1169                                                                ®break Try®;
     1170                                                                ®break For®;      /* or */  ®continue For®;
     1171                                                                ®break While®;  /* or */  ®continue While®;
     1172                                                                ®break Do®;      /* or */  ®continue Do®;
     1173                                                                ®break If®;
     1174                                                                ®break Switch®;
    11751175                                                        } // switch
    11761176                                                } else {
    1177                                                         ... @break If@; ...     // terminate if
     1177                                                        ... ®break If®; ...     // terminate if
    11781178                                                } // if
    11791179                                } while ( ... ); // do
    11801180                        } // while
    11811181                } // for
    1182         } @finally@ { // always executed
     1182        } ®finally® { // always executed
    11831183        } // try
    11841184} // compound
     
    11901190{
    11911191
    1192                 @ForC:@ for ( ... ) {
    1193                         @WhileC:@ while ( ... ) {
    1194                                 @DoC:@ do {
     1192                ®ForC:® for ( ... ) {
     1193                        ®WhileC:® while ( ... ) {
     1194                                ®DoC:® do {
    11951195                                        if ( ... ) {
    11961196                                                switch ( ... ) {
    11971197                                                        case 3:
    1198                                                                 @goto Compound@;
    1199                                                                 @goto Try@;
    1200                                                                 @goto ForB@;      /* or */  @goto ForC@;
    1201                                                                 @goto WhileB@;  /* or */  @goto WhileC@;
    1202                                                                 @goto DoB@;      /* or */  @goto DoC@;
    1203                                                                 @goto If@;
    1204                                                                 @goto Switch@;
    1205                                                         } @Switch:@ ;
     1198                                                                ®goto Compound®;
     1199                                                                ®goto Try®;
     1200                                                                ®goto ForB®;      /* or */  ®goto ForC®;
     1201                                                                ®goto WhileB®;  /* or */  ®goto WhileC®;
     1202                                                                ®goto DoB®;      /* or */  ®goto DoC®;
     1203                                                                ®goto If®;
     1204                                                                ®goto Switch®;
     1205                                                        } ®Switch:® ;
    12061206                                                } else {
    1207                                                         ... @goto If@; ...      // terminate if
    1208                                                 } @If:@;
    1209                                 } while ( ... ); @DoB:@ ;
    1210                         } @WhileB:@ ;
    1211                 } @ForB:@ ;
    1212 
    1213 
    1214 } @Compound:@ ;
     1207                                                        ... ®goto If®; ...      // terminate if
     1208                                                } ®If:®;
     1209                                } while ( ... ); ®DoB:® ;
     1210                        } ®WhileB:® ;
     1211                } ®ForB:® ;
     1212
     1213
     1214} ®Compound:® ;
    12151215\end{cfa}
    12161216\end{lrbox}
     
    12411241
    12421242
    1243 %\subsection{\texorpdfstring{\protect\lstinline@with@ Statement}{with Statement}}
     1243%\subsection{\texorpdfstring{\protect\lstinline{with} Statement}{with Statement}}
    12441244\subsection{\texorpdfstring{\LstKeywordStyle{with} Statement}{with Statement}}
    12451245\label{s:WithStatement}
     
    12561256\begin{cfa}
    12571257Person p
    1258 @p.@name; @p.@address; @p.@sex; $\C{// access containing fields}$
     1258®p.®name; ®p.®address; ®p.®sex; $\C{// access containing fields}$
    12591259\end{cfa}
    12601260which extends to multiple levels of qualification for nested aggregates and multiple aggregates.
    12611261\begin{cfa}
    12621262struct Ticket { ... } t;
    1263 @p.name@.first; @p.address@.street;             $\C{// access nested fields}$
    1264 @t.@departure; @t.@cost;                                $\C{// access multiple aggregate}$
     1263®p.name®.first; ®p.address®.street;             $\C{// access nested fields}$
     1264®t.®departure; ®t.®cost;                                $\C{// access multiple aggregate}$
    12651265\end{cfa}
    12661266Repeated aggregate qualification is tedious and makes code difficult to read.
     
    12851285\begin{C++}
    12861286struct S {
    1287         char @c@;   int @i@;   double @d@;
     1287        char ®c®;   int ®i®;   double ®d®;
    12881288        void f( /* S * this */ ) {                              $\C{// implicit ``this'' parameter}$
    1289                 @c@;   @i@;   @d@;                                      $\C{// this->c; this->i; this->d;}$
     1289                ®c®;   ®i®;   ®d®;                                      $\C{// this->c; this->i; this->d;}$
    12901290        }
    12911291}
     
    12951295\begin{cfa}
    12961296struct T {
    1297         char @m@;   int @i@;   double @n@;              $\C{// derived class variables}$
     1297        char ®m®;   int ®i®;   double ®n®;              $\C{// derived class variables}$
    12981298};
    12991299struct S : public T {
    1300         char @c@;   int @i@;   double @d@;              $\C{// class variables}$
    1301         void g( double @d@, T & t ) {
    1302                 d;   @t@.m;   @t@.i;   @t@.n;           $\C{// function parameter}$
    1303                 c;   i;   @this->@d;   @S::@d;          $\C{// class S variables}$
    1304                 m;   @T::@i;   n;                                       $\C{// class T variables}$
     1300        char ®c®;   int ®i®;   double ®d®;              $\C{// class variables}$
     1301        void g( double ®d®, T & t ) {
     1302                d;   ®t®.m;   ®t®.i;   ®t®.n;           $\C{// function parameter}$
     1303                c;   i;   ®this->®d;   ®S::®d;          $\C{// class S variables}$
     1304                m;   ®T::®i;   n;                                       $\C{// class T variables}$
    13051305        }
    13061306};
     
    13121312Hence, the qualified fields become variables with the side-effect that it is simpler to write, easier to read, and optimize field references in a block.
    13131313\begin{cfa}
    1314 void f( S & this ) @with ( this )@ {            $\C{// with statement}$
    1315         @c@;   @i@;   @d@;                                              $\C{// this.c, this.i, this.d}$
     1314void f( S & this ) ®with ( this )® {            $\C{// with statement}$
     1315        ®c®;   ®i®;   ®d®;                                              $\C{// this.c, this.i, this.d}$
    13161316}
    13171317\end{cfa}
    13181318with the generality of opening multiple aggregate-parameters:
    13191319\begin{cfa}
    1320 void g( S & s, T & t ) @with ( s, t )@ {        $\C{// multiple aggregate parameters}$
    1321         c;   @s.@i;   d;                                                $\C{// s.c, s.i, s.d}$
    1322         m;   @t.@i;   n;                                                $\C{// t.m, t.i, t.n}$
     1320void g( S & s, T & t ) ®with ( s, t )® {        $\C{// multiple aggregate parameters}$
     1321        c;   ®s.®i;   d;                                                $\C{// s.c, s.i, s.d}$
     1322        m;   ®t.®i;   n;                                                $\C{// t.m, t.i, t.n}$
    13231323}
    13241324\end{cfa}
     
    13391339The difference between parallel and nesting occurs for fields with the same name and type:
    13401340\begin{cfa}
    1341 struct Q { int @i@; int k; int @m@; } q, w;
    1342 struct R { int @i@; int j; double @m@; } r, w;
     1341struct Q { int ®i®; int k; int ®m®; } q, w;
     1342struct R { int ®i®; int j; double ®m®; } r, w;
    13431343with ( r, q ) {
    13441344        j + k;                                                                  $\C{// unambiguous, r.j + q.k}$
     
    13731373\begin{cfa}
    13741374void ?{}( S & s, int i ) with ( s ) { $\C{// constructor}$
    1375         @s.i = i;@  j = 3;  m = 5.5; $\C{// initialize fields}$
     1375        ®s.i = i;®  j = 3;  m = 5.5; $\C{// initialize fields}$
    13761376}
    13771377\end{cfa}
     
    13861386and implicitly opened \emph{after} a function-body open, to give them higher priority:
    13871387\begin{cfa}
    1388 void ?{}( S & s, int @i@ ) with ( s ) @with( $\emph{\R{params}}$ )@ { // syntax not allowed, illustration only
    1389         s.i = @i@; j = 3; m = 5.5;
     1388void ?{}( S & s, int ®i® ) with ( s ) ®with( $\emph{\R{params}}$ )® { // syntax not allowed, illustration only
     1389        s.i = ®i®; j = 3; m = 5.5;
    13901390}
    13911391\end{cfa}
     
    14701470For example, a routine returning a \Index{pointer} to an array of integers is defined and used in the following way:
    14711471\begin{cfa}
    1472 int @(*@f@())[@5@]@ {...}; $\C{// definition}$
    1473  ... @(*@f@())[@3@]@ += 1; $\C{// usage}$
     1472int ®(*®f®())[®5®]® {...}; $\C{// definition}$
     1473 ... ®(*®f®())[®3®]® += 1; $\C{// usage}$
    14741474\end{cfa}
    14751475Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
     
    14871487\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    14881488\begin{cfa}[moredelim={**[is][\color{blue}]{\#}{\#}}]
    1489 #[5] *# @int@ x1;
    1490 #* [5]# @int@ x2;
    1491 #[* [5] int]# f@( int p )@;
     1489#[5] *# ®int® x1;
     1490#* [5]# ®int® x2;
     1491#[* [5] int]# f®( int p )®;
    14921492\end{cfa}
    14931493&
    14941494\begin{cfa}[moredelim={**[is][\color{blue}]{\#}{\#}}]
    1495 @int@ #*# x1 #[5]#;
    1496 @int@ #(*#x2#)[5]#;
    1497 #int (*#f@( int p )@#)[5]#;
     1495®int® #*# x1 #[5]#;
     1496®int® #(*#x2#)[5]#;
     1497#int (*#f®( int p )®#)[5]#;
    14981498\end{cfa}
    14991499\end{tabular}
     
    15071507\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    15081508\begin{cfa}
    1509 @*@ int x, y;
     1509®*® int x, y;
    15101510\end{cfa}
    15111511&
    15121512\begin{cfa}
    1513 int @*@x, @*@y;
     1513int ®*®x, ®*®y;
    15141514\end{cfa}
    15151515\end{tabular}
     
    15201520\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    15211521\begin{cfa}
    1522 @*@ int x;
     1522®*® int x;
    15231523int y;
    15241524\end{cfa}
    15251525&
    15261526\begin{cfa}
    1527 int @*@x, y;
     1527int ®*®x, y;
    15281528
    15291529\end{cfa}
     
    16611661&
    16621662\begin{cfa}
    1663 int * @const@ x = (int *)100
     1663int * ®const® x = (int *)100
    16641664*x = 3;                 // implicit dereference
    1665 int * @const@ y = (int *)104;
     1665int * ®const® y = (int *)104;
    16661666*y = *x;                        // implicit dereference
    16671667\end{cfa}
     
    17011701\begin{tabular}{@{}l@{\hspace{2em}}l@{}}
    17021702\begin{cfa}
    1703 int x, y, @*@ p1, @*@ p2, @**@ p3;
    1704 p1 = @&@x;     // p1 points to x
     1703int x, y, ®*® p1, ®*® p2, ®**® p3;
     1704p1 = ®&®x;     // p1 points to x
    17051705p2 = p1;     // p2 points to x
    1706 p1 = @&@y;     // p1 points to y
     1706p1 = ®&®y;     // p1 points to y
    17071707p3 = &p2;  // p3 points to p2
    17081708\end{cfa}
     
    17301730\begin{cfa}
    17311731p1 = p2; $\C{// pointer address assignment}$
    1732 @*@p2 = @*@p1 + x; $\C{// pointed-to value assignment / operation}$
     1732®*®p2 = ®*®p1 + x; $\C{// pointed-to value assignment / operation}$
    17331733\end{cfa}
    17341734The C semantics work well for situations where manipulation of addresses is the primary meaning and data is rarely accessed, such as storage management (©malloc©/©free©).
     
    17461746To support this common case, a reference type is introduced in \CFA, denoted by ©&©, which is the opposite dereference semantics to a pointer type, making the value at the pointed-to location the implicit semantics for dereferencing (similar but not the same as \CC \Index{reference type}s).
    17471747\begin{cfa}
    1748 int x, y, @&@ r1, @&@ r2, @&&@ r3;
    1749 @&@r1 = &x; $\C{// r1 points to x}$
    1750 @&@r2 = &r1; $\C{// r2 points to x}$
    1751 @&@r1 = &y; $\C{// r1 points to y}$
    1752 @&&@r3 = @&@&r2; $\C{// r3 points to r2}$
     1748int x, y, ®&® r1, ®&® r2, ®&&® r3;
     1749®&®r1 = &x; $\C{// r1 points to x}$
     1750®&®r2 = &r1; $\C{// r2 points to x}$
     1751®&®r1 = &y; $\C{// r1 points to y}$
     1752®&&®r3 = ®&®&r2; $\C{// r3 points to r2}$
    17531753r2 = ((r1 + r2) * (r3 - r1)) / (r3 - 15); $\C{// implicit dereferencing}$
    17541754\end{cfa}
     
    17571757One way to conceptualize a reference is via a rewrite rule, where the compiler inserts a dereference operator before the reference variable for each reference qualifier in a declaration, so the previous example becomes:
    17581758\begin{cfa}
    1759 @*@r2 = ((@*@r1 + @*@r2) @*@ (@**@r3 - @*@r1)) / (@**@r3 - 15);
     1759®*®r2 = ((®*®r1 + ®*®r2) ®*® (®**®r3 - ®*®r1)) / (®**®r3 - 15);
    17601760\end{cfa}
    17611761When a reference operation appears beside a dereference operation, \eg ©&*©, they cancel out.
     
    17661766For a \CFA reference type, the cancellation on the left-hand side of assignment leaves the reference as an address (\Index{lvalue}):
    17671767\begin{cfa}
    1768 (&@*@)r1 = &x; $\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}$
     1768(&®*®)r1 = &x; $\C{// (\&*) cancel giving address in r1 not variable pointed-to by r1}$
    17691769\end{cfa}
    17701770Similarly, the address of a reference can be obtained for assignment or computation (\Index{rvalue}):
    17711771\begin{cfa}
    1772 (&(&@*@)@*@)r3 = &(&@*@)r2; $\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}$
     1772(&(&®*®)®*®)r3 = &(&®*®)r2; $\C{// (\&*) cancel giving address in r2, (\&(\&*)*) cancel giving address in r3}$
    17731773\end{cfa}
    17741774Cancellation\index{cancellation!pointer/reference}\index{pointer!cancellation} works to arbitrary depth.
     
    17931793const int cx = 5; $\C{// cannot change cx;}$
    17941794const int & cr = cx; $\C{// cannot change what cr points to}$
    1795 @&@cr = &cx; $\C{// can change cr}$
     1795®&®cr = &cx; $\C{// can change cr}$
    17961796cr = 7; $\C{// error, cannot change cx}$
    17971797int & const rc = x; $\C{// must be initialized}$
    1798 @&@rc = &x; $\C{// error, cannot change rc}$
     1798®&®rc = &x; $\C{// error, cannot change rc}$
    17991799const int & const crc = cx; $\C{// must be initialized}$
    18001800crc = 7; $\C{// error, cannot change cx}$
    1801 @&@crc = &cx; $\C{// error, cannot change crc}$
     1801®&®crc = &cx; $\C{// error, cannot change crc}$
    18021802\end{cfa}
    18031803Hence, for type ©& const©, there is no pointer assignment, so ©&rc = &x© is disallowed, and \emph{the address value cannot be the null pointer unless an arbitrary pointer is coerced\index{coercion} into the reference}:
     
    18201820\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
    18211821\begin{cfa}
    1822 @const@ * @const@ * const int ccp;
    1823 @const@ & @const@ & const int ccr;
     1822®const® * ®const® * const int ccp;
     1823®const® & ®const® & const int ccr;
    18241824\end{cfa}
    18251825&
    18261826\begin{cfa}
    1827 const int * @const@ * @const@ ccp;
     1827const int * ®const® * ®const® ccp;
    18281828
    18291829\end{cfa}
     
    18571857\begin{cfa}
    18581858int * p = &x; $\C{// assign address of x}$
    1859 @int * p = x;@ $\C{// assign value of x}$
     1859®int * p = x;® $\C{// assign value of x}$
    18601860int & r = x; $\C{// must have address of x}$
    18611861\end{cfa}
     
    18811881When a pointer/reference parameter has a ©const© value (immutable), it is possible to pass literals and expressions.
    18821882\begin{cfa}
    1883 void f( @const@ int & cr );
    1884 void g( @const@ int * cp );
    1885 f( 3 );                   g( @&@3 );
    1886 f( x + y );             g( @&@(x + y) );
     1883void f( ®const® int & cr );
     1884void g( ®const® int * cp );
     1885f( 3 );                   g( ®&®3 );
     1886f( x + y );             g( ®&®(x + y) );
    18871887\end{cfa}
    18881888Here, the compiler passes the address to the literal 3 or the temporary for the expression ©x + y©, knowing the argument cannot be changed through the parameter.
     
    18951895void f( int & r );
    18961896void g( int * p );
    1897 f( 3 );                   g( @&@3 ); $\C{// compiler implicit generates temporaries}$
    1898 f( x + y );             g( @&@(x + y) ); $\C{// compiler implicit generates temporaries}$
     1897f( 3 );                   g( ®&®3 ); $\C{// compiler implicit generates temporaries}$
     1898f( x + y );             g( ®&®(x + y) ); $\C{// compiler implicit generates temporaries}$
    18991899\end{cfa}
    19001900Essentially, there is an implicit \Index{rvalue} to \Index{lvalue} conversion in this case.\footnote{
     
    19171917Instead, a routine object should be referenced by a ©const© reference:
    19181918\begin{cfa}
    1919 @const@ void (@&@ fr)( int ) = f; $\C{// routine reference}$
     1919®const® void (®&® fr)( int ) = f; $\C{// routine reference}$
    19201920fr = ... $\C{// error, cannot change code}$
    19211921&fr = ...; $\C{// changing routine reference}$
     
    19791979\begin{cfa}
    19801980int x, &r = x, f( int p );
    1981 x = @r@ + f( @r@ ); $\C{// lvalue reference converts to rvalue}$
     1981x = ®r® + f( ®r® ); $\C{// lvalue reference converts to rvalue}$
    19821982\end{cfa}
    19831983An rvalue has no type qualifiers (©cv©), so the reference qualifiers are dropped.
    19841984
    19851985\item
    1986 lvalue to reference conversion: \lstinline[deletekeywords=lvalue]@lvalue-type cv1 T@ converts to ©cv2 T &©, which allows implicitly converting variables to references.
    1987 \begin{cfa}
    1988 int x, &r = @x@, f( int & p ); $\C{// lvalue variable (int) convert to reference (int \&)}$
    1989 f( @x@ ); $\C{// lvalue variable (int) convert to reference (int \&)}$
     1986lvalue to reference conversion: \lstinline[deletekeywords=lvalue]{lvalue-type cv1 T} converts to ©cv2 T &©, which allows implicitly converting variables to references.
     1987\begin{cfa}
     1988int x, &r = ®x®, f( int & p ); $\C{// lvalue variable (int) convert to reference (int \&)}$
     1989f( ®x® ); $\C{// lvalue variable (int) convert to reference (int \&)}$
    19901990\end{cfa}
    19911991Conversion can restrict a type, where ©cv1© $\le$ ©cv2©, \eg passing an ©int© to a ©const volatile int &©, which has low cost.
     
    19971997\begin{cfa}
    19981998int x, & f( int & p );
    1999 f( @x + 3@ );   $\C[1.5in]{// rvalue parameter (int) implicitly converts to lvalue temporary reference (int \&)}$
    2000 @&f@(...) = &x; $\C{// rvalue result (int \&) implicitly converts to lvalue temporary reference (int \&)}\CRT$
     1999f( ®x + 3® );   $\C[1.5in]{// rvalue parameter (int) implicitly converts to lvalue temporary reference (int \&)}$
     2000®&f®(...) = &x; $\C{// rvalue result (int \&) implicitly converts to lvalue temporary reference (int \&)}\CRT$
    20012001\end{cfa}
    20022002In both case, modifications to the temporary are inaccessible (\Index{warning}).
     
    22242224\CFA allows other integral types with associated values.
    22252225\begin{cfa}
    2226 enum( @char@ ) Letter { A @= 'A'@,  B,  C,  I @= 'I'@,  J,  K };
    2227 enum( @long long int@ ) BigNum { X = 123_456_789_012_345,  Y = 345_012_789_456_123 };
     2226enum( ®char® ) Letter { A ®= 'A'®,  B,  C,  I ®= 'I'®,  J,  K };
     2227enum( ®long long int® ) BigNum { X = 123_456_789_012_345,  Y = 345_012_789_456_123 };
    22282228\end{cfa}
    22292229For enumeration ©Letter©, enum ©A©'s value is explicitly set to ©'A'©, with ©B© and ©C© implicitly numbered with increasing values from ©'A'©, and similarly for enums ©I©, ©J©, and ©K©.
     
    22322232\begin{cfa}
    22332233// non-integral numeric
    2234 enum( @double@ ) Math { PI_2 = 1.570796, PI = 3.141597,  E = 2.718282 }
     2234enum( ®double® ) Math { PI_2 = 1.570796, PI = 3.141597,  E = 2.718282 }
    22352235// pointer
    2236 enum( @char *@ ) Name { Fred = "Fred",  Mary = "Mary",  Jane = "Jane" };
     2236enum( ®char *® ) Name { Fred = "Fred",  Mary = "Mary",  Jane = "Jane" };
    22372237int i, j, k;
    2238 enum( @int *@ ) ptr { I = &i,  J = &j,  K = &k };
    2239 enum( @int &@ ) ref { I = i,  J = j,  K = k };
     2238enum( ®int *® ) ptr { I = &i,  J = &j,  K = &k };
     2239enum( ®int &® ) ref { I = i,  J = j,  K = k };
    22402240// tuple
    2241 enum( @[int, int]@ ) { T = [ 1, 2 ] };
     2241enum( ®[int, int]® ) { T = [ 1, 2 ] };
    22422242// function
    22432243void f() {...}   void g() {...}
    2244 enum( @void (*)()@ ) funs { F = f,  F = g };
     2244enum( ®void (*)()® ) funs { F = f,  F = g };
    22452245// aggregate
    22462246struct S { int i, j; };
    2247 enum( @S@ ) s { A = { 3,  4 }, B = { 7,  8 } };
     2247enum( ®S® ) s { A = { 3,  4 }, B = { 7,  8 } };
    22482248// enumeration
    2249 enum( @Letter@ ) Greek { Alph = A, Beta = B, /* more enums */  }; // alphabet intersection
     2249enum( ®Letter® ) Greek { Alph = A, Beta = B, /* more enums */  }; // alphabet intersection
    22502250\end{cfa}
    22512251Enumeration ©Greek© may have more or less enums than ©Letter©, but the enum values \emph{must} be from ©Letter©.
     
    22702270A fallback is explicit C-style initialization using ©@=©.
    22712271\begin{cfa}
    2272 enum( struct vec3 ) Axis { Up $@$= { 1, 0, 0 }, Left $@$= { 0, 1, 0 }, Front $@$= { 0, 0, 1 } }
     2272enum( struct vec3 ) Axis { Up @= { 1, 0, 0 }, Left @= { 0, 1, 0 }, Front @= { 0, 0, 1 } }
    22732273\end{cfa}
    22742274Finally, enumeration variables are assignable and comparable only if the appropriate operators are defined for its enum type.
     
    22792279\Index{Plan-9}\index{inheritance!enumeration} inheritance may be used with enumerations.
    22802280\begin{cfa}
    2281 enum( char * ) Name2 { @inline Name@, Jack = "Jack", Jill = "Jill" };
    2282 enum @/* inferred */@  Name3 { @inline Name2@, Sue = "Sue", Tom = "Tom" };
     2281enum( char * ) Name2 { ®inline Name®, Jack = "Jack", Jill = "Jill" };
     2282enum ®/* inferred */®  Name3 { ®inline Name2®, Sue = "Sue", Tom = "Tom" };
    22832283\end{cfa}
    22842284Enumeration ©Name2© inherits all the enums and their values from enumeration ©Name© by containment, and a ©Name© enumeration is a subtype of enumeration ©Name2©.
     
    23532353The point of the new syntax is to allow returning multiple values from a routine~\cite{Galletly96,CLU}, \eg:
    23542354\begin{cfa}
    2355 @[ int o1, int o2, char o3 ]@ f( int i1, char i2, char i3 ) {
     2355®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) {
    23562356        $\emph{routine body}$
    23572357}
     
    23652365Declaration qualifiers can only appear at the start of a routine definition, \eg:
    23662366\begin{cfa}
    2367 @extern@ [ int x ] g( int y ) {$\,$}
     2367®extern® [ int x ] g( int y ) {$\,$}
    23682368\end{cfa}
    23692369Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified;
     
    24232423\begin{minipage}{\linewidth}
    24242424\begin{cfa}
    2425 @[ int x, int y ]@ f() {
     2425®[ int x, int y ]® f() {
    24262426        int z;
    24272427        ... x = 0; ... y = z; ...
    2428         @return;@ $\C{// implicitly return x, y}$
     2428        ®return;® $\C{// implicitly return x, y}$
    24292429}
    24302430\end{cfa}
     
    27582758
    27592759int fred() {
    2760         s.t.c = @S.@R;  // type qualification
    2761         struct @S.@T t = { @S.@R, 1, 2 };
    2762         enum @S.@C c;
    2763         union @S.T.@U u;
     2760        s.t.c = ®S.®R;  // type qualification
     2761        struct ®S.®T t = { ®S.®R, 1, 2 };
     2762        enum ®S.®C c;
     2763        union ®S.T.®U u;
    27642764}
    27652765\end{cfa}
     
    27872787qsort( ia, size ); $\C{// sort ascending order using builtin ?<?}$
    27882788{
    2789         @int ?<?( int x, int y ) { return x > y; }@ $\C{// nested routine}$
     2789        ®int ?<?( int x, int y ) { return x > y; }® $\C{// nested routine}$
    27902790        qsort( ia, size ); $\C{// sort descending order by local redefinition}$
    27912791}
     
    27972797\begin{cfa}
    27982798[* [int]( int )] foo() { $\C{// int (* foo())( int )}$
    2799         int @i@ = 7;
     2799        int ®i® = 7;
    28002800        int bar( int p ) {
    2801                 @i@ += 1; $\C{// dependent on local variable}$
    2802                 sout | @i@;
     2801                ®i® += 1; $\C{// dependent on local variable}$
     2802                sout | ®i®;
    28032803        }
    28042804        return bar; $\C{// undefined because of local dependence}$
     
    28182818In C and \CFA, lists of elements appear in several contexts, such as the parameter list of a routine call.
    28192819\begin{cfa}
    2820 f( @2, x, 3 + i@ ); $\C{// element list}$
     2820f( ®2, x, 3 + i® ); $\C{// element list}$
    28212821\end{cfa}
    28222822A list of elements is called a \newterm{tuple}, and is different from a \Index{comma expression}.
     
    29312931In \CFA, it is possible to overcome this restriction by declaring a \newterm{tuple variable}.
    29322932\begin{cfa}
    2933 [int, int] @qr@ = div( 13, 5 ); $\C{// initialize tuple variable}$
    2934 printf( "%d %d\n", @qr@ ); $\C{// print quotient/remainder}$
     2933[int, int] ®qr® = div( 13, 5 ); $\C{// initialize tuple variable}$
     2934printf( "%d %d\n", ®qr® ); $\C{// print quotient/remainder}$
    29352935\end{cfa}
    29362936It is now possible to match the multiple return-values to a single variable, in much the same way as \Index{aggregation}.
     
    35963596\begin{cfa}
    35973597int x = 1, y = 2, z = 3;
    3598 sout | x @|@ y @|@ z;
     3598sout | x ®|® y ®|® z;
    35993599\end{cfa}
    36003600&
    36013601\begin{cfa}
    36023602
    3603 cout << x @<< " "@ << y @<< " "@ << z << endl;
     3603cout << x ®<< " "® << y ®<< " "® << z << endl;
    36043604\end{cfa}
    36053605&
     
    36103610\\
    36113611\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3612 1@ @2@ @3
     36121® ®2® ®3
    36133613\end{cfa}
    36143614&
    36153615\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3616 1@ @2@ @3
     36161® ®2® ®3
    36173617\end{cfa}
    36183618&
    36193619\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3620 1@ @2@ @3
     36201® ®2® ®3
    36213621\end{cfa}
    36223622\end{tabular}
    36233623\end{cquote}
    36243624The \CFA form has half the characters of the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators and newline.
    3625 Similar simplification occurs for \Index{tuple} I/O, which flattens the tuple and prints each value separated by ``\lstinline[showspaces=true]@, @''.
     3625Similar simplification occurs for \Index{tuple} I/O, which flattens the tuple and prints each value separated by ``\lstinline[showspaces=true]{, }''.
    36263626\begin{cfa}
    36273627[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
     
    36293629\end{cfa}
    36303630\begin{cfa}[showspaces=true,aboveskip=0pt]
    3631 1@, @2@, @3 4@, @5@, @6
     36311®, ®2®, ®3 4®, ®5®, ®6
    36323632\end{cfa}
    36333633Finally, \CFA uses the logical-or operator for I/O as it is the lowest-priority \emph{overloadable} operator, other than assignment.
     
    36383638&
    36393639\begin{cfa}
    3640 sout | x * 3 | y + 1 | z << 2 | x == y | @(@x | y@)@ | @(@x || y@)@ | @(@x > z ? 1 : 2@)@;
     3640sout | x * 3 | y + 1 | z << 2 | x == y | ®(®x | y®)® | ®(®x || y®)® | ®(®x > z ? 1 : 2®)®;
    36413641\end{cfa}
    36423642\\
     
    36443644&
    36453645\begin{cfa}
    3646 cout << x * 3 << y + 1 << @(@z << 2@)@ << @(@x == y@)@ << @(@x | y@)@ << @(@x || y@)@ << @(@x > z ? 1 : 2@)@ << endl;
     3646cout << x * 3 << y + 1 << ®(®z << 2®)® << ®(®x == y®)® << ®(®x | y®)® << ®(®x || y®)® << ®(®x > z ? 1 : 2®)® << endl;
    36473647\end{cfa}
    36483648\\
     
    36793679\\
    36803680\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3681 @1@ @2.5@ @A@
     3681®1® ®2.5® ®A®
    36823682
    36833683
     
    36853685&
    36863686\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3687 @1@ @2.5@ @A@
     3687®1® ®2.5® ®A®
    36883688
    36893689
     
    36913691&
    36923692\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3693 @1@
    3694 @2.5@
    3695 @A@
     3693®1®
     3694®2.5®
     3695®A®
    36963696\end{cfa}
    36973697\end{tabular}
     
    37293729
    37303730\item
    3731 A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \LstStringStyle{,.;!?)]\}\%\textcent\guillemotright}, where \LstStringStyle{\guillemotright} a closing citation mark.
     3731A separator does not appear before a C string starting with the (extended) \Index*{ASCII}\index{ASCII!extended} characters: \LstStringStyle{,.;!?)]\}\%\textcent\guillemotright}, where \LstStringStyle{\guillemotright} is a closing citation mark.
    37323732\begin{cfa}
    37333733sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     
    37353735\end{cfa}
    37363736\begin{cfa}[showspaces=true]
    3737 1@,@ x 2@.@ x 3@;@ x 4@!@ x 5@?@ x 6@%@ x 7$\R{\LstStringStyle{\textcent}}$ x 8$\R{\LstStringStyle{\guillemotright}}$ x 9@)@ x 10@]@ x 11@}@ x
     37371®,® x 2®.® x 3®;® x 4®!® x 5®?® x 6®%® x 7$\R{\LstStringStyle{\textcent}}$ x 8$\R{\LstStringStyle{\guillemotright}}$ x 9®)® x 10®]® x 11®}® x
    37383738\end{cfa}
    37393739
     
    37423742%$
    37433743\begin{cfa}
    3744 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x $\LstStringStyle{\textsterling}$" | 6 | "x $\LstStringStyle{\textyen}$"
     3744sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $\LstStringStyle{\textdollar}$" | 5 | "x $\LstStringStyle{\textsterling}$" | 6 | "x $\LstStringStyle{\textyen}$"
    37453745           | 7 | "x $\LstStringStyle{\textexclamdown}$" | 8 | "x $\LstStringStyle{\textquestiondown}$" | 9 | "x $\LstStringStyle{\guillemotleft}$" | 10;
    37463746\end{cfa}
    37473747%$
    37483748\begin{cfa}[showspaces=true]
    3749 x @(@1 x @[@2 x @{@3 x @=@4 x $\LstStringStyle{\textdollar}$5 x $\R{\LstStringStyle{\textsterling}}$6 x $\R{\LstStringStyle{\textyen}}$7 x $\R{\LstStringStyle{\textexclamdown}}$8 x $\R{\LstStringStyle{\textquestiondown}}$9 x $\R{\LstStringStyle{\guillemotleft}}$10
     3749x ®(®1 x ®[®2 x ®{®3 x ®=®4 x $\LstStringStyle{\textdollar}$5 x $\R{\LstStringStyle{\textsterling}}$6 x $\R{\LstStringStyle{\textyen}}$7 x $\R{\LstStringStyle{\textexclamdown}}$8 x $\R{\LstStringStyle{\textquestiondown}}$9 x $\R{\LstStringStyle{\guillemotleft}}$10
    37503750\end{cfa}
    37513751%$
    37523752
    37533753\item
    3754 A seperator does not appear before/after a C string starting/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]{`'": \t\v\f\r\n}
     3754A separator does not appear before/after a C string starting/ending with the \Index*{ASCII} quote or whitespace characters: \lstinline[basicstyle=\tt,showspaces=true]{`'": \t\v\f\r\n}
    37553755\begin{cfa}
    37563756sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx";
    37573757\end{cfa}
    37583758\begin{cfa}[showspaces=true,showtabs=true]
    3759 x@`@1@`@x$\R{\texttt{'}}$2$\R{\texttt{'}}$x$\R{\texttt{"}}$3$\R{\texttt{"}}$x@:@4@:@x@ @5@ @x@  @6@     @x
     3759x®`®1®`®x$\R{\texttt{'}}$2$\R{\texttt{'}}$x$\R{\texttt{"}}$3$\R{\texttt{"}}$x®:®4®:®x® ®5® ®x®  ®6®     ®x
    37603760\end{cfa}
    37613761
     
    37663766\end{cfa}
    37673767\begin{cfa}[showspaces=true,showtabs=true]
    3768 x (@ @1@ @) x 2@ @, x 3@ @:x:@ @4
     3768x (® ®1® ®) x 2® ®, x 3® ®:x:® ®4
    37693769\end{cfa}
    37703770\end{enumerate}
     
    37793779\Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} and \Indexc{sep}\index{manipulator!sep@©sep©}/\Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} set and get the separator string.
    37803780The separator string can be at most 16 characters including the ©'\0'© string terminator (15 printable characters).
    3781 \begin{cfa}[escapechar=off,belowskip=0pt]
    3782 sepSet( sout, ", $" ); $\C{// set separator from " " to ", \$"}$
    3783 sout | 1 | 2 | 3 | " \"" | @sep@ | "\"";
    3784 \end{cfa}
    3785 %$
    3786 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
    3787 1@, $@2@, $@3 @", $"@
    3788 \end{cfa}
    3789 %$
     3781\begin{cfa}[belowskip=0pt]
     3782sepSet( sout, ", $\LstStringStyle{\textdollar}$" ); $\C{// set separator from " " to ", \$"}$
     3783sout | 1 | 2 | 3 | " \"" | ®sep® | "\"";
     3784\end{cfa}
     3785\begin{cfa}[showspaces=true,aboveskip=0pt]
     37861®, $\LstStringStyle{\textdollar}$®2®, $\LstStringStyle{\textdollar}$®3 ®", $\LstStringStyle{\textdollar}$"®
     3787\end{cfa}
    37903788\begin{cfa}[belowskip=0pt]
    37913789sepSet( sout, " " ); $\C{// reset separator to " "}$
    3792 sout | 1 | 2 | 3 | " \"" | @sepGet( sout )@ | "\"";
     3790sout | 1 | 2 | 3 | " \"" | ®sepGet( sout )® | "\"";
    37933791\end{cfa}
    37943792\begin{cfa}[showspaces=true,aboveskip=0pt]
    3795 1@ @2@ @3 @" "@
     37931® ®2® ®3 ®" "®
    37963794\end{cfa}
    37973795©sepGet© can be used to store a separator and then restore it:
    37983796\begin{cfa}[belowskip=0pt]
    3799 char store[@sepSize@]; $\C{// sepSize is the maximum separator size}$
     3797char store[®sepSize®]; $\C{// sepSize is the maximum separator size}$
    38003798strcpy( store, sepGet( sout ) ); $\C{// copy current separator}$
    38013799sepSet( sout, "_" ); $\C{// change separator to underscore}$
     
    38033801\end{cfa}
    38043802\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3805 1@_@2@_@3
     38031®_®2®_®3
    38063804\end{cfa}
    38073805\begin{cfa}[belowskip=0pt]
     
    38103808\end{cfa}
    38113809\begin{cfa}[showspaces=true,aboveskip=0pt]
    3812 1@ @2@ @3
     38101® ®2® ®3
    38133811\end{cfa}
    38143812
     
    38183816\begin{cfa}[belowskip=0pt]
    38193817sepSetTuple( sout, " " ); $\C{// set tuple separator from ", " to " "}$
    3820 sout | t1 | t2 | " \"" | @sepTuple@ | "\"";
     3818sout | t1 | t2 | " \"" | ®sepTuple® | "\"";
    38213819\end{cfa}
    38223820\begin{cfa}[showspaces=true,aboveskip=0pt]
    3823 1 2 3 4 5 6 @" "@
     38211 2 3 4 5 6 ®" "®
    38243822\end{cfa}
    38253823\begin{cfa}[belowskip=0pt]
    38263824sepSetTuple( sout, ", " ); $\C{// reset tuple separator to ", "}$
    3827 sout | t1 | t2 | " \"" | @sepGetTuple( sout )@ | "\"";
     3825sout | t1 | t2 | " \"" | ®sepGetTuple( sout )® | "\"";
    38283826\end{cfa}
    38293827\begin{cfa}[showspaces=true,aboveskip=0pt]
    3830 1, 2, 3 4, 5, 6 @", "@
     38281, 2, 3 4, 5, 6 ®", "®
    38313829\end{cfa}
    38323830As for ©sepGet©, ©sepGetTuple© can be use to store a tuple separator and then restore it.
     
    38803878\end{cfa}
    38813879\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    3882 @ @1 2 3@ @
     3880® ®1 2 3® ®
    38833881\end{cfa}
    38843882\end{enumerate}
     
    39003898For example, in:
    39013899\begin{cfa}
    3902 sin | i | @nl@ | j;
    3903 1 @2@
     3900sin | i | ®nl® | j;
     39011 ®2®
    390439023
    39053903\end{cfa}
     
    394239400b0 0b11011 0b11011 0b11011 0b11011
    39433941sout | bin( -27HH ) | bin( -27H ) | bin( -27 ) | bin( -27L );
    3944 0b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b@(58 1s)@100101
     39420b11100101 0b1111111111100101 0b11111111111111111111111111100101 0b®(58 1s)®100101
    39453943\end{cfa}
    39463944
     
    39783976
    39793977\item
     3978\Indexc{eng}( floating-point )\index{manipulator!eng@©eng©} print value in engineering notation with exponent, which means the exponent is adjusted to a multiple of 3.
     3979\begin{cfa}[belowskip=0pt]
     3980sout | eng( 0.0 ) | eng( 27000.5 ) | eng( -27.5e7 );
     39810®e0® 27.0005®e3® -275®e6®
     3982\end{cfa}
     3983
     3984\item
     3985\Indexc{unit}( engineering-notation )\index{manipulator!unit@©unit©} print engineering exponent as a letter between the range $10^{-24}$ and $10^{24}$:
     3986©y© $\Rightarrow 10^{-24}$, ©z© $\Rightarrow 10^{-21}$, ©a© $\Rightarrow 10^{-18}$, ©f© $\Rightarrow 10^{-15}$, ©p© $\Rightarrow 10^{-12}$, ©n© $\Rightarrow 10^{-9}$, ©u© $\Rightarrow 10^{-6}$, ©m© $\Rightarrow 10^{-3}$, ©K© $\Rightarrow 10^{3}$, ©M© $\Rightarrow 10^{6}$, ©G© $\Rightarrow 10^{9}$, ©T© $\Rightarrow 10^{12}$, ©P© $\Rightarrow 10^{15}$, ©E© $\Rightarrow 10^{18}$, ©Z© $\Rightarrow 10^{21}$, ©Y© $\Rightarrow 10^{24}$.
     3987For exponent $10^{0}$, no decimal point or letter is printed.
     3988\begin{cfa}[belowskip=0pt]
     3989sout | unit(eng( 0.0 )) | unit(eng( 27000.5 )) | unit(eng( -27.5e7 ));
     39900 27.0005®K® -275®M®
     3991\end{cfa}
     3992
     3993\item
    39803994\Indexc{upcase}( bin / hex / floating-point )\index{manipulator!upcase@©upcase©} print letters in a value in upper case. Lower case is the default.
    39813995\begin{cfa}[belowskip=0pt]
    39823996sout | upcase( bin( 27 ) ) | upcase( hex( 27 ) ) | upcase( 27.5e-10 ) | upcase( hex( 27.5 ) );
    3983 0@B@11011 0@X@1@B@ 2.75@E@-09 0@X@1.@B@8@P@+4
     39970®B®11011 0®X®1®B® 2.75®E®-09 0®X®1.®B®8®P®+4
    39843998\end{cfa}
    39853999
     
    39974011\begin{cfa}[belowskip=0pt]
    39984012sout | 0. | nodp( 0. ) | 27.0 | nodp( 27.0 ) | nodp( 27.5 );
    3999 0.0 @0@ 27.0 @27@ 27.5
     40130.0 ®0® 27.0 ®27® 27.5
    40004014\end{cfa}
    40014015
     
    40044018\begin{cfa}[belowskip=0pt]
    40054019sout | sign( 27 ) | sign( -27 ) | sign( 27. ) | sign( -27. ) | sign( 27.5 ) | sign( -27.5 );
    4006 @+@27 -27 @+@27.0 -27.0 @+@27.5 -27.5
    4007 \end{cfa}
    4008 
    4009 \item
    4010 \Indexc{wd}©( unsigned char minimum, T val )©\index{manipulator!wd@©wd©}, ©wd( unsigned char minimum, unsigned char precision, T val )©
    4011 For all types, ©minimum© is the minimum number of printed characters.
     4020®+®27 -27 ®+®27.0 -27.0 ®+®27.5 -27.5
     4021\end{cfa}
     4022
     4023\item
     4024\Indexc{wd}( minimum, value )\index{manipulator!wd@©wd©}, ©wd©( minimum, precision, value )
     4025For all types, minimum is the number of printed characters.
    40124026If the value is shorter than the minimum, it is padded on the right with spaces.
    40134027\begin{cfa}[belowskip=0pt]
     
    40174031\end{cfa}
    40184032\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4019 @  @34 @ @34 34
    4020 @  @4.000000 @ @4.000000 4.000000
    4021 @  @ab @ @ab ab
    4022 \end{cfa}
    4023 If the value is larger, it is printed without truncation, ignoring the ©minimum©.
     4033®  ®34 ® ®34 34
     4034®  ®4.000000 ® ®4.000000 4.000000
     4035®  ®ab ® ®ab ab
     4036\end{cfa}
     4037If the value is larger, it is printed without truncation, ignoring the minimum.
    40244038\begin{cfa}[belowskip=0pt]
    40254039sout | wd( 4, 34567 ) | wd( 3, 34567 ) | wd( 2, 34567 );
     
    40284042\end{cfa}
    40294043\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4030 3456@7@ 345@67@ 34@567@
    4031 3456@.@ 345@6.@ 34@56.@
    4032 abcd@e@ abc@de@ ab@cde@
    4033 \end{cfa}
    4034 
    4035 For integer types, ©precision© is the minimum number of printed digits.
     40443456®7® 345®67® 34®567®
     40453456®.® 345®6.® 34®56.®
     4046abcd®e® abc®de® ab®cde®
     4047\end{cfa}
     4048
     4049For integer types, precision is the minimum number of printed digits.
    40364050If the value is shorter, it is padded on the left with leading zeros.
    40374051\begin{cfa}[belowskip=0pt]
     
    40394053\end{cfa}
    40404054\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4041  @0@34     @00@34 @00000000@34
    4042 \end{cfa}
    4043 If the value is larger, it is printed without truncation, ignoring the ©precision©.
     4055 ®0®34     ®00®34 ®00000000®34
     4056\end{cfa}
     4057If the value is larger, it is printed without truncation, ignoring the precision.
    40444058\begin{cfa}[belowskip=0pt]
    40454059sout | wd( 4,1, 3456 ) | wd( 8,2, 3456 ) | wd( 10,3, 3456 );
     
    404840623456     3456       3456
    40494063\end{cfa}
    4050 If ©precision© is 0, nothing is printed for zero.
    4051 If ©precision© is greater than the minimum, it becomes the minimum.
     4064If precision is 0, nothing is printed for zero.
     4065If precision is greater than the minimum, it becomes the minimum.
    40524066\begin{cfa}[belowskip=0pt]
    40534067sout | wd( 4,0, 0 ) | wd( 3,10, 34 );
    40544068\end{cfa}
    40554069\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4056 @    @ @00000000@34
    4057 \end{cfa}
    4058 For floating-point types, ©precision© is the minimum number of digits after the decimal point.
     4070®    ® ®00000000®34
     4071\end{cfa}
     4072For floating-point types, precision is the minimum number of digits after the decimal point.
    40594073\begin{cfa}[belowskip=0pt]
    40604074sout | wd( 6,3, 27.5 ) | wd( 8,1, 27.5 ) | wd( 8,0, 27.5 ) | wd( 3,8, 27.5 );
    40614075\end{cfa}
    40624076\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4063 27.@500@     27.@5@      28. 27.@50000000@
    4064 \end{cfa}
    4065 For the C-string type, ©precision© is the maximum number of printed characters, so the string is truncated if it exceeds the maximum.
     407727.®500®     27.®5®      28. 27.®50000000®
     4078\end{cfa}
     4079For the C-string type, precision is the maximum number of printed characters, so the string is truncated if it exceeds the maximum.
    40664080\begin{cfa}[belowskip=0pt]
    40674081sout | wd( 6,8, "abcd" ) | wd( 6,8, "abcdefghijk" ) | wd( 6,3, "abcd" );
     
    40724086
    40734087\item
    4074 \Indexc{ws( unsigned char minimum, unsigned char significant, floating-point )}\index{manipulator!ws@©ws©}
    4075 For floating-point type, ©minimum© is the same as for manipulator ©wd©, but ©significant© is the maximum number of significant digits to be printed for both the integer and fractions (versus only the fraction for ©wd©).
    4076 If a value's significant digits is greater than ©significant©, the last significant digit is rounded up.
     4088\begin{sloppypar}
     4089\Indexc{ws}( minimum, significant, floating-point )\index{manipulator!ws@©ws©}
     4090For floating-point types, minimum is the same as for manipulator ©wd©, but significant is the maximum number of significant digits to be printed for both the integer and fractions (versus only the fraction for ©wd©).
     4091If a value's significant digits is greater than significant, the last significant digit is rounded up.
     4092\end{sloppypar}
    40774093\begin{cfa}[belowskip=0pt]
    40784094sout | ws(6,6, 234.567) | ws(6,5, 234.567) | ws(6,4, 234.567) | ws(6,3, 234.567);
    40794095\end{cfa}
    40804096\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4081 234.567 234.5@7@  234.@6@    23@5@
    4082 \end{cfa}
    4083 If a value's magnitude is greater than ©significant©, the value is printed in scientific notation with the specified number of significant digits.
     4097234.567 234.5®7®  234.®6®    23®5®
     4098\end{cfa}
     4099If a value's magnitude is greater than significant, the value is printed in scientific notation with the specified number of significant digits.
    40844100\begin{cfa}[belowskip=0pt]
    40854101sout | ws(6,6, 234567.) | ws(6,5, 234567.) | ws(6,4, 234567.) | ws(6,3, 234567.);
    40864102\end{cfa}
    40874103\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4088 234567. 2.3457@e+05@ 2.346@e+05@ 2.35@e+05@
    4089 \end{cfa}
    4090 If ©significant© is greater than ©minimum©, it defines the number of printed characters.
     4104234567. 2.3457®e+05® 2.346®e+05® 2.35®e+05®
     4105\end{cfa}
     4106If significant is greater than minimum, it defines the number of printed characters.
    40914107\begin{cfa}[belowskip=0pt]
    40924108sout | ws(3,6, 234567.) | ws(4,6, 234567.) | ws(5,6, 234567.) | ws(6,6, 234567.);
     
    41024118\end{cfa}
    41034119\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4104 27@  @ 27.000000  27.500000  027  27.500@    @
     412027®  ® 27.000000  27.500000  027  27.500®    ®
    41054121\end{cfa}
    41064122
     
    41094125\begin{cfa}[belowskip=0pt]
    41104126sout | pad0( wd( 4, 27 ) ) | pad0( wd( 4,3, 27 ) ) | pad0( wd( 8,3, 27.5 ) );
    4111 @00@27  @0@27 @00@27.500
     4127®00®27  ®0®27 ®00®27.500
    41124128\end{cfa}
    41134129\end{enumerate}
     
    41944210\begin{enumerate}
    41954211\item
    4196 \Indexc{skip( const char * pattern )}\index{manipulator!skip@©skip©} / ©skip( unsigned int length )© / ©const char * pattern©
    4197 The argument defines a ©pattern© or ©length©.
    4198 The ©pattern© is composed of white-space and non-white-space characters, where \emph{any} white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character.
    4199 The ©length© is composed of the next $N$ characters, including the newline character.
     4212\Indexc{skip}( pattern )\index{manipulator!skip@©skip©}, ©skip©( length )
     4213The pattern is composed of white-space and non-white-space characters, where \emph{any} white-space character matches 0 or more input white-space characters (hence, consecutive white-space characters in the pattern are combined), and each non-white-space character matches exactly with an input character.
     4214The length is composed of the next $N$ characters, including the newline character.
    42004215If the match successes, the input characters are discarded, and input continues with the next character.
    42014216If the match fails, the input characters are left unread.
     
    42054220\end{cfa}
    42064221\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4207 @abc   @
    4208 @abc  @
    4209 @xx@
    4210 \end{cfa}
    4211 
    4212 \item
    4213 \Indexc{wdi}©( unsigned int maximum, T & val )©\index{manipulator!wdi@©wdi©}
    4214 For all types except ©char©, ©maximum© is the maximum number of characters read for the current operation.
     4222®abc   ®
     4223®abc  ®
     4224®xx®
     4225\end{cfa}
     4226
     4227\item
     4228\Indexc{wdi}( maximum, reference-value )\index{manipulator!wdi@©wdi©}
     4229For all types except ©char©, maximum is the maximum number of characters read for the current operation.
    42154230\begin{cfa}[belowskip=0pt]
    42164231char s[10];   int i;   double d;   
     
    42184233\end{cfa}
    42194234\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4220 @abcd1233.456E+2@
     4235®abcd1233.456E+2®
    42214236\end{cfa}
    42224237Note, input ©wdi© cannot be overloaded with output ©wd© because both have the same parameters but return different types.
     
    42244239
    42254240\item
    4226 \Indexc{ignore( T & val )}\index{manipulator!ignore@©ignore©}
     4241\Indexc{ignore}( reference-value )\index{manipulator!ignore@©ignore©}
    42274242For all types, the data is read from the stream depending on the argument type but ignored, \ie it is not stored in the argument.
    42284243\begin{cfa}[belowskip=0pt]
     
    42314246\end{cfa}
    42324247\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4233 @  -75.35e-4@ 25
    4234 \end{cfa}
    4235 
    4236 \item
    4237 \Indexc{incl( const char * scanset, char * s )}\index{manipulator!incl@©incl©}
    4238 For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{in} the set.
    4239 Matching characters are read into the C string and null terminated.
     4248®  -75.35e-4® 25
     4249\end{cfa}
     4250
     4251\item
     4252\Indexc{incl}( scanset, input-string )\index{manipulator!incl@©incl©}
     4253For C-string types, the scanset matches any number of characters \emph{in} the set.
     4254Matching characters are read into the C input-string and null terminated.
    42404255\begin{cfa}[belowskip=0pt]
    42414256char s[10];
     
    42434258\end{cfa}
    42444259\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4245 @bca@xyz
    4246 \end{cfa}
    4247 
    4248 \item
    4249 \Indexc{excl( const char * scanset, char * s )}\index{manipulator!excl@©excl©}
    4250 For the C-string type, the argument defines a ©scanset© that matches any number of characters \emph{not in} the set.
    4251 Non-matching characters are read into the C string and null terminated.
     4260®bca®xyz
     4261\end{cfa}
     4262
     4263\item
     4264\Indexc{excl}( scanset, input-string )\index{manipulator!excl@©excl©}
     4265For C-string types, the scanset matches any number of characters \emph{not in} the set.
     4266Non-matching characters are read into the C input-string and null terminated.
    42524267\begin{cfa}[belowskip=0pt]
    42534268char s[10];
     
    42554270\end{cfa}
    42564271\begin{cfa}[showspaces=true,aboveskip=0pt,belowskip=0pt]
    4257 @xyz@bca
     4272®xyz®bca
    42584273\end{cfa}
    42594274\end{enumerate}
     
    43064321The common usage is manipulator ©acquire©\index{ostream@©ostream©!acquire@©acquire©} to lock a stream during a single cascaded I/O expression, with the manipulator appearing as the first item in a cascade list, \eg:
    43074322\begin{cfa}
    4308 $\emph{thread\(_1\)}$ : sout | @acquire@ | "abc " | "def ";   // manipulator
    4309 $\emph{thread\(_2\)}$ : sout | @acquire@ | "uvw " | "xyz ";
     4323$\emph{thread\(_1\)}$ : sout | ®acquire® | "abc " | "def ";   // manipulator
     4324$\emph{thread\(_2\)}$ : sout | ®acquire® | "uvw " | "xyz ";
    43104325\end{cfa}
    43114326Now, the order of the thread execution is still non-deterministic, but the output is constrained to two possible lines in either order.
     
    43294344\begin{cfa}
    43304345{       // acquire sout for block duration
    4331         @osacquire@ acq = { sout };                             $\C{// named stream locker}$
     4346        ®osacquire® acq = { sout };                             $\C{// named stream locker}$
    43324347        sout | 1;
    4333         sout | @acquire@ | 2 | 3;                               $\C{// unnecessary, but ok to acquire and release again}$
     4348        sout | ®acquire® | 2 | 3;                               $\C{// unnecessary, but ok to acquire and release again}$
    43344349        sout | 4;
    43354350}       // implicitly release the lock when "acq" is deallocated
     
    43414356\begin{cfa}
    43424357{       // acquire sin lock for block duration
    4343         @isacquire acq = { sin };@                              $\C{// named stream locker}$
     4358        ®isacquire acq = { sin };®                              $\C{// named stream locker}$
    43444359        int x, y, z, w;
    43454360        sin | x;
    4346         sin | @acquire@ | y | z;                                $\C{// unnecessary, but ok to acquire and release again}$
     4361        sin | ®acquire® | y | z;                                $\C{// unnecessary, but ok to acquire and release again}$
    43474362        sin | w;
    43484363}       // implicitly release the lock when "acq" is deallocated
     
    43534368\Textbf{WARNING:} The general problem of \Index{nested locking} can occur if routines are called in an I/O sequence that block, \eg:
    43544369\begin{cfa}
    4355 sout | @acquire@ | "data:" | rtn( mon );        $\C{// mutex call on monitor}$
     4370sout | ®acquire® | "data:" | rtn( mon );        $\C{// mutex call on monitor}$
    43564371\end{cfa}
    43574372If the thread executing the I/O expression blocks in the monitor with the ©sout© lock, other threads writing to ©sout© also block until the thread holding the lock is unblocked and releases it.
     
    43594374To prevent nested locking, a simple precaution is to factor out the blocking call from the expression, \eg:
    43604375\begin{cfa}
    4361 int @data@ = rtn( mon );
    4362 sout | acquire | "data:" | @data@;
     4376int ®data® = rtn( mon );
     4377sout | acquire | "data:" | ®data®;
    43634378\end{cfa}
    43644379
     
    48094824For example, given
    48104825\begin{cfa}
    4811 auto j = @...@
     4826auto j = ®...®
    48124827\end{cfa}
    48134828and the need to write a routine to compute using ©j©
    48144829\begin{cfa}
    4815 void rtn( @...@ parm );
     4830void rtn( ®...® parm );
    48164831rtn( j );
    48174832\end{cfa}
     
    50515066\begin{cfa}
    50525067#include <fstream.hfa>
    5053 #include @<coroutine.hfa>@
    5054 
    5055 @coroutine@ Fibonacci {
     5068#include ®<coroutine.hfa>®
     5069
     5070®coroutine® Fibonacci {
    50565071        int fn; $\C{// used for communication}$
    50575072};
     
    50605075        int fn1, fn2; $\C{// retained between resumes}$
    50615076        fn = 0;  fn1 = fn; $\C{// 1st case}$
    5062         @suspend;@ $\C{// restart last resume}$
     5077        ®suspend;® $\C{// restart last resume}$
    50635078        fn = 1;  fn2 = fn1;  fn1 = fn; $\C{// 2nd case}$
    5064         @suspend;@ $\C{// restart last resume}$
     5079        ®suspend;® $\C{// restart last resume}$
    50655080        for () {
    50665081                fn = fn1 + fn2;  fn2 = fn1;  fn1 = fn; $\C{// general case}$
    5067                 @suspend;@ $\C{// restart last resume}$
     5082                ®suspend;® $\C{// restart last resume}$
    50685083        }
    50695084}
    50705085int next( Fibonacci & fib ) with( fib ) {
    5071         @resume( fib );@ $\C{// restart last suspend}$
     5086        ®resume( fib );® $\C{// restart last suspend}$
    50725087        return fn;
    50735088}
     
    51065121\begin{cfa}
    51075122#include <fstream.hfa>
    5108 #include @<thread.hfa>@
    5109 
    5110 @monitor@ AtomicCnt { int counter; };
     5123#include ®<thread.hfa>®
     5124
     5125®monitor® AtomicCnt { int counter; };
    51115126void ?{}( AtomicCnt & c, int init = 0 ) with(c) { counter = init; }
    5112 int inc( AtomicCnt & @mutex@ c, int inc = 1 ) with(c) { return counter += inc; }
    5113 int dec( AtomicCnt & @mutex@ c, int dec = 1 ) with(c) { return counter -= dec; }
     5127int inc( AtomicCnt & ®mutex® c, int inc = 1 ) with(c) { return counter += inc; }
     5128int dec( AtomicCnt & ®mutex® c, int dec = 1 ) with(c) { return counter -= dec; }
    51145129forall( ostype & | ostream( ostype ) ) { $\C{// print any stream}$
    51155130        ostype & ?|?( ostype & os, AtomicCnt c ) { return os | c.counter; }
     
    65996614
    66006615C has a number of syntax ambiguities, which are resolved by taking the longest sequence of overlapping characters that constitute a token.
    6601 For example, the program fragment ©x+++++y© is parsed as \lstinline[showspaces=true]@x ++ ++ + y@ because operator tokens ©++© and ©+© overlap.
    6602 Unfortunately, the longest sequence violates a constraint on increment operators, even though the parse \lstinline[showspaces=true]@x ++ + ++ y@ might yield a correct expression.
     6616For example, the program fragment ©x+++++y© is parsed as \lstinline[showspaces=true]{x ++ ++ + y} because operator tokens ©++© and ©+© overlap.
     6617Unfortunately, the longest sequence violates a constraint on increment operators, even though the parse \lstinline[showspaces=true]{x ++ + ++ y} might yield a correct expression.
    66036618Hence, C programmers are aware that spaces have to added to disambiguate certain syntactic cases.
    66046619
     
    66206635requiring arbitrary whitespace look-ahead for the routine-call parameter-list to disambiguate.
    66216636However, the dereference operator \emph{must} have a parameter/argument to dereference ©*?(...)©.
    6622 Hence, always interpreting the string ©*?()© as \lstinline[showspaces=true]@* ?()@ does not preclude any meaningful program.
     6637Hence, always interpreting the string ©*?()© as \lstinline[showspaces=true]{* ?()} does not preclude any meaningful program.
    66236638
    66246639The remaining cases are with the increment/decrement operators and conditional expression, \eg:
     
    67286743\begin{cfa}
    67296744int i; $\C{// forward definition}$
    6730 int *j = @&i@; $\C{// forward reference, valid in C, invalid in \CFA}$
     6745int *j = ®&i®; $\C{// forward reference, valid in C, invalid in \CFA}$
    67316746int i = 0; $\C{// definition}$
    67326747\end{cfa}
     
    67366751struct X { int i; struct X *next; };
    67376752static struct X a; $\C{// forward definition}$
    6738 static struct X b = { 0, @&a@ };$\C{// forward reference, valid in C, invalid in \CFA}$
     6753static struct X b = { 0, ®&a® };$\C{// forward reference, valid in C, invalid in \CFA}$
    67396754static struct X a = { 1, &b }; $\C{// definition}$
    67406755\end{cfa}
     
    67496764\item[Change:] have ©struct© introduce a scope for nested types:
    67506765\begin{cfa}
    6751 enum @Colour@ { R, G, B, Y, C, M };
     6766enum ®Colour® { R, G, B, Y, C, M };
    67526767struct Person {
    6753         enum @Colour@ { R, G, B };      $\C[7cm]{// nested type}$
     6768        enum ®Colour® { R, G, B };      $\C[7cm]{// nested type}$
    67546769        struct Face { $\C{// nested type}$
    6755                 @Colour@ Eyes, Hair; $\C{// type defined outside (1 level)}$
     6770                ®Colour® Eyes, Hair; $\C{// type defined outside (1 level)}$
    67566771        };
    6757         @.Colour@ shirt; $\C{// type defined outside (top level)}$
    6758         @Colour@ pants; $\C{// type defined same level}$
     6772        ®.Colour® shirt; $\C{// type defined outside (top level)}$
     6773        ®Colour® pants; $\C{// type defined same level}$
    67596774        Face looks[10]; $\C{// type defined same level}$
    67606775};
    6761 @Colour@ c = R; $\C{// type/enum defined same level}$
    6762 Person@.Colour@ pc = Person@.@R;$\C{// type/enum defined inside}$
    6763 Person@.@Face pretty; $\C{// type defined inside}\CRT$
     6776®Colour® c = R; $\C{// type/enum defined same level}$
     6777Person®.Colour® pc = Person®.®R;$\C{// type/enum defined inside}$
     6778Person®.®Face pretty; $\C{// type defined inside}\CRT$
    67646779\end{cfa}
    67656780In C, the name of the nested types belongs to the same scope as the name of the outermost enclosing structure, \ie the nested types are hoisted to the scope of the outer-most type, which is not useful and confusing.
     
    70647079// assume ?|? operator for printing an S
    70657080
    7066 S & sp = *@new@( 3 );                                                   $\C{// call constructor after allocation}$
     7081S & sp = *®new®( 3 );                                                   $\C{// call constructor after allocation}$
    70677082sout | sp.i;
    7068 @delete@( &sp );
    7069 
    7070 S * spa = @anew@( 10, 5 );                                              $\C{// allocate array and initialize each array element}$
     7083®delete®( &sp );
     7084
     7085S * spa = ®anew®( 10, 5 );                                              $\C{// allocate array and initialize each array element}$
    70717086for ( i; 10 ) sout | spa[i] | nonl;
    70727087sout | nl;
    7073 @adelete@( 10, spa );
     7088®adelete®( 10, spa );
    70747089\end{cfa}
    70757090Allocation routines ©new©/©anew© allocate a variable/array and initialize storage using the allocated type's constructor.
     
    76837698
    76847699
    7685 %\subsection{\texorpdfstring{\protect\lstinline@Duration@}{Duration}}
     7700%\subsection{\texorpdfstring{\protect\lstinline{Duration}}{Duration}}
    76867701\subsection{\texorpdfstring{\LstBasicStyle{Duration}}{Duration}}
    76877702\label{s:Duration}
     
    77777792
    77787793
    7779 %\subsection{\texorpdfstring{\protect\lstinline@\timeval@}{timeval}}
     7794%\subsection{\texorpdfstring{\protect\lstinline{timeval}}{timeval}}
    77807795\subsection{\texorpdfstring{\LstBasicStyle{timeval}}{timeval}}
    77817796\label{s:timeval}
     
    77977812
    77987813
    7799 %\subsection{\texorpdfstring{\protect\lstinline@timespec@}{timespec}}
     7814%\subsection{\texorpdfstring{\protect\lstinline{timespec}}{timespec}}
    78007815\subsection{\texorpdfstring{\LstBasicStyle{timespec}}{timespec}}
    78017816\label{s:timespec}
     
    78177832
    78187833
    7819 %\subsection{\texorpdfstring{\protect\lstinline@itimerval@}{itimerval}}
     7834%\subsection{\texorpdfstring{\protect\lstinline{itimerval}}{itimerval}}
    78207835\subsection{\texorpdfstring{\LstBasicStyle{itimerval}}{itimerval}}
    78217836\label{s:itimerval}
     
    78287843
    78297844
    7830 %\subsection{\texorpdfstring{\protect\lstinline@Time@}{Time}}
     7845%\subsection{\texorpdfstring{\protect\lstinline{Time}}{Time}}
    78317846\subsection{\texorpdfstring{\LstBasicStyle{Time}}{Time}}
    78327847\label{s:Time}
     
    78947909
    78957910
    7896 %\subsection{\texorpdfstring{\protect\lstinline@Clock@}{Clock}}
     7911%\subsection{\texorpdfstring{\protect\lstinline{Clock}}{Clock}}
    78977912\subsection{\texorpdfstring{\LstBasicStyle{Clock}}{Clock}}
    78987913\label{s:Clock}
     
    81158130#include <gmp.h>$\indexc{gmp.h}$
    81168131int main( void ) {
    8117         @gmp_printf@( "Factorial Numbers\n" );
    8118         @mpz_t@ fact;
    8119         @mpz_init_set_ui@( fact, 1 );
    8120         @gmp_printf@( "%d %Zd\n", 0, fact );
     8132        ®gmp_printf®( "Factorial Numbers\n" );
     8133        ®mpz_t® fact;
     8134        ®mpz_init_set_ui®( fact, 1 );
     8135        ®gmp_printf®( "%d %Zd\n", 0, fact );
    81218136        for ( unsigned int i = 1; i <= 40; i += 1 ) {
    8122                 @mpz_mul_ui@( fact, fact, i );
    8123                 @gmp_printf@( "%d %Zd\n", i, fact );
     8137                ®mpz_mul_ui®( fact, fact, i );
     8138                ®gmp_printf®( "%d %Zd\n", i, fact );
    81248139        }
    81258140}
  • libcfa/src/concurrency/coroutine.cfa

    re9c0b4c radaee12  
    6161forall(T & | is_coroutine(T))
    6262void __cfaehm_cancelled_coroutine(
    63                 T & cor, $coroutine * desc, _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable ) {
     63                T & cor, $coroutine * desc, EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)) ) {
    6464        verify( desc->cancellation );
    6565        desc->state = Cancelled;
     
    145145// Part of the Public API
    146146// Not inline since only ever called once per coroutine
    147 forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
     147forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)); })
    148148void prime(T& cor) {
    149149        $coroutine* this = get_coroutine(cor);
  • libcfa/src/concurrency/coroutine.hfa

    re9c0b4c radaee12  
    6060//-----------------------------------------------------------------------------
    6161// Public coroutine API
    62 forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
     62forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)); })
    6363void prime(T & cor);
    6464
     
    131131forall(T & | is_coroutine(T))
    132132void __cfaehm_cancelled_coroutine(
    133         T & cor, $coroutine * desc, _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable );
     133        T & cor, $coroutine * desc, EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)) );
    134134
    135135// Resume implementation inlined for performance
    136 forall(T & | is_coroutine(T) | { _EHM_VTABLE_TYPE(CoroutineCancelled)(T) & const _default_vtable; })
     136forall(T & | is_coroutine(T) | { EHM_DEFAULT_VTABLE(CoroutineCancelled, (T)); })
    137137static inline T & resume(T & cor) {
    138138        // optimization : read TLS once and reuse it
  • libcfa/src/concurrency/stats.cfa

    re9c0b4c radaee12  
    126126
    127127                char buf[1024];
    128                 strstream sstr = { buf, 1024 };
     128                ostrstream sstr = { buf, 1024 };
    129129
    130130                if( flags & CFA_STATS_READY_Q ) {
  • libcfa/src/concurrency/thread.cfa

    re9c0b4c radaee12  
    8282
    8383forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))
    84     | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; })
     84    | { EHM_DEFAULT_VTABLE(ThreadCancelled, (T)); })
    8585void ?{}( thread_dtor_guard_t & this,
    8686                T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) {
     
    161161//-----------------------------------------------------------------------------
    162162forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))
    163     | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; })
     163    | { EHM_DEFAULT_VTABLE(ThreadCancelled, (T)); })
    164164T & join( T & this ) {
    165165        thread_dtor_guard_t guard = { this, defaultResumptionHandler };
  • libcfa/src/concurrency/thread.hfa

    re9c0b4c radaee12  
    8080
    8181forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))
    82     | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; } )
     82    | { EHM_DEFAULT_VTABLE(ThreadCancelled, (T)); })
    8383void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) );
    8484void ^?{}( thread_dtor_guard_t & this );
     
    127127// join
    128128forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))
    129     | { _EHM_VTABLE_TYPE(ThreadCancelled)(T) & const _default_vtable; } )
     129    | { EHM_DEFAULT_VTABLE(ThreadCancelled, (T)); })
    130130T & join( T & this );
    131131
  • libcfa/src/exception.hfa

    re9c0b4c radaee12  
    6464        _EHM_VIRTUAL_TABLE(exception_name, arguments, table_name)
    6565
    66 #define EHM_TYPE_ID(exception_name) _EHM_TYPE_ID_TYPE(exception_name)
    67 
    68 #define EHM_MATCH_ALL __cfa__parent_vtable
     66// EHM_DEFAULT_VTABLE(exception_name, (arguments))
     67// Create a declaration for a (possibly polymorphic) default vtable.
     68#define EHM_DEFAULT_VTABLE(exception_name, arguments) \
     69        _EHM_VTABLE_TYPE(exception_name) arguments & const _default_vtable
    6970
    7071// IS_EXCEPTION(exception_name [, (...parameters)])
  • libcfa/src/fstream.cfa

    re9c0b4c radaee12  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 24 09:05:16 2021
    13 // Update Count     : 426
    14 //
    15 
    16 #include "fstream.hfa"
     12// Last Modified On : Tue Apr 27 22:08:57 2021
     13// Update Count     : 442
     14//
     15
     16#include "fstream.hfa"                                                                  // also includes iostream.hfa
    1717
    1818#include <stdio.h>                                                                              // vfprintf, vfscanf
     
    196196ofstream & abort = abortFile;
    197197
     198ofstream & nl( ofstream & os ) {
     199        nl$( os );                                                                                      // call basic_ostream nl
     200        flush( os );
     201        return os;
     202        // (ofstream &)(os | '\n');
     203        // setPrt$( os, false );                                                        // turn off
     204        // setNL$( os, true );
     205        // flush( os );
     206        // return sepOff( os );                                                 // prepare for next line
     207} // nl
    198208
    199209// *********************************** ifstream ***********************************
  • libcfa/src/fstream.hfa

    re9c0b4c radaee12  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 24 09:04:03 2021
    13 // Update Count     : 219
     12// Last Modified On : Tue Apr 27 22:00:30 2021
     13// Update Count     : 226
    1414//
    1515
     
    7171bool fail( ofstream & );
    7272int flush( ofstream & );
    73 void open( ofstream &, const char name[], const char mode[] );
     73void open( ofstream &, const char name[], const char mode[] ); // FIX ME: use default = "w"
    7474void open( ofstream &, const char name[] );
    7575void close( ofstream & );
     
    8686
    8787void ?{}( ofstream & );
    88 void ?{}( ofstream &, const char name[], const char mode[] );
     88void ?{}( ofstream &, const char name[], const char mode[] ); // FIX ME: use default = "w"
    8989void ?{}( ofstream &, const char name[] );
    9090void ^?{}( ofstream & );
     91
     92// private
     93static inline ofstream & nl$( ofstream & os ) { return nl( os ); } // remember basic_ostream nl
     94// public
     95ofstream & nl( ofstream & os );                                                 // override basic_ostream nl
    9196
    9297extern ofstream & sout, & stdout, & serr, & stderr;             // aliases
     
    111116bool getANL( ifstream & );
    112117void ends( ifstream & );
     118int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
     119
    113120bool fail( ifstream & is );
    114121int eof( ifstream & is );
    115 void open( ifstream & is, const char name[], const char mode[] );
     122void open( ifstream & is, const char name[], const char mode[] ); // FIX ME: use default = "r"
    116123void open( ifstream & is, const char name[] );
    117124void close( ifstream & is );
    118125ifstream & read( ifstream & is, char * data, size_t size );
    119126ifstream & ungetc( ifstream & is, char c );
    120 int fmt( ifstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
     127
    121128void acquire( ifstream & is );
    122129void release( ifstream & is );
     
    129136
    130137void ?{}( ifstream & is );
    131 void ?{}( ifstream & is, const char name[], const char mode[] );
     138void ?{}( ifstream & is, const char name[], const char mode[] ); // FIX ME: use default = "r"
    132139void ?{}( ifstream & is, const char name[] );
    133140void ^?{}( ifstream & is );
  • libcfa/src/iostream.cfa

    re9c0b4c radaee12  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 24 10:03:54 2021
    13 // Update Count     : 1329
     12// Last Modified On : Tue Apr 27 18:01:03 2021
     13// Update Count     : 1330
    1414//
    1515
     
    145145        } // ?|?
    146146
    147 #if defined( __SIZEOF_INT128__ )
     147        #if defined( __SIZEOF_INT128__ )
    148148        //      UINT64_MAX 18_446_744_073_709_551_615_ULL
    149149        #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
    150150
    151151        static inline void base10_128( ostype & os, unsigned int128 val ) {
    152 #if defined(__GNUC__) && __GNUC_PREREQ(7,0)                             // gcc version >= 7
     152                #if defined(__GNUC__) && __GNUC_PREREQ(7,0)             // gcc version >= 7
    153153                if ( val > P10_UINT64 ) {
    154 #else
     154                #else
    155155                if ( (uint64_t)(val >> 64) != 0 || (uint64_t)val > P10_UINT64 ) { // patch gcc 5 & 6 -O3 bug
    156 #endif // __GNUC_PREREQ(7,0)
     156                #endif // __GNUC_PREREQ(7,0)
    157157                        base10_128( os, val / P10_UINT64 );                     // recursive
    158158                        fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
     
    187187                (ostype &)(os | ullli); ends( os );
    188188        } // ?|?
    189 #endif // __SIZEOF_INT128__
     189        #endif // __SIZEOF_INT128__
    190190
    191191        #define PrintWithDP( os, format, val, ... ) \
     
    361361                setPrt$( os, false );                                                   // turn off
    362362                setNL$( os, true );
    363                 flush( os );
    364363                return sepOff( os );                                                    // prepare for next line
    365364        } // nl
     
    808807
    809808
    810 forall( istype & | istream( istype ) ) {
     809forall( istype & | basic_istream( istype ) ) {
    811810        istype & ?|?( istype & is, bool & b ) {
    812811                char val[6];
     
    918917        } // ?|?
    919918
    920 #if defined( __SIZEOF_INT128__ )
     919        #if defined( __SIZEOF_INT128__ )
    921920        istype & ?|?( istype & is, int128 & llli ) {
    922921                return (istype &)(is | (unsigned int128 &)llli);
     
    944943                (istype &)(is | ullli); ends( is );
    945944        } // ?|?
    946 #endif // __SIZEOF_INT128__
     945        #endif // __SIZEOF_INT128__
    947946
    948947        istype & ?|?( istype & is, float & f ) {
     
    10351034                return is;
    10361035        } // nlOff
    1037 
     1036} // distribution
     1037
     1038forall( istype & | istream( istype ) ) {
    10381039        istype & acquire( istype & is ) {
    10391040                acquire( is );                                                                  // call void returning
     
    10441045// *********************************** manipulators ***********************************
    10451046
    1046 forall( istype & | istream( istype ) ) {
     1047forall( istype & | basic_istream( istype ) ) {
    10471048        istype & ?|?( istype & is, _Istream_Cstr f ) {
    10481049                // skip xxx
     
    10921093
    10931094#define InputFMTImpl( T, CODE ) \
    1094 forall( istype & | istream( istype ) ) { \
     1095forall( istype & | basic_istream( istype ) ) { \
    10951096        istype & ?|?( istype & is, _Istream_Manip(T) f ) { \
    10961097                enum { size = 16 }; \
     
    11251126InputFMTImpl( long double, "Lf" )
    11261127
    1127 forall( istype & | istream( istype ) ) {
     1128forall( istype & | basic_istream( istype ) ) {
    11281129        istype & ?|?( istype & is, _Istream_Manip(float _Complex) fc ) {
    11291130                float re, im;
  • libcfa/src/iostream.hfa

    re9c0b4c radaee12  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 24 09:28:56 2021
    13 // Update Count     : 393
     12// Last Modified On : Tue Apr 27 17:59:21 2021
     13// Update Count     : 398
    1414//
    1515
     
    4949        void ends( ostype & );                                                          // end of output statement
    5050        int fmt( ostype &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    51         int flush( ostype & );
    5251}; // basic_ostream
    5352       
    5453trait ostream( ostype & | basic_ostream( ostype ) ) {
     54        int flush( ostype & );
    5555        bool fail( ostype & );                                                          // operation failed?
    5656        void open( ostype &, const char name[], const char mode[] );
     
    9797        ostype & ?|?( ostype &, unsigned long long int );
    9898        void ?|?( ostype &, unsigned long long int );
    99 #if defined( __SIZEOF_INT128__ )
     99        #if defined( __SIZEOF_INT128__ )
    100100        ostype & ?|?( ostype &, int128 );
    101101        void ?|?( ostype &, int128 );
    102102        ostype & ?|?( ostype &, unsigned int128 );
    103103        void ?|?( ostype &, unsigned int128 );
    104 #endif // __SIZEOF_INT128__
     104        #endif // __SIZEOF_INT128__
    105105
    106106        ostype & ?|?( ostype &, float );
     
    121121        void ?|?( ostype &, const char [] );
    122122        // ostype & ?|?( ostype &, const char16_t * );
    123 #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
     123        #if ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 ) // char32_t == wchar_t => ambiguous
    124124        // ostype & ?|?( ostype &, const char32_t * );
    125 #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
     125        #endif // ! ( __ARM_ARCH_ISA_ARM == 1 && __ARM_32BIT_STATE == 1 )
    126126        // ostype & ?|?( ostype &, const wchar_t * );
    127127        ostype & ?|?( ostype &, const void * );
     
    164164struct _Ostream_Manip {
    165165        T val;                                                                                          // polymorphic base-type
    166         int wd, pc;                                                                                     // width, precision
     166        int wd, pc;                                                                                     // width, precision: signed for computations
    167167        char base;                                                                                      // numeric base / floating-point style
    168168        union {
     
    192192        _Ostream_Manip(T) hex( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'x', { .all : 0 } }; } \
    193193        _Ostream_Manip(T) wd( unsigned int w, T val ) { return (_Ostream_Manip(T))@{ val, w, 0, CODE, { .all : 0 } }; } \
    194         _Ostream_Manip(T) wd( unsigned int w, unsigned char pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, CODE, { .flags.pc : true } }; } \
     194        _Ostream_Manip(T) wd( unsigned int w, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, CODE, { .flags.pc : true } }; } \
    195195        _Ostream_Manip(T) & wd( unsigned int w, _Ostream_Manip(T) & fmt ) { fmt.wd = w; return fmt; } \
    196         _Ostream_Manip(T) & wd( unsigned int w, unsigned char pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \
     196        _Ostream_Manip(T) & wd( unsigned int w, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \
    197197        _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \
    198198        _Ostream_Manip(T) & upcase( _Ostream_Manip(T) & fmt ) { if ( fmt.base == 'x' || fmt.base == 'b' ) fmt.base -= 32; /* upper case */ return fmt; } \
     
    231231        _Ostream_Manip(T) eng( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'g', { .flags.eng : true } }; } \
    232232        _Ostream_Manip(T) wd( unsigned int w, T val ) { return (_Ostream_Manip(T))@{ val, w, 0, 'g', { .all : 0 } }; } \
    233         _Ostream_Manip(T) wd( unsigned int w, unsigned char pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'f', { .flags.pc : true } }; } \
    234         _Ostream_Manip(T) ws( unsigned int w, unsigned char pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'g', { .flags.pc : true } }; } \
     233        _Ostream_Manip(T) wd( unsigned int w, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'f', { .flags.pc : true } }; } \
     234        _Ostream_Manip(T) ws( unsigned int w, unsigned int pc, T val ) { return (_Ostream_Manip(T))@{ val, w, pc, 'g', { .flags.pc : true } }; } \
    235235        _Ostream_Manip(T) & wd( unsigned int w, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = w; return fmt; } \
    236         _Ostream_Manip(T) & wd( unsigned int w, unsigned char pc, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \
    237         _Ostream_Manip(T) & ws( unsigned int w, unsigned char pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \
     236        _Ostream_Manip(T) & wd( unsigned int w, unsigned int pc, _Ostream_Manip(T) & fmt ) { if ( fmt.flags.eng ) fmt.base = 'f'; fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \
     237        _Ostream_Manip(T) & ws( unsigned int w, unsigned int pc, _Ostream_Manip(T) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; } \
    238238        _Ostream_Manip(T) & left( _Ostream_Manip(T) & fmt ) { fmt.flags.left = true; return fmt; } \
    239239        _Ostream_Manip(T) upcase( T val ) { return (_Ostream_Manip(T))@{ val, 1, 0, 'G', { .all : 0 } }; } \
     
    279279        _Ostream_Manip(const char *) hex( const char s[] ) { return (_Ostream_Manip(const char *))@{ s, 1, 0, 'x', { .all : 0 } }; }
    280280        _Ostream_Manip(const char *) wd( unsigned int w, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, 0, 's', { .all : 0 } }; }
    281         _Ostream_Manip(const char *) wd( unsigned int w, unsigned char pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; }
     281        _Ostream_Manip(const char *) wd( unsigned int w, unsigned int pc, const char s[] ) { return (_Ostream_Manip(const char *))@{ s, w, pc, 's', { .flags.pc : true } }; }
    282282        _Ostream_Manip(const char *) & wd( unsigned int w, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; return fmt; }
    283         _Ostream_Manip(const char *) & wd( unsigned int w, unsigned char pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; }
     283        _Ostream_Manip(const char *) & wd( unsigned int w, unsigned int pc, _Ostream_Manip(const char *) & fmt ) { fmt.wd = w; fmt.pc = pc; fmt.flags.pc = true; return fmt; }
    284284        _Ostream_Manip(const char *) & left( _Ostream_Manip(const char *) & fmt ) { fmt.flags.left = true; return fmt; }
    285285        _Ostream_Manip(const char *) & nobase( _Ostream_Manip(const char *) & fmt ) { fmt.flags.nobsdp = true; return fmt; }
     
    294294
    295295
    296 trait istream( istype & ) {
     296trait basic_istream( istype & ) {
     297        bool getANL( istype & );                                                        // get scan newline (on/off)
    297298        void nlOn( istype & );                                                          // read newline
    298299        void nlOff( istype & );                                                         // scan newline
    299         bool getANL( istype & );                                                        // get scan newline (on/off)
    300300
    301301        void ends( istype & os );                                                       // end of output statement
     302        int fmt( istype &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
     303        istype & ungetc( istype &, char );
     304        int eof( istype & );
     305}; // basic_istream
     306
     307trait istream( istype & | basic_istream( istype ) ) {
    302308        bool fail( istype & );
    303         int eof( istype & );
    304309        void open( istype & is, const char name[] );
    305310        void close( istype & is );
    306311        istype & read( istype &, char *, size_t );
    307         istype & ungetc( istype &, char );
    308         int fmt( istype &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
    309         void acquire( istype & );
     312        void acquire( istype & );                                                       // concurrent access
    310313}; // istream
    311314
     
    314317}; // readable
    315318
    316 forall( istype & | istream( istype ) ) {
     319forall( istype & | basic_istream( istype ) ) {
    317320        istype & ?|?( istype &, bool & );
    318321        void ?|?( istype &, bool & );
     
    341344        istype & ?|?( istype &, unsigned long long int & );
    342345        void ?|?( istype &, unsigned long long int & );
    343 #if defined( __SIZEOF_INT128__ )
     346        #if defined( __SIZEOF_INT128__ )
    344347        istype & ?|?( istype &, int128 & );
    345348        void ?|?( istype &, int128 & );
    346349        istype & ?|?( istype &, unsigned int128 & );
    347350        void ?|?( istype &, unsigned int128 & );
    348 #endif // __SIZEOF_INT128__
     351        #endif // __SIZEOF_INT128__
    349352
    350353        istype & ?|?( istype &, float & );
     
    372375        istype & nlOn( istype & );
    373376        istype & nlOff( istype & );
     377} // distribution
     378
     379forall( istype & | istream( istype ) ) {
    374380        istype & acquire( istype & );
    375381} // distribution
     
    391397
    392398static inline {
     399        _Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
    393400        _Istream_Cstr skip( unsigned int n ) { return (_Istream_Cstr){ 0p, 0p, n, { .all : 0 } }; }
    394         _Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr){ 0p, scanset, -1, { .all : 0 } }; }
    395401        _Istream_Cstr incl( const char scanset[], char * s ) { return (_Istream_Cstr){ s, scanset, -1, { .flags.inex : false } }; }
    396402        _Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
     
    402408        _Istream_Cstr & wdi( unsigned int w, _Istream_Cstr & fmt ) { fmt.wd = w; return fmt; }
    403409} // distribution
    404 forall( istype & | istream( istype ) ) {
     410forall( istype & | basic_istream( istype ) ) {
    405411        istype & ?|?( istype & is, _Istream_Cstr f );
    406412        void ?|?( istype & is, _Istream_Cstr f );
     
    415421        _Istream_Char & ignore( _Istream_Char & fmt ) { fmt.ignore = true; return fmt; }
    416422} // distribution
    417 forall( istype & | istream( istype ) ) {
     423forall( istype & | basic_istream( istype ) ) {
    418424        istype & ?|?( istype & is, _Istream_Char f );
    419425        void ?|?( istype & is, _Istream_Char f );
     
    434440        _Istream_Manip(T) & wdi( unsigned int w, _Istream_Manip(T) & fmt ) { fmt.wd = w; return fmt; } \
    435441} /* distribution */ \
    436 forall( istype & | istream( istype ) ) { \
     442forall( istype & | basic_istream( istype ) ) { \
    437443        istype & ?|?( istype & is, _Istream_Manip(T) f ); \
    438444        void ?|?( istype & is, _Istream_Manip(T) f ); \
  • libcfa/src/strstream.cfa

    re9c0b4c radaee12  
    1010// Created On       : Thu Apr 22 22:24:35 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 24 11:15:47 2021
    13 // Update Count     : 73
     12// Last Modified On : Tue Apr 27 20:59:53 2021
     13// Update Count     : 78
    1414//
    1515
     
    2323#include <unistd.h>                                                                             // sbrk, sysconf
    2424
     25
    2526// *********************************** strstream ***********************************
    2627
     
    2930
    3031// private
    31 bool sepPrt$( strstream & os ) { setNL$( os, false ); return os.sepOnOff$; }
    32 void sepReset$( strstream & os ) { os.sepOnOff$ = os.sepDefault$; }
    33 void sepReset$( strstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; }
    34 const char * sepGetCur$( strstream & os ) { return os.sepCur$; }
    35 void sepSetCur$( strstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; }
    36 bool getNL$( strstream & os ) { return os.sawNL$; }
    37 void setNL$( strstream & os, bool state ) { os.sawNL$ = state; }
    38 bool getANL$( strstream & os ) { return os.nlOnOff$; }
    39 bool getPrt$( strstream & os ) { return os.prt$; }
    40 void setPrt$( strstream & os, bool state ) { os.prt$ = state; }
     32bool sepPrt$( ostrstream & os ) { setNL$( os, false ); return os.sepOnOff$; }
     33void sepReset$( ostrstream & os ) { os.sepOnOff$ = os.sepDefault$; }
     34void sepReset$( ostrstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; }
     35const char * sepGetCur$( ostrstream & os ) { return os.sepCur$; }
     36void sepSetCur$( ostrstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; }
     37bool getNL$( ostrstream & os ) { return os.sawNL$; }
     38void setNL$( ostrstream & os, bool state ) { os.sawNL$ = state; }
     39bool getANL$( ostrstream & os ) { return os.nlOnOff$; }
     40bool getPrt$( ostrstream & os ) { return os.prt$; }
     41void setPrt$( ostrstream & os, bool state ) { os.prt$ = state; }
    4142
    4243// public
    43 void ?{}( strstream & os, char buf[], size_t size ) {
     44void ?{}( ostrstream & os, char buf[], size_t size ) {
    4445        os.buf$ = buf;
    4546        os.size$ = size;
     
    5556} // ?{}
    5657
    57 void sepOn( strstream & os ) { os.sepOnOff$ = ! getNL$( os ); }
    58 void sepOff( strstream & os ) { os.sepOnOff$ = false; }
     58void sepOn( ostrstream & os ) { os.sepOnOff$ = ! getNL$( os ); }
     59void sepOff( ostrstream & os ) { os.sepOnOff$ = false; }
    5960
    60 bool sepDisable( strstream & os ) {
     61bool sepDisable( ostrstream & os ) {
    6162        bool temp = os.sepDefault$;
    6263        os.sepDefault$ = false;
     
    6566} // sepDisable
    6667
    67 bool sepEnable( strstream & os ) {
     68bool sepEnable( ostrstream & os ) {
    6869        bool temp = os.sepDefault$;
    6970        os.sepDefault$ = true;
     
    7273} // sepEnable
    7374
    74 void nlOn( strstream & os ) { os.nlOnOff$ = true; }
    75 void nlOff( strstream & os ) { os.nlOnOff$ = false; }
     75void nlOn( ostrstream & os ) { os.nlOnOff$ = true; }
     76void nlOff( ostrstream & os ) { os.nlOnOff$ = false; }
    7677
    77 const char * sepGet( strstream & os ) { return os.separator$; }
    78 void sepSet( strstream & os, const char s[] ) {
     78const char * sepGet( ostrstream & os ) { return os.separator$; }
     79void sepSet( ostrstream & os, const char s[] ) {
    7980        assert( s );
    80         strncpy( os.separator$, s, strstream_sepSize - 1 );
    81         os.separator$[strstream_sepSize - 1] = '\0';
     81        strncpy( os.separator$, s, ostrstream_sepSize - 1 );
     82        os.separator$[ostrstream_sepSize - 1] = '\0';
    8283} // sepSet
    8384
    84 const char * sepGetTuple( strstream & os ) { return os.tupleSeparator$; }
    85 void sepSetTuple( strstream & os, const char s[] ) {
     85const char * sepGetTuple( ostrstream & os ) { return os.tupleSeparator$; }
     86void sepSetTuple( ostrstream & os, const char s[] ) {
    8687        assert( s );
    87         strncpy( os.tupleSeparator$, s, strstream_sepSize - 1 );
    88         os.tupleSeparator$[strstream_sepSize - 1] = '\0';
     88        strncpy( os.tupleSeparator$, s, ostrstream_sepSize - 1 );
     89        os.tupleSeparator$[ostrstream_sepSize - 1] = '\0';
    8990} // sepSet
    9091
    91 void ends( strstream & os ) {
     92void ends( ostrstream & os ) {
    9293        if ( getANL$( os ) ) nl( os );
    9394        else setPrt$( os, false );                                                      // turn off
    9495} // ends
    9596
    96 int fmt( strstream & os, const char format[], ... ) {
     97int fmt( ostrstream & os, const char format[], ... ) {
    9798        va_list args;
    9899        va_start( args, format );
    99100        int len = vsnprintf( os.buf$ + os.cursor$, os.size$ - os.cursor$, format, args );
     101        va_end( args );
    100102        os.cursor$ += len;
    101103        if ( os.cursor$ >= os.size$ ) {                                         // cursor exceeded buffer size?
    102                 #define fmtmsg IO_MSG "strstream truncated write, buffer too small.\n"
     104                #define fmtmsg IO_MSG "ostrstream truncated write, buffer too small.\n"
    103105                write( STDERR_FILENO, fmtmsg, sizeof(fmtmsg) - 1 );
    104106                abort();
    105107        } // if
    106         va_end( args );
    107108
    108109        setPrt$( os, true );                                                            // called in output cascade
     
    111112} // fmt
    112113
    113 int flush( strstream & ) {                                                              // match trait, not used
    114         return 0;
    115 } // flush
    116 
    117 strstream & write( strstream & os ) {
    118         return write( os, stdout );
    119 } // write
    120 strstream & write( strstream & os, FILE * stream ) {
     114ostrstream & write( ostrstream & os, FILE * stream ) {
    121115        if ( fwrite( os.buf$, 1, os.cursor$, stream ) != os.cursor$ ) {
    122                 #define writemsg IO_MSG "strstream write error.\n"
    123                 write( STDERR_FILENO, writemsg, sizeof(writemsg) - 1 );
     116                #define ostrwritemsg IO_MSG "ostrstream write error.\n"
     117                write( STDERR_FILENO, ostrwritemsg, sizeof(ostrwritemsg) - 1 );
    124118                abort();
    125119        } // if
     
    127121} // write
    128122
    129 strstream & sstr;
     123ostrstream & write( ostrstream & os ) {
     124        return write( os, stdout );
     125} // write
     126
     127
     128// *********************************** istrstream ***********************************
     129
     130
     131// public
     132void ?{}( istrstream & is, char buf[] ) {
     133        is.buf$ = buf;
     134        is.cursor$ = 0;
     135        is.nlOnOff$ = false;
     136} // ?{}
     137
     138bool getANL( istrstream & is ) { return is.nlOnOff$; }
     139void nlOn( istrstream & is ) { is.nlOnOff$ = true; }
     140void nlOff( istrstream & is ) { is.nlOnOff$ = false; }
     141
     142void ends( istrstream & is ) {
     143} // ends
     144
     145int eof( istrstream & is ) {
     146        return 0;
     147} // eof
     148
     149istrstream &ungetc( istrstream & is, char c ) {
     150        // if ( ungetc( c, (FILE *)(is.file$) ) == EOF ) {
     151        //      abort | IO_MSG "ungetc" | nl | strerror( errno );
     152        // } // if
     153        return is;
     154} // ungetc
     155
     156int fmt( istrstream & is, const char format[], ... ) {
     157        va_list args;
     158        va_start( args, format );
     159        // This does not work because vsscanf does not return buffer position.
     160        int len = vsscanf( is.buf$ + is.cursor$, format, args );
     161        va_end( args );
     162        if ( len == EOF ) {
     163                int j;
     164                printf( "X %d%n\n", len, &j );
     165        } // if
     166        is.cursor$ += len;
     167        return len;
     168} // fmt
    130169
    131170// Local Variables: //
  • libcfa/src/strstream.hfa

    re9c0b4c radaee12  
    1010// Created On       : Thu Apr 22 22:20:59 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Apr 24 11:17:33 2021
    13 // Update Count     : 37
     12// Last Modified On : Tue Apr 27 20:58:50 2021
     13// Update Count     : 41
    1414//
    1515
     
    2020
    2121
    22 // *********************************** strstream ***********************************
     22// *********************************** ostrstream ***********************************
    2323
    2424
    25 enum { strstream_sepSize = 16 };
    26 struct strstream {                                                                              // satisfied basic_ostream
     25enum { ostrstream_sepSize = 16 };
     26struct ostrstream {                                                                             // satisfied basic_ostream
    2727        char * buf$;
    2828        size_t size$;
     
    3434        bool sawNL$;
    3535        const char * sepCur$;
    36         char separator$[strstream_sepSize];
    37         char tupleSeparator$[strstream_sepSize];
    38 }; // strstream
     36        char separator$[ostrstream_sepSize];
     37        char tupleSeparator$[ostrstream_sepSize];
     38}; // ostrstream
    3939
    4040// Satisfies basic_ostream
    4141
    4242// private
    43 bool sepPrt$( strstream & );
    44 void sepReset$( strstream & );
    45 void sepReset$( strstream &, bool );
    46 const char * sepGetCur$( strstream & );
    47 void sepSetCur$( strstream &, const char [] );
    48 bool getNL$( strstream & );
    49 void setNL$( strstream &, bool );
    50 bool getANL$( strstream & );
    51 bool getPrt$( strstream & );
    52 void setPrt$( strstream &, bool );
     43bool sepPrt$( ostrstream & );
     44void sepReset$( ostrstream & );
     45void sepReset$( ostrstream &, bool );
     46const char * sepGetCur$( ostrstream & );
     47void sepSetCur$( ostrstream &, const char [] );
     48bool getNL$( ostrstream & );
     49void setNL$( ostrstream &, bool );
     50bool getANL$( ostrstream & );
     51bool getPrt$( ostrstream & );
     52void setPrt$( ostrstream &, bool );
    5353
    5454// public
    55 void sepOn( strstream & );
    56 void sepOff( strstream & );
    57 bool sepDisable( strstream & );
    58 bool sepEnable( strstream & );
    59 void nlOn( strstream & );
    60 void nlOff( strstream & );
     55void sepOn( ostrstream & );
     56void sepOff( ostrstream & );
     57bool sepDisable( ostrstream & );
     58bool sepEnable( ostrstream & );
     59void nlOn( ostrstream & );
     60void nlOff( ostrstream & );
    6161
    62 const char * sepGet( strstream & );
    63 void sepSet( strstream &, const char [] );
    64 const char * sepGetTuple( strstream & );
    65 void sepSetTuple( strstream &, const char [] );
     62const char * sepGet( ostrstream & );
     63void sepSet( ostrstream &, const char [] );
     64const char * sepGetTuple( ostrstream & );
     65void sepSetTuple( ostrstream &, const char [] );
    6666
    67 void ends( strstream & );
    68 int fmt( strstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    69 int flush( strstream & );
     67void ends( ostrstream & );
     68int fmt( ostrstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
    7069
    71 strstream & write( strstream & os );                                    // use stdout, default value not working
    72 strstream & write( strstream & os, FILE * stream = stdout );
     70ostrstream & write( ostrstream & os, FILE * stream ); // FIX ME: use default = stdout
     71ostrstream & write( ostrstream & os );
    7372
    74 void ?{}( strstream &, char buf[], size_t size );
     73void ?{}( ostrstream &, char buf[], size_t size );
    7574
    76 extern strstream & sstr;
     75
     76// *********************************** istrstream ***********************************
     77
     78
     79struct istrstream {
     80        char * buf$;
     81        size_t cursor$;
     82        bool nlOnOff$;
     83}; // istrstream
     84
     85// Satisfies basic_istream
     86
     87// public
     88bool getANL( istrstream & );
     89void nlOn( istrstream & );
     90void nlOff( istrstream & );
     91void ends( istrstream & );
     92int fmt( istrstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
     93istrstream & ungetc( istrstream & is, char c );
     94int eof( istrstream & is );
     95
     96void ?{}( istrstream & is, char buf[] );
    7797
    7898// Local Variables: //
  • src/Parser/parser.yy

    re9c0b4c radaee12  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr 14 18:13:44 2021
    13 // Update Count     : 4983
     12// Last Modified On : Mon Apr 26 18:41:54 2021
     13// Update Count     : 4990
    1414//
    1515
     
    211211} // forCtrl
    212212
    213 bool forall = false, yyy = false;                                               // aggregate have one or more forall qualifiers ?
     213bool forall = false;                                                                    // aggregate have one or more forall qualifiers ?
    214214
    215215// https://www.gnu.org/software/bison/manual/bison.html#Location-Type
     
    812812                { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
    813813        | '(' aggregate_control '&' ')' cast_expression         // CFA
     814                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     815        | '(' aggregate_control '*' ')' cast_expression         // CFA
    814816                { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
    815817        | '(' VIRTUAL ')' cast_expression                                       // CFA
     
    21282130aggregate_data:
    21292131        STRUCT vtable_opt
    2130                 { yyy = true; $$ = AggregateDecl::Struct; }
     2132                { $$ = AggregateDecl::Struct; }
    21312133        | UNION
    2132                 { yyy = true; $$ = AggregateDecl::Union; }
     2134                { $$ = AggregateDecl::Union; }
    21332135        | EXCEPTION                                                                                     // CFA
    2134                 { yyy = true; $$ = AggregateDecl::Exception; }
     2136                { $$ = AggregateDecl::Exception; }
    21352137          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    21362138        ;
     
    21382140aggregate_control:                                                                              // CFA
    21392141        MONITOR
    2140                 { yyy = true; $$ = AggregateDecl::Monitor; }
     2142                { $$ = AggregateDecl::Monitor; }
    21412143        | MUTEX STRUCT
    2142                 { yyy = true; $$ = AggregateDecl::Monitor; }
     2144                { $$ = AggregateDecl::Monitor; }
    21432145        | GENERATOR
    2144                 { yyy = true; $$ = AggregateDecl::Generator; }
     2146                { $$ = AggregateDecl::Generator; }
    21452147        | MUTEX GENERATOR
    21462148                { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    21472149        | COROUTINE
    2148                 { yyy = true; $$ = AggregateDecl::Coroutine; }
     2150                { $$ = AggregateDecl::Coroutine; }
    21492151        | MUTEX COROUTINE
    21502152                { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
    21512153        | THREAD
    2152                 { yyy = true; $$ = AggregateDecl::Thread; }
     2154                { $$ = AggregateDecl::Thread; }
    21532155        | MUTEX THREAD
    21542156                { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
  • tests/io/io-acquire.cfa

    re9c0b4c radaee12  
    1010// Created On       : Mon Mar  1 18:40:09 2021
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar  2 12:06:35 2021
    13 // Update Count     : 17
     12// Last Modified On : Tue Apr 27 11:49:34 2021
     13// Update Count     : 18
    1414//
    1515
     
    4343        int a, b, c, d, e, f, g, h, i;
    4444        for ( 100 ) {                                                                           // local protection
    45                 sin  | acquire | a | b | c | d | e | f | g | h | i;
     45                sin | acquire | a | b | c | d | e | f | g | h | i;
    4646        }
    4747        {                                                                                                       // global protection (RAII)
  • tests/strstream.cfa

    re9c0b4c radaee12  
    55    enum { size = 256 };
    66    char buf[size];
    7     strstream sstr = { buf, size };
     7    ostrstream osstr = { buf, size };
    88    int i = 3, j = 5, k = 7;
    99    double x = 12345678.9, y = 98765.4321e-11;
    1010
    11     sstr | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y));
    12     write( sstr );
     11    osstr | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y));
     12    write( osstr );
    1313    printf( "%s", buf );
    1414    sout | i | hex(j) | wd(10, k) | sci(x) | unit(eng(y));
     15
     16    // char buf2[] = "12 14 15 3.5 7e4";
     17    // istrstream isstr = { buf2 };
     18    // isstr | i | j | k | x | y;
     19    // sout | i | j | k | x | y;
    1520}
Note: See TracChangeset for help on using the changeset viewer.