Changeset 547e9b7


Ignore:
Timestamp:
May 16, 2017, 1:50:51 PM (7 years ago)
Author:
Thierry Delisle <tdelisle@…>
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:
eb182b0
Parents:
db0fa7c (diff), 22634b2 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

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

Files:
1 added
10 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.tex

    rdb0fa7c r547e9b7  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sun May 14 18:17:09 2017
    14 %% Update Count     : 295
     13%% Last Modified On : Mon May 15 18:03:29 2017
     14%% Update Count     : 302
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    3636% Names used in the document.
    3737
    38 \newcommand{\CFA}{C\raisebox{\depth}{\rotatebox{180}{\textscale{1.05}{\textsf{A}}}}\xspace} % Cforall symbolic name
    39 \newcommand{\CFL}{Cforall\xspace} % Cforall symbolic name
    40 \newcommand{\Celeven}{C11\xspace} % C11 symbolic name
    41 \newcommand{\CC}{\rm C\kern-.1em\hbox{+\kern-.25em+}\xspace} % C++ symbolic name
    42 \newcommand{\CCeleven}{\rm C\kern-.1em\hbox{+\kern-.25em+}11\xspace} % C++11 symbolic name
    43 \newcommand{\CCfourteen}{\rm C\kern-.1em\hbox{+\kern-.25em+}14\xspace} % C++14 symbolic name
    44 \newcommand{\CCseventeen}{\rm C\kern-.1em\hbox{+\kern-.25em+}17\xspace} % C++17 symbolic name
    45 \newcommand{\CCtwenty}{\rm C\kern-.1em\hbox{+\kern-.25em+}20\xspace} % C++20 symbolic name
     38\newcommand{\CFA}{\textrm{C}\raisebox{\depth}{\rotatebox{180}{\textsf{A}}}\xspace} % Cforall symbolic name
     39\newcommand{\CFL}{\textrm{Cforall}\xspace} % Cforall symbolic name
     40\newcommand{\Celeven}{\textrm{C11}\xspace} % C11 symbolic name
     41\newcommand{\CC}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}\xspace} % C++ symbolic name
     42\newcommand{\CCeleven}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}11\xspace} % C++11 symbolic name
     43\newcommand{\CCfourteen}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}14\xspace} % C++14 symbolic name
     44\newcommand{\CCseventeen}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}17\xspace} % C++17 symbolic name
     45\newcommand{\CCtwenty}{\textrm{C}\kern-.1em\hbox{+\kern-.25em+}20\xspace} % C++20 symbolic name
    4646\newcommand{\Csharp}{C\raisebox{-0.7ex}{\Large$^\sharp$}\xspace} % C# symbolic name
    4747
     
    243243literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1
    244244        {~}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}}1 {`}{\ttfamily\upshape\hspace*{-0.1ex}`}1
    245         {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex\textgreater}2,
     245        {__}{\_\,\_}2 {<-}{$\leftarrow$}2 {=>}{$\Rightarrow$}2 {->}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}\kern-0.2ex\textgreater}2
     246        {___}{\_\,\_\,\_}3,
    246247moredelim=**[is][\color{red}]{®}{®},                                    % red highlighting ®...® (registered trademark symbol) emacs: C-q M-.
    247248moredelim=**[is][\color{blue}]{ß}{ß},                                   % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
  • doc/user/user.tex

    rdb0fa7c r547e9b7  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Tue Apr 18 17:17:24 2017
    14 %% Update Count     : 1430
     13%% Last Modified On : Mon May 15 18:29:58 2017
     14%% Update Count     : 1598
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    3535\usepackage{calc}
    3636\usepackage{xspace}
    37 \usepackage{graphicx}
    3837\usepackage{varioref}                                                                   % extended references
    3938\usepackage{listings}                                                                   % format program code
     
    135134\section{Introduction}
    136135
    137 \CFA\footnote{Pronounced ``C-for-all'', and written \CFA, CFA, or \CFL.} is a modern general-purpose programming-language, designed as an evolutionary step forward from the C programming language.
     136\CFA{}\index{cforall@\CFA}\footnote{Pronounced ``\Index*{C-for-all}'', and written \CFA, CFA, or \CFL.} is a modern general-purpose programming-language, designed as an evolutionary step forward for the C programming language.
    138137The syntax of the \CFA language builds from C, and should look immediately familiar to C/\Index*[C++]{\CC} programmers.
    139138% Any language feature that is not described here can be assumed to be using the standard C11 syntax.
    140 \CFA adds many modern programming-language features that directly lead to increased \emph{safety} and \emph{productivity}, while maintaining interoperability with existing C programs and achieving C performance.
    141 Like C, \CFA is a statically typed, procedural language with a low-overhead runtime, meaning there is no global garbage-collection.
     139\CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving C performance.
     140Like C, \CFA is a statically typed, procedural language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage collection!regional} is possible.
    142141The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules.
    143142
     
    148147instead, a programmer evolves an existing C program into \CFA by incrementally incorporating \CFA features.
    149148New programs can be written in \CFA using a combination of C and \CFA features.
    150 \Index*[C++]{\CC} had a similar goal 30 years ago, but has struggled over the intervening time to incorporate modern programming-language features because of early design choices.
    151 \CFA has 30 years of hindsight and a clean starting point.
     149\Index*[C++]{\CC} had a similar goal 30 years ago, but currently has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
     150In contrast, \CFA has 30 years of hindsight and a clean starting point.
    152151
    153152Like \Index*[C++]{\CC}, there may be both an old and new ways to achieve the same effect.
    154153For example, the following programs compare the \CFA and C I/O mechanisms.
    155154\begin{quote2}
    156 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    157 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{C}}        \\
     155\begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}}
     156\multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{\CFA}}      & \multicolumn{1}{c}{\textbf{C}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
    158157\begin{cfa}
    159158#include <fstream>
     159
    160160int main( void ) {
    161161        int x = 0, y = 1, z = 2;
     
    166166\begin{lstlisting}
    167167#include <stdio.h>
     168
    168169int main( void ) {
    169170        int x = 0, y = 1, z = 2;
     
    171172}
    172173\end{lstlisting}
     174&
     175\begin{lstlisting}
     176#include <iostream>
     177using namespace std;
     178int main() {
     179        int x = 0, y = 1, z = 2;
     180        ®cout<<x<<" "<<y<<" "<<z<<endl;®
     181}
     182\end{lstlisting}
    173183\end{tabular}
    174184\end{quote2}
    175 Both programs output the same result.
    176 While the \CFA I/O looks similar to the \Index*[C++]{\CC} output style, there are important differences, such as automatic spacing between variables as in \Index*{Python} (see also~\VRef{s:IOLibrary}).
     185The programs output the same result.
     186While the \CFA I/O looks similar to the \Index*[C++]{\CC} output style, there are important differences, such as automatic spacing between variables as in \Index*{Python} (see~\VRef{s:IOLibrary}).
    177187
    178188This document is a user manual for the \CFA programming language, targeted at \CFA programmers.
     
    180190In its current state, this document covers the intended core features of the language.
    181191Changes to the syntax and additional features are expected to be included in later revisions.
    182 % For additional information, see \url{http://wiki.do-lang.org}.
    183 
    184 
    185 \section{History}
    186 
    187 The \CFA project started with K-W C~\cite{Buhr94a,Till89}, which extended C with new declaration syntax, multiple return values from routines, and extended assignment capabilities using the notion of tuples.
    188 (See~\cite{Werther96} for some similar work, but for \Index*[C++]{\CC}.)
    189 The original \CFA project~\cite{Ditchfield92} extended the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC} approach of object-oriented extensions to the C type-system.
    190 A first implementation of the core Cforall language was created~\cite{Bilson03,Esteves04}, but at the time there was little interesting in extending C, so work did not continue.
    191 As the saying goes, ``What goes around, comes around.'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted.
    192192
    193193
    194194\section{Why fix C?}
    195195
    196 Even with all its problems, C is a very popular programming language because it allows writing software at virtually any level in a computer system without restriction.
     196The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems (especially UNIX systems) to hobby projects.
     197This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
     198Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction.
    197199For system programming, where direct access to hardware and dealing with real-time issues is a requirement, C is usually the language of choice.
    198 As well, there are millions of lines of C legacy code, forming the base for many software development projects (especially on UNIX systems).
    199 The TIOBE index (\url{http://www.tiobe.com/tiobe_index}) for March 2016 shows programming-language popularity, with \Index*{Java} 20.5\%, C 14.5\%, \Index*[C++]{\CC} 6.7\%, \Csharp 4.3\%, \Index*{Python} 4.3\%, and all other programming languages below 3\%.
     200The TIOBE index~\cite{TIOBE} for March 2016 showed the following programming-language popularity: \Index*{Java} 20.5\%, C 14.5\%, \Index*[C++]{\CC} 6.7\%, \Csharp 4.3\%, \Index*{Python} 4.3\%, where the next 50 languages are less than 3\% each with a long tail.
    200201As well, for 30 years, C has been the number 1 and 2 most popular programming language:
    201202\begin{center}
     
    211212\end{tabular}
    212213\end{center}
    213 Hence, C is still an extremely important programming language, with double the usage of \Index*[C++]{\CC}, where \CC itself is largely C code.
    214 Finally, love it or hate it, C has been an important and influential part of computer science for 40 years and it appears it will continue to be for many more years.
     214Hence, C is still an extremely important programming language, with double the usage of \Index*[C++]{\CC{}}; in many cases, \CC is often used solely as a better C.
     215Love it or hate it, C has been an important and influential part of computer science for 40 years and sit appeal is not diminishing.
    215216Unfortunately, C has too many problems and omissions to make it an acceptable programming language for modern needs.
    216217
    217 The goal of this project is to engineer modern language features into C in an evolutionary rather than revolutionary way.
     218As stated, the goal of the \CFA project is to engineer modern language features into C in an evolutionary rather than revolutionary way.
    218219\CC~\cite{c++,ANSI14:C++} is an example of a similar project;
    219220however, it largely extended the language, and did not address many existing problems.\footnote{%
     
    225226These costs can be prohibitive for many companies with a large software base in C/\CC, and a significant number of programmers requiring retraining to a new programming language.
    226227
    227 The result of this project is a language that is largely backwards compatible with C11~\cite{C11}, but fixing some of the well known C problems and containing many modern language features.
     228The result of this project is a language that is largely backwards compatible with \Index*{C11}~\cite{C11}, but fixing some of the well known C problems and containing many modern language features.
    228229Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers;
    229230as a result, it will fade into disuse.
    230231Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language.
    231 While C11 made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language features.
     232While \Index*{C11} made a few simple extensions to the language, nothing was added to address existing problems in the language or to augment the language with modern language features.
    232233While some may argue that modern language features may make C complex and inefficient, it is clear a language without modern capabilities is insufficient for the advanced programming problems existing today.
     234
     235
     236\section{History}
     237
     238The \CFA project started with \Index*{K-W C}~\cite{Buhr94a,Till89}, which extended C with new declaration syntax, multiple return values from routines, and extended assignment capabilities using the notion of tuples.
     239(See~\cite{Werther96} for similar work in \Index*[C++]{\CC{}}.)
     240A first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}.
     241The signature feature of \CFA is parametric-polymorphic functions~\cite{forceone:impl,Cormack90,Duggan96} with functions generalized using a ©forall© clause (giving the language its name):
     242\begin{lstlisting}
     243®forall( otype T )® T identity( T val ) { return val; }
     244int forty_two = identity( 42 );                 §\C{// T is bound to int, forty\_two == 42}§
     245\end{lstlisting}
     246% extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC} approach of object-oriented extensions.
     247\CFA{}\hspace{1pt}'s polymorphism was originally formalized by Ditchfiled~\cite{Ditchfield92}, and first implemented by Bilson~\cite{Bilson03}.
     248However, at that time, there was little interesting in extending C, so work did not continue.
     249As the saying goes, ``What goes around, comes around.'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted.
    233250
    234251
     
    236253\label{s:Interoperability}
    237254
    238 \CFA is designed to integrate well with existing C programs and libraries.
    239 The most important feature of interoperability is to use the same calling conventions, so there is no overhead to call existing C routines.
    240 This feature allows users of \CFA to take advantage of the existing panoply of C libraries from inside their \CFA code.
    241 In fact, one of the biggest issues for any new programming language is establishing a minimum level of library code to support a large body of activities.
    242 Language developers often state that adequate library support takes more work than designing and implementing the language itself.
    243 Like \Index*[C++]{\CC}, \CFA starts with immediate access to all exiting C libraries, and in many cases, can easily wrap library routines with simpler and safer interfaces, at very low cost.
     255\CFA is designed to integrate directly with existing C programs and libraries.
     256The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no overhead to call existing C routines.
     257This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of external software features.
     258Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself.
     259Fortunately, \CFA, like \Index*[C++]{\CC{}}, starts with immediate access to all exiting C libraries, and in many cases, can easily wrap library routines with simpler and safer interfaces, at very low cost.
    244260Hence, \CFA begins by leveraging the large repository of C libraries with little cost.
     261
     262\begin{comment}
     263A simple example is leveraging the existing type-unsafe (©void *©) C ©bsearch© to binary search a sorted floating-point array:
     264\begin{lstlisting}
     265void * bsearch( const void * key, const void * base, size_t nmemb, size_t size,
     266                                int (* compar)( const void *, const void * ));
     267
     268int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 :
     269                                *(double *)t2 < *(double *)t1 ? 1 : 0; }
     270
     271double key = 5.0, vals[10] = { /* 10 sorted floating-point values */ };
     272double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp );      $\C{// search sorted array}$
     273\end{lstlisting}
     274which can be augmented simply with a polymorphic, type-safe, \CFA-overloaded wrappers:
     275\begin{lstlisting}
     276forall( otype T | { int ?<?( T, T ); } ) T * bsearch( T key, const T * arr, size_t size ) {
     277        int comp( const void * t1, const void * t2 ) { /* as above with double changed to T */ }
     278        return (T *)bsearch( &key, arr, size, sizeof(T), comp ); }
     279
     280forall( otype T | { int ?<?( T, T ); } ) unsigned int bsearch( T key, const T * arr, size_t size ) {
     281        T * result = bsearch( key, arr, size ); $\C{// call first version}$
     282        return result ? result - arr : size; }  $\C{// pointer subtraction includes sizeof(T)}$
     283
     284double * val = bsearch( 5.0, vals, 10 );        $\C{// selection based on return type}$
     285int posn = bsearch( 5.0, vals, 10 );
     286\end{lstlisting}
     287The nested function ©comp© provides the hidden interface from typed \CFA to untyped (©void *©) C, plus the cast of the result.
     288Providing a hidden ©comp© function in \CC is awkward as lambdas do not use C calling-conventions and template declarations cannot appear at block scope.
     289As well, an alternate kind of return is made available: position versus pointer to found element.
     290\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©.
     291
     292\CFA has replacement libraries condensing hundreds of existing C functions into tens of \CFA overloaded functions, all without rewriting the actual computations.
     293For example, it is possible to write a type-safe \CFA wrapper ©malloc© based on the C ©malloc©:
     294\begin{lstlisting}
     295forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }
     296int * ip = malloc();                                    §\C{// select type and size from left-hand side}§
     297double * dp = malloc();
     298struct S {...} * sp = malloc();
     299\end{lstlisting}
     300where the return type supplies the type/size of the allocation, which is impossible in most type systems.
     301\end{comment}
    245302
    246303However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC.
     
    250307char abs( char );
    251308®extern "C" {®
    252 int abs( int );                                 §\C{// use default C routine for int}§
     309int abs( int );                                                 §\C{// use default C routine for int}§
    253310®}® // extern "C"
    254311long int abs( long int );
     
    356413\begin{cfa}
    357414#ifndef __CFORALL__
    358 #include <stdio.h>                              §\C{// C header file}§
     415#include <stdio.h>                                              §\C{// C header file}§
    359416#else
    360 #include <fstream>                              §\C{// \CFA header file}§
     417#include <fstream>                                              §\C{// \CFA header file}§
    361418#endif
    362419\end{cfa}
     
    368425Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, \eg:
    369426\begin{cfa}
    370 2®_®147®_®483®_®648;                    §\C{// decimal constant}§
    371 56_ul;                                                  §\C{// decimal unsigned long constant}§
    372 0_377;                                                  §\C{// octal constant}§
    373 0x_ff_ff;                                               §\C{// hexadecimal constant}§
    374 0x_ef3d_aa5c;                                   §\C{// hexadecimal constant}§
    375 3.141_592_654;                                  §\C{// floating point constant}§
    376 10_e_+1_00;                                             §\C{// floating point constant}§
    377 0x_ff_ff_p_3;                                   §\C{// hexadecimal floating point}§
    378 0x_1.ffff_ffff_p_128_l;                 §\C{// hexadecimal floating point long constant}§
    379 L_"\x_ff_ee";                                   §\C{// wide character constant}§
     4272®_®147®_®483®_®648;                                    §\C{// decimal constant}§
     42856®_®ul;                                                                §\C{// decimal unsigned long constant}§
     4290®_®377;                                                                §\C{// octal constant}§
     4300x®_®ff®_®ff;                                                   §\C{// hexadecimal constant}§
     4310x®_®ef3d®_®aa5c;                                               §\C{// hexadecimal constant}§
     4323.141®_®592®_®654;                                              §\C{// floating point constant}§
     43310®_®e®_®+1®_®00;                                               §\C{// floating point constant}§
     4340x®_®ff®_®ff®_®p®_®3;                                   §\C{// hexadecimal floating point}§
     4350x®_®1.ffff®_®ffff®_®p®_®128®_®l;               §\C{// hexadecimal floating point long constant}§
     436L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§;     §\C{// wide character constant}§
    380437\end{cfa}
    381438The rules for placement of underscores is as follows:
     
    401458\label{s:BackquoteIdentifiers}
    402459
    403 \CFA accommodates keyword clashes by syntactic transformations using the \CFA backquote escape-mechanism:
     460\CFA accommodates keyword clashes with existing C variable-names by syntactic transformations using the \CFA backquote escape-mechanism:
    404461\begin{cfa}
    405462int ®`®otype®`® = 3;                    §\C{// make keyword an identifier}§
    406463double ®`®choose®`® = 3.5;
    407464\end{cfa}
    408 Programs can be converted easily by enclosing keyword identifiers in backquotes, and the backquotes can be removed later when the identifier name is changed to an non-keyword name.
    409 Clashes in C header files (see~\VRef{s:StandardHeaders}) can be handled automatically using the preprocessor, ©#include_next© and ©-I filename©:
     465Programs can be converted easily by enclosing keyword identifiers in backquotes, and the backquotes can be removed later when the identifier name is changed to a  non-keyword name.
     466\VRef[Figure]{f:InterpositionHeaderFile} shows how clashes in C header files (see~\VRef{s:StandardHeaders}) can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©:
     467
     468\begin{figure}
    410469\begin{cfa}
    411470// include file uses the CFA keyword "otype".
     
    422481#endif // otype && __CFA_BFD_H__
    423482\end{cfa}
     483\caption{Interposition of Header File}
     484\label{f:InterpositionHeaderFile}
     485\end{figure}
    424486
    425487
     
    446508... (*f())[3] += 1;
    447509\end{cfa}
    448 Essentially, the return type is wrapped around the routine name in successive layers (like an onion).
     510Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}).
    449511While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice.
    450512
     
    20112073So the type raised would be the mangled name of the exception prototype and that name would be matched at the handler clauses by comparing the strings.
    20122074The arguments for the call would have to be packed in a message and unpacked at handler clause and then a call made to the handler.
     2075
     2076
     2077\section{I/O Library}
     2078\label{s:IOLibrary}
     2079\index{input/output library}
     2080
     2081The goal for the \CFA I/O is to make I/O as simple as possible in the common cases, while fully supporting polymorphism and user defined types in a consistent way.
     2082The common case is printing out a sequence of variables separated by whitespace.
     2083\begin{quote2}
     2084\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     2085\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
     2086\begin{cfa}
     2087int x = 0, y = 1, z = 2;
     2088sout | x ®|® y ®|® z | endl;
     2089\end{cfa}
     2090&
     2091\begin{cfa}
     2092
     2093cout << x ®<< " "® << y ®<< " "® << z << endl;
     2094\end{cfa}
     2095\end{tabular}
     2096\end{quote2}
     2097The \CFA form has half as many characters as the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
     2098
     2099The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment.
     2100Therefore, fewer output expressions require parenthesis.
     2101\begin{quote2}
     2102\begin{tabular}{@{}ll@{}}
     2103\textbf{\CFA:}
     2104&
     2105\begin{cfa}
     2106sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
     2107\end{cfa}
     2108\\
     2109\textbf{\CC:}
     2110&
     2111\begin{cfa}
     2112cout << x * 3 << y + 1 << (z << 2) << (x == y) << (x | y) << (x || y) << (x > z ? 1 : 2) << endl;
     2113\end{cfa}
     2114\end{tabular}
     2115\end{quote2}
     2116Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, where data flows in the correct direction for input but the opposite direction for output.
     2117
     2118The implicit separator\index{I/O separator} character (space/blank) is a separator not a terminator.
     2119The rules for implicitly adding the separator are:
     2120\begin{enumerate}
     2121\item
     2122A separator does not appear at the start or end of a line.
     2123\begin{cfa}[belowskip=0pt]
     2124sout | 1 | 2 | 3 | endl;
     2125\end{cfa}
     2126\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     21271 2 3
     2128\end{cfa}
     2129\item
     2130A separator does not appear before or after a character literal or variable.
     2131\begin{cfa}
     2132sout | '1' | '2' | '3' | endl;
     2133123
     2134\end{cfa}
     2135\item
     2136A separator does not appear before or after a null (empty) C string
     2137\begin{cfa}
     2138sout | 1 | "" | 2 | "" | 3 | endl;
     2139123
     2140\end{cfa}
     2141which is a local mechanism to disable insertion of the separator character.
     2142\item
     2143A separator does not appear before a C string starting with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off]@([{=$£¥¡¿«@
     2144%$
     2145\begin{cfa}[mathescape=off]
     2146sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥"
     2147                | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10 | endl;
     2148\end{cfa}
     2149%$
     2150\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2151x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
     2152\end{cfa}
     2153%$
     2154\item
     2155{\lstset{language=CFA,deletedelim=**[is][]{¢}{¢}}
     2156A seperator does not appear after a C string ending with the (extended) \Index{ASCII}\index{ASCII!extended} characters: ©,.;!?)]}%¢»©
     2157\begin{cfa}[belowskip=0pt]
     2158sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     2159                | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x" | endl;
     2160\end{cfa}
     2161\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     21621, x 2. x 3; x 4! x 5? x 6% x 7§\textcent§ x 8» x 9) x 10] x 11} x
     2163\end{cfa}}%
     2164\item
     2165A seperator does not appear before or after a C string begining/ending with the \Index{ASCII} quote or whitespace characters: \lstinline[showspaces=true]@`'": \t\v\f\r\n@
     2166\begin{cfa}[belowskip=0pt]
     2167sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx" | endl;
     2168\end{cfa}
     2169\begin{cfa}[mathescape=off,showspaces=true,showtabs=true,aboveskip=0pt,belowskip=0pt]
     2170x`1`x'2'x"3"x:4:x 5 x   6       x
     2171\end{cfa}
     2172\end{enumerate}
     2173
     2174The following \CC-style \Index{manipulator}s allow control over implicit seperation.
     2175Manipulators \Indexc{sepOn}\index{manipulator!sepOn@©sepOn©} and \Indexc{sepOff}\index{manipulator!sepOff@©sepOff©} \emph{locally} toggle printing the separator, i.e., the seperator is adjusted only with respect to the next printed item.
     2176\begin{cfa}[mathescape=off,belowskip=0pt]
     2177sout | sepOn | 1 | 2 | 3 | sepOn | endl;        §\C{// separator at start of line}§
     2178\end{cfa}
     2179\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2180 1 2 3
     2181\end{cfa}
     2182\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2183sout | 1 | sepOff | 2 | 3 | endl;                       §\C{// locally turn off implicit separator}§
     2184\end{cfa}
     2185\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     218612 3
     2187\end{cfa}
     2188Manipulators \Indexc{sepDisable}\index{manipulator!sepDisable@©sepDisable©} and \Indexc{sepEnable}\index{manipulator!sepEnable@©sepEnable©} \emph{globally} toggle printing the separator, i.e., the seperator is adjusted with respect to all subsequent printed items, unless locally adjusted.
     2189\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2190sout | sepDisable | 1 | 2 | 3 | endl;           §\C{// globally turn off implicit separation}§
     2191\end{cfa}
     2192\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2193123
     2194\end{cfa}
     2195\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2196sout | 1 | sepOn | 2 | 3 | endl;                        §\C{// locally turn on implicit separator}§
     2197\end{cfa}
     2198\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     21991 23
     2200\end{cfa}
     2201\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2202sout | sepEnable | 1 | 2 | 3 | endl;            §\C{// globally turn on implicit separation}§
     2203\end{cfa}
     2204\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     22051 2 3
     2206\end{cfa}
     2207Printing a tuple outputs all the tuple's values separated by ©", "©:
     2208\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2209sout | [2, 3] | [4, 5] | endl;                          §\C{// print tuple}§
     2210\end{cfa}
     2211\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     22122, 3, 4, 5
     2213\end{cfa}
     2214The tuple separator can also be turned on and off:
     2215\begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
     2216sout | sepOn | [2, 3] | sepOff | [4, 5] | endl; §\C{// locally turn on/off implicit separation}§
     2217\end{cfa}
     2218\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     2219, 2, 34, 5
     2220\end{cfa}
     2221Notice a tuple seperator starts the line because the next item is a tuple.
     2222Finally, the stream routines \Indexc{sepGet}\index{manipulator!sepGet@©sepGet©} and \Indexc{sepSet}\index{manipulator!sepSet@©sepSet©} get and set the basic separator-string.
     2223\begin{cfa}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
     2224sepSet( sout, ", $" );                                          §\C{// set separator from " " to ", \$"}§
     2225sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
     2226\end{cfa}
     2227%$
     2228\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
     22291, $2, $3 ", $"
     2230\end{cfa}
     2231%$
     2232\begin{cfa}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
     2233sepSet( sout, " " );                                            §\C{// reset separator to " "}§
     2234sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
     2235\end{cfa}
     2236\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
     22371 2 3 " "
     2238\end{cfa}
     2239and the stream routines \Indexc{sepGetTuple}\index{manipulator!sepGetTuple@©sepGetTuple©} and \Indexc{sepSetTuple}\index{manipulator!sepSetTuple@©sepSetTuple©} get and set the tuple separator-string.
     2240\begin{cfa}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
     2241sepSetTuple( sout, " " );                                       §\C{// set tuple separator from ", " to " "}§
     2242sout | [2, 3] | [4, 5] | " \"" | sepGetTuple( sout ) | "\"" | endl;
     2243\end{cfa}
     2244\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
     22452 3 4 5 " "
     2246\end{cfa}
     2247\begin{cfa}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
     2248sepSetTuple( sout, ", " );                                      §\C{// reset tuple separator to ", "}§
     2249sout | [2, 3] | [4, 5] | " \"" | sepGetTuple( sout ) | "\"" | endl;
     2250\end{cfa}
     2251\begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
     22522, 3, 4, 5 ", "
     2253\end{cfa}
     2254
     2255\begin{comment}
     2256#include <fstream>
     2257
     2258int main( void ) {
     2259        int x = 0, y = 1, z = 2;
     2260        sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl | endl;
     2261        sout | 1 | 2 | 3 | endl;
     2262        sout | '1' | '2' | '3' | endl;
     2263        sout | 1 | "" | 2 | "" | 3 | endl;
     2264        sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥"
     2265                | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10 | endl;
     2266        sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
     2267                | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x" | endl;
     2268        sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx" | endl;
     2269
     2270        sout | sepOn | 1 | 2 | 3 | sepOn | endl;        // separator at start of line
     2271        sout | 1 | sepOff | 2 | 3 | endl;                       // locally turn off implicit separator
     2272        sout | sepDisable | 1 | 2 | 3 | endl;           // globally turn off implicit separation
     2273        sout | 1 | sepOn | 2 | 3 | endl;                        // locally turn on implicit separator
     2274        sout | sepEnable | 1 | 2 | 3 | endl;            // globally turn on implicit separation
     2275
     2276        sout | [2, 3] | [4, 5] | endl;                          // print tuple
     2277        sout | sepOn | [2, 3] | sepOff | [4, 5] | endl; // locally turn on/off implicit separation
     2278
     2279        sepSet( sout, ", $" );                                          // set separator from " " to ", $"
     2280        sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
     2281        sepSet( sout, " " );                                            // reset separator to " "
     2282        sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl;
     2283
     2284        sepSetTuple( sout, " " );                                       // set tuple separator from ", " to " "
     2285        sout | [2, 3] | [4, 5] | " \"" | sepGetTuple( sout ) | "\"" | endl;
     2286        sepSetTuple( sout, ", " );                                      // reset tuple separator to ", "
     2287        sout | [2, 3] | [4, 5] | " \"" | sepGetTuple( sout ) | "\"" | endl;
     2288}
     2289
     2290// Local Variables: //
     2291// tab-width: 4 //
     2292// End: //
     2293\end{comment}
     2294%$
    20132295
    20142296
     
    24162698\begin{quote2}
    24172699\begin{tabular}{@{}l@{\hspace{3em}}ll@{}}
    2418 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CC}} & \multicolumn{1}{c}{Indexc{gcc}} \\
     2700\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CC}} & \multicolumn{1}{c}{\textbf{\Indexc{gcc}}} \\
    24192701\begin{cfa}
    24202702
     
    27603042The exact set of unsafe C constructs that will be disallowed in \CFA has not yet been decided, but is sure to include pointer arithmetic, pointer casting, etc.
    27613043Once the full set is decided, the rules will be listed here.
    2762 
    2763 
    2764 \section{Syntactic Anomalies}
    2765 
    2766 The number 0 and 1 are treated specially in \CFA, and can be redefined as variables.
    2767 One syntactic anomaly is when a field in an structure is names 0 or 1:
    2768 \begin{cfa}
    2769 struct S {
    2770         int 0, 1;
    2771 } s;
    2772 \end{cfa}
    2773 The problem occurs in accessing these fields using the selection operation ``©.©'':
    2774 \begin{cfa}
    2775 s.0 = 0;        // ambiguity with floating constant .0
    2776 s.1 = 1;        // ambiguity with floating constant .1
    2777 \end{cfa}
    2778 To make this work, a space is required after the field selection:
    2779 \begin{cfa}
    2780 ®s.§\textvisiblespace§0® = 0;
    2781 ®s.§\textvisiblespace§1® = 1;
    2782 \end{cfa}
    2783 While this syntax is awkward, it is unlikely many programmers will name fields of a structure 0 or 1.
    2784 Like the \Index*[C++]{\CC} lexical problem with closing template-syntax, e.g, ©Foo<Bar<int®>>®©, this issue can be solved with a more powerful lexer/parser.
    2785 
    2786 There are several ambiguous cases with operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be lexed as ©*©/©?*?© or ©*?©/©*?©.
    2787 Since it is common practise to put a unary operator juxtaposed to an identifier, \eg ©*i©, users will be annoyed if they cannot do this with respect to operator identifiers.
    2788 Even with this special hack, there are 5 general cases that cannot be handled.
    2789 The first case is for the function-call identifier ©?()©:
    2790 \begin{cfa}
    2791 int *§\textvisiblespace§?()();  // declaration: space required after '*'
    2792 *§\textvisiblespace§?()();              // expression: space required after '*'
    2793 \end{cfa}
    2794 Without the space, the string ©*?()© is ambiguous without N character look ahead;
    2795 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument/parameter list.
    2796 
    2797 The 4 remaining cases occur in expressions:
    2798 \begin{cfa}
    2799 i++§\textvisiblespace§?i:0;             // space required before '?'
    2800 i--§\textvisiblespace§?i:0;             // space required before '?'
    2801 i§\textvisiblespace§?++i:0;             // space required after '?'
    2802 i§\textvisiblespace§?--i:0;             // space required after '?'
    2803 \end{cfa}
    2804 In the first two cases, the string ©i++?© is ambiguous, where this string can be lexed as ©i© / ©++?© or ©i++© / ©?©;
    2805 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list.
    2806 In the second two cases, the string ©?++x© is ambiguous, where this string can be lexed as ©?++© / ©x© or ©?© / y©++x©;
    2807 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list.
    28083044
    28093045
     
    44194655
    44204656
     4657\section{Syntactic Anomalies}
     4658
     4659There are several ambiguous cases with operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be lexed as ©*©~\R{/}~©?*?© or ©*?©~\R{/}~©*?©.
     4660Since it is common practise to put a unary operator juxtaposed to an identifier, \eg ©*i©, users will be annoyed if they cannot do this with respect to operator identifiers.
     4661Even with this special hack, there are 5 general cases that cannot be handled.
     4662The first case is for the function-call identifier ©?()©:
     4663\begin{cfa}
     4664int *§\textvisiblespace§?()();  // declaration: space required after '*'
     4665*§\textvisiblespace§?()();              // expression: space required after '*'
     4666\end{cfa}
     4667Without the space, the string ©*?()© is ambiguous without N character look ahead;
     4668it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument/parameter list.
     4669
     4670The 4 remaining cases occur in expressions:
     4671\begin{cfa}
     4672i++§\textvisiblespace§?i:0;             // space required before '?'
     4673i--§\textvisiblespace§?i:0;             // space required before '?'
     4674i§\textvisiblespace§?++i:0;             // space required after '?'
     4675i§\textvisiblespace§?--i:0;             // space required after '?'
     4676\end{cfa}
     4677In the first two cases, the string ©i++?© is ambiguous, where this string can be lexed as ©i© / ©++?© or ©i++© / ©?©;
     4678it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list.
     4679In the second two cases, the string ©?++x© is ambiguous, where this string can be lexed as ©?++© / ©x© or ©?© / y©++x©;
     4680it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list.
     4681
     4682
    44214683\section{Incompatible}
    44224684
     
    45554817
    45564818
    4557 \section{New Keywords}
    4558 \label{s:NewKeywords}
     4819\section{\protect\CFA Keywords}
     4820\label{s:CFAKeywords}
    45594821
    45604822\begin{quote2}
    45614823\begin{tabular}{lll}
    4562 ©catch©                 & ©fallthrough© & ©otype©               \\
    4563 ©catchResume©   & ©fallthru©    & ©throw©               \\
    4564 ©choose©                & ©finally©             & ©throwResume© \\
    4565 ©disable©               & ©forall©              & ©trait©               \\
    4566 ©dtype©                 & ©ftype©               & ©try©                 \\
    4567 ©enable©                & ©lvalue©              &                               \\
     4824\begin{tabular}{@{}l@{}}
     4825©_AT©                   \\
     4826©catch©                 \\
     4827©catchResume©   \\
     4828©choose©                \\
     4829©coroutine©             \\
     4830©disable©               \\
     4831©dtype©                 \\
     4832©enable©                \\
     4833\end{tabular}
     4834&
     4835\begin{tabular}{@{}l@{}}
     4836©fallthrough©   \\
     4837©fallthru©              \\
     4838©finally©               \\
     4839©forall©                \\
     4840©ftype©                 \\
     4841©lvalue©                \\
     4842©monitor©               \\
     4843©mutex©                 \\
     4844\end{tabular}
     4845&
     4846\begin{tabular}{@{}l@{}}
     4847©one_t©                 \\
     4848©otype©                 \\
     4849©throw©                 \\
     4850©throwResume©   \\
     4851©trait©                 \\
     4852©try©                   \\
     4853©ttype©                 \\
     4854©zero_t©                \\
     4855\end{tabular}
    45684856\end{tabular}
    45694857\end{quote2}
     
    45734861\label{s:StandardHeaders}
    45744862
    4575 C prescribes the following standard header-files~\cite[\S~7.1.2]{C11}:
     4863C11 prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list:
    45764864\begin{quote2}
    4577 \begin{minipage}{\linewidth}
    4578 \begin{tabular}{lll}
    4579 assert.h        & math.h                & stdlib.h              \\
    4580 complex.h       & setjmp.h              & stdnoreturn.h \\
     4865\begin{tabular}{lll|l}
     4866\multicolumn{3}{c|}{C11} & \multicolumn{1}{c}{\CFA}             \\
     4867\hline
     4868assert.h        & math.h                & stdlib.h              & unistd.h      \\
     4869complex.h       & setjmp.h              & stdnoreturn.h & gmp.h         \\
    45814870ctype.h         & signal.h              & string.h              \\
    45824871errno.h         & stdalign.h    & tgmath.h              \\
     
    45864875iso646.h        & stddef.h              & wchar.h               \\
    45874876limits.h        & stdint.h              & wctype.h              \\
    4588 locale.h        & stdio.h               & unistd.h\footnote{\CFA extension}
     4877locale.h        & stdio.h               &                               \\
    45894878\end{tabular}
    4590 \end{minipage}
    45914879\end{quote2}
    45924880For the prescribed head-files, \CFA implicitly wraps their includes in an ©extern "C"©;
    45934881hence, names in these include files are not mangled\index{mangling!name} (see~\VRef{s:Interoperability}).
    45944882All other C header files must be explicitly wrapped in ©extern "C"© to prevent name mangling.
    4595 
    4596 
    4597 \section{I/O Library}
    4598 \label{s:IOLibrary}
    4599 \index{input/output library}
    4600 
    4601 The goal for the \CFA I/O is to make I/O as simple as possible in the common cases, while fully supporting polymorphism and user defined types in a consistent way.
    4602 The common case is printing out a sequence of variables separated by whitespace.
    4603 \begin{quote2}
    4604 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    4605 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c}{\textbf{\CC}}      \\
    4606 \begin{cfa}
    4607 int x = 0, y = 1, z = 2;
    4608 ®sout® ®|® x ®|® y ®|® z ®| endl®;
    4609 \end{cfa}
    4610 &
    4611 \begin{cfa}
    4612 
    4613 cout << x << " " << y << " " << z << endl;
    4614 \end{cfa}
    4615 \end{tabular}
    4616 \end{quote2}
    4617 The \CFA form has half as many characters as the \CC form, and is similar to \Index*{Python} I/O with respect to implicit separators.
    4618 
    4619 The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment.
    4620 Therefore, fewer output expressions require parenthesis.
    4621 \begin{quote2}
    4622 \begin{tabular}{@{}ll@{}}
    4623 \textbf{\CFA:}
    4624 &
    4625 \begin{cfa}
    4626 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
    4627 \end{cfa}
    4628 \\
    4629 \textbf{\CC:}
    4630 &
    4631 \begin{cfa}
    4632 cout << x * 3 << y + 1 << (z << 2) << (x == y) << (x | y) << (x || y) << (x > z ? 1 : 2) << endl;
    4633 \end{cfa}
    4634 \end{tabular}
    4635 \end{quote2}
    4636 Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, although data flows in the opposite direction.
    4637 
    4638 The implicit separator\index{I/O separator} character (space/blank) is a separator not a terminator.
    4639 The rules for implicitly adding the separator are:
    4640 \begin{enumerate}
    4641 \item
    4642 A separator does not appear at the start or end of a line.
    4643 \begin{cfa}[belowskip=0pt]
    4644 sout | 1 | 2 | 3 | endl;
    4645 \end{cfa}
    4646 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4647 1 2 3
    4648 \end{cfa}
    4649 \item
    4650 A separator does not appear before or after a character literal or variable.
    4651 \begin{cfa}
    4652 sout | '1' | '2' | '3' | endl;
    4653 123
    4654 \end{cfa}
    4655 \item
    4656 A separator does not appear before or after a null (empty) C string
    4657 \begin{cfa}
    4658 sout | 1 | "" | 2 | "" | 3 | endl;
    4659 123
    4660 \end{cfa}
    4661 which is a local mechanism to disable insertion of the separator character.
    4662 \item
    4663 A separator does not appear before a C string starting with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off]@([{=$£¥¡¿«@
    4664 %$
    4665 \begin{cfa}[mathescape=off]
    4666 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥" | 7
    4667          | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10 | endl;
    4668 \end{cfa}
    4669 %$
    4670 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4671 x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
    4672 \end{cfa}
    4673 %$
    4674 \item
    4675 {\lstset{deletedelim=**[is][]{¢}{¢}}
    4676 A seperator does not appear after a C string ending with the (extended) \Index{ASCII}\index{ASCII!extended} characters: ©,.:;!?)]}%¢»©
    4677 \begin{cfa}[belowskip=0pt]
    4678 sout | 1 | ", x" | 2 | ". x" | 3 | ": x" | 4 | "; x" | 5 | "! x" | 6 | "? x" | 7 | "% x"
    4679          | 8 | "¢ x" | 9 | "» x" | 10 | ") x" | 11 | "] x" | 12 | "} x" | endl;
    4680 \end{cfa}
    4681 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4682 1, x 2. x 3: x 4; x 5! x 6? x 7% x 8¢ x 9» x 10) x 11] x 12} x
    4683 \end{cfa}}%
    4684 \item
    4685 A seperator does not appear before or after a C string begining/ending with the \Index{ASCII} quote or whitespace characters: \lstinline[showspaces=true]@`'" \t\v\f\r\n@
    4686 \begin{cfa}[belowskip=0pt]
    4687 sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x" | "x " | 4 | " x" | "x\t" | 1 | "\tx" | endl;
    4688 \end{cfa}
    4689 \begin{cfa}[mathescape=off,showspaces=true,showtabs=true,aboveskip=0pt,belowskip=0pt]
    4690 x`1`x'2'x"3"x x 4 x x   1       x
    4691 \end{cfa}
    4692 \end{enumerate}
    4693 The following \CC-style \Index{manipulator}s allow further control over implicit seperation.
    4694 \begin{cfa}[mathescape=off,belowskip=0pt]
    4695 sout | sepOn | 1 | 2 | 3 | sepOn | endl;        §\C{// separator at start of line}§
    4696 \end{cfa}
    4697 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4698  1 2 3
    4699 \end{cfa}
    4700 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    4701 sout | 1 | sepOff | 2 | 3 | endl;                       §\C{// turn off implicit separator locally}§
    4702 \end{cfa}
    4703 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4704 12 3
    4705 \end{cfa}
    4706 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    4707 sout | sepDisable | 1 | 2 | 3 | endl;           §\C{// turn off implicit separation globally}§
    4708 \end{cfa}
    4709 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4710 123
    4711 \end{cfa}
    4712 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    4713 sout | 1 | sepOn | 2 | 3 | endl;                        §\C{// turn on implicit separator locally}§
    4714 \end{cfa}
    4715 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4716 1 23
    4717 \end{cfa}
    4718 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt]
    4719 sout | sepEnable | 1 | 2 | 3 | endl;            §\C{// turn on implicit separation globally}§
    4720 \end{cfa}
    4721 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4722  1 2 3
    4723 \end{cfa}
    4724 \begin{cfa}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
    4725 sepSet( sout, ", $" );                                          §\C{// change separator from " " to ", \$"}§
    4726 sout | 1 | 2 | 3 | endl;
    4727 \end{cfa}
    4728 %$
    4729 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt]
    4730 1, $2, $3
    4731 \end{cfa}
    4732 %$
    4733 \begin{comment}
    4734 #include <fstream>
    4735 
    4736 int main() {
    4737         int x = 0, y = 1, z = 2;
    4738         sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl | endl;
    4739         sout | 1 | 2 | 3 | endl;
    4740         sout | '1' | '2' | '3' | endl;
    4741         sout | 1 | "" | 2 | "" | 3 | endl;
    4742         sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥" | 7
    4743                 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10 | endl;
    4744         sout | 1 | ", x" | 2 | ". x" | 3 | ": x" | 4 | "; x" | 5 | "! x" | 6 | "? x" | 7 | "% x"
    4745                 | 8 | "¢ x" | 9 | "» x" | 10 | ") x" | 11 | "] x" | 12 | "} x" | endl;
    4746         sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x" | "x " | 4 | " x" | "x\t" | 1 | "\tx" | endl;
    4747         sout | sepOn | 1 | 2 | 3 | sepOn | endl;        // separator at start of line
    4748         sout | 1 | sepOff | 2 | 3 | endl;                       // turn off implicit separator temporarily
    4749         sout | sepDisable | 1 | 2 | 3 | endl;           // turn off implicit separation, affects all subsequent prints
    4750         sout | 1 | sepOn | 2 | 3 | endl;                        // turn on implicit separator temporarily
    4751         sout | sepEnable | 1 | 2 | 3 | endl;            // turn on implicit separation, affects all subsequent prints
    4752         sepSet( sout, ", $" );                                          // change separator from " " to ", $"
    4753         sout | 1 | 2 | 3 | endl;
    4754 
    4755 }
    4756 
    4757 // Local Variables: //
    4758 // tab-width: 4 //
    4759 // End: //
    4760 \end{comment}
    4761 %$
    47624883
    47634884
  • src/libcfa/fstream

    rdb0fa7c r547e9b7  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 21 15:57:24 2017
    13 // Update Count     : 102
     12// Last Modified On : Mon May 15 18:11:09 2017
     13// Update Count     : 104
    1414//
    1515
     
    2929}; // ofstream
    3030
     31// private
    3132_Bool sepPrt( ofstream * );
    32 void sepOn( ofstream * );
    33 void sepOff( ofstream * );
    3433void sepReset( ofstream * );
    3534void sepReset( ofstream *, _Bool );
    3635const char * sepGetCur( ofstream * );
    3736void sepSetCur( ofstream *, const char * );
     37
     38// public
     39void sepOn( ofstream * );
     40void sepOff( ofstream * );
     41_Bool sepDisable( ofstream * );
     42_Bool sepEnable( ofstream * );
     43
    3844const char * sepGet( ofstream * );
    3945void sepSet( ofstream *, const char * );
    4046const char * sepGetTuple( ofstream * );
    4147void sepSetTuple( ofstream *, const char * );
    42 _Bool sepDisable( ofstream * );
    43 _Bool sepEnable( ofstream * );
    4448
    4549int fail( ofstream * );
  • src/libcfa/fstream.c

    rdb0fa7c r547e9b7  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 23 08:20:41 2017
    13 // Update Count     : 226
     12// Last Modified On : Mon May 15 18:11:11 2017
     13// Update Count     : 234
    1414//
    1515
     
    3838}
    3939
     40// private
    4041_Bool sepPrt( ofstream * os ) { return os->sepOnOff; }
     42void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
     43void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
     44const char * sepGetCur( ofstream * os ) { return os->sepCur; }
     45void sepSetCur( ofstream * os, const char * sepCur ) { os->sepCur = sepCur; }
     46
     47// public
    4148void sepOn( ofstream * os ) { os->sepOnOff = 1; }
    4249void sepOff( ofstream * os ) { os->sepOnOff = 0; }
    43 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; }
    44 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; }
    45 
    46 const char * sepGetCur( ofstream * os ) { return os->sepCur; }
    47 void sepSetCur( ofstream * os, const char * sepCur ) { os->sepCur = sepCur; }
    48 
    49 const char * sepGet( ofstream * os ) { return os->separator; }
    50 
    51 void sepSet( ofstream * os, const char * s ) {
    52         assert( s );
    53         strncpy( os->separator, s, separateSize - 1 );
    54         os->separator[separateSize - 1] = '\0';
    55 } // sepSet
    56 
    57 const char * sepGetTuple( ofstream * os ) { return os->tupleSeparator; }
    58 
    59 void sepSetTuple( ofstream * os, const char * s ) {
    60         assert( s );
    61         strncpy( os->tupleSeparator, s, separateSize - 1 );
    62         os->tupleSeparator[separateSize - 1] = '\0';
    63 } // sepSet
    6450
    6551_Bool sepDisable( ofstream *os ) {
     
    7359        _Bool temp = os->sepDefault;
    7460        os->sepDefault = true;
    75         sepReset( os );
     61        if ( os->sepOnOff ) sepReset( os );                                     // start of line ?
    7662        return temp;
    7763} // sepEnable
     64
     65const char * sepGet( ofstream * os ) { return os->separator; }
     66void sepSet( ofstream * os, const char * s ) {
     67        assert( s );
     68        strncpy( os->separator, s, separateSize - 1 );
     69        os->separator[separateSize - 1] = '\0';
     70} // sepSet
     71
     72const char * sepGetTuple( ofstream * os ) { return os->tupleSeparator; }
     73void sepSetTuple( ofstream * os, const char * s ) {
     74        assert( s );
     75        strncpy( os->tupleSeparator, s, separateSize - 1 );
     76        os->tupleSeparator[separateSize - 1] = '\0';
     77} // sepSet
    7878
    7979int fail( ofstream * os ) {
  • src/libcfa/gmp

    rdb0fa7c r547e9b7  
    1010// Created On       : Tue Apr 19 08:43:43 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 13 22:52:26 2017
    13 // Update Count     : 8
    14 //
    15 
    16 extern "C" {
     12// Last Modified On : Sun May 14 23:47:36 2017
     13// Update Count     : 9
     14//
     15
    1716// https://gmplib.org/gmp-man-6.1.1.pdf
     17
    1818#include <gmp.h>                                                                                // GNU multi-precise integers
    19 // some code for operators "/" and "%" taken from g++ gmpxx.h
    20 }
    2119#include <fstream>                                                                              // sout
    2220
     
    146144Int ?*=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs * rhs; }
    147145
     146// some code for operators "/" and "%" taken from g++ gmpxx.h
    148147Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; }
    149148Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; }
  • src/libcfa/iostream

    rdb0fa7c r547e9b7  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Mar 21 15:57:29 2017
    13 // Update Count     : 104
     12// Last Modified On : Mon May 15 18:08:44 2017
     13// Update Count     : 105
    1414//
    1515
     
    2020
    2121trait ostream( dtype ostype ) {
     22        // private
    2223        _Bool sepPrt( ostype * );                                                       // return separator state (on/off)
    23         void sepOn( ostype * );                                                         // turn separator state on
    24         void sepOff( ostype * );                                                        // turn separator state off
    2524        void sepReset( ostype * );                                                      // set separator state to default state
    2625        void sepReset( ostype *, _Bool );                                       // set separator and default state
    2726        const char * sepGetCur( ostype * );                                     // get current separator string
    2827        void sepSetCur( ostype *, const char * );                       // set current separator string
     28        // public
     29        void sepOn( ostype * );                                                         // turn separator state on
     30        void sepOff( ostype * );                                                        // turn separator state off
     31        _Bool sepDisable( ostype * );                                           // set default state to off, and return previous state
     32        _Bool sepEnable( ostype * );                                            // set default state to on, and return previous state
     33
    2934        const char * sepGet( ostype * );                                        // get separator string
    3035        void sepSet( ostype *, const char * );                          // set separator to string (15 character maximum)
    3136        const char * sepGetTuple( ostype * );                           // get tuple separator string
    3237        void sepSetTuple( ostype *, const char * );                     // set tuple separator to string (15 character maximum)
    33         _Bool sepDisable( ostype * );                                           // set default state to off, and return previous state
    34         _Bool sepEnable( ostype * );                                            // set default state to on, and return previous state
    3538
    3639        int fail( ostype * );
  • src/libcfa/rational

    rdb0fa7c r547e9b7  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Sun May 14 16:49:13 2017
    15 // Update Count     : 78
     14// Last Modified On : Mon May 15 21:30:12 2017
     15// Update Count     : 90
    1616//
    1717
     
    128128
    129129// conversion
    130 // forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    131 // double widen( Rational(RationalImpl) r );
    132 // forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    133 // Rational(RationalImpl) narrow( double f, RationalImpl md );
     130forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     131double widen( Rational(RationalImpl) r );
     132forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl );  RationalImpl convert( double );} )
     133Rational(RationalImpl) narrow( double f, RationalImpl md );
    134134
    135135// I/O
  • src/libcfa/rational.c

    rdb0fa7c r547e9b7  
    1010// Created On       : Wed Apr  6 17:54:28 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 14 17:25:19 2017
    13 // Update Count     : 131
     12// Last Modified On : Mon May 15 21:29:23 2017
     13// Update Count     : 149
    1414//
    1515
     
    190190// conversion
    191191
    192 // forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    193 // double widen( Rational(RationalImpl) r ) {
    194 //      return (double)r.numerator / (double)r.denominator;
    195 // } // widen
    196 
    197 // // http://www.ics.uci.edu/~eppstein/numth/frap.c
    198 // forall ( otype RationalImpl | arithmetic( RationalImpl ) )
    199 // Rational(RationalImpl) narrow( double f, RationalImpl md ) {
    200 //      if ( md <= 1 ) {                                                                        // maximum fractional digits too small?
    201 //              return (Rational(RationalImpl)){ f, 1};                 // truncate fraction
    202 //      } // if
    203 
    204 //      // continued fraction coefficients
    205 //      RationalImpl m00 = 1, m11 = 1, m01 = 0, m10 = 0;
    206 //      RationalImpl ai, t;
    207 
    208 //      // find terms until denom gets too big
    209 //      for ( ;; ) {
    210 //              ai = (RationalImpl)f;
    211 //        if ( ! (m10 * ai + m11 <= md) ) break;
    212 //              t = m00 * ai + m01;
    213 //              m01 = m00;
    214 //              m00 = t;
    215 //              t = m10 * ai + m11;
    216 //              m11 = m10;
    217 //              m10 = t;
    218 //              t = (double)ai;
    219 //        if ( f == t ) break;                                                          // prevent division by zero
    220 //        f = 1 / (f - (double)t);
    221 //        if ( f > (double)0x7FFFFFFF ) break;                          // representation failure
    222 //      }
    223 //      return (Rational(RationalImpl)){ m00, m10 };
    224 // } // narrow
     192forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } )
     193double widen( Rational(RationalImpl) r ) {
     194        return convert( r.numerator ) / convert( r.denominator );
     195} // widen
     196
     197// http://www.ics.uci.edu/~eppstein/numth/frap.c
     198forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } )
     199Rational(RationalImpl) narrow( double f, RationalImpl md ) {
     200        if ( md <= (RationalImpl){1} ) {                                        // maximum fractional digits too small?
     201                return (Rational(RationalImpl)){ convert( f ), (RationalImpl){1}}; // truncate fraction
     202        } // if
     203
     204        // continued fraction coefficients
     205        RationalImpl m00 = {1}, m11 = { 1 }, m01 = { 0 }, m10 = { 0 };
     206        RationalImpl ai, t;
     207
     208        // find terms until denom gets too big
     209        for ( ;; ) {
     210                ai = convert( f );
     211          if ( ! (m10 * ai + m11 <= md) ) break;
     212                t = m00 * ai + m01;
     213                m01 = m00;
     214                m00 = t;
     215                t = m10 * ai + m11;
     216                m11 = m10;
     217                m10 = t;
     218                double temp = convert( ai );
     219          if ( f == temp ) break;                                                       // prevent division by zero
     220                f = 1 / (f - temp);
     221          if ( f > (double)0x7FFFFFFF ) break;                          // representation failure
     222        } // for
     223        return (Rational(RationalImpl)){ m00, m10 };
     224} // narrow
    225225
    226226
  • src/tests/.expect/rational.txt

    rdb0fa7c r547e9b7  
    17173/1
    18184/3
     19conversion
     200.75
     210.142857142857143
     223.14159292035398
     233/4
     241/7
     25355/113
    1926decompose
    2027more tests
  • src/tests/rational.c

    rdb0fa7c r547e9b7  
    1010// Created On       : Mon Mar 28 08:43:12 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 14 18:10:28 2017
    13 // Update Count     : 57
     12// Last Modified On : Mon May 15 21:32:22 2017
     13// Update Count     : 64
    1414//
    1515
     
    2323void ?{}( int * this, zero_t ) { *this = 0; }
    2424void ?{}( int * this, one_t ) { *this = 1; }
     25double convert( int i ) { return (double)i; }
     26int convert( double d ) { return (int)d; }
    2527
    2628int main() {
     
    5759        sout | a / b | endl;
    5860
    59 //      sout | "conversion" | endl;
    60 //      a = (Rational(int)){ 3, 4 };
    61 //      sout | widen( a ) | endl;
    62 //      a = (Rational(int)){ 1, 7 };
    63 //      sout | widen( a ) | endl;
    64 //      a = (Rational(int)){ 355, 113 };
    65 //      sout | widen( a ) | endl;
    66 //      sout | narrow( 0.75, 4 ) | endl;
    67 //      sout | narrow( 0.14285714285714, 16 ) | endl;
    68 //      sout | narrow( 3.14159265358979, 256 ) | endl;
     61        sout | "conversion" | endl;
     62        a = (Rational(int)){ 3, 4 };
     63        sout | widen( a ) | endl;
     64        a = (Rational(int)){ 1, 7 };
     65        sout | widen( a ) | endl;
     66        a = (Rational(int)){ 355, 113 };
     67        sout | widen( a ) | endl;
     68        sout | narrow( 0.75, 4 ) | endl;
     69        sout | narrow( 0.14285714285714, 16 ) | endl;
     70        sout | narrow( 3.14159265358979, 256 ) | endl;
    6971
    7072        sout | "decompose" | endl;
Note: See TracChangeset for help on using the changeset viewer.