Changeset 547e9b7
- Timestamp:
- May 16, 2017, 1:50:51 PM (7 years ago)
- 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. - Files:
-
- 1 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.tex
rdb0fa7c r547e9b7 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun May 14 18:17:09 201714 %% Update Count : 29513 %% Last Modified On : Mon May 15 18:03:29 2017 14 %% Update Count : 302 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 36 36 % Names used in the document. 37 37 38 \newcommand{\CFA}{ C\raisebox{\depth}{\rotatebox{180}{\textscale{1.05}{\textsf{A}}}}\xspace} % Cforall symbolic name39 \newcommand{\CFL}{ Cforall\xspace} % Cforall symbolic name40 \newcommand{\Celeven}{ C11\xspace} % C11 symbolic name41 \newcommand{\CC}{\ rm C\kern-.1em\hbox{+\kern-.25em+}\xspace} % C++ symbolic name42 \newcommand{\CCeleven}{\ rm C\kern-.1em\hbox{+\kern-.25em+}11\xspace} % C++11 symbolic name43 \newcommand{\CCfourteen}{\ rm C\kern-.1em\hbox{+\kern-.25em+}14\xspace} % C++14 symbolic name44 \newcommand{\CCseventeen}{\ rm C\kern-.1em\hbox{+\kern-.25em+}17\xspace} % C++17 symbolic name45 \newcommand{\CCtwenty}{\ rm C\kern-.1em\hbox{+\kern-.25em+}20\xspace} % C++20 symbolic name38 \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 46 46 \newcommand{\Csharp}{C\raisebox{-0.7ex}{\Large$^\sharp$}\xspace} % C# symbolic name 47 47 … … 243 243 literate={-}{\makebox[1ex][c]{\raisebox{0.4ex}{\rule{0.8ex}{0.075ex}}}}1 {^}{\raisebox{0.6ex}{$\scriptscriptstyle\land\,$}}1 244 244 {~}{\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, 246 247 moredelim=**[is][\color{red}]{®}{®}, % red highlighting ®...® (registered trademark symbol) emacs: C-q M-. 247 248 moredelim=**[is][\color{blue}]{ß}{ß}, % blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_ -
doc/user/user.tex
rdb0fa7c r547e9b7 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Tue Apr 18 17:17:24201714 %% Update Count : 1 43013 %% Last Modified On : Mon May 15 18:29:58 2017 14 %% Update Count : 1598 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 35 35 \usepackage{calc} 36 36 \usepackage{xspace} 37 \usepackage{graphicx}38 37 \usepackage{varioref} % extended references 39 38 \usepackage{listings} % format program code … … 135 134 \section{Introduction} 136 135 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 fromthe 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. 138 137 The syntax of the \CFA language builds from C, and should look immediately familiar to C/\Index*[C++]{\CC} programmers. 139 138 % 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. 140 Like 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. 142 141 The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules. 143 142 … … 148 147 instead, a programmer evolves an existing C program into \CFA by incrementally incorporating \CFA features. 149 148 New 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. 150 In contrast, \CFA has 30 years of hindsight and a clean starting point. 152 151 153 152 Like \Index*[C++]{\CC}, there may be both an old and new ways to achieve the same effect. 154 153 For example, the following programs compare the \CFA and C I/O mechanisms. 155 154 \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}} \\ 158 157 \begin{cfa} 159 158 #include <fstream> 159 160 160 int main( void ) { 161 161 int x = 0, y = 1, z = 2; … … 166 166 \begin{lstlisting} 167 167 #include <stdio.h> 168 168 169 int main( void ) { 169 170 int x = 0, y = 1, z = 2; … … 171 172 } 172 173 \end{lstlisting} 174 & 175 \begin{lstlisting} 176 #include <iostream> 177 using namespace std; 178 int main() { 179 int x = 0, y = 1, z = 2; 180 ®cout<<x<<" "<<y<<" "<<z<<endl;® 181 } 182 \end{lstlisting} 173 183 \end{tabular} 174 184 \end{quote2} 175 Bothprograms 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}).185 The programs output the same result. 186 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~\VRef{s:IOLibrary}). 177 187 178 188 This document is a user manual for the \CFA programming language, targeted at \CFA programmers. … … 180 190 In its current state, this document covers the intended core features of the language. 181 191 Changes 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.192 192 193 193 194 194 \section{Why fix C?} 195 195 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. 196 The 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. 197 This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more. 198 Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction. 197 199 For 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\%. 200 The 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. 200 201 As well, for 30 years, C has been the number 1 and 2 most popular programming language: 201 202 \begin{center} … … 211 212 \end{tabular} 212 213 \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.214 Hence, 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. 215 Love it or hate it, C has been an important and influential part of computer science for 40 years and sit appeal is not diminishing. 215 216 Unfortunately, C has too many problems and omissions to make it an acceptable programming language for modern needs. 216 217 217 The goal of thisproject is to engineer modern language features into C in an evolutionary rather than revolutionary way.218 As stated, the goal of the \CFA project is to engineer modern language features into C in an evolutionary rather than revolutionary way. 218 219 \CC~\cite{c++,ANSI14:C++} is an example of a similar project; 219 220 however, it largely extended the language, and did not address many existing problems.\footnote{% … … 225 226 These 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. 226 227 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.228 The 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. 228 229 Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers; 229 230 as a result, it will fade into disuse. 230 231 Considering 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 C11made 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.232 While \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. 232 233 While 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 238 The \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{}}.) 240 A first \CFA implementation of these extensions was by Esteves~\cite{Esteves04}. 241 The 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; } 244 int 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}. 248 However, at that time, there was little interesting in extending C, so work did not continue. 249 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. 233 250 234 251 … … 236 253 \label{s:Interoperability} 237 254 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. 256 The most important feature of \Index{interoperability} is using the same \Index{calling convention}s, so there is no overhead to call existing C routines. 257 This feature allows \CFA programmers to take advantage of the existing panoply of C libraries to access thousands of external software features. 258 Language developers often state that adequate \Index{library support} takes more work than designing and implementing the language itself. 259 Fortunately, \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. 244 260 Hence, \CFA begins by leveraging the large repository of C libraries with little cost. 261 262 \begin{comment} 263 A simple example is leveraging the existing type-unsafe (©void *©) C ©bsearch© to binary search a sorted floating-point array: 264 \begin{lstlisting} 265 void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, 266 int (* compar)( const void *, const void * )); 267 268 int comp( const void * t1, const void * t2 ) { return *(double *)t1 < *(double *)t2 ? -1 : 269 *(double *)t2 < *(double *)t1 ? 1 : 0; } 270 271 double key = 5.0, vals[10] = { /* 10 sorted floating-point values */ }; 272 double * val = (double *)bsearch( &key, vals, 10, sizeof(vals[0]), comp ); $\C{// search sorted array}$ 273 \end{lstlisting} 274 which can be augmented simply with a polymorphic, type-safe, \CFA-overloaded wrappers: 275 \begin{lstlisting} 276 forall( 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 280 forall( 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 284 double * val = bsearch( 5.0, vals, 10 ); $\C{// selection based on return type}$ 285 int posn = bsearch( 5.0, vals, 10 ); 286 \end{lstlisting} 287 The nested function ©comp© provides the hidden interface from typed \CFA to untyped (©void *©) C, plus the cast of the result. 288 Providing a hidden ©comp© function in \CC is awkward as lambdas do not use C calling-conventions and template declarations cannot appear at block scope. 289 As 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. 293 For example, it is possible to write a type-safe \CFA wrapper ©malloc© based on the C ©malloc©: 294 \begin{lstlisting} 295 forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); } 296 int * ip = malloc(); §\C{// select type and size from left-hand side}§ 297 double * dp = malloc(); 298 struct S {...} * sp = malloc(); 299 \end{lstlisting} 300 where the return type supplies the type/size of the allocation, which is impossible in most type systems. 301 \end{comment} 245 302 246 303 However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC. … … 250 307 char abs( char ); 251 308 ®extern "C" {® 252 int abs( int ); §\C{// use default C routine for int}§309 int abs( int ); §\C{// use default C routine for int}§ 253 310 ®}® // extern "C" 254 311 long int abs( long int ); … … 356 413 \begin{cfa} 357 414 #ifndef __CFORALL__ 358 #include <stdio.h> §\C{// C header file}§415 #include <stdio.h> §\C{// C header file}§ 359 416 #else 360 #include <fstream> §\C{// \CFA header file}§417 #include <fstream> §\C{// \CFA header file}§ 361 418 #endif 362 419 \end{cfa} … … 368 425 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, \eg: 369 426 \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}§427 2®_®147®_®483®_®648; §\C{// decimal constant}§ 428 56®_®ul; §\C{// decimal unsigned long constant}§ 429 0®_®377; §\C{// octal constant}§ 430 0x®_®ff®_®ff; §\C{// hexadecimal constant}§ 431 0x®_®ef3d®_®aa5c; §\C{// hexadecimal constant}§ 432 3.141®_®592®_®654; §\C{// floating point constant}§ 433 10®_®e®_®+1®_®00; §\C{// floating point constant}§ 434 0x®_®ff®_®ff®_®p®_®3; §\C{// hexadecimal floating point}§ 435 0x®_®1.ffff®_®ffff®_®p®_®128®_®l; §\C{// hexadecimal floating point long constant}§ 436 L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§; §\C{// wide character constant}§ 380 437 \end{cfa} 381 438 The rules for placement of underscores is as follows: … … 401 458 \label{s:BackquoteIdentifiers} 402 459 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: 404 461 \begin{cfa} 405 462 int ®`®otype®`® = 3; §\C{// make keyword an identifier}§ 406 463 double ®`®choose®`® = 3.5; 407 464 \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©: 465 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 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} 410 469 \begin{cfa} 411 470 // include file uses the CFA keyword "otype". … … 422 481 #endif // otype && __CFA_BFD_H__ 423 482 \end{cfa} 483 \caption{Interposition of Header File} 484 \label{f:InterpositionHeaderFile} 485 \end{figure} 424 486 425 487 … … 446 508 ... (*f())[3] += 1; 447 509 \end{cfa} 448 Essentially, the return type is wrapped around the routine name in successive layers (like an onion).510 Essentially, the return type is wrapped around the routine name in successive layers (like an \Index{onion}). 449 511 While attempting to make the two contexts consistent is a laudable goal, it has not worked out in practice. 450 512 … … 2011 2073 So 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. 2012 2074 The 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 2081 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. 2082 The 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} 2087 int x = 0, y = 1, z = 2; 2088 sout | x ®|® y ®|® z | endl; 2089 \end{cfa} 2090 & 2091 \begin{cfa} 2092 2093 cout << x ®<< " "® << y ®<< " "® << z << endl; 2094 \end{cfa} 2095 \end{tabular} 2096 \end{quote2} 2097 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. 2098 2099 The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment. 2100 Therefore, fewer output expressions require parenthesis. 2101 \begin{quote2} 2102 \begin{tabular}{@{}ll@{}} 2103 \textbf{\CFA:} 2104 & 2105 \begin{cfa} 2106 sout | 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} 2112 cout << 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} 2116 Finally, 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 2118 The implicit separator\index{I/O separator} character (space/blank) is a separator not a terminator. 2119 The rules for implicitly adding the separator are: 2120 \begin{enumerate} 2121 \item 2122 A separator does not appear at the start or end of a line. 2123 \begin{cfa}[belowskip=0pt] 2124 sout | 1 | 2 | 3 | endl; 2125 \end{cfa} 2126 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 2127 1 2 3 2128 \end{cfa} 2129 \item 2130 A separator does not appear before or after a character literal or variable. 2131 \begin{cfa} 2132 sout | '1' | '2' | '3' | endl; 2133 123 2134 \end{cfa} 2135 \item 2136 A separator does not appear before or after a null (empty) C string 2137 \begin{cfa} 2138 sout | 1 | "" | 2 | "" | 3 | endl; 2139 123 2140 \end{cfa} 2141 which is a local mechanism to disable insertion of the separator character. 2142 \item 2143 A 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] 2146 sout | "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] 2151 x (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][]{¢}{¢}} 2156 A seperator does not appear after a C string ending with the (extended) \Index{ASCII}\index{ASCII!extended} characters: ©,.;!?)]}%¢»© 2157 \begin{cfa}[belowskip=0pt] 2158 sout | 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] 2162 1, 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 2165 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@ 2166 \begin{cfa}[belowskip=0pt] 2167 sout | "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] 2170 x`1`x'2'x"3"x:4:x 5 x 6 x 2171 \end{cfa} 2172 \end{enumerate} 2173 2174 The following \CC-style \Index{manipulator}s allow control over implicit seperation. 2175 Manipulators \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] 2177 sout | 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] 2183 sout | 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] 2186 12 3 2187 \end{cfa} 2188 Manipulators \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] 2190 sout | 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] 2193 123 2194 \end{cfa} 2195 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2196 sout | 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] 2199 1 23 2200 \end{cfa} 2201 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2202 sout | 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] 2205 1 2 3 2206 \end{cfa} 2207 Printing a tuple outputs all the tuple's values separated by ©", "©: 2208 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2209 sout | [2, 3] | [4, 5] | endl; §\C{// print tuple}§ 2210 \end{cfa} 2211 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 2212 2, 3, 4, 5 2213 \end{cfa} 2214 The tuple separator can also be turned on and off: 2215 \begin{cfa}[mathescape=off,aboveskip=0pt,belowskip=0pt] 2216 sout | 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} 2221 Notice a tuple seperator starts the line because the next item is a tuple. 2222 Finally, 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] 2224 sepSet( sout, ", $" ); §\C{// set separator from " " to ", \$"}§ 2225 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl; 2226 \end{cfa} 2227 %$ 2228 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt] 2229 1, $2, $3 ", $" 2230 \end{cfa} 2231 %$ 2232 \begin{cfa}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt] 2233 sepSet( sout, " " ); §\C{// reset separator to " "}§ 2234 sout | 1 | 2 | 3 | " \"" | sepGet( sout ) | "\"" | endl; 2235 \end{cfa} 2236 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt] 2237 1 2 3 " " 2238 \end{cfa} 2239 and 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] 2241 sepSetTuple( sout, " " ); §\C{// set tuple separator from ", " to " "}§ 2242 sout | [2, 3] | [4, 5] | " \"" | sepGetTuple( sout ) | "\"" | endl; 2243 \end{cfa} 2244 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt] 2245 2 3 4 5 " " 2246 \end{cfa} 2247 \begin{cfa}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt] 2248 sepSetTuple( sout, ", " ); §\C{// reset tuple separator to ", "}§ 2249 sout | [2, 3] | [4, 5] | " \"" | sepGetTuple( sout ) | "\"" | endl; 2250 \end{cfa} 2251 \begin{cfa}[mathescape=off,showspaces=true,aboveskip=0pt] 2252 2, 3, 4, 5 ", " 2253 \end{cfa} 2254 2255 \begin{comment} 2256 #include <fstream> 2257 2258 int 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 %$ 2013 2295 2014 2296 … … 2416 2698 \begin{quote2} 2417 2699 \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}}} \\ 2419 2701 \begin{cfa} 2420 2702 … … 2760 3042 The 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. 2761 3043 Once 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 .02776 s.1 = 1; // ambiguity with floating constant .12777 \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.2808 3044 2809 3045 … … 4419 4655 4420 4656 4657 \section{Syntactic Anomalies} 4658 4659 There are several ambiguous cases with operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be lexed as ©*©~\R{/}~©?*?© or ©*?©~\R{/}~©*?©. 4660 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. 4661 Even with this special hack, there are 5 general cases that cannot be handled. 4662 The first case is for the function-call identifier ©?()©: 4663 \begin{cfa} 4664 int *§\textvisiblespace§?()(); // declaration: space required after '*' 4665 *§\textvisiblespace§?()(); // expression: space required after '*' 4666 \end{cfa} 4667 Without the space, the string ©*?()© is ambiguous without N character look ahead; 4668 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument/parameter list. 4669 4670 The 4 remaining cases occur in expressions: 4671 \begin{cfa} 4672 i++§\textvisiblespace§?i:0; // space required before '?' 4673 i--§\textvisiblespace§?i:0; // space required before '?' 4674 i§\textvisiblespace§?++i:0; // space required after '?' 4675 i§\textvisiblespace§?--i:0; // space required after '?' 4676 \end{cfa} 4677 In the first two cases, the string ©i++?© is ambiguous, where this string can be lexed as ©i© / ©++?© or ©i++© / ©?©; 4678 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list. 4679 In the second two cases, the string ©?++x© is ambiguous, where this string can be lexed as ©?++© / ©x© or ©?© / y©++x©; 4680 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list. 4681 4682 4421 4683 \section{Incompatible} 4422 4684 … … 4555 4817 4556 4818 4557 \section{ NewKeywords}4558 \label{s: NewKeywords}4819 \section{\protect\CFA Keywords} 4820 \label{s:CFAKeywords} 4559 4821 4560 4822 \begin{quote2} 4561 4823 \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} 4568 4856 \end{tabular} 4569 4857 \end{quote2} … … 4573 4861 \label{s:StandardHeaders} 4574 4862 4575 C prescribes the following standard header-files~\cite[\S~7.1.2]{C11}:4863 C11 prescribes the following standard header-files~\cite[\S~7.1.2]{C11} and \CFA adds to this list: 4576 4864 \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 4868 assert.h & math.h & stdlib.h & unistd.h \\ 4869 complex.h & setjmp.h & stdnoreturn.h & gmp.h \\ 4581 4870 ctype.h & signal.h & string.h \\ 4582 4871 errno.h & stdalign.h & tgmath.h \\ … … 4586 4875 iso646.h & stddef.h & wchar.h \\ 4587 4876 limits.h & stdint.h & wctype.h \\ 4588 locale.h & stdio.h & unistd.h\footnote{\CFA extension}4877 locale.h & stdio.h & \\ 4589 4878 \end{tabular} 4590 \end{minipage}4591 4879 \end{quote2} 4592 4880 For the prescribed head-files, \CFA implicitly wraps their includes in an ©extern "C"©; 4593 4881 hence, names in these include files are not mangled\index{mangling!name} (see~\VRef{s:Interoperability}). 4594 4882 All 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 \item4642 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 34648 \end{cfa}4649 \item4650 A separator does not appear before or after a character literal or variable.4651 \begin{cfa}4652 sout | '1' | '2' | '3' | endl;4653 1234654 \end{cfa}4655 \item4656 A separator does not appear before or after a null (empty) C string4657 \begin{cfa}4658 sout | 1 | "" | 2 | "" | 3 | endl;4659 1234660 \end{cfa}4661 which is a local mechanism to disable insertion of the separator character.4662 \item4663 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 ¥" | 74667 | "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 «104672 \end{cfa}4673 %$4674 \item4675 {\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} x4683 \end{cfa}}%4684 \item4685 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 x4691 \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 34699 \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 34705 \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 1234711 \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 234717 \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 34723 \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, $34731 \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 ¥" | 74743 | "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 line4748 sout | 1 | sepOff | 2 | 3 | endl; // turn off implicit separator temporarily4749 sout | sepDisable | 1 | 2 | 3 | endl; // turn off implicit separation, affects all subsequent prints4750 sout | 1 | sepOn | 2 | 3 | endl; // turn on implicit separator temporarily4751 sout | sepEnable | 1 | 2 | 3 | endl; // turn on implicit separation, affects all subsequent prints4752 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 %$4762 4883 4763 4884 -
src/libcfa/fstream
rdb0fa7c r547e9b7 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 21 15:57:24201713 // Update Count : 10 212 // Last Modified On : Mon May 15 18:11:09 2017 13 // Update Count : 104 14 14 // 15 15 … … 29 29 }; // ofstream 30 30 31 // private 31 32 _Bool sepPrt( ofstream * ); 32 void sepOn( ofstream * );33 void sepOff( ofstream * );34 33 void sepReset( ofstream * ); 35 34 void sepReset( ofstream *, _Bool ); 36 35 const char * sepGetCur( ofstream * ); 37 36 void sepSetCur( ofstream *, const char * ); 37 38 // public 39 void sepOn( ofstream * ); 40 void sepOff( ofstream * ); 41 _Bool sepDisable( ofstream * ); 42 _Bool sepEnable( ofstream * ); 43 38 44 const char * sepGet( ofstream * ); 39 45 void sepSet( ofstream *, const char * ); 40 46 const char * sepGetTuple( ofstream * ); 41 47 void sepSetTuple( ofstream *, const char * ); 42 _Bool sepDisable( ofstream * );43 _Bool sepEnable( ofstream * );44 48 45 49 int fail( ofstream * ); -
src/libcfa/fstream.c
rdb0fa7c r547e9b7 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Mar 23 08:20:41 201713 // Update Count : 2 2612 // Last Modified On : Mon May 15 18:11:11 2017 13 // Update Count : 234 14 14 // 15 15 … … 38 38 } 39 39 40 // private 40 41 _Bool sepPrt( ofstream * os ) { return os->sepOnOff; } 42 void sepReset( ofstream * os ) { os->sepOnOff = os->sepDefault; } 43 void sepReset( ofstream * os, _Bool reset ) { os->sepDefault = reset; os->sepOnOff = os->sepDefault; } 44 const char * sepGetCur( ofstream * os ) { return os->sepCur; } 45 void sepSetCur( ofstream * os, const char * sepCur ) { os->sepCur = sepCur; } 46 47 // public 41 48 void sepOn( ofstream * os ) { os->sepOnOff = 1; } 42 49 void 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 } // sepSet56 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 } // sepSet64 50 65 51 _Bool sepDisable( ofstream *os ) { … … 73 59 _Bool temp = os->sepDefault; 74 60 os->sepDefault = true; 75 sepReset( os );61 if ( os->sepOnOff ) sepReset( os ); // start of line ? 76 62 return temp; 77 63 } // sepEnable 64 65 const char * sepGet( ofstream * os ) { return os->separator; } 66 void 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 72 const char * sepGetTuple( ofstream * os ) { return os->tupleSeparator; } 73 void sepSetTuple( ofstream * os, const char * s ) { 74 assert( s ); 75 strncpy( os->tupleSeparator, s, separateSize - 1 ); 76 os->tupleSeparator[separateSize - 1] = '\0'; 77 } // sepSet 78 78 79 79 int fail( ofstream * os ) { -
src/libcfa/gmp
rdb0fa7c r547e9b7 10 10 // Created On : Tue Apr 19 08:43:43 2016 11 11 // 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 17 16 // https://gmplib.org/gmp-man-6.1.1.pdf 17 18 18 #include <gmp.h> // GNU multi-precise integers 19 // some code for operators "/" and "%" taken from g++ gmpxx.h20 }21 19 #include <fstream> // sout 22 20 … … 146 144 Int ?*=?( Int * lhs, unsigned long int rhs ) { return *lhs = *lhs * rhs; } 147 145 146 // some code for operators "/" and "%" taken from g++ gmpxx.h 148 147 Int ?/?( Int dividend, Int divisor ) { Int quotient; mpz_tdiv_q( quotient.mpz, dividend.mpz, divisor.mpz ); return quotient; } 149 148 Int ?/?( Int dividend, unsigned long int divisor ) { Int quotient; mpz_tdiv_q_ui( quotient.mpz, dividend.mpz, divisor ); return quotient; } -
src/libcfa/iostream
rdb0fa7c r547e9b7 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Mar 21 15:57:29201713 // Update Count : 10 412 // Last Modified On : Mon May 15 18:08:44 2017 13 // Update Count : 105 14 14 // 15 15 … … 20 20 21 21 trait ostream( dtype ostype ) { 22 // private 22 23 _Bool sepPrt( ostype * ); // return separator state (on/off) 23 void sepOn( ostype * ); // turn separator state on24 void sepOff( ostype * ); // turn separator state off25 24 void sepReset( ostype * ); // set separator state to default state 26 25 void sepReset( ostype *, _Bool ); // set separator and default state 27 26 const char * sepGetCur( ostype * ); // get current separator string 28 27 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 29 34 const char * sepGet( ostype * ); // get separator string 30 35 void sepSet( ostype *, const char * ); // set separator to string (15 character maximum) 31 36 const char * sepGetTuple( ostype * ); // get tuple separator string 32 37 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 state34 _Bool sepEnable( ostype * ); // set default state to on, and return previous state35 38 36 39 int fail( ostype * ); -
src/libcfa/rational
rdb0fa7c r547e9b7 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Sun May 14 16:49:13201715 // Update Count : 7814 // Last Modified On : Mon May 15 21:30:12 2017 15 // Update Count : 90 16 16 // 17 17 … … 128 128 129 129 // 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 );130 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 131 double widen( Rational(RationalImpl) r ); 132 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double );} ) 133 Rational(RationalImpl) narrow( double f, RationalImpl md ); 134 134 135 135 // I/O -
src/libcfa/rational.c
rdb0fa7c r547e9b7 10 10 // Created On : Wed Apr 6 17:54:28 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 14 17:25:19201713 // Update Count : 1 3112 // Last Modified On : Mon May 15 21:29:23 2017 13 // Update Count : 149 14 14 // 15 15 … … 190 190 // conversion 191 191 192 // forall ( otype RationalImpl | arithmetic( RationalImpl ))193 //double widen( Rational(RationalImpl) r ) {194 // return (double)r.numerator / (double)r.denominator;195 //} // widen196 197 // //http://www.ics.uci.edu/~eppstein/numth/frap.c198 // 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 fraction202 //} // if203 204 //// continued fraction coefficients205 // RationalImpl m00 = 1, m11 = 1, m01 = 0, m10 = 0;206 //RationalImpl ai, t;207 208 //// find terms until denom gets too big209 //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 zero220 // f = 1 / (f - (double)t);221 //if ( f > (double)0x7FFFFFFF ) break; // representation failure222 // } 223 //return (Rational(RationalImpl)){ m00, m10 };224 //} // narrow192 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); } ) 193 double 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 198 forall ( otype RationalImpl | arithmetic( RationalImpl ) | { double convert( RationalImpl ); RationalImpl convert( double ); } ) 199 Rational(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 225 225 226 226 -
src/tests/.expect/rational.txt
rdb0fa7c r547e9b7 17 17 3/1 18 18 4/3 19 conversion 20 0.75 21 0.142857142857143 22 3.14159292035398 23 3/4 24 1/7 25 355/113 19 26 decompose 20 27 more tests -
src/tests/rational.c
rdb0fa7c r547e9b7 10 10 // Created On : Mon Mar 28 08:43:12 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun May 14 18:10:28201713 // Update Count : 5712 // Last Modified On : Mon May 15 21:32:22 2017 13 // Update Count : 64 14 14 // 15 15 … … 23 23 void ?{}( int * this, zero_t ) { *this = 0; } 24 24 void ?{}( int * this, one_t ) { *this = 1; } 25 double convert( int i ) { return (double)i; } 26 int convert( double d ) { return (int)d; } 25 27 26 28 int main() { … … 57 59 sout | a / b | endl; 58 60 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; 69 71 70 72 sout | "decompose" | endl;
Note: See TracChangeset
for help on using the changeset viewer.