Changeset f4abc58


Ignore:
Timestamp:
Mar 7, 2018, 5:09:18 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
fb11446e
Parents:
b2e8841 (diff), 7b0dfa4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Files:
28 edited

Legend:

Unmodified
Added
Removed
  • doc/bibliography/pl.bib

    rb2e8841 rf4abc58  
    14391439    contributer = {pabuhr@plg},
    14401440    author      = {Peter A. Buhr},
    1441     title       = {$\mu${C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Annotated Reference Manual, Version 6.1.0},
     1441    title       = {$\mu${C}{\kern-.1em\hbox{\large\texttt{+\kern-.25em+}}} Annotated Reference Manual, Version 7.0.0},
    14421442    institution = {School of Computer Science, University of Waterloo},
    14431443    address     = {Waterloo, Ontario, Canada, N2L 3G1},
    1444     month       = jul,
    1445     year        = 2015,
    1446     note        = {\href{http://plg.uwaterloo.ca/~usystem/pub/uSystem/u++-6.1.0.sh}{http://\-plg.\-uwaterloo.\-ca/\-$\sim$usystem/\-pub/\-uSystem/\-u++-6.1.0.sh}},
     1444    month       = dec,
     1445    year        = 2017,
     1446    note        = {\href{http://plg.uwaterloo.ca/~usystem/pub/uSystem/u++-7.0.0.sh}{http://\-plg.\-uwaterloo.\-ca/\-$\sim$usystem/\-pub/\-uSystem/\-u++-7.0.0.sh}},
    14471447}
    14481448
  • doc/papers/general/Paper.tex

    rb2e8841 rf4abc58  
    1313\usepackage{pslatex}                                            % reduce size of san serif font
    1414\usepackage[plainpages=false,pdfpagelabels,pdfpagemode=UseNone,pagebackref=true,breaklinks=true,colorlinks=true,linkcolor=blue,citecolor=blue,urlcolor=blue]{hyperref}
     15\urlstyle{sf}
     16\usepackage{breakurl}
    1517
    1618\setlength{\textheight}{9in}
     
    5658\setlength{\parindentlnth}{\parindent}
    5759
     60\newcommand{\LstBasicStyle}[1]{{\lst@basicstyle{\lst@basicstyle{#1}}}}
    5861\newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}}
    5962\newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}}
     
    229232All of the features discussed in this paper are working, unless a feature states it is a future feature for completion.
    230233
     234Finally, it is impossible to describe a programming language without usages before definitions.
     235Therefore, syntax and semantics appear before explanations;
     236hence, patience is necessary until details are presented.
     237
    231238
    232239\section{Polymorphic Functions}
     
    261268\end{cfa}
    262269\CFA maximizes the ability to reuse names to aggressively address the naming problem.
    263 In some cases, hundreds of names can be reduced to tens, resulting in a significant cognitive reduction for a programmer.
     270In some cases, hundreds of names can be reduced to tens, resulting in a significant cognitive reduction.
    264271In the above, the name @max@ has a consistent meaning, and a programmer only needs to remember the single concept: maximum.
    265272To prevent significant ambiguities, \CFA uses the return type in selecting overloads, \eg in the assignment to @m@, the compiler use @m@'s type to unambiguously select the most appropriate call to function @max@ (as does Ada).
    266273As is shown later, there are a number of situations where \CFA takes advantage of available type information to disambiguate, where other programming languages generate ambiguities.
    267274
    268 \Celeven added @_Generic@ expressions, which can be used in preprocessor macros to provide a form of ad-hoc polymorphism; however, this polymorphism is both functionally and ergonomically inferior to \CFA name overloading.
    269 The macro wrapping the generic expression imposes some limitations; as an example, it could not implement the example above, because the variables @max@ would collide with the functions @max@.
    270 Ergonomic limitations of @_Generic@ include the necessity to put a fixed list of supported types in a single place and manually dispatch to appropriate overloads, as well as possible namespace pollution from the functions dispatched to, which must all have distinct names.
    271 Though name-overloading removes a major use-case for @_Generic@ expressions, \CFA implements @_Generic@ for backwards-compatibility purposes. \TODO{actually implement that}
     275\Celeven added @_Generic@ expressions, which is used in preprocessor macros to provide a form of ad-hoc polymorphism;
     276however, this polymorphism is both functionally and ergonomically inferior to \CFA name overloading.
     277The macro wrapping the generic expression imposes some limitations;
     278\eg, it cannot implement the example above, because the variables @max@ are ambiguous with the functions @max@.
     279Ergonomic limitations of @_Generic@ include the necessity to put a fixed list of supported types in a single place and manually dispatch to appropriate overloads, as well as possible namespace pollution from the dispatch functions, which must all have distinct names.
     280For backwards compatibility, \CFA supports @_Generic@ expressions, but it is an unnecessary mechanism. \TODO{actually implement that}
    272281
    273282% http://fanf.livejournal.com/144696.html
     
    284293int forty_two = identity( 42 );                         $\C{// T is bound to int, forty\_two == 42}$
    285294\end{cfa}
    286 The @identity@ function above can be applied to any complete \newterm{object type} (or @otype@).
     295This @identity@ function can be applied to any complete \newterm{object type} (or @otype@).
    287296The type variable @T@ is transformed into a set of additional implicit parameters encoding sufficient information about @T@ to create and return a variable of that type.
    288297The \CFA implementation passes the size and alignment of the type represented by an @otype@ parameter, as well as an assignment operator, constructor, copy constructor and destructor.
    289298If this extra information is not needed, \eg for a pointer, the type parameter can be declared as a \newterm{data type} (or @dtype@).
    290299
    291 In \CFA, the polymorphism runtime-cost is spread over each polymorphic call, due to passing more arguments to polymorphic functions;
     300In \CFA, the polymorphic runtime-cost is spread over each polymorphic call, because more arguments are passed to polymorphic functions;
    292301the experiments in Section~\ref{sec:eval} show this overhead is similar to \CC virtual-function calls.
    293302A design advantage is that, unlike \CC template-functions, \CFA polymorphic-functions are compatible with C \emph{separate compilation}, preventing compilation and code bloat.
     
    301310which works for any type @T@ with a matching addition operator.
    302311The polymorphism is achieved by creating a wrapper function for calling @+@ with @T@ bound to @double@, then passing this function to the first call of @twice@.
    303 There is now the option of using the same @twice@ and converting the result to @int@ on assignment, or creating another @twice@ with type parameter @T@ bound to @int@ because \CFA uses the return type~\cite{Cormack81,Baker82,Ada}, in its type analysis.
     312There is now the option of using the same @twice@ and converting the result to @int@ on assignment, or creating another @twice@ with type parameter @T@ bound to @int@ because \CFA uses the return type~\cite{Cormack81,Baker82,Ada} in its type analysis.
    304313The first approach has a late conversion from @double@ to @int@ on the final assignment, while the second has an eager conversion to @int@.
    305314\CFA minimizes the number of conversions and their potential to lose information, so it selects the first approach, which corresponds with C-programmer intuition.
     
    310319\begin{cfa}
    311320void * bsearch( const void * key, const void * base, size_t nmemb, size_t size,
    312                                 int (* compar)( const void *, const void * ));
    313 
    314 int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 :
    315                                 *(double *)t2 < *(double *)t1 ? 1 : 0; }
    316 
     321                                         int (* compar)( const void *, const void * ));
     322int comp( const void * t1, const void * t2 ) {
     323         return *(double *)t1 < *(double *)t2 ? -1 : *(double *)t2 < *(double *)t1 ? 1 : 0;
     324}
    317325double key = 5.0, vals[10] = { /* 10 sorted float values */ };
    318326double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp );      $\C{// search sorted array}$
     
    322330forall( otype T | { int ?<?( T, T ); } ) T * bsearch( T key, const T * arr, size_t size ) {
    323331        int comp( const void * t1, const void * t2 ) { /* as above with double changed to T */ }
    324         return (T *)bsearch( &key, arr, size, sizeof(T), comp ); }
    325 
     332        return (T *)bsearch( &key, arr, size, sizeof(T), comp );
     333}
    326334forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) {
    327335        T * result = bsearch( key, arr, size ); $\C{// call first version}$
    328         return result ? result - arr : size; }  $\C{// pointer subtraction includes sizeof(T)}$
    329 
     336        return result ? result - arr : size;    $\C{// pointer subtraction includes sizeof(T)}$
     337}
    330338double * val = bsearch( 5.0, vals, 10 );        $\C{// selection based on return type}$
    331339int posn = bsearch( 5.0, vals, 10 );
     
    334342Providing a hidden @comp@ function in \CC is awkward as lambdas do not use C calling-conventions and template declarations cannot appear at block scope.
    335343As well, an alternate kind of return is made available: position versus pointer to found element.
    336 \CC's type-system cannot disambiguate between the two versions of @bsearch@ because it does not use the return type in overload resolution, nor can \CC separately compile a templated @bsearch@.
     344\CC's type-system cannot disambiguate between the two versions of @bsearch@ because it does not use the return type in overload resolution, nor can \CC separately compile a template @bsearch@.
    337345
    338346\CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations (see Section~\ref{sec:libraries}).
     
    380388\begin{cfa}
    381389trait otype( dtype T | sized(T) ) {  // sized is a pseudo-trait for types with known size and alignment
    382         void ?{}( T * );                                                $\C{// default constructor}$
    383         void ?{}( T *, T );                                             $\C{// copy constructor}$
    384         void ?=?( T *, T );                                             $\C{// assignment operator}$
    385         void ^?{}( T * ); };                                    $\C{// destructor}$
     390        void ?{}( T & );                                                $\C{// default constructor}$
     391        void ?{}( T &, T );                                             $\C{// copy constructor}$
     392        void ?=?( T &, T );                                             $\C{// assignment operator}$
     393        void ^?{}( T & ); };                                    $\C{// destructor}$
    386394\end{cfa}
    387395Given the information provided for an @otype@, variables of polymorphic type can be treated as if they were a complete type: stack-allocatable, default or copy-initialized, assigned, and deleted.
     
    427435One approach is to write bespoke data-structures for each context in which they are needed.
    428436While this approach is flexible and supports integration with the C type-checker and tooling, it is also tedious and error-prone, especially for more complex data structures.
    429 A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@, which allows reuse of code with common functionality.
     437A second approach is to use @void *@--based polymorphism, \eg the C standard-library functions @bsearch@ and @qsort@, which allow reuse of code with common functionality.
    430438However, basing all polymorphism on @void *@ eliminates the type-checker's ability to ensure that argument types are properly matched, often requiring a number of extra function parameters, pointer indirection, and dynamic allocation that is not otherwise needed.
    431439A third approach to generic code is to use preprocessor macros, which does allow the generated code to be both generic and type-checked, but errors may be difficult to interpret.
    432 Furthermore, writing and using preprocessor macros can be unnatural and inflexible.
     440Furthermore, writing and using preprocessor macros is unnatural and inflexible.
    433441
    434442\CC, Java, and other languages use \newterm{generic types} to produce type-safe abstract data-types.
     
    442450        S second;
    443451};
    444 forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; }
    445 forall( dtype F, otype T ) T value( pair( F *, T * ) p ) { return *p.second; }
    446 
    447 pair( const char *, int ) p = { "magic", 42 };
     452forall( otype T ) T value( pair( const char *, T ) p ) { return p.second; } $\C{// dynamic}$
     453forall( dtype F, otype T ) T value( pair( F *, T * ) p ) { return *p.second; } $\C{// dtype-static (concrete)}$
     454
     455pair( const char *, int ) p = { "magic", 42 }; $\C{// concrete}$
    448456int i = value( p );
    449 pair( void *, int * ) q = { 0, &p.second };
     457pair( void *, int * ) q = { 0, &p.second }; $\C{// concrete}$
    450458i = value( q );
    451459double d = 1.0;
    452 pair( double *, double * ) r = { &d, &d };
     460pair( double *, double * ) r = { &d, &d }; $\C{// concrete}$
    453461d = value( r );
    454462\end{cfa}
     
    456464\CFA classifies generic types as either \newterm{concrete} or \newterm{dynamic}.
    457465Concrete types have a fixed memory layout regardless of type parameters, while dynamic types vary in memory layout depending on their type parameters.
    458 A type may have polymorphic parameters but still be concrete, called \newterm{dtype-static}.
     466A \newterm{dtype-static} type has polymorphic parameters but is still concrete.
    459467Polymorphic pointers are an example of dtype-static types, \eg @forall(dtype T) T *@ is a polymorphic type, but for any @T@, @T *@  is a fixed-sized pointer, and therefore, can be represented by a @void *@ in code generation.
    460468
     
    473481For example, the concrete instantiation for @pair( const char *, int )@ is:
    474482\begin{cfa}
    475 struct _pair_conc1 {
     483struct _pair_conc0 {
    476484        const char * first;
    477485        int second;
     
    480488
    481489A concrete generic-type with dtype-static parameters is also expanded to a structure type, but this type is used for all matching instantiations.
    482 In the above example, the @pair( F *, T * )@ parameter to @value_p@ is such a type; its expansion is below and it is used as the type of the variables @q@ and @r@ as well, with casts for member access where appropriate:
    483 \begin{cfa}
    484 struct _pair_conc0 {
     490In the above example, the @pair( F *, T * )@ parameter to @value@ is such a type; its expansion is below and it is used as the type of the variables @q@ and @r@ as well, with casts for member access where appropriate:
     491\begin{cfa}
     492struct _pair_conc1 {
    485493        void * first;
    486494        void * second;
     
    494502As mentioned in Section~\ref{sec:poly-fns}, @otype@ function parameters (in fact all @sized@ polymorphic parameters) come with implicit size and alignment parameters provided by the caller.
    495503Dynamic generic-types also have an \newterm{offset array} containing structure-member offsets.
    496 A dynamic generic-union needs no such offset array, as all members are at offset 0, but size and alignment are still necessary.
     504A dynamic generic-@union@ needs no such offset array, as all members are at offset 0, but size and alignment are still necessary.
    497505Access to members of a dynamic structure is provided at runtime via base-displacement addressing with the structure pointer and the member offset (similar to the @offsetof@ macro), moving a compile-time offset calculation to runtime.
    498506
    499507The offset arrays are statically generated where possible.
    500508If a dynamic generic-type is declared to be passed or returned by value from a polymorphic function, the translator can safely assume the generic type is complete (\ie has a known layout) at any call-site, and the offset array is passed from the caller;
    501 if the generic type is concrete at the call site, the elements of this offset array can even be statically generated using the C @offsetof@ macro.
    502 As an example, @p.second@ in the @value@ function above is implemented as @*(p + _offsetof_pair[1])@, where @p@ is a @void *@, and @_offsetof_pair@ is the offset array passed into @value@ for @pair( const char *, T )@.
    503 The offset array @_offsetof_pair@ is generated at the call site as @size_t _offsetof_pair[] = { offsetof(_pair_conc1, first), offsetof(_pair_conc1, second) }@.
     509if the generic type is concrete at the call site, the elements of this offset array can even be statically generated using the C @offsetof@ macro.
     510As an example, the body of the second @value@ function is implemented like this:
     511\begin{cfa}
     512_assign_T(_retval, p + _offsetof_pair[1]); $\C{// return *p.second}$
     513\end{cfa}
     514@_assign_T@ is passed in as an implicit parameter from @otype T@, and takes two @T*@ (@void*@ in the generated code), a destination and a source; @_retval@ is the pointer to a caller-allocated buffer for the return value, the usual \CFA method to handle dynamically-sized return types.
     515@_offsetof_pair@ is the offset array passed into @value@; this array is generated at the call site as:
     516\begin{cfa}
     517size_t _offsetof_pair[] = { offsetof(_pair_conc0, first), offsetof(_pair_conc0, second) }
     518\end{cfa}
    504519
    505520In some cases the offset arrays cannot be statically generated.
     
    584599\subsection{Tuple Expressions}
    585600
    586 The addition of multiple-return-value functions (MRVF) are useless without a syntax for accepting multiple values at the call-site.
     601The addition of multiple-return-value functions (MRVF) are \emph{useless} without a syntax for accepting multiple values at the call-site.
    587602The simplest mechanism for capturing the return values is variable assignment, allowing the values to be retrieved directly.
    588603As such, \CFA allows assigning multiple values from a function into multiple variables, using a square-bracketed list of lvalue expressions (as above), called a \newterm{tuple}.
     
    820835\end{cfa}
    821836so the thunk provides flattening and structuring conversions to inferred functions, improving the compatibility of tuples and polymorphism.
    822 These thunks take advantage of gcc C nested-functions to produce closures that have the usual function-pointer signature.
     837These thunks take advantage of gcc C nested-functions to produce closures that have the usual function-pointer signature WHAT DOES THIS MEAN???.
    823838
    824839
     
    876891        print(arg);  print(rest);
    877892}
    878 void print( char * x ) { printf( "%s", x ); }
     893void print( const char * x ) { printf( "%s", x ); }
    879894void print( int x ) { printf( "%d", x ); }
    880895void print( S s ) { print( "{ ", s.x, ",", s.y, " }" ); }
     
    885900The polymorphic @print@ allows printing any list of types, where as each individual type has a @print@ function.
    886901The individual print functions can be used to build up more complicated @print@ functions, such as @S@, which cannot be done with @printf@ in C.
     902This mechanism is used to seamlessly print tuples in the \CFA I/O library (see Section~\ref{s:IOLibrary}).
    887903
    888904Finally, it is possible to use @ttype@ polymorphism to provide arbitrary argument forwarding functions.
     
    9881004\section{Control Structures}
    9891005
    990 \CFA identifies missing and problematic control structures in C, and extends and modifies these control structures to increase functionality and safety.
     1006\CFA identifies inconsistent, problematic, and missing control structures in C, and extends, modifies, and adds to control structures to increase functionality and safety.
     1007
     1008
     1009\subsection{\texorpdfstring{\LstKeywordStyle{if} Statement}{if Statement}}
     1010
     1011The @if@ expression allows declarations, similar to @for@ declaration expression:
     1012\begin{cfa}
     1013if ( int x = f() ) ...                                          $\C{// x != 0}$
     1014if ( int x = f(), y = g() ) ...                         $\C{// x != 0 \&\& y != 0}$
     1015if ( int x = f(), y = g(); `x < y` ) ...        $\C{// relational expression}$
     1016\end{cfa}
     1017Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the @if@ expression, and the results are combined using the logical @&&@ operator.\footnote{\CC only provides a single declaration always compared not equal to 0.}
     1018The scope of the declaration(s) is local to the @if@ statement but exist within both the ``then'' and ``else'' clauses.
     1019
     1020
     1021\subsection{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}
     1022
     1023There are a number of deficiencies with the C @switch@ statements: enumerating @case@ lists, placement of @case@ clauses, scope of the switch body, and fall through between case clauses.
     1024
     1025C has no shorthand for specifying a list of case values, whether the list is non-contiguous or contiguous\footnote{C provides this mechanism via fall through.}.
     1026\CFA provides a shorthand for a non-contiguous list:
     1027\begin{cquote}
     1028\lstDeleteShortInline@%
     1029\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     1030\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
     1031\begin{cfa}
     1032case 2, 10, 34, 42:
     1033\end{cfa}
     1034&
     1035\begin{cfa}
     1036case 2: case 10: case 34: case 42:
     1037\end{cfa}
     1038\end{tabular}
     1039\lstMakeShortInline@%
     1040\end{cquote}
     1041for a contiguous list:\footnote{gcc provides the same mechanism with awkward syntax, \lstinline@2 ... 42@, where spaces are required around the ellipse.}
     1042\begin{cquote}
     1043\lstDeleteShortInline@%
     1044\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     1045\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
     1046\begin{cfa}
     1047case 2~42:
     1048\end{cfa}
     1049&
     1050\begin{cfa}
     1051case 2: case 3: ... case 41: case 42:
     1052\end{cfa}
     1053\end{tabular}
     1054\lstMakeShortInline@%
     1055\end{cquote}
     1056and a combination:
     1057\begin{cfa}
     1058case -12~-4, -1~5, 14~21, 34~42:
     1059\end{cfa}
     1060
     1061C allows placement of @case@ clauses \emph{within} statements nested in the @switch@ body (see Duff's device~\cite{Duff83});
     1062\begin{cfa}
     1063switch ( i ) {
     1064  case 0:
     1065        for ( int i = 0; i < 10; i += 1 ) {
     1066                ...
     1067  `case 1:`             // no initialization of loop index
     1068                ...
     1069        }
     1070}
     1071\end{cfa}
     1072\CFA precludes this form of transfer into a control structure because it causes undefined behaviour, especially with respect to missed initialization, and provides very limited functionality.
     1073
     1074C allows placement of declaration within the @switch@ body and unreachable code at the start, resulting in undefined behaviour:
     1075\begin{cfa}
     1076switch ( x ) {
     1077        `int y = 1;`                                                    $\C{// unreachable initialization}$
     1078        `x = 7;`                                                                $\C{// unreachable code without label/branch}$
     1079  case 0:
     1080        ...
     1081        `int z = 0;`                                                    $\C{// unreachable initialization, cannot appear after case}$
     1082        z = 2;
     1083  case 1:
     1084        `x = z;`                                                                $\C{// without fall through, z is undefined}$
     1085}
     1086\end{cfa}
     1087\CFA allows the declaration of local variables, \eg @y@, at the start of the @switch@ with scope across the entire @switch@ body, \ie all @case@ clauses.
     1088\CFA disallows the declaration of local variable, \eg @z@, directly within the @switch@ body, because a declaration cannot occur immediately after a @case@ since a label can only be attached to a statement, and the use of @z@ is undefined in @case 1@ as neither storage allocation nor initialization may have occurred.
     1089
     1090C @switch@ provides multiple entry points into the statement body, but once an entry point is selected, control continues across \emph{all} @case@ clauses until the end of the @switch@ body, called \newterm{fall through};
     1091@case@ clauses are made disjoint by the @break@ statement.
     1092While the ability to fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in many errors from missing @break@ statements.
     1093For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through (see Figure~\ref{f:ChooseSwitchStatements}).
     1094
     1095Collectively, these enhancements reduce programmer burden and increase readability and safety.
     1096
     1097\begin{figure}
     1098\centering
     1099\lstDeleteShortInline@%
     1100\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
     1101\multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}}    & \multicolumn{1}{c}{\textbf{C}}        \\
     1102\begin{cfa}
     1103`choose` ( day ) {
     1104  case Mon~Thu:  // program
     1105
     1106  case Fri:  // program
     1107        wallet += pay;
     1108        `fallthrough;`
     1109  case Sat:  // party
     1110        wallet -= party;
     1111
     1112  case Sun:  // rest
     1113
     1114  default:  // error
     1115}
     1116\end{cfa}
     1117&
     1118\begin{cfa}
     1119switch ( day ) {
     1120  case Mon: case Tue: case Wed: case Thu:  // program
     1121        `break;`
     1122  case Fri:  // program
     1123        wallet += pay;
     1124
     1125  case Sat:  // party
     1126        wallet -= party;
     1127        `break;`
     1128  case Sun:  // rest
     1129        `break;`
     1130  default:  // error
     1131}
     1132\end{cfa}
     1133\end{tabular}
     1134\lstMakeShortInline@%
     1135\caption{\lstinline|choose| versus \lstinline|switch| Statements}
     1136\label{f:ChooseSwitchStatements}
     1137\end{figure}
     1138
     1139\begin{comment}
     1140Forgotten @break@ statements at the end of @switch@ cases are a persistent sort of programmer error in C, and the @break@ statements themselves introduce visual clutter and an un-C-like keyword-based block delimiter.
     1141\CFA addresses this error by introducing a @choose@ statement, which works identically to a @switch@ except that its default end-of-case behaviour is to break rather than to fall through for all non-empty cases.
     1142Since empty cases like @case 7:@ in @case 7: case 11:@ still have fall-through semantics and explicit @break@ is still allowed at the end of a @choose@ case, many idiomatic uses of @switch@ in standard C can be converted to @choose@ statements by simply changing the keyword.
     1143Where fall-through is desired for a non-empty case, it can be specified with the new @fallthrough@ statement, making @choose@ equivalently powerful to @switch@, but more concise in the common case where most non-empty cases end with a @break@ statement, as in the example below:
     1144
     1145\begin{cfa}
     1146choose( i ) {
     1147        case 2:
     1148                printf("even ");
     1149                fallthrough;
     1150        case 3: case 5: case 7:
     1151                printf("small prime\n");
     1152        case 4,6,8,9:
     1153                printf("small composite\n");
     1154        case 13~19:
     1155                printf("teen\n");
     1156        default:
     1157                printf("something else\n");
     1158}
     1159\end{cfa}
     1160\end{comment}
    9911161
    9921162
     
    10481218                } else {
    10491219                        ... goto `LIF`; ...
    1050                 } `L3:` ;
     1220                } `LIF:` ;
    10511221        } `LS:` ;
    10521222} `LC:` ;
     
    10821252\end{figure}
    10831253
    1084 Both labelled @continue@ and @break@ are a @goto@ restricted in the following ways:
     1254With respect to safety, both labelled @continue@ and @break@ are a @goto@ restricted in the following ways:
    10851255\begin{itemize}
    10861256\item
     
    10951265With @goto@, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader.
    10961266Finally, using an explicit target for the transfer instead of an implicit target allows new constructs to be added or removed without affecting existing constructs.
    1097 The implicit targets of the current @continue@ and @break@, \ie the closest enclosing loop or @switch@, change as certain constructs are added or removed.
    1098 
    1099 
    1100 \subsection{\texorpdfstring{Enhanced \LstKeywordStyle{switch} Statement}{Enhanced switch Statement}}
    1101 
    1102 There are a number of deficiencies with the C @switch@ statements: enumerating @case@ lists, placement of @case@ clauses, scope of the switch body, and fall through between case clauses.
    1103 
    1104 C has no shorthand for specifying a list of case values, whether the list is non-contiguous or contiguous\footnote{C provides this mechanism via fall through.}.
    1105 \CFA provides a shorthand for a non-contiguous list:
     1267Otherwise, the implicit targets of the current @continue@ and @break@, \ie the closest enclosing loop or @switch@, change as certain constructs are added or removed.
     1268
     1269
     1270\subsection{Exception Handling}
     1271
     1272The following framework for \CFA exception handling is in place, excluding some run-time type-information and dynamic casts.
     1273\CFA provides two forms of exception handling: \newterm{fix-up} and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling})~\cite{Buhr92b,Buhr00a}.
     1274Both mechanisms provide dynamic call to a handler using dynamic name-lookup, where fix-up has dynamic return and recovery has static return from the handler.
     1275\CFA restricts exception types to those defined by aggregate type @exception@.
     1276The form of the raise dictates the set of handlers examined during propagation: \newterm{resumption propagation} (@resume@) only examines resumption handlers (@catchResume@); \newterm{terminating propagation} (@throw@) only examines termination handlers (@catch@).
     1277If @resume@ or @throw@ have no exception type, it is a reresume/rethrow, meaning the currently exception continues propagation.
     1278If there is no current exception, the reresume/rethrow results in a runtime error.
     1279
     1280\begin{figure}
    11061281\begin{cquote}
    11071282\lstDeleteShortInline@%
    1108 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    1109 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    1110 \begin{cfa}
    1111 case 2, 10, 34, 42:
    1112 \end{cfa}
    1113 &
    1114 \begin{cfa}
    1115 case 2: case 10: case 34: case 42:
     1283\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
     1284\multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{Resumption}}      & \multicolumn{1}{c}{\textbf{Termination}}      \\
     1285\begin{cfa}
     1286`exception R { int fix; };`
     1287void f() {
     1288        R r;
     1289        ... `resume( r );` ...
     1290        ... r.fix // control does return here after handler
     1291}
     1292`try` {
     1293        ... f(); ...
     1294} `catchResume( R r )` {
     1295        ... r.fix = ...; // return correction to raise
     1296} // dynamic return to _Resume
     1297\end{cfa}
     1298&
     1299\begin{cfa}
     1300`exception T {};`
     1301void f() {
     1302
     1303        ... `throw( T{} );` ...
     1304        // control does NOT return here after handler
     1305}
     1306`try` {
     1307        ... f(); ...
     1308} `catch( T t )` {
     1309        ... // recover and continue
     1310} // static return to next statement
    11161311\end{cfa}
    11171312\end{tabular}
    11181313\lstMakeShortInline@%
    11191314\end{cquote}
    1120 for a contiguous list:\footnote{gcc provides the same mechanism with awkward syntax, \lstinline@2 ... 42@, where spaces are required around the ellipse.}
     1315\caption{\CFA Exception Handling}
     1316\label{f:CFAExceptionHandling}
     1317\end{figure}
     1318
     1319The set of exception types in a list of catch clause may include both a resumption and termination handler:
     1320\begin{cfa}
     1321try {
     1322        ... resume( `R{}` ); ...
     1323} catchResume( `R` r ) { ... throw( R{} ); ... } $\C{\color{red}// H1}$
     1324   catch( `R` r ) { ... }                                       $\C{\color{red}// H2}$
     1325
     1326\end{cfa}
     1327The resumption propagation raises @R@ and the stack is not unwound;
     1328the exception is caught by the @catchResume@ clause and handler H1 is invoked.
     1329The termination propagation in handler H1 raises @R@ and the stack is unwound;
     1330the exception is caught by the @catch@ clause and handler H2 is invoked.
     1331The termination handler is available because the resumption propagation did not unwind the stack.
     1332
     1333An additional feature is conditional matching in a catch clause:
     1334\begin{cfa}
     1335try {
     1336        ... write( `datafile`, ... ); ...               $\C{// may throw IOError}$
     1337        ... write( `logfile`, ... ); ...
     1338} catch ( IOError err; `err.file == datafile` ) { ... } $\C{// handle datafile error}$
     1339   catch ( IOError err; `err.file == logfile` ) { ... } $\C{// handle logfile error}$
     1340   catch ( IOError err ) { ... }                        $\C{// handler error from other files}$
     1341\end{cfa}
     1342where the throw inserts the failing file-handle in the I/O exception.
     1343Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible..
     1344
     1345The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}:
     1346\begin{cfa}
     1347resume( $\emph{exception-type}$, $\emph{alternate-stack}$ )
     1348resume( $\emph{alternate-stack}$ )
     1349\end{cfa}
     1350These overloads of @resume@ raise the specified exception or the currently propagating exception (reresume) at another \CFA coroutine or task~\cite{Delisle18}.\footnote{\CFA coroutine and concurrency features are discussed in a separately submitted paper.}
     1351Nonlocal raise is restricted to resumption to provide the exception handler the greatest flexibility because processing the exception does not unwind its stack, allowing it to continue after the handle returns.
     1352
     1353To facilitate nonlocal exception, \CFA provides dynamic enabling and disabling of nonlocal exception-propagation.
     1354The constructs for controlling propagation of nonlocal exceptions are the @enable@ and the @disable@ blocks:
    11211355\begin{cquote}
    11221356\lstDeleteShortInline@%
    1123 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    1124 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    1125 \begin{cfa}
    1126 case 2~42:
    1127 \end{cfa}
    1128 &
    1129 \begin{cfa}
    1130 case 2: case 3: ... case 41: case 42:
     1357\begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
     1358\begin{cfa}
     1359enable $\emph{exception-type-list}$ {
     1360        // allow non-local resumption
     1361}
     1362\end{cfa}
     1363&
     1364\begin{cfa}
     1365disable $\emph{exception-type-list}$ {
     1366        // disallow non-local resumption
     1367}
    11311368\end{cfa}
    11321369\end{tabular}
    11331370\lstMakeShortInline@%
    11341371\end{cquote}
    1135 and a combination:
    1136 \begin{cfa}
    1137 case -12~-4, -1~5, 14~21, 34~42:
    1138 \end{cfa}
    1139 
    1140 C allows placement of @case@ clauses \emph{within} statements nested in the @switch@ body (see Duff's device~\cite{Duff83});
    1141 \begin{cfa}
    1142 switch ( i ) {
    1143   case 0:
    1144         for ( int i = 0; i < 10; i += 1 ) {
    1145                 ...
    1146   `case 1:`             // no initialization of loop index
    1147                 ...
     1372The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively.
     1373Specifying no exception type is shorthand for specifying all exception types.
     1374Both @enable@ and @disable@ blocks can be nested, turning propagation on/off on entry, and on exit, the specified exception types are restored to their prior state.
     1375Coroutines and tasks start with non-local exceptions disabled, allowing handlers to be put in place, before non-local exceptions are explicitly enabled.
     1376\begin{cfa}
     1377void main( mytask & c ) {
     1378        try {
     1379                enable {                        $\C{// now allow non-local exception delivery}$
     1380                        // task body
     1381                }
     1382        // appropriate catchResume/catch
    11481383        }
    11491384}
    11501385\end{cfa}
    1151 \CFA precludes this form of transfer into a control structure because it causes undefined behaviour, especially with respect to missed initialization, and provides very limited functionality.
    1152 
    1153 C allows placement of declaration within the @switch@ body and unreachable code at the start, resulting in undefined behaviour:
    1154 \begin{cfa}
    1155 switch ( x ) {
    1156         `int y = 1;`                            $\C{// unreachable initialization}$
    1157         `x = 7;`                                        $\C{// unreachable code without label/branch}$
    1158   case 0:
    1159         ...
    1160         `int z = 0;`                            $\C{// unreachable initialization, cannot appear after case}$
    1161         z = 2;
    1162   case 1:
    1163         `x = z;`                                        $\C{// without fall through, z is undefined}$
    1164 }
    1165 \end{cfa}
    1166 \CFA allows the declaration of local variables, \eg @y@, at the start of the @switch@ with scope across the entire @switch@ body, \ie all @case@ clauses.
    1167 \CFA disallows the declaration of local variable, \eg @z@, directly within the @switch@ body, because a declaration cannot occur immediately after a @case@ since a label can only be attached to a statement, and the use of @z@ is undefined in @case 1@ as neither storage allocation nor initialization may have occurred.
    1168 
    1169 C @switch@ provides multiple entry points into the statement body, but once an entry point is selected, control continues across \emph{all} @case@ clauses until the end of the @switch@ body, called \newterm{fall through};
    1170 @case@ clauses are made disjoint by the @break@ statement.
    1171 While the ability to fall through \emph{is} a useful form of control flow, it does not match well with programmer intuition, resulting in many errors from missing @break@ statements.
    1172 For backwards compatibility, \CFA provides a \emph{new} control structure, @choose@, which mimics @switch@, but reverses the meaning of fall through (see Figure~\ref{f:ChooseSwitchStatements}).
    1173 Collectively, these enhancements reduce programmer burden and increase readability and safety.
    1174 
    1175 \begin{figure}
    1176 \centering
    1177 \lstDeleteShortInline@%
    1178 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
    1179 \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{\CFA}}    & \multicolumn{1}{c}{\textbf{C}}        \\
    1180 \begin{cfa}
    1181 `choose` ( day ) {
    1182   case Mon~Thu:  // program
    1183 
    1184   case Fri:  // program
    1185         wallet += pay;
    1186         `fallthrough;`
    1187   case Sat:  // party
    1188         wallet -= party;
    1189 
    1190   case Sun:  // rest
    1191 
    1192   default:  // error
    1193 }
    1194 \end{cfa}
    1195 &
    1196 \begin{cfa}
    1197 switch ( day ) {
    1198   case Mon: case Tue: case Wed: case Thu:  // program
    1199         `break;`
    1200   case Fri:  // program
    1201         wallet += pay;
    1202 
    1203   case Sat:  // party
    1204         wallet -= party;
    1205         `break;`
    1206   case Sun:  // rest
    1207         `break;`
    1208   default:  // error
    1209 }
    1210 \end{cfa}
    1211 \end{tabular}
    1212 \lstMakeShortInline@%
    1213 \caption{\lstinline|choose| versus \lstinline|switch| Statements}
    1214 \label{f:ChooseSwitchStatements}
    1215 \end{figure}
    1216 
    1217 \begin{comment}
    1218 Forgotten @break@ statements at the end of @switch@ cases are a persistent sort of programmer error in C, and the @break@ statements themselves introduce visual clutter and an un-C-like keyword-based block delimiter.
    1219 \CFA addresses this error by introducing a @choose@ statement, which works identically to a @switch@ except that its default end-of-case behaviour is to break rather than to fall through for all non-empty cases.
    1220 Since empty cases like @case 7:@ in @case 7: case 11:@ still have fall-through semantics and explicit @break@ is still allowed at the end of a @choose@ case, many idiomatic uses of @switch@ in standard C can be converted to @choose@ statements by simply changing the keyword.
    1221 Where fall-through is desired for a non-empty case, it can be specified with the new @fallthrough@ statement, making @choose@ equivalently powerful to @switch@, but more concise in the common case where most non-empty cases end with a @break@ statement, as in the example below:
    1222 
    1223 \begin{cfa}
    1224 choose( i ) {
    1225         case 2:
    1226                 printf("even ");
    1227                 fallthrough;
    1228         case 3: case 5: case 7:
    1229                 printf("small prime\n");
    1230         case 4,6,8,9:
    1231                 printf("small composite\n");
    1232         case 13~19:
    1233                 printf("teen\n");
    1234         default:
    1235                 printf("something else\n");
    1236 }
    1237 \end{cfa}
    1238 \end{comment}
     1386
     1387Finally, \CFA provides a Java like  @finally@ clause after the catch clauses:
     1388\begin{cfa}
     1389try {
     1390        ... f(); ...
     1391// catchResume or catch clauses
     1392} `finally` {
     1393        // house keeping
     1394}
     1395\end{cfa}
     1396The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised.
     1397If an exception is raised and caught, the handler is run before the finally clause.
     1398Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated.
     1399Mimicking the @finally@ clause with mechanisms like RAII is non-trivially when there are multiple types and local accesses.
    12391400
    12401401
     
    12511412S s, as[10];
    12521413\end{cfa}
    1253 However, routines manipulating aggregates must repeat the aggregate name to access its containing fields:
     1414However, functions manipulating aggregates must repeat the aggregate name to access its containing fields:
    12541415\begin{cfa}
    12551416void f( S s ) {
     
    12691430}
    12701431\end{C++}
    1271 Object-oriented nesting of member routines in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
     1432Object-oriented nesting of member functions in a \lstinline[language=C++]@class@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
    12721433However, for other aggregate parameters, qualification is necessary:
    12731434\begin{cfa}
     
    12991460        'with' '(' $\emph{expression-list}$ ')' $\emph{compound-statement}$
    13001461\end{cfa}
    1301 and may appear as the body of a routine or nested within a routine body.
     1462and may appear as the body of a function or nested within a function body.
    13021463Each expression in the expression-list provides a type and object.
    13031464The type must be an aggregate type.
     
    13261487Qualification or a cast is used to disambiguate.
    13271488
    1328 There is an interesting problem between parameters and the routine @with@, \eg:
     1489There is an interesting problem between parameters and the function-body @with@, \eg:
    13291490\begin{cfa}
    13301491void ?{}( S & s, int i ) with ( s ) {           $\C{// constructor}$
     
    13321493}
    13331494\end{cfa}
    1334 Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the routine @with@.
     1495Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the function-body @with@.
    13351496To solve this problem, parameters are treated like an initialized aggregate:
    13361497\begin{cfa}
     
    13401501} params;
    13411502\end{cfa}
    1342 and implicitly opened \emph{after} a routine open, to give them higher priority:
    1343 \begin{cfa}
    1344 void ?{}( S & s, int i ) with ( s ) `with( $\emph{\color{red}params}$ )` {
    1345         s.i = i; j = 3; m = 5.5;
     1503and implicitly opened \emph{after} a function-body open, to give them higher priority:
     1504\begin{cfa}
     1505void ?{}( S & s, int `i` ) with ( s ) `with( $\emph{\color{red}params}$ )` {
     1506        s.i = `i`; j = 3; m = 5.5;
    13461507}
    13471508\end{cfa}
     
    13681529
    13691530
    1370 \subsection{Exception Handling}
    1371 
    1372 The following framework for \CFA exception handling is in place, excluding a run-time type information and dynamic casts.
    1373 \CFA provides two forms of exception handling: \newterm{fix-up} and \newterm{recovery} (see Figure~\ref{f:CFAExceptionHandling}).
    1374 Both mechanisms provide dynamic call to a handler using dynamic name-lookup, where fix-up has dynamic return and recovery has static return from the handler.
    1375 \CFA restricts exception types to those defined by aggregate type @exception@.
    1376 The form of the raise dictates the set of handlers examined during propagation: \newterm{resumption propagation} (@resume@) only examines resumption handlers (@catchResume@); \newterm{terminating propagation} (@throw@) only examines termination handlers (@catch@).
    1377 If @resume@ or @throw@ have no exception type, it is a reresume/rethrow, meaning the currently exception continues propagation.
    1378 If there is no current exception, the reresume/rethrow results in a runtime error.
    1379 
    1380 \begin{figure}
    1381 \begin{cquote}
    1382 \lstDeleteShortInline@%
    1383 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
    1384 \multicolumn{1}{c@{\hspace{2\parindentlnth}}}{\textbf{Resumption}}      & \multicolumn{1}{c}{\textbf{Termination}}      \\
    1385 \begin{cfa}
    1386 `exception R { int fix; };`
    1387 void f() {
    1388         R r;
    1389         ... `resume( r );` ...
    1390         ... r.fix // control does return here after handler
    1391 }
    1392 `try` {
    1393         ... f(); ...
    1394 } `catchResume( R r )` {
    1395         ... r.fix = ...; // return correction to raise
    1396 } // dynamic return to _Resume
    1397 \end{cfa}
    1398 &
    1399 \begin{cfa}
    1400 `exception T {};`
    1401 void f() {
    1402 
    1403         ... `throw( T{} );` ...
    1404         // control does NOT return here after handler
    1405 }
    1406 `try` {
    1407         ... f(); ...
    1408 } `catch( T t )` {
    1409         ... // recover and continue
    1410 } // static return to next statement
    1411 \end{cfa}
    1412 \end{tabular}
    1413 \lstMakeShortInline@%
    1414 \end{cquote}
    1415 \caption{\CFA Exception Handling}
    1416 \label{f:CFAExceptionHandling}
    1417 \end{figure}
    1418 
    1419 The set of exception types in a list of catch clause may include both a resumption and termination handler:
    1420 \begin{cfa}
    1421 try {
    1422         ... resume( `R{}` ); ...
    1423 } catchResume( `R` r ) { ... throw( R{} ); ... } $\C{\color{red}// H1}$
    1424    catch( `R` r ) { ... }                                       $\C{\color{red}// H2}$
    1425 
    1426 \end{cfa}
    1427 The resumption propagation raises @R@ and the stack is not unwound;
    1428 the exception is caught by the @catchResume@ clause and handler H1 is invoked.
    1429 The termination propagation in handler H1 raises @R@ and the stack is unwound;
    1430 the exception is caught by the @catch@ clause and handler H2 is invoked.
    1431 The termination handler is available because the resumption propagation did not unwind the stack.
    1432 
    1433 An additional feature is conditional matching in a catch clause:
    1434 \begin{cfa}
    1435 try {
    1436         ... write( `datafile`, ... ); ...               $\C{// may throw IOError}$
    1437         ... write( `logfile`, ... ); ...
    1438 } catch ( IOError err; `err.file == datafile` ) { ... } $\C{// handle datafile error}$
    1439    catch ( IOError err; `err.file == logfile` ) { ... } $\C{// handle logfile error}$
    1440    catch ( IOError err ) { ... }                        $\C{// handler error from other files}$
    1441 \end{cfa}
    1442 where the throw inserts the failing file-handle in the I/O exception.
    1443 Conditional catch cannot be trivially mimicked by other mechanisms because once an exception is caught, handler clauses in that @try@ statement are no longer eligible..
    1444 
    1445 The resumption raise can specify an alternate stack on which to raise an exception, called a \newterm{nonlocal raise}:
    1446 \begin{cfa}
    1447 resume( $\emph{exception-type}$, $\emph{alternate-stack}$ )
    1448 resume( $\emph{alternate-stack}$ )
    1449 \end{cfa}
    1450 These overloads of @resume@ raise the specified exception or the currently propagating exception (reresume) at another coroutine or task~\cite{Delisle18}.
    1451 Nonlocal raise is restricted to resumption to provide the exception handler the greatest flexibility because processing the exception does not unwind its stack, allowing it to continue after the handle returns.
    1452 
    1453 To facilitate nonlocal exception, \CFA provides dynamic enabling and disabling of nonlocal exception-propagation.
    1454 The constructs for controlling propagation of nonlocal exceptions are the @enable@ and the @disable@ blocks:
    1455 \begin{cquote}
    1456 \lstDeleteShortInline@%
    1457 \begin{tabular}{@{}l@{\hspace{2\parindentlnth}}l@{}}
    1458 \begin{cfa}
    1459 enable $\emph{exception-type-list}$ {
    1460         // allow non-local resumption
    1461 }
    1462 \end{cfa}
    1463 &
    1464 \begin{cfa}
    1465 disable $\emph{exception-type-list}$ {
    1466         // disallow non-local resumption
    1467 }
    1468 \end{cfa}
    1469 \end{tabular}
    1470 \lstMakeShortInline@%
    1471 \end{cquote}
    1472 The arguments for @enable@/@disable@ specify the exception types allowed to be propagated or postponed, respectively.
    1473 Specifying no exception type is shorthand for specifying all exception types.
    1474 Both @enable@ and @disable@ blocks can be nested, turning propagation on/off on entry, and on exit, the specified exception types are restored to their prior state.
    1475 
    1476 Finally, \CFA provides a Java like  @finally@ clause after the catch clauses:
    1477 \begin{cfa}
    1478 try {
    1479         ... f(); ...
    1480 // catchResume or catch clauses
    1481 } `finally` {
    1482         // house keeping
    1483 }
    1484 \end{cfa}
    1485 The finally clause is always executed, i.e., if the try block ends normally or if an exception is raised.
    1486 If an exception is raised and caught, the handler is run before the finally clause.
    1487 Like a destructor (see Section~\ref{s:ConstructorsDestructors}), a finally clause can raise an exception but not if there is an exception being propagated.
    1488 Mimicking the @finally@ clause with mechanisms like RAII is non-trivially when there are multiple types and local accesses.
    1489 
    1490 
    14911531\section{Declarations}
    14921532
     
    15161556Is this an array of 5 pointers to integers or a pointer to an array of 5 integers?
    15171557If there is any doubt, it implies productivity and safety issues even for basic programs.
    1518 Another example of confusion results from the fact that a routine name and its parameters are embedded within the return type, mimicking the way the return value is used at the routine's call site.
    1519 For example, a routine returning a pointer to an array of integers is defined and used in the following way:
     1558Another example of confusion results from the fact that a function name and its parameters are embedded within the return type, mimicking the way the return value is used at the function's call site.
     1559For example, a function returning a pointer to an array of integers is defined and used in the following way:
    15201560\begin{cfa}
    15211561int `(*`f`())[`5`]` {...};                                      $\C{// definition}$
    15221562 ... `(*`f`())[`3`]` += 1;                                      $\C{// usage}$
    15231563\end{cfa}
    1524 Essentially, the return type is wrapped around the routine name in successive layers (like an onion).
     1564Essentially, the return type is wrapped around the function name in successive layers (like an onion).
    15251565While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
    15261566
    1527 \CFA provides its own type, variable and routine declarations, using a different syntax.
     1567\CFA provides its own type, variable and function declarations, using a different syntax~\cite[pp.~856--859]{Buhr94a}.
    15281568The new declarations place qualifiers to the left of the base type, while C declarations place qualifiers to the right.
    15291569The qualifiers have the same meaning but are ordered left to right to specify a variable's type.
     
    15531593\end{cquote}
    15541594The only exception is bit field specification, which always appear to the right of the base type.
    1555 % Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@ are used to indicate a routine parameter.
     1595% Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@ are used to indicate a function parameter.
    15561596However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list.
    15571597For instance, variables @x@ and @y@ of type pointer to integer are defined in \CFA as follows:
     
    16391679\lstMakeShortInline@%
    16401680\end{cquote}
    1641 Specifiers must appear at the start of a \CFA routine declaration\footnote{\label{StorageClassSpecifier}
     1681Specifiers must appear at the start of a \CFA function declaration\footnote{\label{StorageClassSpecifier}
    16421682The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}}.
    16431683
    1644 The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-routine @sizeof@:
     1684The new declaration syntax can be used in other contexts where types are required, \eg casts and the pseudo-function @sizeof@:
    16451685\begin{cquote}
    16461686\lstDeleteShortInline@%
     
    16601700\end{cquote}
    16611701
    1662 The syntax of the new routine prototype declaration follows directly from the new routine definition syntax;
     1702The syntax of the new function-prototype declaration follows directly from the new function-definition syntax;
    16631703as well, parameter names are optional, \eg:
    16641704\begin{cfa}
     
    16691709[ * int, int ] j ( int );                                       $\C{// returning pointer to int and int, with int parameter}$
    16701710\end{cfa}
    1671 This syntax allows a prototype declaration to be created by cutting and pasting source text from the routine definition header (or vice versa).
    1672 Like C, it is possible to declare multiple routine-prototypes in a single declaration, where the return type is distributed across \emph{all} routine names in the declaration list, \eg:
     1711This syntax allows a prototype declaration to be created by cutting and pasting source text from the function-definition header (or vice versa).
     1712Like C, it is possible to declare multiple function-prototypes in a single declaration, where the return type is distributed across \emph{all} function names in the declaration list, \eg:
    16731713\begin{cquote}
    16741714\lstDeleteShortInline@%
     
    16851725\lstMakeShortInline@%
    16861726\end{cquote}
    1687 where \CFA allows the last routine in the list to define its body.
    1688 
    1689 The syntax for pointers to \CFA routines specifies the pointer name on the right, \eg:
    1690 \begin{cfa}
    1691 * [ int x ] () fp;                                                      $\C{// pointer to routine returning int with no parameters}$
    1692 * [ * int ] ( int y ) gp;                                       $\C{// pointer to routine returning pointer to int with int parameter}$
    1693 * [ ] ( int, char ) hp;                                         $\C{// pointer to routine returning no result with int and char parameters}$
    1694 * [ * int, int ] ( int ) jp;                            $\C{// pointer to routine returning pointer to int and int, with int parameter}$
    1695 \end{cfa}
    1696 Note, a routine name cannot be specified:
    1697 \begin{cfa}
    1698 * [ int x ] f () fp;                                            $\C{// routine name "f" is disallowed}$
     1727where \CFA allows the last function in the list to define its body.
     1728
     1729The syntax for pointers to \CFA functions specifies the pointer name on the right, \eg:
     1730\begin{cfa}
     1731* [ int x ] () fp;                                                      $\C{// pointer to function returning int with no parameters}$
     1732* [ * int ] ( int y ) gp;                                       $\C{// pointer to function returning pointer to int with int parameter}$
     1733* [ ] ( int, char ) hp;                                         $\C{// pointer to function returning no result with int and char parameters}$
     1734* [ * int, int ] ( int ) jp;                            $\C{// pointer to function returning pointer to int and int, with int parameter}$
     1735\end{cfa}
     1736Note, a function name cannot be specified:
     1737\begin{cfa}
     1738* [ int x ] f () fp;                                            $\C{// function name "f" is disallowed}$
    16991739\end{cfa}
    17001740
     
    19161956Destruction parameters are useful for specifying storage-management actions, such as de-initialize but not deallocate.}.
    19171957\begin{cfa}
    1918 struct VLA {
    1919         int len, * data;
    1920 };
    1921 void ?{}( VLA & vla ) with ( vla ) {            $\C{// default constructor}$
    1922         len = 10;  data = alloc( len );                 $\C{// shallow copy}$
    1923 }
    1924 void ^?{}( VLA & vla ) with ( vla ) {           $\C{// destructor}$
    1925         free( data );
    1926 }
     1958struct VLA { int len, * data; };
     1959void ?{}( VLA & vla ) with ( vla ) { len = 10;  data = alloc( len ); }  $\C{// default constructor}$
     1960void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$
    19271961{
    19281962        VLA x;                                                                  $\C{// implicit:  ?\{\}( x );}$
    19291963}                                                                                       $\C{// implicit:  ?\^{}\{\}( x );}$
    19301964\end{cfa}
    1931 (Note, the example is purposely kept simple by using shallow-copy semantics.)
    19321965@VLA@ is a \newterm{managed type}\footnote{
    19331966A managed type affects the runtime environment versus a self-contained type.}: a type requiring a non-trivial constructor or destructor, or with a field of a managed type.
     
    19371970\CFA also provides syntax for \newterm{initialization} and \newterm{copy}:
    19381971\begin{cfa}
    1939 void ?{}( VLA & vla, int size, char fill ) with ( vla ) {       $\C{// initialization}$
     1972void ?{}( VLA & vla, int size, char fill ) with ( vla ) {  $\C{// initialization}$
    19401973        len = size;  data = alloc( len, fill );
    19411974}
    1942 void ?{}( VLA & vla, VLA other ) {                      $\C{// copy}$
     1975void ?{}( VLA & vla, VLA other ) {                      $\C{// copy, shallow}$
    19431976        vla.len = other.len;  vla.data = other.data;
    19441977}
    19451978\end{cfa}
     1979(Note, the example is purposely simplified using shallow-copy semantics.)
    19461980An initialization constructor-call has the same syntax as a C initializer, except the initialization values are passed as arguments to a matching constructor (number and type of paremeters).
    19471981\begin{cfa}
     
    19571991\begin{cfa}
    19581992{
    1959         VLA x,  y = { 20, 0x01 },  z = y;
    1960         // implicit:  ?{}( x );  ?{}( y, 20, 0x01 );  ?{}( z, y ); z points to y
     1993        VLA  x,            y = { 20, 0x01 },     z = y; $\C{// z points to y}$
     1994        //      ?{}( x );  ?{}( y, 20, 0x01 );  ?{}( z, y );
    19611995        ^x{};                                                                   $\C{// deallocate x}$
    19621996        x{};                                                                    $\C{// reallocate x}$
     
    19651999        y{ x };                                                                 $\C{// reallocate y, points to x}$
    19662000        x{};                                                                    $\C{// reallocate x, not pointing to y}$
    1967         // implicit:  ^?{}(z);  ^?{}(y);  ^?{}(x);
     2001        // ^?{}(z);  ^?{}(y);  ^?{}(x);
    19682002}
    19692003\end{cfa}
     
    19962030C already includes limited polymorphism for literals -- @0@ can be either an integer or a pointer literal, depending on context, while the syntactic forms of literals of the various integer and float types are very similar, differing from each other only in suffix.
    19972031In keeping with the general \CFA approach of adding features while respecting the ``C-style'' of doing things, C's polymorphic constants and typed literal syntax are extended to interoperate with user-defined types, while maintaining a backwards-compatible semantics.
    1998 A trivial example is allowing the underscore to separate prefixes, digits, and suffixes in all \CFA constants, as in Ada, \eg @0x`_`1.ffff`_`ffff`_`p`_`128`_`l@.
     2032
     2033A simple example is allowing the underscore, as in Ada, to separate prefixes, digits, and suffixes in all \CFA constants, \eg @0x`_`1.ffff`_`ffff`_`p`_`128`_`l@, where the underscore is also the standard separator in C identifiers.
     2034\CC uses a single quote as a separator but it is restricted among digits, precluding its use in the literal prefix or suffix, \eg @0x1.ffff@@`'@@ffffp128l@, and causes problems with most IDEs, which must be extended to deal with this alternate use of the single quote.
     2035
     2036
     2037\subsection{Integral Suffixes}
     2038
     2039Additional integral suffixes are added to cover all the integral types and lengths.
     2040\begin{cquote}
     2041\lstDeleteShortInline@%
     2042\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
     2043\begin{cfa}
     204420_`hh`     // signed char
     204521_`hhu`   // unsigned char
     204622_`h`       // signed short int
     204723_`uh`     // unsigned short int
     204824_`z`       // size_t
     2049\end{cfa}
     2050&
     2051\begin{cfa}
     205220_`L8`      // int8_t
     205321_`ul8`     // uint8_t
     205422_`l16`     // int16_t
     205523_`ul16`   // uint16_t
     205624_`l32`     // int32_t
     2057\end{cfa}
     2058&
     2059\begin{cfa}
     206025_`ul32`      // uint32_t
     206126_`l64`        // int64_t
     206227_`l64u`      // uint64_t
     206326_`L128`     // int128
     206427_`L128u`   // unsigned int128
     2065\end{cfa}
     2066\end{tabular}
     2067\lstMakeShortInline@%
     2068\end{cquote}
    19992069
    20002070
     
    20132083
    20142084
    2015 \subsection{Integral Suffixes}
    2016 
    2017 Additional integral suffixes are added to cover all the integral types and lengths.
    2018 \begin{cquote}
     2085\subsection{User Literals}
     2086
     2087For readability, it is useful to associate units to scale literals, \eg weight (stone, pound, kilogram) or time (seconds, minutes, hours).
     2088The left of Figure~\ref{f:UserLiteral} shows the \CFA alternative call-syntax (literal argument before function name), using the backquote, to convert basic literals into user literals.
     2089The backquote is a small character, making the unit (function name) predominate.
     2090For examples, the multi-precision integers in Section~\ref{s:MultiPrecisionIntegers} make use of user literals:
     2091{\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
     2092\begin{cfa}
     2093y = 9223372036854775807L|`mp| * 18446744073709551615UL|`mp|;
     2094y = "12345678901234567890123456789"|`mp| + "12345678901234567890123456789"|`mp|;
     2095\end{cfa}
     2096Because \CFA uses a standard function, all types and literals are applicable, as well as overloading and conversions.
     2097}%
     2098
     2099The right of Figure~\ref{f:UserLiteral} shows the equivalent \CC version using the underscore for the call-syntax.
     2100However, \CC restricts the types, \eg @unsigned long long int@ and @long double@ to represent integral and floating literals.
     2101After which, user literals must match (no conversions);
     2102hence, it is necessary to overload the unit with all appropriate types.
     2103
     2104\begin{figure}
     2105\centering
     2106\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
    20192107\lstDeleteShortInline@%
    2020 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{\hspace{\parindentlnth}}l@{}}
    2021 \begin{cfa}
    2022 20_hh     // signed char
    2023 21_hhu   // unsigned char
    2024 22_h      // signed short int
    2025 23_uh    // unsigned short int
    2026 24z        // size_t
    2027 \end{cfa}
    2028 &
    2029 \begin{cfa}
    2030 20_L8     // int8_t
    2031 21_ul8    // uint8_t
    2032 22_l16    // int16_t
    2033 23_ul16  // uint16_t
    2034 24_l32    // int32_t
    2035 \end{cfa}
    2036 &
    2037 \begin{cfa}
    2038 25_ul32      // uint32_t
    2039 26_l64        // int64_t
    2040 27_l64u      // uint64_t
    2041 26_L128     // int128
    2042 27_L128u  // unsigned int128
     2108\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     2109\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{\CC}}      \\
     2110\begin{cfa}
     2111struct W {
     2112        double stones;
     2113};
     2114void ?{}( W & w ) { w.stones = 0; }
     2115void ?{}( W & w, double w ) { w.stones = w; }
     2116W ?+?( W l, W r ) {
     2117        return (W){ l.stones + r.stones };
     2118}
     2119W |?`st|( double w ) { return (W){ w }; }
     2120W |?`lb|( double w ) { return (W){ w / 14.0 }; }
     2121W |?`kg|( double w ) { return (W) { w * 0.16 }; }
     2122
     2123
     2124
     2125int main() {
     2126        W w, heavy = { 20 };
     2127        w = 155|`lb|;
     2128        w = 0b_1111|`st|;
     2129        w = 0_233|`lb|;
     2130        w = 0x_9b_u|`kg|;
     2131        w = 5.5|`st| + 8|`kg| + 25.01|`lb| + heavy;
     2132}
     2133\end{cfa}
     2134&
     2135\begin{cfa}
     2136struct W {
     2137    double stones;
     2138    W() { stones = 0.0; }
     2139    W( double w ) { stones = w; }
     2140};
     2141W operator+( W l, W r ) {
     2142        return W( l.stones + r.stones );
     2143}
     2144W |operator"" _st|( unsigned long long int w ) { return W( w ); }
     2145W |operator"" _lb|( unsigned long long int w ) { return W( w / 14.0 ); }
     2146W |operator"" _kg|( unsigned long long int w ) { return W( w * 0.16 ); }
     2147W |operator"" _st|( long double w ) { return W( w ); }
     2148W |operator"" _lb|( long double w ) { return W( w / 14.0 ); }
     2149W |operator"" _kg|( long double w ) { return W( w * 0.16 ); }
     2150int main() {
     2151        W w, heavy = { 20 };
     2152        w = 155|_lb|;
     2153        w = 0b1111|_lb|;       // error, binary unsupported
     2154        w = 0${\color{red}\LstBasicStyle{'}}$233|_lb|;          // quote separator
     2155        w = 0x9b|_kg|;
     2156        w = 5.5d|_st| + 8|_kg| + 25.01|_lb| + heavy;
     2157}
    20432158\end{cfa}
    20442159\end{tabular}
    20452160\lstMakeShortInline@%
    2046 \end{cquote}
    2047 
    2048 
    2049 \subsection{Units}
    2050 
    2051 Alternative call syntax (literal argument before routine name) to convert basic literals into user literals.
    2052 
    2053 {\lstset{language=CFA,moredelim=**[is][\color{red}]{|}{|},deletedelim=**[is][]{`}{`}}
    2054 \begin{cfa}
    2055 struct Weight { double stones; };
    2056 void ?{}( Weight & w ) { w.stones = 0; }        $\C{// operations}$
    2057 void ?{}( Weight & w, double w ) { w.stones = w; }
    2058 Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; }
    2059 
    2060 Weight |?`st|( double w ) { return (Weight){ w }; } $\C{// backquote for units}$
    2061 Weight |?`lb|( double w ) { return (Weight){ w / 14.0 }; }
    2062 Weight |?`kg|( double w ) { return (Weight) { w * 0.1575}; }
    2063 
    2064 int main() {
    2065         Weight w, heavy = { 20 };                               $\C{// 20 stone}$
    2066         w = 155|`lb|;
    2067         w = 0x_9b_u|`lb|;                                               $\C{// hexadecimal unsigned weight (155)}$
    2068         w = 0_233|`lb|;                                                 $\C{// octal weight (155)}$
    2069         w = 5|`st| + 8|`kg| + 25|`lb| + heavy;
    2070 }
    2071 \end{cfa}
    2072 }%
     2161\caption{User Literal}
     2162\label{f:UserLiteral}
     2163\end{figure}
    20732164
    20742165
     
    20802171In many cases, the interface is an inline wrapper providing overloading during compilation but zero cost at runtime.
    20812172The following sections give a glimpse of the interface reduction to many C libraries.
    2082 In many cases, @signed@/@unsigned@ @char@, @short@, and @_Complex@ routines are available (but not shown) to ensure expression computations remain in a single type, as conversions can distort results.
     2173In many cases, @signed@/@unsigned@ @char@, @short@, and @_Complex@ functions are available (but not shown) to ensure expression computations remain in a single type, as conversions can distort results.
    20832174
    20842175
     
    21082199\begin{cquote}
    21092200\lstDeleteShortInline@%
    2110 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    2111 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
     2201\lstset{basicstyle=\linespread{0.9}\sf\small}
     2202\begin{tabular}{@{}l@{\hspace{0.5\parindentlnth}}l@{}}
     2203\multicolumn{1}{c@{\hspace{0.5\parindentlnth}}}{\textbf{\CFA}}  & \multicolumn{1}{c}{\textbf{C}}        \\
    21122204\begin{cfa}
    21132205MIN
    2114 
    21152206MAX
    2116 
    21172207PI
    21182208E
     
    21202210&
    21212211\begin{cfa}
    2122 SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN,
    2123                 FLT_MIN, DBL_MIN, LDBL_MIN
    2124 SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX,
    2125                  FLT_MAX, DBL_MAX, LDBL_MAX
     2212SCHAR_MIN, CHAR_MIN, SHRT_MIN, INT_MIN, LONG_MIN, LLONG_MIN, FLT_MIN, DBL_MIN, LDBL_MIN
     2213SCHAR_MAX, UCHAR_MAX, SHRT_MAX, INT_MAX, LONG_MAX, LLONG_MAX, FLT_MAX, DBL_MAX, LDBL_MAX
    21262214M_PI, M_PIl
    21272215M_E, M_El
     
    21342222\subsection{Math}
    21352223
    2136 C library @math.h@ provides many mathematical routines.
    2137 \CFA routine overloading is used to condense these mathematical routines, \eg:
     2224C library @math.h@ provides many mathematical functions.
     2225\CFA function overloading is used to condense these mathematical functions, \eg:
    21382226\begin{cquote}
    21392227\lstDeleteShortInline@%
     
    21542242\lstMakeShortInline@%
    21552243\end{cquote}
    2156 The result is a significant reduction in names to access math routines, \eg:
     2244The result is a significant reduction in names to access math functions, \eg:
    21572245\begin{cquote}
    21582246\lstDeleteShortInline@%
     
    21732261\lstMakeShortInline@%
    21742262\end{cquote}
    2175 While \Celeven has type-generic math~\cite[\S~7.25]{C11} in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a routine name with a single set of floating type(s).
     2263While \Celeven has type-generic math~\cite[\S~7.25]{C11} in @tgmath.h@ to provide a similar mechanism, these macros are limited, matching a function name with a single set of floating type(s).
    21762264For example, it is impossible to overload @atan@ for both one and two arguments;
    21772265instead the names @atan@ and @atan2@ are required (see Section~\ref{s:NameOverloading}).
    2178 The key observation is that only a restricted set of type-generic macros are provided for a limited set of routine names, which do not generalize across the type system, as in \CFA.
     2266The key observation is that only a restricted set of type-generic macros are provided for a limited set of function names, which do not generalize across the type system, as in \CFA.
    21792267
    21802268
    21812269\subsection{Standard}
    21822270
    2183 C library @stdlib.h@ provides many general routines.
    2184 \CFA routine overloading is used to condense these utility routines, \eg:
     2271C library @stdlib.h@ provides many general functions.
     2272\CFA function overloading is used to condense these utility functions, \eg:
    21852273\begin{cquote}
    21862274\lstDeleteShortInline@%
     
    22012289\lstMakeShortInline@%
    22022290\end{cquote}
    2203 The result is a significant reduction in names to access utility routines, \eg:
     2291The result is a significant reduction in names to access utility functions, \eg:
    22042292\begin{cquote}
    22052293\lstDeleteShortInline@%
     
    22202308\lstMakeShortInline@%
    22212309\end{cquote}
    2222 In additon, there are polymorphic routines, like @min@ and @max@, which work on any type with operators @?<?@ or @?>?@.
     2310In additon, there are polymorphic functions, like @min@ and @max@, which work on any type with operators @?<?@ or @?>?@.
    22232311
    22242312The following shows one example where \CFA \emph{extends} an existing standard C interface to reduce complexity and provide safety.
     
    22262314\begin{description}[topsep=3pt,itemsep=2pt,parsep=0pt]
    22272315\item[fill]
    2228 after allocation the storage is filled with a specified character.
     2316an allocation with a specified character.
    22292317\item[resize]
    2230 an existing allocation is decreased or increased in size.
     2318an existing allocation to decreased or increased its size.
    22312319In either case, new storage may or may not be allocated and, if there is a new allocation, as much data from the existing allocation is copied.
    22322320For an increase in storage size, new storage after the copied data may be filled.
    22332321\item[alignment]
    2234 an allocation starts on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes.
     2322an allocation on a specified memory boundary, \eg, an address multiple of 64 or 128 for cache-line purposes.
    22352323\item[array]
    2236 the allocation size is scaled to the specified number of array elements.
     2324allocation of the specified number of elements.
    22372325An array may be filled, resized, or aligned.
    22382326\end{description}
    2239 Table~\ref{t:StorageManagementOperations} shows the capabilities provided by C/\Celeven allocation-routines and how all the capabilities can be combined into two \CFA routines.
    2240 
    2241 \CFA storage-management routines extend the C equivalents by overloading, providing shallow type-safety, and removing the need to specify the base allocation-size.
    2242 The following example contrasts \CFA and C storage-allocation operation performing the same operations with the same type safety:
    2243 \begin{cquote}
    2244 \begin{cfa}[aboveskip=0pt]
    2245 size_t  dim = 10;                                                       $\C{// array dimension}$
    2246 char fill = '\xff';                                                     $\C{// initialization fill value}$
    2247 int * ip;
    2248 \end{cfa}
    2249 \lstDeleteShortInline@%
    2250 \begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
    2251 \multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
    2252 \begin{cfa}
    2253 ip = alloc();
    2254 ip = alloc( fill );
    2255 ip = alloc( dim );
    2256 ip = alloc( dim, fill );
    2257 ip = alloc( ip, 2 * dim );
    2258 ip = alloc( ip, 4 * dim, fill );
    2259 
    2260 ip = align_alloc( 16 );
    2261 ip = align_alloc( 16, fill );
    2262 ip = align_alloc( 16, dim );
    2263 ip = align_alloc( 16, dim, fill );
    2264 \end{cfa}
    2265 &
    2266 \begin{cfa}
    2267 ip = (int *)malloc( sizeof( int ) );
    2268 ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, sizeof( int ) );
    2269 ip = (int *)malloc( dim * sizeof( int ) );
    2270 ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
    2271 ip = (int *)realloc( ip, 2 * dim * sizeof( int ) );
    2272 ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) );
    2273 
    2274 ip = memalign( 16, sizeof( int ) );
    2275 ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) );
    2276 ip = memalign( 16, dim * sizeof( int ) );
    2277 ip = memalign( 16, dim * sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
    2278 \end{cfa}
    2279 \end{tabular}
    2280 \lstMakeShortInline@%
    2281 \end{cquote}
    2282 Variadic @new@ (see Section~\ref{sec:variadic-tuples}) cannot support the same overloading because extra parameters are for initialization.
    2283 Hence, there are @new@ and @anew@ routines for single and array variables, and the fill value is the arguments to the constructor, \eg:
    2284 \begin{cfa}
    2285 struct S { int i, j; };
    2286 void ?{}( S & s, int i, int j ) { s.i = i; s.j = j; }
    2287 S * s = new( 2, 3 );                                            $\C{// allocate storage and run constructor}$
    2288 S * as = anew( dim, 2, 3 );                                     $\C{// each array element initialized to 2, 3}$
    2289 \end{cfa}
    2290 Note, \CC can only initialization array elements via the default constructor.
    2291 
    2292 Finally, the \CFA memory-allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap.
    2293 When a @realloc@ is performed, the sticky properties are respected, so that new storage is correctly aligned and initialized with the fill character.
     2327Table~\ref{t:StorageManagementOperations} shows the capabilities provided by C/\Celeven allocation-functions and how all the capabilities can be combined into two \CFA functions.
     2328\CFA storage-management functions extend the C equivalents by overloading, providing shallow type-safety, and removing the need to specify the base allocation-size.
     2329Figure~\ref{f:StorageAllocation} contrasts \CFA and C storage-allocation performing the same operations with the same type safety.
    22942330
    22952331\begin{table}
     
    23172353\end{table}
    23182354
     2355\begin{figure}
     2356\centering
     2357\begin{cquote}
     2358\begin{cfa}[aboveskip=0pt]
     2359size_t  dim = 10;                                                       $\C{// array dimension}$
     2360char fill = '\xff';                                                     $\C{// initialization fill value}$
     2361int * ip;
     2362\end{cfa}
     2363\lstDeleteShortInline@%
     2364\begin{tabular}{@{}l@{\hspace{\parindentlnth}}l@{}}
     2365\multicolumn{1}{c@{\hspace{\parindentlnth}}}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{C}}        \\
     2366\begin{cfa}
     2367ip = alloc();
     2368ip = alloc( fill );
     2369ip = alloc( dim );
     2370ip = alloc( dim, fill );
     2371ip = alloc( ip, 2 * dim );
     2372ip = alloc( ip, 4 * dim, fill );
     2373
     2374ip = align_alloc( 16 );
     2375ip = align_alloc( 16, fill );
     2376ip = align_alloc( 16, dim );
     2377ip = align_alloc( 16, dim, fill );
     2378\end{cfa}
     2379&
     2380\begin{cfa}
     2381ip = (int *)malloc( sizeof( int ) );
     2382ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, sizeof( int ) );
     2383ip = (int *)malloc( dim * sizeof( int ) );
     2384ip = (int *)malloc( sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
     2385ip = (int *)realloc( ip, 2 * dim * sizeof( int ) );
     2386ip = (int *)realloc( ip, 4 * dim * sizeof( int ) ); memset( ip, fill, 4 * dim * sizeof( int ) );
     2387
     2388ip = memalign( 16, sizeof( int ) );
     2389ip = memalign( 16, sizeof( int ) ); memset( ip, fill, sizeof( int ) );
     2390ip = memalign( 16, dim * sizeof( int ) );
     2391ip = memalign( 16, dim * sizeof( int ) ); memset( ip, fill, dim * sizeof( int ) );
     2392\end{cfa}
     2393\end{tabular}
     2394\lstMakeShortInline@%
     2395\end{cquote}
     2396\caption{\CFA versus C Storage-Allocation}
     2397\label{f:StorageAllocation}
     2398\end{figure}
     2399
     2400Variadic @new@ (see Section~\ref{sec:variadic-tuples}) cannot support the same overloading because extra parameters are for initialization.
     2401Hence, there are @new@ and @anew@ functions for single and array variables, and the fill value is the arguments to the constructor, \eg:
     2402\begin{cfa}
     2403struct S { int i, j; };
     2404void ?{}( S & s, int i, int j ) { s.i = i; s.j = j; }
     2405S * s = new( 2, 3 );                                            $\C{// allocate storage and run constructor}$
     2406S * as = anew( dim, 2, 3 );                                     $\C{// each array element initialized to 2, 3}$
     2407\end{cfa}
     2408Note, \CC can only initialization array elements via the default constructor.
     2409
     2410Finally, the \CFA memory-allocator has \newterm{sticky properties} for dynamic storage: fill and alignment are remembered with an object's storage in the heap.
     2411When a @realloc@ is performed, the sticky properties are respected, so that new storage is correctly aligned and initialized with the fill character.
     2412
    23192413
    23202414\subsection{I/O}
     
    23762470\end{cfa}
    23772471\\
    2378 \textbf{output:}
    23792472&
    23802473\begin{cfa}[showspaces=true,aboveskip=0pt]
     
    24042497}%
    24052498\end{itemize}
    2406 There are routines to set and get the separator string, and manipulators to toggle separation on and off in the middle of output.
     2499There are functions to set and get the separator string, and manipulators to toggle separation on and off in the middle of output.
    24072500
    24082501
     
    24112504
    24122505\CFA has an interface to the GMP multi-precision signed-integers~\cite{GMP}, similar to the \CC interface provided by GMP.
    2413 The \CFA interface wraps GMP routines into operator routines to make programming with multi-precision integers identical to using fixed-sized integers.
     2506The \CFA interface wraps GMP functions into operator functions to make programming with multi-precision integers identical to using fixed-sized integers.
    24142507The \CFA type name for multi-precision signed-integers is @Int@ and the header file is @gmp@.
    24152508The following multi-precision factorial programs contrast using GMP with the \CFA and C interfaces.
     
    24562549Since all these languages share a subset essentially comprising standard C, maximal-performance benchmarks would show little runtime variance, other than in length and clarity of source code.
    24572550A more illustrative benchmark measures the costs of idiomatic usage of each language's features.
    2458 Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked-list, a generic pair-data-structure, and a variadic @print@ routine similar to that in Section~\ref{sec:variadic-tuples}.
     2551Figure~\ref{fig:BenchmarkTest} shows the \CFA benchmark tests for a generic stack based on a singly linked-list, a generic pair-data-structure, and a variadic @print@ function similar to that in Section~\ref{sec:variadic-tuples}.
    24592552The benchmark test is similar for C and \CC.
    24602553The experiment uses element types @int@ and @pair(_Bool, char)@, and pushes $N=40M$ elements on a generic stack, copies the stack, clears one of the stacks, finds the maximum value in the other stack, and prints $N/2$ (to reduce graph height) constants.
     
    24632556\begin{cfa}[xleftmargin=3\parindentlnth,aboveskip=0pt,belowskip=0pt]
    24642557int main( int argc, char * argv[] ) {
    2465         ofstream out = { "cfa-out.txt" };
    24662558        int max = 0, val = 42;
    2467         stack( int ) si, t;
     2559        stack( int ) si, ti;
    24682560
    24692561        REPEAT_TIMED( "push_int", N, push( si, val ); )
    2470         TIMED( "copy_int", t = si; )
     2562        TIMED( "copy_int", ti = si; )
    24712563        TIMED( "clear_int", clear( si ); )
    2472         REPEAT_TIMED( "pop_int", N, int x = pop( t ); max = max( x, max ); )
    2473         REPEAT_TIMED( "print_int", N/2, out | val | ':' | val | endl; )
     2564        REPEAT_TIMED( "pop_int", N,
     2565                int x = pop( ti ); if ( x > max ) max = x; )
    24742566
    24752567        pair( _Bool, char ) max = { (_Bool)0, '\0' }, val = { (_Bool)1, 'a' };
    2476         stack( pair( _Bool, char ) ) s, t;
    2477 
    2478         REPEAT_TIMED( "push_pair", N, push( s, val ); )
    2479         TIMED( "copy_pair", t = s; )
    2480         TIMED( "clear_pair", clear( s ); )
    2481         REPEAT_TIMED( "pop_pair", N, pair(_Bool, char) x = pop( t ); max = max( x, max ); )
    2482         REPEAT_TIMED( "print_pair", N/2, out | val | ':' | val | endl; )
     2568        stack( pair( _Bool, char ) ) sp, tp;
     2569
     2570        REPEAT_TIMED( "push_pair", N, push( sp, val ); )
     2571        TIMED( "copy_pair", tp = sp; )
     2572        TIMED( "clear_pair", clear( sp ); )
     2573        REPEAT_TIMED( "pop_pair", N,
     2574                pair(_Bool, char) x = pop( tp ); if ( x > max ) max = x; )
    24832575}
    24842576\end{cfa}
     
    25512643\CC is the most similar language to \CFA;
    25522644both are extensions to C with source and runtime backwards compatibility.
    2553 The fundamental difference is in their engineering approach to C compatibility and programmer expectation.
    2554 While \CC provides good backwards compatibility with C, it has a steep learning curve for many of its extensions.
     2645The fundamental difference is the engineering approach to maintain C compatibility and programmer expectation.
     2646While \CC provides good compatibility with C, it has a steep learning curve for many of its extensions.
    25552647For example, polymorphism is provided via three disjoint mechanisms: overloading, inheritance, and templates.
    25562648The overloading is restricted because resolution does not use the return type, inheritance requires learning object-oriented programming and coping with a restricted nominal-inheritance hierarchy, templates cannot be separately compiled resulting in compilation/code bloat and poor error messages, and determining how these mechanisms interact and which to use is confusing.
    25572649In contrast, \CFA has a single facility for polymorphic code supporting type-safe separate-compilation of polymorphic functions and generic (opaque) types, which uniformly leverage the C procedural paradigm.
    2558 The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed properties for a type.
    2559 Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function in code beyond compilation errors during template expansion;
     2650The key mechanism to support separate compilation is \CFA's \emph{explicit} use of assumed type properties.
     2651Until \CC concepts~\cite{C++Concepts} are standardized (anticipated for \CCtwenty), \CC provides no way to specify the requirements of a generic function beyond compilation errors during template expansion;
    25602652furthermore, \CC concepts are restricted to template polymorphism.
    25612653
     
    26082700
    26092701
     2702\subsection{Control Structures / Declarations / Literals}
     2703
     2704Java has default fall through like C/\CC.
     2705Pascal/Ada/Go/Rust do not have default fall through.
     2706\Csharp does not have fall through but still requires a break.
     2707Python uses dictionary mapping. \\
     2708\CFA choose is like Rust match.
     2709
     2710Java has labelled break/continue. \\
     2711Languages with and without exception handling.
     2712
     2713Alternative C declarations. \\
     2714Different references \\
     2715Constructors/destructors
     2716
     27170/1 Literals \\
     2718user defined: D, Objective-C
     2719
    26102720\section{Conclusion and Future Work}
    26112721
     
    26132723While other programming languages purport to be a better C, they are in fact new and interesting languages in their own right, but not C extensions.
    26142724The purpose of this paper is to introduce \CFA, and showcase language features that illustrate the \CFA type-system and approaches taken to achieve the goal of evolutionary C extension.
    2615 The contributions are a powerful type-system using parametric polymorphism and overloading, generic types, and tuples, which all have complex interactions.
     2725The contributions are a powerful type-system using parametric polymorphism and overloading, generic types, tuples, advanced control structures, and extended declarations, which all have complex interactions.
    26162726The work is a challenging design, engineering, and implementation exercise.
    26172727On the surface, the project may appear as a rehash of similar mechanisms in \CC.
     
    26202730Finally, we demonstrate that \CFA performance for some idiomatic cases is better than C and close to \CC, showing the design is practically applicable.
    26212731
    2622 There is ongoing work on a wide range of \CFA feature extensions, including arrays with size, exceptions, concurrent primitives, modules, and user-defined conversions.
     2732There is ongoing work on a wide range of \CFA feature extensions, including arrays with size, user-defined conversions, concurrent primitives, and modules.
    26232733(While all examples in the paper compile and run, a public beta-release of \CFA will take another 8--12 months to finalize these additional extensions.)
    26242734In addition, there are interesting future directions for the polymorphism design.
     
    26332743\section{Acknowledgments}
    26342744
    2635 The authors would like to recognize the design assistance of Glen Ditchfield, Richard Bilson, and Thierry Delisle on the features described in this paper, and thank Magnus Madsen for feedback in the writing.
    2636 %This work is supported in part by a corporate partnership with \grantsponsor{Huawei}{Huawei Ltd.}{http://www.huawei.com}, and Aaron Moss and Peter Buhr are funded by the \grantsponsor{Natural Sciences and Engineering Research Council} of Canada.
     2745The authors would like to recognize the design assistance of Glen Ditchfield, Richard Bilson, Thierry Delisle, and Andrew Beach on the features described in this paper, and thank Magnus Madsen for feedback in the writing.
     2746This work is supported through a corporate partnership with Huawei Ltd.\ (\url{http://www.huawei.com}), and Aaron Moss and Peter Buhr are partially funded by the Natural Sciences and Engineering Research Council of Canada.
     2747
    26372748% the first author's \grantsponsor{NSERC-PGS}{NSERC PGS D}{http://www.nserc-crsng.gc.ca/Students-Etudiants/PG-CS/BellandPostgrad-BelletSuperieures_eng.asp} scholarship.
    26382749
     
    26662777        stack_node(T) ** crnt = &s.head;
    26672778        for ( stack_node(T) * next = t.head; next; next = next->next ) {
    2668                 *crnt = malloc(){ next->value };
     2779                stack_node(T) * new_node = ((stack_node(T)*)malloc());
     2780                (*new_node){ next->value }; /***/
     2781                *crnt = new_node;
    26692782                stack_node(T) * acrnt = *crnt;
    26702783                crnt = &acrnt->next;
     
    26812794forall(otype T) _Bool empty( const stack(T) & s ) { return s.head == 0; }
    26822795forall(otype T) void push( stack(T) & s, T value ) {
    2683         s.head = malloc(){ value, s.head };
     2796        stack_node(T) * new_node = ((stack_node(T)*)malloc());
     2797        (*new_node){ value, s.head }; /***/
     2798        s.head = new_node;
    26842799}
    26852800forall(otype T) T pop( stack(T) & s ) {
    26862801        stack_node(T) * n = s.head;
    26872802        s.head = n->next;
    2688         T x = n->value;
    2689         ^n{};
    2690         free( n );
    2691         return x;
     2803        T v = n->value;
     2804        delete( n );
     2805        return v;
    26922806}
    26932807forall(otype T) void clear( stack(T) & s ) {
     
    28452959
    28462960
    2847 \begin{comment}
    2848 \subsubsection{bench.h}
    2849 (\texttt{bench.hpp} is similar.)
    2850 
    2851 \lstinputlisting{evaluation/bench.h}
    2852 
    2853 \subsection{C}
    2854 
    2855 \subsubsection{c-stack.h} ~
    2856 
    2857 \lstinputlisting{evaluation/c-stack.h}
    2858 
    2859 \subsubsection{c-stack.c} ~
    2860 
    2861 \lstinputlisting{evaluation/c-stack.c}
    2862 
    2863 \subsubsection{c-pair.h} ~
    2864 
    2865 \lstinputlisting{evaluation/c-pair.h}
    2866 
    2867 \subsubsection{c-pair.c} ~
    2868 
    2869 \lstinputlisting{evaluation/c-pair.c}
    2870 
    2871 \subsubsection{c-print.h} ~
    2872 
    2873 \lstinputlisting{evaluation/c-print.h}
    2874 
    2875 \subsubsection{c-print.c} ~
    2876 
    2877 \lstinputlisting{evaluation/c-print.c}
    2878 
    2879 \subsubsection{c-bench.c} ~
    2880 
    2881 \lstinputlisting{evaluation/c-bench.c}
    2882 
    2883 \subsection{\CFA}
    2884 
    2885 \subsubsection{cfa-stack.h} ~
    2886 
    2887 \lstinputlisting{evaluation/cfa-stack.h}
    2888 
    2889 \subsubsection{cfa-stack.c} ~
    2890 
    2891 \lstinputlisting{evaluation/cfa-stack.c}
    2892 
    2893 \subsubsection{cfa-print.h} ~
    2894 
    2895 \lstinputlisting{evaluation/cfa-print.h}
    2896 
    2897 \subsubsection{cfa-print.c} ~
    2898 
    2899 \lstinputlisting{evaluation/cfa-print.c}
    2900 
    2901 \subsubsection{cfa-bench.c} ~
    2902 
    2903 \lstinputlisting{evaluation/cfa-bench.c}
    2904 
    2905 \subsection{\CC}
    2906 
    2907 \subsubsection{cpp-stack.hpp} ~
    2908 
    2909 \lstinputlisting[language=c++]{evaluation/cpp-stack.hpp}
    2910 
    2911 \subsubsection{cpp-print.hpp} ~
    2912 
    2913 \lstinputlisting[language=c++]{evaluation/cpp-print.hpp}
    2914 
    2915 \subsubsection{cpp-bench.cpp} ~
    2916 
    2917 \lstinputlisting[language=c++]{evaluation/cpp-bench.cpp}
    2918 
    2919 \subsection{\CCV}
    2920 
    2921 \subsubsection{object.hpp} ~
    2922 
    2923 \lstinputlisting[language=c++]{evaluation/object.hpp}
    2924 
    2925 \subsubsection{cpp-vstack.hpp} ~
    2926 
    2927 \lstinputlisting[language=c++]{evaluation/cpp-vstack.hpp}
    2928 
    2929 \subsubsection{cpp-vstack.cpp} ~
    2930 
    2931 \lstinputlisting[language=c++]{evaluation/cpp-vstack.cpp}
    2932 
    2933 \subsubsection{cpp-vprint.hpp} ~
    2934 
    2935 \lstinputlisting[language=c++]{evaluation/cpp-vprint.hpp}
    2936 
    2937 \subsubsection{cpp-vbench.cpp} ~
    2938 
    2939 \lstinputlisting[language=c++]{evaluation/cpp-vbench.cpp}
    2940 \end{comment}
    2941 
    29422961\end{document}
    29432962
  • doc/papers/general/evaluation/Makefile

    rb2e8841 rf4abc58  
    22CFA = cfa
    33DEPFLAGS = -MMD -MP
     4ifdef DBG
     5CFLAGS = -O0 -ggdb -DN=500
     6else
    47CFLAGS = -O2
    58ifdef N
    69CFLAGS += -DN=$(N)
     10endif
    711endif
    812CXXFLAGS = $(CFLAGS) --std=c++14
     
    2731        $(COMPILE.cfa) $(OUTPUT_OPTION) -c $<
    2832
    29 COBJS = c-stack.o c-pair.o c-print.o c-bench.o
     33COBJS = c-stack.o c-pair.o c-bench.o
    3034CPPOBJS = cpp-bench.o
    3135CPPVOBJS = cpp-vstack.o cpp-vbench.o
    32 CFAOBJS = cfa-stack.o cfa-pair.o cfa-print.o cfa-bench.o
     36CFAOBJS = cfa-stack.o cfa-pair.o cfa-bench.o
    3337
    3438${COBJS} ${CPPOBJS} ${CPPVOBJS} ${CFAOBJS} : ${MAKEFILE_NAME}
    3539
    3640CFILES = bench.h $(patsubst c-bench.h,,$(COBJS:.o=.h)) $(COBJS:.o=.c)
    37 CPPFILES = bench.hpp cpp-stack.hpp cpp-pair.hpp cpp-print.hpp $(CPPOBJS:.o=.cpp)
    38 CPPVFILES = bench.hpp object.hpp cpp-vprint.hpp $(patsubst cpp-vbench.hpp,,$(CPPVOBJS:.o=.hpp)) $(CPPVOBJS:.o=.cpp)
     41CPPFILES = bench.hpp cpp-stack.hpp cpp-pair.hpp $(CPPOBJS:.o=.cpp)
     42CPPVFILES = bench.hpp object.hpp $(patsubst cpp-vbench.hpp,,$(CPPVOBJS:.o=.hpp)) $(CPPVOBJS:.o=.cpp)
    3943CFAFILES = bench.h $(patsubst cfa-bench.h,,$(CFAOBJS:.o=.h)) $(CFAOBJS:.o=.c)
    4044
  • doc/papers/general/evaluation/bench.h

    rb2e8841 rf4abc58  
    55long ms_between(clock_t start, clock_t end) { return (end - start) / (CLOCKS_PER_SEC / 1000); }
    66
     7#ifndef N
    78#define N 40000000
     9#endif
     10
    811#define TIMED(name, code) { \
    912        volatile clock_t _start, _end; \
  • doc/papers/general/evaluation/bench.hpp

    rb2e8841 rf4abc58  
    66long ms_between(clock_t start, clock_t end) { return (end - start) / (CLOCKS_PER_SEC / 1000); }
    77
     8#ifndef N
    89static const int N = 40000000;
     10#endif
     11
    912#define TIMED(name, code) { \
    1013        volatile clock_t _start, _end; \
  • doc/papers/general/evaluation/c-bench.c

    rb2e8841 rf4abc58  
    44#include "c-pair.h"
    55#include "c-stack.h"
    6 #include "c-print.h"
    76
    87_Bool* new_bool( _Bool b ) {
     
    3938
    4039int main(int argc, char** argv) {
    41         FILE * out = fopen("/dev/null", "w");
    4240        int maxi = 0, vali = 42;
    4341        struct stack si = new_stack(), ti;
     
    5048                if ( *xi > maxi ) { maxi = *xi; }
    5149                free(xi); )
    52         REPEAT_TIMED( "print_int", N/2, print( out, "dsds", vali, ":", vali, "\n" ); /***/ )
    5350
    5451        struct pair * maxp = new_pair( new_bool(0), new_char('\0') ),
     
    6764                        free_pair_bool_char( xp ); /***/
    6865                } )
    69         REPEAT_TIMED( "print_pair", N/2, print( out, "pbcspbcs", *valp, ":", *valp, "\n" ); /***/ )
    7066        free_pair_bool_char( maxp ); /***/
    7167        free_pair_bool_char( valp ); /***/
    72         fclose(out);
    7368}
  • doc/papers/general/evaluation/cfa-bench.c

    rb2e8841 rf4abc58  
    1 #include <fstream>
    2 #include <stdlib>
    31#include "bench.h"
    42#include "cfa-stack.h"
    53#include "cfa-pair.h"
    6 #include "cfa-print.h"
    74
    85int main( int argc, char * argv[] ) {
    9         ofstream out = { "/dev/null" };
    106        int max = 0, val = 42;
    11         stack( int ) si, t;
     7        stack( int ) si, ti;
    128
    139        REPEAT_TIMED( "push_int", N, push( si, val ); )
    14         TIMED( "copy_int", t = si; )
     10        TIMED( "copy_int", ti = si; )
    1511        TIMED( "clear_int", clear( si ); )
    16         REPEAT_TIMED( "pop_int", N, int x = pop( t ); max = max( x, max ); )
    17         REPEAT_TIMED( "print_int", N/2, out | val | ':' | val | endl; )
     12        REPEAT_TIMED( "pop_int", N,
     13                int x = pop( ti ); if ( x > max ) max = x; )
    1814
    19         pair( _Bool, char ) max = { (_Bool)0, '\0' }, val = { (_Bool)1, 'a' };
    20         stack( pair( _Bool, char ) ) s, t;
     15        pair( _Bool, char ) max = { (_Bool)0 /***/, '\0' }, val = { (_Bool)1 /***/, 'a' };
     16        stack( pair( _Bool, char ) ) sp, tp;
    2117
    22         REPEAT_TIMED( "push_pair", N, push( s, val ); )
    23         TIMED( "copy_pair", t = s; )
    24         TIMED( "clear_pair", clear( s ); )
    25         REPEAT_TIMED( "pop_pair", N, pair(_Bool, char) x = pop( t ); max = max( x, max ); )
    26         REPEAT_TIMED( "print_pair", N/2, out | val | ':' | val | endl; )
     18        REPEAT_TIMED( "push_pair", N, push( sp, val ); )
     19        TIMED( "copy_pair", tp = sp; )
     20        TIMED( "clear_pair", clear( sp ); )
     21        REPEAT_TIMED( "pop_pair", N,
     22                pair(_Bool, char) x = pop( tp ); if ( x > max ) max = x; )
    2723}
  • doc/papers/general/evaluation/cfa-pair.c

    rb2e8841 rf4abc58  
    3636}
    3737
    38 forall(otype R, otype S)
    39 forall(dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, R ); ostype & ?|?( ostype &, S );  })
    40 ostype & ?|?( ostype & os, pair(R, S) p ) {
    41         return os | '[' | p.first | ',' | p.second | ']';
    42 } // ?|?
     38// forall(otype R, otype S)
     39// forall(dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, R ); ostype & ?|?( ostype &, S );  })
     40// ostype & ?|?( ostype & os, pair(R, S) p ) {
     41//      return os | '[' | p.first | ',' | p.second | ']';
     42// } // ?|?
  • doc/papers/general/evaluation/cfa-pair.h

    rb2e8841 rf4abc58  
    3030int ?>=?(pair(R, S) p, pair(R, S) q);
    3131
    32 forall(otype R, otype S)
    33 forall(dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, pair(R, S) ); })
    34 ostype & ?|?( ostype & os, pair(R, S) );
     32// forall(otype R, otype S)
     33// forall(dtype ostype | ostream( ostype ) | { ostype & ?|?( ostype &, R ); ostype & ?|?( ostype &, S ); })
     34// ostype & ?|?( ostype & os, pair(R, S) );
  • doc/papers/general/evaluation/cfa-stack.c

    rb2e8841 rf4abc58  
    66        stack_node(T) * next;
    77};
    8 forall(otype T) void ?{}( stack_node(T) & node, T value, stack_node(T) * next ) {
    9     node.value = value;
    10     node.next = next;
    11 }
    128
    139forall(otype T) void ?{}( stack(T) & s ) { (s.head){ 0 }; }
     
    1612        stack_node(T) ** crnt = &s.head;
    1713        for ( stack_node(T) * next = t.head; next; next = next->next ) {
    18                 // *crnt = new( next->value, (stack_node(T)*)0 );
    19                 stack_node(T)* new_node = ((stack_node(T)*)malloc());
    20                 (*new_node){ next->value }; /***/
     14                stack_node(T)* new_node = (stack_node(T)*)malloc(); /***/
     15                (*new_node){ next->value };
    2116                *crnt = new_node;
    22                 stack_node(T) * acrnt = *crnt;
    23                 crnt = &acrnt->next;
     17                crnt = &(*crnt)->next;
    2418        }
    2519        *crnt = 0;
     
    3832
    3933forall(otype T) void push( stack(T) & s, T value ) {
    40         // s.head = new( value, s.head );
    41         stack_node(T)* new_node = ((stack_node(T)*)malloc());
    42         (*new_node){ value, s.head }; /***/
     34        stack_node(T)* new_node = (stack_node(T)*)malloc(); /***/
     35        (*new_node){ value, s.head };
    4336        s.head = new_node;
    4437}
     
    4841        s.head = n->next;
    4942        T v = n->value;
    50         delete( n );
     43        ^(*n){};
     44        free( n );
    5145        return v;
    5246}
     
    5650                stack_node(T) * crnt = next;
    5751                next = crnt->next;
    58                 delete( crnt );
     52                ^(*crnt){};
     53                free(crnt);
    5954        }
    6055        s.head = 0;
  • doc/papers/general/evaluation/cpp-bench.cpp

    rb2e8841 rf4abc58  
    11#include <algorithm>
    2 #include <fstream>
    32#include "bench.hpp"
    43#include "cpp-stack.hpp"
    54#include "cpp-pair.hpp"
    6 #include "cpp-print.hpp"
    75
    86int main(int argc, char** argv) {
    9         std::ofstream out{"/dev/null"};
    107        int maxi = 0, vali = 42;
    118        stack<int> si, ti;
     
    1512        TIMED( "clear_int", si.clear(); )
    1613        REPEAT_TIMED( "pop_int", N, maxi = std::max( maxi, ti.pop() ); )
    17         REPEAT_TIMED( "print_int", N/2, print( out, vali, ":", vali, "\n" ); )
    1814
    1915        pair<bool, char> maxp = { false, '\0' }, valp = { true, 'a' };
     
    2420        TIMED( "clear_pair", sp.clear(); )
    2521        REPEAT_TIMED( "pop_pair", N, maxp = std::max( maxp, tp.pop() ); )
    26         REPEAT_TIMED( "print_pair", N/2, print( out, valp, ":", valp, "\n" ); )
    2722}
  • doc/papers/general/evaluation/cpp-vbench.cpp

    rb2e8841 rf4abc58  
    11#include <algorithm>
    2 #include <fstream>
    32#include "bench.hpp"
    43#include "cpp-vstack.hpp"
    5 #include "cpp-vprint.hpp"
    64#include "object.hpp"
    75
    86int main(int argc, char** argv) {
    9         std::ofstream out{"/dev/null"};
    107        integer maxi{ 0 }, vali{ 42 };
    118        stack si, ti;
     
    1512        TIMED( "clear_int", si.clear(); )
    1613        REPEAT_TIMED( "pop_int", N, maxi = std::max( maxi, ti.pop()->as<integer>() ); /***/ )
    17         REPEAT_TIMED( "print_int", N/2, print( out, vali, c_string{":"}, vali, c_string{"\n"} ); )
    1814
    1915        ptr<pair> maxp = make<pair>( make<boolean>(false), make<character>('\0') );
     
    2723                ptr<pair> xp = as_ptr<pair>( tp.pop() ); /***/
    2824                if ( *xp > *maxp ) { maxp = std::move(xp); } )
    29         REPEAT_TIMED( "print_pair", N/2, print( out, valp, c_string{":"}, valp, c_string{"\n"} ); )
    3025}
  • doc/papers/general/evaluation/timing.dat

    rb2e8841 rf4abc58  
    11"400 million repetitions"       "C"     "\\CFA{}"       "\\CC{}"        "\\CC{obj}"
    2 "push\nint"     3002    2459    1520    3305
    3 "copy\nint"     2985    2057    1521    3152
    4 "clear\nint"    1374    827     718     1469
    5 "pop\nint"      1416    1221    717     5467
    6 "print\nint"    5656    6758    3120    3121
    7 "push\npair"    4214    2752    946     6826
    8 "copy\npair"    6127    2105    993     7330
    9 "clear\npair"   2881    885     711     3564
    10 "pop\npair"     3046    5434    783     26538
    11 "print\npair"   7514    10714   8717    16525
     2"push\nint"     2976    2225    1522    3266
     3"copy\nnt"      2932    7072    1526    3110
     4"clear\nint"    1380    731     750     1488
     5"pop\nint"      1444    1196    756     5156
     6"push\npair"    3695    2257    953     6840
     7"copy\npair"    6034    6650    994     7224
     8"clear\npair"   2832    848     742     3297
     9"pop\npair"     3009    5348    797     25235
     10
  • src/Common/SemanticError.h

    rb2e8841 rf4abc58  
    7272}
    7373
    74 
    75 
    76 
    7774// Local Variables: //
    7875// tab-width: 4 //
  • src/Parser/ExpressionNode.cc

    rb2e8841 rf4abc58  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Sep 27 22:51:55 2017
    13 // Update Count     : 781
     12// Last Modified On : Sat Mar  3 18:22:33 2018
     13// Update Count     : 796
    1414//
    1515
     
    5858static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
    5959static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
     60static inline bool checkB( char c ) { return c == 'b' || c == 'B'; }
    6061static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
    6162
     
    116117
    117118        unsigned long long int v;                                                       // converted integral value
    118         size_t last = str.length() - 1;                                         // last character of constant
     119        size_t last = str.length() - 1;                                         // last subscript of constant
    119120        Expression * ret;
    120121
     
    129130        } // if
    130131
    131         if ( str[0] == '0' ) {                                                          // octal/hex constant ?
     132        // Cannot be "0"
     133
     134        if ( str[0] == '0' ) {                                                          // radix character ?
    132135                dec = false;
    133                 if ( last != 0 && checkX( str[1] ) ) {                  // hex constant ?
     136                if ( checkX( str[1] ) ) {                                               // hex constant ?
    134137                        sscanf( (char *)str.c_str(), "%llx", &v );
     138                        //printf( "%llx %llu\n", v, v );
     139                } else if ( checkB( str[1] ) ) {                                // binary constant ?
     140                        v = 0;
     141                        for ( unsigned int i = 2;; i += 1 ) {           // compute value
     142                                if ( str[i] == '1' ) v |= 1;
     143                          if ( i == last ) break;
     144                                v <<= 1;
     145                        } // for
    135146                        //printf( "%llx %llu\n", v, v );
    136147                } else {                                                                                // octal constant
  • src/Parser/lex.ll

    rb2e8841 rf4abc58  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Feb 22 18:11:27 2018
    13  * Update Count     : 637
     12 * Last Modified On : Sat Mar  3 18:38:16 2018
     13 * Update Count     : 640
    1414 */
    1515
     
    7777%}
    7878
     79binary [0-1]
    7980octal [0-7]
    8081nonzero [1-9]
     
    103104nonzero_digits ({nonzero})|({nonzero}({decimal}|"_")*{decimal})
    104105decimal_constant {nonzero_digits}{integer_suffix_opt}
     106
     107binary_digits ({binary})|({binary}({binary}|"_")*{binary})
     108binary_prefix "0"[bB]"_"?
     109binary_constant {binary_prefix}{binary_digits}{integer_suffix_opt}
    105110
    106111hex_digits ({hex})|({hex}({hex}|"_")*{hex})
     
    315320
    316321                                /* numeric constants */
     322{binary_constant} { NUMERIC_RETURN(INTEGERconstant); }
     323{octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
    317324{decimal_constant} { NUMERIC_RETURN(INTEGERconstant); }
    318 {octal_constant} { NUMERIC_RETURN(INTEGERconstant); }
    319325{hex_constant}  { NUMERIC_RETURN(INTEGERconstant); }
    320326{floating_decimal}      { NUMERIC_RETURN(FLOATING_DECIMALconstant); } // must appear before floating_constant
  • src/libcfa/concurrency/kernel

    rb2e8841 rf4abc58  
    7979
    8080// Processor
     81coroutine processorCtx_t {
     82        struct processor * proc;
     83};
     84
    8185// Wrapper around kernel threads
    8286struct processor {
    8387        // Main state
    8488        // Coroutine ctx who does keeps the state of the processor
    85         struct processorCtx_t * runner;
     89        struct processorCtx_t runner;
    8690
    8791        // Cluster from which to get threads
  • src/libcfa/concurrency/kernel.c

    rb2e8841 rf4abc58  
    124124//-----------------------------------------------------------------------------
    125125// Processor coroutine
     126void ?{}(processorCtx_t & this) {}
    126127
    127128// Construct the processor context of the main processor
     
    130131        this.__cor.starter = NULL;
    131132        this.proc = proc;
    132         proc->runner = &this;
    133133}
    134134
     
    137137        (this.__cor){ info };
    138138        this.proc = proc;
    139         proc->runner = &this;
    140139}
    141140
     
    150149        preemption_alarm = NULL;
    151150        pending_preemption = false;
     151        runner.proc = &this;
    152152
    153153        start( &this );
     
    161161        pending_preemption = false;
    162162        kernel_thread = pthread_self();
    163 
    164         this.runner = &runner;
     163        runner.proc = &this;
     164
    165165        __cfaabi_dbg_print_safe("Kernel : constructing main processor context %p\n", &runner);
    166166        runner{ &this };
     
    196196void main(processorCtx_t & runner) {
    197197        processor * this = runner.proc;
     198        verify(this);
    198199
    199200        __cfaabi_dbg_print_safe("Kernel : core %p starting\n", this);
     
    241242void runThread(processor * this, thread_desc * dst) {
    242243        assert(dst->curr_cor);
    243         coroutine_desc * proc_cor = get_coroutine(*this->runner);
     244        coroutine_desc * proc_cor = get_coroutine(this->runner);
    244245        coroutine_desc * thrd_cor = dst->curr_cor;
    245246
     
    256257
    257258void returnToKernel() {
    258         coroutine_desc * proc_cor = get_coroutine(*this_processor->runner);
     259        coroutine_desc * proc_cor = get_coroutine(this_processor->runner);
    259260        coroutine_desc * thrd_cor = this_thread->curr_cor = this_coroutine;
    260261        ThreadCtxSwitch(thrd_cor, proc_cor);
     
    317318        machine_context_t ctx;
    318319        info.context = &ctx;
    319         processorCtx_t proc_cor_storage = { proc, &info };
    320 
    321         __cfaabi_dbg_print_safe("Coroutine : created stack %p\n", proc_cor_storage.__cor.stack.base);
     320        (proc->runner){ proc, &info };
     321
     322        __cfaabi_dbg_print_safe("Coroutine : created stack %p\n", get_coroutine(proc->runner)->stack.base);
    322323
    323324        //Set global state
    324         this_coroutine = &proc->runner->__cor;
     325        this_coroutine = get_coroutine(proc->runner);
    325326        this_thread = NULL;
    326327
    327328        //We now have a proper context from which to schedule threads
    328         __cfaabi_dbg_print_safe("Kernel : core %p created (%p, %p)\n", proc, proc->runner, &ctx);
     329        __cfaabi_dbg_print_safe("Kernel : core %p created (%p, %p)\n", proc, &proc->runner, &ctx);
    329330
    330331        // SKULLDUGGERY: Since the coroutine doesn't have its own stack, we can't
     
    332333        // back to here. Instead directly call the main since we already are on the
    333334        // appropriate stack.
    334         proc_cor_storage.__cor.state = Active;
    335         main( proc_cor_storage );
    336         proc_cor_storage.__cor.state = Halted;
     335        get_coroutine(proc->runner)->state = Active;
     336        main( proc->runner );
     337        get_coroutine(proc->runner)->state = Halted;
    337338
    338339        // Main routine of the core returned, the core is now fully terminated
    339         __cfaabi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, proc->runner);
     340        __cfaabi_dbg_print_safe("Kernel : core %p main ended (%p)\n", proc, &proc->runner);
    340341
    341342        return NULL;
     
    352353void kernel_first_resume(processor * this) {
    353354        coroutine_desc * src = this_coroutine;
    354         coroutine_desc * dst = get_coroutine(*this->runner);
     355        coroutine_desc * dst = get_coroutine(this->runner);
    355356
    356357        verify( !preemption_state.enabled );
    357358
    358359        create_stack(&dst->stack, dst->stack.size);
    359         CtxStart(this->runner, CtxInvokeCoroutine);
     360        CtxStart(&this->runner, CtxInvokeCoroutine);
    360361
    361362        verify( !preemption_state.enabled );
     
    411412        verify( !preemption_state.enabled );
    412413        lock( ready_queue_lock __cfaabi_dbg_ctx2 );
    413         //TEMP hack to find a bug
    414         if(this_processor != mainProcessor) {
    415                 if(ready_queue.head == mainThread) {
    416                         unlock( ready_queue_lock );
    417                         return NULL;
    418                 }
    419         }
    420 
    421414        thread_desc * head = pop_head( ready_queue );
    422415        unlock( ready_queue_lock );
     
    584577        // Destroy the main processor and its context in reverse order of construction
    585578        // These were manually constructed so we need manually destroy them
    586         ^(*mainProcessor->runner){};
     579        ^(mainProcessor->runner){};
    587580        ^(mainProcessor){};
    588581
  • src/libcfa/concurrency/kernel_private.h

    rb2e8841 rf4abc58  
    5252//-----------------------------------------------------------------------------
    5353// Processor
    54 coroutine processorCtx_t {
    55         processor * proc;
    56 };
    57 
    5854void main(processorCtx_t *);
    5955void start(processor * this);
  • src/tests/.expect/literals.x64.txt

    rb2e8841 rf4abc58  
    522522signed int __main__Fi___1(){
    523523    __attribute__ ((unused)) signed int ___retval_main__i_1;
     524    ((void)0b01101011);
     525    ((void)0b01101011u);
     526    ((void)0b01101011l);
     527    ((void)0b01101011ll);
     528    ((void)0b01101011ul);
     529    ((void)0b01101011lu);
     530    ((void)0b01101011ull);
     531    ((void)0b01101011llu);
     532    ((void)(+0b01101011));
     533    ((void)(+0b01101011u));
     534    ((void)(+0b01101011l));
     535    ((void)(+0b01101011ll));
     536    ((void)(+0b01101011ul));
     537    ((void)(+0b01101011lu));
     538    ((void)(+0b01101011ull));
     539    ((void)(+0b01101011llu));
     540    ((void)(-0b01101011));
     541    ((void)(-0b01101011u));
     542    ((void)(-0b01101011l));
     543    ((void)(-0b01101011ll));
     544    ((void)(-0b01101011ul));
     545    ((void)(-0b01101011lu));
     546    ((void)(-0b01101011ull));
     547    ((void)(-0b01101011llu));
    524548    ((void)01234567);
    525549    ((void)01234567u);
     
    10171041    ((void)(-0X0123456789.0123456789P-09F));
    10181042    ((void)(-0X0123456789.0123456789P-09L));
     1043    ((void)((signed char )0b01101011));
     1044    ((void)((signed short int )0b01101011));
     1045    ((void)((signed int )0b01101011));
     1046    ((void)((signed long int )0b01101011));
     1047    ((void)((__int128 )0b01101011));
     1048    ((void)((unsigned char )0b01101011u));
     1049    ((void)((signed short int )0b01101011u));
     1050    ((void)((unsigned int )0b01101011u));
     1051    ((void)((signed long int )0b01101011u));
     1052    ((void)((__int128 )0b01101011u));
     1053    ((void)(+((signed int )((signed char )0b01101011))));
     1054    ((void)(+((signed int )((signed short int )0b01101011))));
     1055    ((void)(+((signed int )0b01101011)));
     1056    ((void)(+((signed long int )0b01101011)));
     1057    ((void)(+((float )((__int128 )0b01101011))));
     1058    ((void)(+((signed int )((unsigned char )0b01101011u))));
     1059    ((void)(+((signed int )((signed short int )0b01101011u))));
     1060    ((void)(+((unsigned int )0b01101011u)));
     1061    ((void)(+((signed long int )0b01101011u)));
     1062    ((void)(+((float )((__int128 )0b01101011u))));
     1063    ((void)(-((signed int )((signed char )0b01101011))));
     1064    ((void)(-((signed int )((signed short int )0b01101011))));
     1065    ((void)(-((signed int )0b01101011)));
     1066    ((void)(-((signed long int )0b01101011)));
     1067    ((void)(-((float )((__int128 )0b01101011))));
     1068    ((void)(-((signed int )((unsigned char )0b01101011u))));
     1069    ((void)(-((signed int )((signed short int )0b01101011u))));
     1070    ((void)(-((unsigned int )0b01101011u)));
     1071    ((void)(-((signed long int )0b01101011u)));
     1072    ((void)(-((float )((__int128 )0b01101011u))));
    10191073    ((void)((signed char )01234567));
    10201074    ((void)((signed short int )01234567));
  • src/tests/.expect/literals.x86.txt

    rb2e8841 rf4abc58  
    522522signed int __main__Fi___1(){
    523523    __attribute__ ((unused)) signed int ___retval_main__i_1;
     524    ((void)0b01101011);
     525    ((void)0b01101011u);
     526    ((void)0b01101011l);
     527    ((void)0b01101011ll);
     528    ((void)0b01101011ul);
     529    ((void)0b01101011lu);
     530    ((void)0b01101011ull);
     531    ((void)0b01101011llu);
     532    ((void)(+0b01101011));
     533    ((void)(+0b01101011u));
     534    ((void)(+0b01101011l));
     535    ((void)(+0b01101011ll));
     536    ((void)(+0b01101011ul));
     537    ((void)(+0b01101011lu));
     538    ((void)(+0b01101011ull));
     539    ((void)(+0b01101011llu));
     540    ((void)(-0b01101011));
     541    ((void)(-0b01101011u));
     542    ((void)(-0b01101011l));
     543    ((void)(-0b01101011ll));
     544    ((void)(-0b01101011ul));
     545    ((void)(-0b01101011lu));
     546    ((void)(-0b01101011ull));
     547    ((void)(-0b01101011llu));
    524548    ((void)01234567);
    525549    ((void)01234567u);
     
    10171041    ((void)(-0X0123456789.0123456789P-09F));
    10181042    ((void)(-0X0123456789.0123456789P-09L));
     1043    ((void)((signed char )0b01101011));
     1044    ((void)((signed short int )0b01101011));
     1045    ((void)((signed int )0b01101011));
     1046    ((void)((signed long long int )0b01101011));
     1047    ((void)((__int128 )0b01101011));
     1048    ((void)((unsigned char )0b01101011u));
     1049    ((void)((signed short int )0b01101011u));
     1050    ((void)((unsigned int )0b01101011u));
     1051    ((void)((signed long long int )0b01101011u));
     1052    ((void)((__int128 )0b01101011u));
     1053    ((void)(+((signed int )((signed char )0b01101011))));
     1054    ((void)(+((signed int )((signed short int )0b01101011))));
     1055    ((void)(+((signed int )0b01101011)));
     1056    ((void)(+((signed long long int )0b01101011)));
     1057    ((void)(+((float )((__int128 )0b01101011))));
     1058    ((void)(+((signed int )((unsigned char )0b01101011u))));
     1059    ((void)(+((signed int )((signed short int )0b01101011u))));
     1060    ((void)(+((unsigned int )0b01101011u)));
     1061    ((void)(+((signed long long int )0b01101011u)));
     1062    ((void)(+((float )((__int128 )0b01101011u))));
     1063    ((void)(-((signed int )((signed char )0b01101011))));
     1064    ((void)(-((signed int )((signed short int )0b01101011))));
     1065    ((void)(-((signed int )0b01101011)));
     1066    ((void)(-((signed long long int )0b01101011)));
     1067    ((void)(-((float )((__int128 )0b01101011))));
     1068    ((void)(-((signed int )((unsigned char )0b01101011u))));
     1069    ((void)(-((signed int )((signed short int )0b01101011u))));
     1070    ((void)(-((unsigned int )0b01101011u)));
     1071    ((void)(-((signed long long int )0b01101011u)));
     1072    ((void)(-((float )((__int128 )0b01101011u))));
    10191073    ((void)((signed char )01234567));
    10201074    ((void)((signed short int )01234567));
  • src/tests/.expect/user_literals.txt

    rb2e8841 rf4abc58  
    1111.0714285714286
    2 11.07225
     215
    3311.0714285714286
     424.8
     511.248
    4611.0714285714286
    5 11.0714285714286
    6 22.0457142857143
     728.0657142857143
    78secs 1
    89secs 23
  • src/tests/Makefile.am

    rb2e8841 rf4abc58  
    123123        ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
    124124
     125# Warnings
    125126warnings/self-assignment: warnings/self-assignment.c @CFA_BINDIR@/@CFA_NAME@
    126         ${CC} ${AM_CFLAGS} ${CFLAGS} ${<} -o ${@}
    127         echo > ${@}
     127        ${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
  • src/tests/Makefile.in

    rb2e8841 rf4abc58  
    800800        ${CC} ${AM_CFLAGS} ${CFLAGS} -DERR1 ${<} -o ${@}
    801801
     802# Warnings
    802803warnings/self-assignment: warnings/self-assignment.c @CFA_BINDIR@/@CFA_NAME@
    803         ${CC} ${AM_CFLAGS} ${CFLAGS} ${<} -o ${@}
    804         echo > ${@}
     804        ${CC} ${AM_CFLAGS} ${CFLAGS} ${<} 2> ${@} -fsyntax-only
    805805
    806806# Tell versions [3.59,3.63) of GNU make to not export all variables.
  • src/tests/literals.c

    rb2e8841 rf4abc58  
    1010// Created On       : Sat Sep  9 16:34:38 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Sep 25 20:26:00 2017
    13 // Update Count     : 132
     12// Last Modified On : Sun Mar  4 10:41:31 2018
     13// Update Count     : 134
    1414//
    1515
     
    3131// integer literals
    3232
     33        // binary
     34         0b01101011;   0b01101011u;   0b01101011l;   0b01101011ll;   0b01101011ul;   0b01101011lu;   0b01101011ull;   0b01101011llu;
     35        +0b01101011;  +0b01101011u;  +0b01101011l;  +0b01101011ll;  +0b01101011ul;  +0b01101011lu;  +0b01101011ull;  +0b01101011llu;
     36        -0b01101011;  -0b01101011u;  -0b01101011l;  -0b01101011ll;  -0b01101011ul;  -0b01101011lu;  -0b01101011ull;  -0b01101011llu;
     37
    3338        // octal
    3439         01234567;   01234567u;   01234567l;   01234567ll;   01234567ul;   01234567lu;   01234567ull;   01234567llu;
     
    148153#ifdef __CFA__
    149154// fixed-size length
     155
     156        // binary
     157         0b01101011_l8;   0b01101011_l16;   0b01101011_l32;   0b01101011_l64;   0b01101011_l128;   0b01101011_l8u;   0b01101011_ul16;   0b01101011_l32u;   0b01101011_ul64;   0b01101011_ul128;
     158        +0b01101011_l8;  +0b01101011_l16;  +0b01101011_l32;  +0b01101011_l64;  +0b01101011_l128;  +0b01101011_l8u;  +0b01101011_ul16;  +0b01101011_l32u;  +0b01101011_ul64;  +0b01101011_ul128;
     159        -0b01101011_l8;  -0b01101011_l16;  -0b01101011_l32;  -0b01101011_l64;  -0b01101011_l128;  -0b01101011_l8u;  -0b01101011_ul16;  -0b01101011_l32u;  -0b01101011_ul64;  -0b01101011_ul128;
    150160
    151161        // octal
  • src/tests/user_literals.c

    rb2e8841 rf4abc58  
    1010// Created On       : Wed Sep  6 21:40:50 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Dec  7 09:12:36 2017
    13 // Update Count     : 50
     12// Last Modified On : Sun Mar  4 11:14:02 2018
     13// Update Count     : 52
    1414//
    1515
     
    3131
    3232
    33 struct Weight {
    34         double stones;
    35 };
    36 void ?{}( Weight & w ) { w.stones = 0; }                                // operations
     33struct Weight { double stones; };
     34void ?{}( Weight & w ) { w.stones = 0; }
    3735void ?{}( Weight & w, double w ) { w.stones = w; }
    38 Weight ?+?( Weight l, Weight r ) { return (Weight){ l.stones + r.stones }; }
     36Weight ?+?( Weight l, Weight r ) {
     37        return (Weight){ l.stones + r.stones };
     38}
    3939ofstream & ?|?( ofstream & os, Weight w ) { return os | w.stones; }
    4040
    4141Weight ?`st( double w ) { return (Weight){ w }; }               // backquote for user literals
    4242Weight ?`lb( double w ) { return (Weight){ w / 14.0 }; }
    43 Weight ?`kg( double w ) { return (Weight) { w * 0.1575}; }
    44 
     43Weight ?`kg( double w ) { return (Weight) { w * 0.16 }; }
    4544
    4645int main() {
    47         Weight w, hw = { 14 };                                                          // 14 stone
    48         w = 11`st + 1`lb;
     46        Weight w, heavy = { 20 };                                                       // 20 stone
     47        w = 155`lb;
     48        sout | w | endl;
     49        w = 0b_1111`st;
     50        sout | w | endl;
     51        w = 0_233`lb;                                                                           // octal weight (155)
     52        sout | w | endl;
     53        w = 0x_9b_u`kg;
    4954        sout | w | endl;
    5055        w = 70.3`kg;
    5156        sout | w | endl;
    52         w = 155`lb;
     57        w = 11`st + 1`lb;
    5358        sout | w | endl;
    54         w = 0x_9b_u`lb;                                                                         // hexadecimal unsigned weight (155)
    55         sout | w | endl;
    56         w = 0_233`lb;                                                                           // octal weight (155)
    57         sout | w | endl;
    58         w = 5`st + 8`kg + 25`lb + hw;
     59        w = 5`st + 8`kg + 25`lb + heavy;
    5960        sout | w | endl;
    6061
  • src/tests/warnings/.expect/self-assignment.txt

    rb2e8841 rf4abc58  
     1warnings/self-assignment.c:29:1 warning: self assignment of expression: Cast of:
     2  Variable Expression: j: signed int
     3... to:
     4  reference to signed int
     5warnings/self-assignment.c:30:1 warning: self assignment of expression: Cast of:
     6  Variable Expression: s: instance of struct S with body 1
     7... to:
     8  reference to instance of struct S with body 1
     9warnings/self-assignment.c:31:1 warning: self assignment of expression: Cast of:
     10  Member Expression, with field:
     11    i: signed int
     12  ... from aggregate:
     13    Variable Expression: s: instance of struct S with body 1
     14... to:
     15  reference to signed int
     16warnings/self-assignment.c:32:1 warning: self assignment of expression: Cast of:
     17  Member Expression, with field:
     18    i: signed int
     19  ... from aggregate:
     20    Member Expression, with field:
     21      s: instance of struct S with body 1
     22    ... from aggregate:
     23      Variable Expression: t: instance of struct T with body 1
     24... to:
     25  reference to signed int
Note: See TracChangeset for help on using the changeset viewer.