Changes in / [9ef9644:a556492]


Ignore:
Files:
2 added
4 deleted
31 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile

    r9ef9644 ra556492  
    161161                Tools.BuildStage('Test: full', Settings.RunAllTests) {
    162162                        dir (BuildDir) {
    163                                         jopt = ""
    164                                         if( Settings.Architecture.node == 'x86' ) {
    165                                                 jopt = "-j2"
    166                                         }
    167163                                        //Run the tests from the tests directory
    168                                         sh """make ${jopt} --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
    169                                         sh """make ${jopt} --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no  archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
     164                                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=yes archiveerrors=${BuildDir}/tests/crashes/full-debug"""
     165                                        sh """make --no-print-directory -C tests timeouts="--timeout=600 --global-timeout=14400" all-tests debug=no  archiveerrors=${BuildDir}/tests/crashes/full-nodebug"""
    170166                        }
    171167                }
  • benchmark/io/http/Makefile.am

    r9ef9644 ra556492  
    5050.dummy_hackxx.cpp:
    5151        @echo "int bar() { return 0; }" > ${@}
    52 
    53 # add dependency of cfa files
    54 nodist_httpforall_OBJECTS = $(addsuffix .o, $(basename $(filter %.cfa,$(nodist_httpforall_SOURCES))))
    55 $(nodist_httpforall_OBJECTS) : @CFACC@ @CFACPP@
    56 
    57 # .deps inclusion is not done automatically by automake for new languages
    58 nodist_httpforall_DEPENDS = $(join \
    59         $(addsuffix $(DEPDIR)/ , $(dir $(nodist_httpforall_OBJECTS) ) ), \
    60         $(notdir ${nodist_httpforall_OBJECTS:.o=.Po}) \
    61 )
    62 
    63 -include $(nodist_httpforall_DEPENDS)
    64 
    65 list_libdeps:
    66         echo "objects: " $(nodist_httpforall_OBJECTS)
    67         echo "depends: " $(nodist_httpforall_DEPENDS)
  • doc/user/user.tex

    r9ef9644 ra556492  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Feb 12 17:04:03 2022
    14 %% Update Count     : 5376
     13%% Last Modified On : Sun Oct 10 12:45:00 2021
     14%% Update Count     : 5095
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
    1717% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
    1818
    19 \documentclass[twoside]{article}
     19\documentclass[twoside,11pt]{article}
    2020
    2121%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     
    4040% blue highlighting ß...ß (sharp s symbol) emacs: C-q M-_
    4141% green highlighting ¢...¢ (cent symbol) emacs: C-q M-"
    42 % LaTex escape ...§ (section symbol) emacs: C-q M-'
     42% LaTex escape §...§ (section symbol) emacs: C-q M-'
    4343% keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
    4444% math escape $...$ (dollar symbol)
     
    8585\newcommand{\B}[1]{{\Textbf[blue]{#1}}}
    8686\newcommand{\G}[1]{{\Textbf[OliveGreen]{#1}}}
    87 \newcommand{\Sp}{\R{\textvisiblespace}}
    8887\newcommand{\KWC}{K-W C\xspace}
    8988
     
    157156One of the main design philosophies of \CFA is to ``\Index{describe not prescribe}'', which means \CFA tries to provide a pathway from low-level C programming to high-level \CFA programming, but it does not force programmers to ``do the right thing''.
    158157Programmers can cautiously add \CFA extensions to their C programs in any order and at any time to incrementally move towards safer, higher-level programming.
    159 A programmer is always free to reach back to C from \CFA, for any reason, and in many cases, new \CFA features can be locally switched back to their C counterpart.
    160 There is no notion or requirement for \emph{rewriting} a legacy C program to \CFA;
     158A programmer is always free to reach back to C from \CFA, for any reason, and in many cases, new \CFA features can be locally switched back to there C counterpart.
     159There is no notion or requirement for \emph{rewriting} a legacy C program in \CFA;
    161160instead, a programmer evolves a legacy program into \CFA by incrementally incorporating \CFA features.
    162161As well, new programs can be written in \CFA using a combination of C and \CFA features.
     
    164163
    165164\Index*[C++]{\CC{}}~\cite{c++:v1} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C.
    166 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that are difficult to update, and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
     165However, \CC currently has the disadvantages of a strong object-oriented bias, 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.
    167166In contrast, \CFA has 30 years of hindsight and a clean starting point.
    168167
    169168Like \Index*[C++]{\CC{}}, there may be both old and new ways to achieve the same effect.
    170169For example, the following programs compare the C, \CFA, and \CC I/O mechanisms, where the programs output the same result.
    171 \begin{flushleft}
     170\begin{center}
    172171\begin{tabular}{@{}l@{\hspace{1em}}l@{\hspace{1em}}l@{}}
    173 \multicolumn{1}{@{}c@{\hspace{1em}}}{\textbf{C}}        & \multicolumn{1}{c}{\textbf{\CFA}}     & \multicolumn{1}{c@{}}{\textbf{\CC}}   \\
    174 \begin{cfa}[tabsize=3]
     172\multicolumn{1}{c@{\hspace{1em}}}{\textbf{C}}   & \multicolumn{1}{c}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{\CC}}      \\
     173\begin{cfa}
    175174#include <stdio.h>$\indexc{stdio.h}$
    176175
     
    181180\end{cfa}
    182181&
    183 \begin{cfa}[tabsize=3]
     182\begin{cfa}
    184183#include <fstream>$\indexc{fstream}$
    185184
     
    190189\end{cfa}
    191190&
    192 \begin{cfa}[tabsize=3]
     191\begin{cfa}
    193192#include <iostream>$\indexc{iostream}$
    194193using namespace std;
    195194int main() {
    196195        int x = 0, y = 1, z = 2;
    197         ®cout << x << ' ' << y << ' ' << z << endl;®
     196        ®cout<<x<<" "<<y<<" "<<z<<endl;®
    198197}
    199198\end{cfa}
    200199\end{tabular}
    201 \end{flushleft}
     200\end{center}
    202201While \CFA I/O \see{\VRef{s:StreamIOLibrary}} looks similar to \Index*[C++]{\CC{}}, there are important differences, such as automatic spacing between variables and an implicit newline at the end of the expression list, similar to \Index*{Python}~\cite{Python}.
    203202
     
    239238however, it largely extended the C language, and did not address many of C's existing problems.\footnote{%
    240239Two important existing problems addressed were changing the type of character literals from ©int© to ©char© and enumerator from ©int© to the type of its enumerators.}
    241 \Index*{Fortran}~\cite{Fortran08}, \Index*{Cobol}~\cite{Cobol14}, and \Index*{Ada}~\cite{Ada12} are examples of programming languages that took an evolutionary approach, where modern language-features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language.
     240\Index*{Fortran}~\cite{Fortran08}, \Index*{Ada}~\cite{Ada12}, and \Index*{Cobol}~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language-features (\eg objects, concurrency) are added and problems fixed within the framework of the existing language.
    242241\Index*{Java}~\cite{Java8}, \Index*{Go}~\cite{Go}, \Index*{Rust}~\cite{Rust} and \Index*{D}~\cite{D} are examples of the revolutionary approach for modernizing C/\CC, resulting in a new language rather than an extension of the descendent.
    243242These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management or garbage collection.
     
    334333long double _Complex ®abs®( long double _Complex );
    335334\end{cfa}
    336 The problem is a \Index{name clash} between the C name ©abs© and the \CFA names ©abs©, resulting in two name linkages\index{C linkage}: ©extern "C"© and ©extern "Cforall"© (default).
     335The problem is \Index{name clash} between the C name ©abs© and the \CFA names ©abs©, resulting in two name linkages\index{C linkage}: ©extern "C"© and ©extern "Cforall"© (default).
    337336Overloaded names must use \newterm{name mangling}\index{mangling!name} to create unique names that are different from unmangled C names.
    338337Hence, there is the same need as in \CC to know if a name is a C or \CFA name, so it can be correctly formed.
     
    378377The program is linked with the debugging version of the runtime system.
    379378The debug version performs runtime checks to aid the debugging phase of a \CFA program, but can substantially slow program execution.
    380 The runtime checks should only be removed after a program is completely debugged.
     379The runtime checks should only be removed after the program is completely debugged.
    381380\textbf{This option is the default.}
    382381
     
    453452cfa $test$.cfa -XCFA -P -XCFA parse -XCFA -n # show program parse without prelude
    454453\end{lstlisting}
    455 Alternatively, multiple flages can be specified separated with commas and \emph{without} spaces.
    456 \begin{lstlisting}[language=sh,{moredelim=**[is][\protect\color{red}]{®}{®}}]
    457 cfa $test$.cfa -XCFA®,®-Pparse®,®-n # show program parse without prelude
    458 \end{lstlisting}
    459454\begin{description}[topsep=5pt,itemsep=0pt,parsep=0pt]
    460455\item
     
    538533double ®``®forall = 3.5;
    539534\end{cfa}
    540 Existing C programs with keyword clashes can be converted by prefixing the keyword identifiers with double backquotes, and eventually the identifier name can be changed to a non-keyword name.
     535
     536Existing C programs with keyword clashes can be converted by enclosing keyword identifiers in backquotes, and eventually the identifier name can be changed to a non-keyword name.
    541537\VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files \see{\VRef{s:StandardHeaders}} can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©.
    542538Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is a seamless programming-experience.
     
    631627\subsection{\texorpdfstring{\LstKeywordStyle{if} / \LstKeywordStyle{while} Statement}{if / while Statement}}
    632628
    633 The \Indexc{if}/\Indexc{while} expression allows declarations, similar to \Indexc{for} declaration expression.\footnote{
    634 Declarations in the \Indexc{do}-©while© condition are not useful because they appear after the loop body.}
     629The ©if©/©while© expression allows declarations, similar to ©for© declaration expression.\footnote{
     630Declarations in the ©do©-©while© condition are not useful because they appear after the loop body.}
    635631\begin{cfa}
    636632if ( ®int x = f()® ) ... $\C{// x != 0}$
     
    644640while ( ®struct S { int i; } x = { f() }; x.i < 4® ) ... $\C{// relational expression}$
    645641\end{cfa}
    646 Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the ©if©/©while© expression, and the results are combined using the logical \Indexc{&&} operator.
    647 The scope of the declaration(s) is local to the ©if©/©while© statement, \ie in both \emph{then} and \emph{else} clauses for ©if©, and loop body for ©while©.
     642Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the ©if©/©while© expression, and the results are combined using the logical ©&&© operator.
     643The scope of the declaration(s) is local to the ©if© statement but exist within both the \emph{then} and \emph{else} clauses.
    648644\CC only provides a single declaration always compared ©!=© to 0.
    649645
     
    653649\label{s:caseClause}
    654650
    655 C restricts the \Indexc{case} clause of a \Indexc{switch} statement to a single value.
     651C restricts the ©case© clause of a ©switch© statement to a single value.
    656652For multiple ©case© clauses associated with the same statement, it is necessary to have multiple ©case© clauses rather than multiple values.
    657 Requiring a ©case© clause for each value is not in the spirit of brevity normally associated with C.
    658 Therefore, the ©case© clause is extended with a list of values.
     653Requiring a ©case© clause for each value does not seem to be in the spirit of brevity normally associated with C.
     654Therefore, the ©case© clause is extended with a list of values, as in:
    659655\begin{cquote}
    660656\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
     
    707703\subsection{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}
    708704
    709 C allows a number of questionable forms for the \Indexc{switch} statement:
     705C allows a number of questionable forms for the ©switch© statement:
    710706\begin{enumerate}
    711707\item
    712 By default, the end of a \Indexc{case} clause\footnote{
     708By default, the end of a ©case© clause\footnote{
    713709In this section, the term \emph{case clause} refers to either a ©case© or ©default© clause.}
    714710\emph{falls through} to the next ©case© clause in the ©switch© statement;
    715 to exit a ©switch© statement from a ©case© clause requires explicitly terminating the clause with a transfer statement, most commonly \Indexc{break}:
     711to exit a ©switch© statement from a ©case© clause requires explicitly terminating the clause with a transfer statement, most commonly ©break©:
    716712\begin{cfa}
    717713switch ( i ) {
    718714  case 1:
    719715        ...
    720         $\R{\LstCommentStyle{// fall-through}}$
     716        // fall-through
    721717  case 2:
    722718        ...
    723         ®break;®        // exit switch statement
     719        break;  // exit switch statement
    724720}
    725721\end{cfa}
     
    767763}
    768764\end{cfa}
    769 This situation is better handled by a list of case values \see{\VRef{s:caseClause}}.
     765This situation better handled without fall-through by allowing a list of case values \see{\VRef{s:caseClause}}.
    770766While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from most programming languages with a ©switch© statement.
    771767Hence, default fall-through semantics results in a large number of programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through.
     
    781777                ...
    782778        } // if
     779  case 2:
     780        while ( j < 5 ) {
     781                ...
     782          ®case 3:®             // transfer into "while" statement
     783                ...
     784        } // while
     785} // switch
    783786\end{cfa}
    784787This usage branches into control structures, which is known to cause both comprehension and technical difficulties.
     
    786789The technical problem results from the inability to ensure declaration and initialization of variables when blocks are not entered at the beginning.
    787790There are few arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it.
    788 
    789 This C idiom is known as ``\Index*{Duff's device}''~\cite{Duff83}, from this example:
     791Nevertheless, C does have an idiom where this capability is used, known as ``\Index*{Duff's device}''~\cite{Duff83}:
    790792\begin{cfa}
    791793register int n = (count + 7) / 8;
     
    856858still works.
    857859Nevertheless, reversing the default action would have a non-trivial effect on case actions that compound, such as the above example of processing shell arguments.
    858 Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called \Indexc{choose}, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword \Indexc{fallthrough}/\Indexc{fallthru}, \eg:
     860Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, \eg:
    859861\begin{cfa}
    860862®choose® ( i ) {
     
    883885Therefore, no change is made for this issue.
    884886\item
    885 Dealing with unreachable code in a ©switch©/©choose© body is solved by restricting declarations and initialization to the start of statement body, which is executed \emph{before} the transfer to the appropriate ©case© clause\footnote{
     887Dealing with unreachable code in a ©switch©/©choose© body is solved by restricting declarations and associated initialization to the start of statement body, which is executed \emph{before} the transfer to the appropriate ©case© clause\footnote{
    886888Essentially, these declarations are hoisted before the ©switch©/©choose© statement and both declarations and statement are surrounded by a compound statement.} and precluding statements before the first ©case© clause.
    887889Further declarations at the same nesting level as the statement body are disallowed to ensure every transfer into the body is sound.
     
    906908\subsection{Non-terminating and Labelled \texorpdfstring{\LstKeywordStyle{fallthrough}}{Non-terminating and Labelled fallthrough}}
    907909
    908 The \Indexc{fallthrough} clause may be non-terminating within a \Indexc{case} clause or have a target label to common code from multiple case clauses.
     910The ©fallthrough© clause may be non-terminating within a ©case© clause or have a target label to common code from multiple case clauses.
    909911\begin{center}
    910912\begin{tabular}{@{}lll@{}}
     
    958960\end{tabular}
    959961\end{center}
    960 The target label must be below the \Indexc{fallthrough} and may not be nested in a control structure, and
    961 the target label must be at the same or higher level as the containing \Indexc{case} clause and located at
    962 the same level as a ©case© clause; the target label may be case \Indexc{default}, but only associated
    963 with the current \Indexc{switch}/\Indexc{choose} statement.
     962The target label must be below the ©fallthrough© and may not be nested in a control structure, and
     963the target label must be at the same or higher level as the containing ©case© clause and located at
     964the same level as a ©case© clause; the target label may be case ©default©, but only associated
     965with the current ©switch©/©choose© statement.
    964966
    965967\begin{figure}
     
    10741076Looping a fixed number of times, possibly with a loop index, occurs frequently.
    10751077\CFA condenses simply looping to facilitate coding speed and safety.
    1076 The \Indexc{for}, \Indexc{while}, and \Indexc{do} loop-control is augmented as follows \see{examples in \VRef[Figure]{f:LoopControlExamples}}:
     1078The ©for©/©while©/©do-while© loop-control is augmented as follows \see{examples in \VRef[Figure]{f:LoopControlExamples}}:
    10771079\begin{itemize}[itemsep=0pt]
    10781080\item
     
    11431145\subsection{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break} Statement}{Labelled continue / break Statement}}
    11441146
    1145 C \Indexc{continue} and \Indexc{break} statements, for altering control flow, are restricted to one level of nesting for a particular control structure.
     1147C ©continue© and ©break© statements, for altering control flow, are restricted to one level of nesting for a particular control structure.
    11461148This restriction forces programmers to use \Indexc{goto} to achieve the equivalent control-flow for more than one level of nesting.
    11471149To prevent having to switch to the ©goto©, \CFA extends the \Indexc{continue}\index{continue@©continue©!labelled}\index{labelled!continue@©continue©} and \Indexc{break}\index{break@©break©!labelled}\index{labelled!break@©break©} with a target label to support static multi-level exit\index{multi-level exit}\index{static multi-level exit}~\cite{Buhr85}, as in Java.
    1148 For both ©continue© and ©break©, the target label must be directly associated with a \Indexc{for}, \Indexc{while} or \Indexc{do} statement;
    1149 for ©break©, the target label can also be associated with a \Indexc{switch}, \Indexc{if} or compound (©{}©) statement.
     1150For both ©continue© and ©break©, the target label must be directly associated with a ©for©, ©while© or ©do© statement;
     1151for ©break©, the target label can also be associated with a ©switch©, ©if© or compound (©{}©) statement.
    11501152\VRef[Figure]{f:MultiLevelExit} shows a comparison between labelled ©continue© and ©break© and the corresponding C equivalent using ©goto© and labels.
    11511153The innermost loop has 8 exit points, which cause continuation or termination of one or more of the 7 \Index{nested control-structure}s.
     
    12221224\end{figure}
    12231225
    1224 Both labelled \Indexc{continue} and \Indexc{break} are a \Indexc{goto}\index{goto@©goto©!restricted} restricted in the following ways:
     1226Both labelled ©continue© and ©break© are a ©goto©\index{goto@©goto©!restricted} restricted in the following ways:
    12251227\begin{itemize}
    12261228\item
     
    12381240
    12391241
    1240 \subsection{\texorpdfstring{Extended \LstKeywordStyle{else}}{Extended else}}
    1241 \label{s:ExtendedElse}
    1242 \index{extended ©else©}
    1243 
    1244 The ©if© statement has an optional ©else© clause executed if the conditional is false.
    1245 This concept is extended to the \Indexc{while}, \Indexc{for}, and \Indexc{do} looping constructs (like Python).
    1246 Hence, if the loop conditional becomes false, looping stops and the corresponding ©else© clause is executed, if present.
    1247 
    1248 The following example is a linear search for the key 3 in an array, where finding the key is handled with a ©break© and not finding with the ©else© clause on the loop construct.
    1249 \begin{cquote}
    1250 \begin{cfa}
    1251 int a[10];
    1252 \end{cfa}
    1253 \begin{tabular}{@{}lll@{}}
    1254 \begin{cfa}
    1255 
    1256 while ( int i = 0; i < 10 ) {
    1257   if ( a[i] == 3 ) break; // found
    1258         i += 1;
    1259 } ®else® { // i == 10
    1260         sout | "not found";
    1261 }
    1262 \end{cfa}
    1263 &
    1264 \begin{cfa}
    1265 
    1266 for ( i; 10 ) {
    1267   if ( a[i] == 3 ) break; // found
    1268 
    1269 } ®else® { // i == 10
    1270         sout | "not found";
    1271 }
    1272 \end{cfa}
    1273 &
    1274 \begin{cfa}
    1275 int i = 0;
    1276 do {
    1277   if ( a[i] == 3 ) break; // found
    1278         i += 1;
    1279 } while( i < 10 ) ®else® { // i == 10
    1280         sout | "not found";
    1281 }
    1282 \end{cfa}
    1283 \end{tabular}
    1284 \end{cquote}
    1285 Note, \Index{dangling else} now occurs with \Indexc{if}, \Indexc{while}, \Indexc{for}, \Indexc{do}, and \Indexc{waitfor}.
    1286 
    1287 
    12881242%\subsection{\texorpdfstring{\protect\lstinline{with} Statement}{with Statement}}
    12891243\subsection{\texorpdfstring{\LstKeywordStyle{with} Statement}{with Statement}}
     
    13121266Therefore, reducing aggregate qualification is a useful language design goal.
    13131267
    1314 C partially addresses the problem by eliminating qualification for enumerated types and unnamed \emph{nested} aggregates, which open their scope into the containing aggregate.
     1268C allows unnamed nested aggregates that open their scope into the containing aggregate.
    13151269This feature is used to group fields for attributes and/or with ©union© aggregates.
    13161270\begin{cfa}
    13171271struct S {
    1318         struct $\R{\LstCommentStyle{/* unnamed */}}$ { int g,  h; } __attribute__(( aligned(64) ));
     1272        struct { int g,  h; } __attribute__(( aligned(64) ));
    13191273        int tag;
    1320         union $\R{\LstCommentStyle{/* unnamed */}}$ {
     1274        union {
    13211275                struct { char c1,  c2; } __attribute__(( aligned(128) ));
    13221276                struct { int i1,  i2; };
    13231277                struct { double d1,  d2; };
    13241278        };
    1325 } s;
    1326 enum { R, G, B };
    1327 s.g; s.h;   s.tag = R;   s.c1; s.c2;   s.i1 = G; s.i2 = B;   s.d1; s.d2;
     1279};
     1280s.g; s.h; s.tag; s.c1; s.c2; s.i1; s.i2; s.d1; s.d2;
    13281281\end{cfa}
    13291282
     
    13701323\end{cfa}
    13711324where qualification is only necessary to disambiguate the shadowed variable ©i©.
    1372 In detail, the ©with© statement may form a function body or be nested within a function body.
    1373 
     1325
     1326In detail, the ©with© statement may appear as the body of a function or nested within a function body.
    13741327The ©with© clause takes a list of expressions, where each expression provides an aggregate type and object.
    13751328(Enumerations are already opened.)
     
    13801333\end{cfa}
    13811334The expression object is the implicit qualifier for the open structure-fields.
    1382 
    13831335\CFA's ability to overload variables \see{\VRef{s:VariableOverload}} and use the left-side of assignment in type resolution means most fields with the same name but different types are automatically disambiguated, eliminating qualification.
    13841336All expressions in the expression list are open in parallel within the compound statement.
     
    14101362\end{cfa}
    14111363A cast or qualification can be used to disambiguate variables within a ©with© \emph{statement}.
    1412 A cast can also be used to disambiguate among overload variables in a ©with© \emph{expression}:
     1364A cast can be used to disambiguate among overload variables in a ©with© \emph{expression}:
    14131365\begin{cfa}
    14141366with ( w ) { ... }                                                      $\C{// ambiguous, same name and no context}$
     
    14191371Finally, there is an interesting problem between parameters and the function-body ©with©, \eg:
    14201372\begin{cfa}
    1421 void f( S & s, char c ) with ( s ) {
    1422         ®s.c = c;®  i = 3;  d = 5.5;                    $\C{// initialize fields}$
    1423 }
    1424 \end{cfa}
    1425 Here, the assignment ©s.c = c© means ©s.c = s.c©, which is meaningless, and there is no mechanism to qualify the parameter ©c©, making the assignment impossible using the function-body ©with©.
    1426 To solve this problem, parameters \emph{not} explicitly opened are treated like an initialized aggregate:
    1427 \begin{cfa}
    1428 struct Params {                                                         $\C{// s explicitly opened so S \& s elided}$
    1429         char c;
     1373void ?{}( S & s, int i ) with ( s ) { $\C{// constructor}$
     1374        ®s.i = i;®  j = 3;  m = 5.5; $\C{// initialize fields}$
     1375}
     1376\end{cfa}
     1377Here, the assignment ©s.i = i© means ©s.i = s.i©, which is meaningless, and there is no mechanism to qualify the parameter ©i©, making the assignment impossible using the function-body ©with©.
     1378To solve this problem, parameters are treated like an initialized aggregate:
     1379\begin{cfa}
     1380struct Params {
     1381        S & s;
     1382        int i;
    14301383} params;
    14311384\end{cfa}
    14321385and implicitly opened \emph{after} a function-body open, to give them higher priority:
    14331386\begin{cfa}
    1434 void f( S & s, char ®c® ) with ( s ) ®with( $\emph{\R{params}}$ )® { // syntax not allowed, illustration only
    1435         s.c = ®c;®  i = 3;  d = 5.5;
     1387void ?{}( S & s, int ®i® ) with ( s ) ®with( $\emph{\R{params}}$ )® { // syntax not allowed, illustration only
     1388        s.i = ®i®; j = 3; m = 5.5;
    14361389}
    14371390\end{cfa}
    14381391This implicit semantic matches with programmer expectation.
     1392
    14391393
    14401394
     
    34433397This requirement is the same as for comma expressions in argument lists.
    34443398
    3445 Type qualifiers, \ie ©const© and ©volatile©, may modify a tuple type.
    3446 The meaning is to distribute the qualifier across all of the types in the tuple, \eg:
     3399Type qualifiers, \ie const and volatile, may modify a tuple type.
     3400The meaning is the same as for a type qualifier modifying an aggregate type [Int99, x 6.5.2.3(7),x 6.7.3(11)], \ie the qualifier is distributed across all of the types in the tuple, \eg:
    34473401\begin{cfa}
    34483402const volatile [ int, float, const int ] x;
     
    36433597Stream ©exit© implicitly returns ©EXIT_FAILURE© to the shell.
    36443598\begin{cfa}
    3645 ®exit®   | "x (" | x | ") negative value.";   // terminate and return EXIT_FAILURE to shell
    3646 ®abort® | "x (" | x | ") negative value.";   // terminate and generate stack trace and core file
     3599®exit®   | "x (" | x | ") negative value."; // terminate and return EXIT_FAILURE to shell
     3600®abort® | "x (" | x | ") negative value."; // terminate and generate stack trace and core file
    36473601\end{cfa}
    36483602Note, \CFA stream variables ©stdin©, ©stdout©, ©stderr©, ©exit©, and ©abort© overload C variables ©stdin©, ©stdout©, ©stderr©, and functions ©exit© and ©abort©, respectively.
     
    43134267        sout | '1' | '2' | '3';
    43144268        sout | 1 | "" | 2 | "" | 3;
    4315         sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x Â¥"
    4316                 | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10;
     4269        sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x =" | 4 | "x $" | 5 | "x £" | 6 | "x ¥"
     4270                | 7 | "x ¡" | 8 | "x ¿" | 9 | "x «" | 10;
    43174271        sout | 1 | ", x" | 2 | ". x" | 3 | "; x" | 4 | "! x" | 5 | "? x" | 6 | "% x"
    4318                 | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";
     4272                | 7 | "¢ x" | 8 | "» x" | 9 | ") x" | 10 | "] x" | 11 | "} x";
    43194273        sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x:" | 4 | ":x " | 5 | " x\t" | 6 | "\tx";
    43204274        sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4;
     
    44924446The common usage is the short form of the mutex statement\index{ostream@©ostream©!mutex@©mutex©} to lock a stream during a single cascaded I/O expression, \eg:
    44934447\begin{cfa}
    4494 $\emph{thread\(_1\)}$ : ®mutex( sout )® sout | "abc " | "def ";
    4495 $\emph{thread\(_2\)}$ : ®mutex( sout )® sout | "uvw " | "xyz ";
     4448$\emph{thread\(_1\)}$ : ®mutex()® sout | "abc " | "def ";
     4449$\emph{thread\(_2\)}$ : ®mutex()® sout | "uvw " | "xyz ";
    44964450\end{cfa}
    44974451Now, the order of the thread execution is still non-deterministic, but the output is constrained to two possible lines in either order.
     
    45164470®mutex( sout )® {
    45174471        sout | 1;
    4518         ®mutex( sout ) sout® | 2 | 3;                           $\C{// unnecessary, but ok because of recursive lock}$
     4472        ®mutex() sout® | 2 | 3;                         $\C{// unnecessary, but ok because of recursive lock}$
    45194473        sout | 4;
    45204474} // implicitly release sout lock
     
    45284482        int x, y, z, w;
    45294483        sin | x;
    4530         ®mutex( sin )® sin | y | z;                                     $\C{// unnecessary, but ok because of recursive lock}$
     4484        ®mutex() sin® | y | z;                          $\C{// unnecessary, but ok because of recursive lock}$
    45314485        sin | w;
    45324486} // implicitly release sin lock
     
    45374491\Textbf{WARNING:} The general problem of \Index{nested locking} can occur if routines are called in an I/O sequence that block, \eg:
    45384492\begin{cfa}
    4539 ®mutex( sout )® sout | "data:" | rtn( mon );    $\C{// mutex call on monitor}$
     4493®mutex() sout® | "data:" | rtn( mon );  $\C{// mutex call on monitor}$
    45404494\end{cfa}
    45414495If the thread executing the I/O expression blocks in the monitor with the ©sout© lock, other threads writing to ©sout© also block until the thread holding the lock is unblocked and releases it.
     
    45444498\begin{cfa}
    45454499int ®data® = rtn( mon );
    4546 mutex( sout ) sout | "data:" | ®data®;
    4547 \end{cfa}
    4548 
    4549 
    4550 \subsection{Locale}
    4551 \index{stream!locale}
    4552 \index{locale!stream}
    4553 
    4554 Cultures use different syntax, called a \newterm{locale}, for printing numbers so they are easier to read, \eg:
    4555 \begin{cfa}
    4556 12®,®345®.®123          $\C[1.25in]{// comma separator, period decimal-point}$
    4557 12®.®345®,®123          $\C{// period separator, comma decimal-point}$
    4558 12$\Sp$345®,®123®.®     $\C{// space separator, comma decimal-point, period terminator}\CRT$
    4559 \end{cfa}
    4560 A locale is selected with function ©setlocale©, and the corresponding locale package \emph{must} be installed on the underlying system;
    4561 ©setlocale© returns ©0p© if the requested locale is unavailable.
    4562 Furthermore, a locale covers the syntax for many cultural items, \eg address, measurement, money, etc.
    4563 This discussion applies to item ©LC_NUMERIC© for formatting non-monetary integral and floating-point values.
    4564 \VRef[Figure]{f:StreamLocale} shows selecting different cultural syntax, which may be associated with one or more countries.
    4565 
    4566 \begin{figure}
    4567 \begin{cfa}
    4568 #include <fstream.hfa>
    4569 #include <locale.h>                                                     $\C{// setlocale}$
    4570 #include <stdlib.h>                                                     $\C{// getenv}$
    4571 
    4572 int main() {
    4573         void print() {
    4574                 sout | 12 | 123 | 1234 | 12345 | 123456 | 1234567;
    4575                 sout | 12. | 123.1 | 1234.12 | 12345.123 | 123456.1234 | 1234567.12345;
    4576                 sout | nl;
    4577         }
    4578         sout | "Default locale off";
    4579         print();
    4580         sout | "Locale on" | ®setlocale( LC_NUMERIC, getenv( "LANG" ) )®;  // enable local locale
    4581         print();
    4582         sout | "German" | ®setlocale( LC_NUMERIC, "de_DE.UTF-8" )®;  // enable German locale
    4583         print();
    4584         sout | "Ukraine" | ®setlocale( LC_NUMERIC, "uk_UA.utf8" )®;  // enable Ukraine locale
    4585         print();
    4586         sout | "Default locale off" | ®setlocale( LC_NUMERIC, "C" )®;  // disable locale
    4587         print();
    4588 }
    4589 
    4590 Default locale off
    4591 12 123 1234 12345 123456 1234567
    4592 12. 123.1 1234.12 12345.123 123456.1234 1234567.12345
    4593 
    4594 Locale on en_US.UTF-8
    4595 12 123 1®,®234 12®,®345 123®,®456 1®,®234®,®567
    4596 12®.® 123®.®1 1®,®234®.®12 12®,®345®.®123 123®,®456®.®1234 1®,®234®,®567®.®12345
    4597 
    4598 German de_DE.UTF-8
    4599 12 123 1®.®234 12®.®345 123®.®456 1®.®234®.®567
    4600 12®.® 123®,®1®.® 1®.®234®,®12 12®.®345®,®123 123®.®456®,®1234 1®.®234®.®567®,®12345
    4601 
    4602 Ukraine uk_UA.utf8
    4603 12 123 1 234 12 345 123 456 1 234 567
    4604 12®.® 123®,®1®.® 1$\Sp$234®,®12®.® 12$\Sp$ 345®,®123®.® 123$\Sp$ 456®,®1234®.® 1$\Sp$ 234$\Sp$567®,®12345®.®
    4605 
    4606 Default locale off C
    4607 12 123 1234 12345 123456 1234567
    4608 12. 123.1 1234.12 12345.123 123456.1234 1234567.12345
    4609 \end{cfa}
    4610 \caption{Stream Locale}
    4611 \label{f:StreamLocale}
    4612 \end{figure}
     4500mutex() sout | "data:" | ®data®;
     4501\end{cfa}
    46134502
    46144503
     
    46664555\end{figure}
    46674556
    4668 
    46694557\begin{comment}
    46704558\section{Types}
     
    47494637
    47504638
    4751 \section{Structures}
     4639\subsection{Structures}
    47524640
    47534641Structures in \CFA are basically the same as structures in C.
     
    53825270\subsection{Coroutine}
    53835271
    5384 \Index{Coroutines} are the precursor to threads.
     5272\Index{Coroutines} are the precursor to tasks.
    53855273\VRef[Figure]{f:FibonacciCoroutine} shows a coroutine that computes the \Index*{Fibonacci} numbers.
    53865274
     
    54845372
    54855373
    5486 \subsection{Threads}
     5374\subsection{Tasks}
    54875375
    54885376\CFA also provides a simple mechanism for creating and utilizing user level threads.
    5489 A thread provides mutual exclusion like a monitor, and also has its own execution state and a thread of control.
    5490 Similar to a monitor, a thread is defined like a structure:
     5377A task provides mutual exclusion like a monitor, and also has its own execution state and a thread of control.
     5378Similar to a monitor, a task is defined like a structure:
    54915379
    54925380\begin{figure}
     
    55325420}
    55335421\end{cfa}
    5534 \caption{Simple Threads}
    5535 \label{f:SimpleThreads}
     5422\caption{Simple Tasks}
     5423\label{f:SimpleTasks}
    55365424\end{figure}
    55375425
     
    69006788In \CFA, there are ambiguous cases with dereference and operator identifiers, \eg ©int *?*?()©, where the string ©*?*?© can be interpreted as:
    69016789\begin{cfa}
    6902 *?$\Sp$*? $\C{// dereference operator, dereference operator}$
    6903 *$\Sp$?*? $\C{// dereference, multiplication operator}$
     6790*?$\R{\textvisiblespace}$*? $\C{// dereference operator, dereference operator}$
     6791*$\R{\textvisiblespace}$?*? $\C{// dereference, multiplication operator}$
    69046792\end{cfa}
    69056793By default, the first interpretation is selected, which does not yield a meaningful parse.
     
    69256813Therefore, it is necessary to disambiguate these cases with a space:
    69266814\begin{cfa}
    6927 i++$\Sp$? i : 0;
    6928 i?$\Sp$++i : 0;
     6815i++$\R{\textvisiblespace}$? i : 0;
     6816i?$\R{\textvisiblespace}$++i : 0;
    69296817\end{cfa}
    69306818
     
    75427430char random( void );$\indexc{random}$
    75437431char random( char u ); $\C{// [0,u)}$
    7544 char random( char l, char u ); $\C{// [l,u]}$
     7432char random( char l, char u ); $\C{// [l,u)}$
    75457433int random( void );
    75467434int random( int u ); $\C{// [0,u)}$
    7547 int random( int l, int u ); $\C{// [l,u]}$
     7435int random( int l, int u ); $\C{// [l,u)}$
    75487436unsigned int random( void );
    75497437unsigned int random( unsigned int u ); $\C{// [0,u)}$
    7550 unsigned int random( unsigned int l, unsigned int u ); $\C{// [l,u]}$
     7438unsigned int random( unsigned int l, unsigned int u ); $\C{// [l,u)}$
    75517439long int random( void );
    75527440long int random( long int u ); $\C{// [0,u)}$
    7553 long int random( long int l, long int u ); $\C{// [l,u]}$
     7441long int random( long int l, long int u ); $\C{// [l,u)}$
    75547442unsigned long int random( void );
    75557443unsigned long int random( unsigned long int u ); $\C{// [0,u)}$
    7556 unsigned long int random( unsigned long int l, unsigned long int u ); $\C{// [l,u]}$
     7444unsigned long int random( unsigned long int l, unsigned long int u ); $\C{// [l,u)}$
    75577445float random( void );                                            $\C{// [0.0, 1.0)}$
    75587446double random( void );                                           $\C{// [0.0, 1.0)}$
     
    82188106
    82198107
    8220 \section{Pseudo Random Number Generator}
    8221 \label{s:PRNG}
    8222 
    8223 Random numbers are values generated independently, i.e., new values do not depend on previous values (independent trials), \eg lottery numbers, shuffled cards, dice roll, coin flip.
    8224 While a primary goal of programming is computing values that are \emph{not} random, random values are useful in simulation, cryptography, games, etc.
    8225 A random-number generator is an algorithm computing independent values.
    8226 If the algorithm uses deterministic computation (predictable sequence of values), it generates \emph{pseudo} random numbers versus \emph{true} random numbers.
    8227 
    8228 All \newterm{pseudo random-number generators} (\newterm{PRNG}) involve some technique to scramble bits of a value, \eg multiplicative recurrence:
    8229 \begin{cfa}
    8230 rand = 36973 * (rand & 65535) + (rand >> 16); // scramble bits
    8231 \end{cfa}
    8232 Multiplication of large values adds new least-significant bits and drops most-significant bits.
    8233 \begin{quote}
    8234 \begin{tabular}{@{}r|l@{}}
    8235 bits 63--32 (most)      & bits 31--0 (least)    \\
    8236 \hline
    8237 0x0                                     & 0x3e8e36                              \\
    8238 0x5f                            & 0x718c25e1                    \\
    8239 0xad3e                          & 0x7b5f1dbe                    \\
    8240 0xbc3b                          & 0xac69ff19                    \\
    8241 0x1070f                         & 0x2d258dc6                    \\
    8242 \end{tabular}
    8243 \end{quote}
    8244 By dropping bits 63--32, bits 31--0 become scrambled after each multiply.
    8245 The least-significant bits \emph{appear} random but the same bits are always generated given a fixed starting value, called the \newterm{seed} (value 0x3e8e36 above).
    8246 Hence, if a program uses the same seed, the same sequence of pseudo-random values is generated from the PRNG.
    8247 Often the seed is set to another random value like a program's process identifier (©getpid©\index{getpid@©getpid©}) or time when the program is run;
    8248 hence, one random value bootstraps another.
    8249 Finally, a PRNG usually generates a range of large values, \eg ©[0, UINT_MAX]©, which are scaled using the modulus operator, \eg ©prng() % 5© produces random values in the range 0--4.
    8250 
    8251 \CFA provides a sequential and concurrent PRNGs.
    8252 \begin{itemize}
    8253 \item
    8254 For sequential programs, like coroutining, the PRNG is used to randomize behaviour or values during execution, \eg in games, a character makes a random move or an object takes on a random value.
    8255 \begin{cfa}
    8256 struct PRNG { ... }; $\C[3.75in]{// opaque type}$
    8257 void ?{}( PRNG & prng ); $\C{// random seed}$
    8258 void ?{}( PRNG & prng, uint32_t seed ); $\C{// fixed seed}$
    8259 void set_seed( PRNG & prng, uint32_t seed ); $\C{// set seed}$
    8260 uint32_t get_seed( PRNG & prng ); $\C{// get seed}$
    8261 uint32_t prng( PRNG & prng ); $\C{// [0,UINT\_MAX]}$
    8262 uint32_t prng( PRNG & prng, uint32_t u ); $\C{// [0,u)}$
    8263 uint32_t prng( PRNG & prng, uint32_t l, uint32_t u ); $\C{// [l,u]}$
    8264 uint32_t calls( PRNG & prng ); $\C{// number of calls}\CRT$
    8265 \end{cfa}
    8266 Sequential execution is repeatable given the same starting seeds for all ©PRNG©s.
    8267 In this scenario, it is useful to have multiple ©PRNG©, \eg one per player or object so a type is provided to generate multiple instances.
    8268 \VRef[Figure]{f:SequentialPRNG} shows an example that creates two sequential ©PRNG©s, sets both to the same seed (1009), and illustrates the three forms for generating random values, where both ©PRNG©s generate the same sequence of values.
    8269 
    8270 \begin{figure}
    8271 \begin{cfa}
    8272 PRNG prng1, prng2;
    8273 ®set_seed( prng1, 1009 )®;   ®set_seed( prng2, 1009 )®;
    8274 for ( 10 ) {
    8275         // Do not cascade prng calls because side-effect functions called in arbitrary order.
    8276         sout | nlOff | ®prng( prng1 )®;  sout | ®prng( prng1, 5 )®;  sout | ®prng( prng1, 0, 5 )® | '\t';
    8277         sout | ®prng( prng2 )®;  sout | ®prng( prng2, 5 )®;  sout | ®prng( prng2, 0, 5 )® | nlOn;
    8278 }
    8279 \end{cfa}
    8280 \begin{cquote}
    8281 \begin{tabular}{@{}ll@{}}
    8282 \begin{cfa}
    8283 37301721 2 2
    8284 1681308562 1 3
    8285 290112364 3 2
    8286 1852700364 4 3
    8287 733221210 1 3
    8288 1775396023 2 3
    8289 123981445 2 3
    8290 2062557687 2 0
    8291 283934808 1 0
    8292 672325890 1 3
    8293 \end{cfa}
    8294 &
    8295 \begin{cfa}
    8296 37301721 2 2
    8297 1681308562 1 3
    8298 290112364 3 2
    8299 1852700364 4 3
    8300 733221210 1 3
    8301 1775396023 2 3
    8302 123981445 2 3
    8303 2062557687 2 0
    8304 283934808 1 0
    8305 672325890 1 3
    8306 \end{cfa}
    8307 \end{tabular}
    8308 \end{cquote}
    8309 \vspace{-10pt}
    8310 \caption{Sequential PRNG}
    8311 \label{f:SequentialPRNG}
    8312 \end{figure}
    8313 
    8314 \item
    8315 For concurrent programs, it is important the PRNG is thread-safe and not a point of contention.
    8316 A PRNG in concurrent programs is often used to randomize execution in short-running programs, \eg ©yield( prng() % 5 )©.
    8317 
    8318 Because concurrent execution is non-deterministic, seeding the concurrent PRNG is less important, as repeatable execution is impossible.
    8319 Hence, there is one system-wide PRNG (global seed) but each \CFA thread has its own non-contended PRNG state.
    8320 If the global seed is set, threads start with this seed, until it is reset and than threads start with the reset seed.
    8321 Hence, these threads generate the same sequence of random numbers from their specific starting seed.
    8322 If the global seed is \emph{not} set, threads start with a random seed, until the global seed is set.
    8323 Hence, these threads generate different sequences of random numbers.
    8324 If each thread needs its own seed, use a sequential ©PRNG© in each thread.
    8325 
    8326 There are two versions of the PRNG functions to manipulate the thread-local PRNG-state, which are differentiated by performance.
    8327 \begin{cfa}
    8328 void set_seed( uint32_t seed ); $\C[3.75in]{// set global seed}$
    8329 uint32_t get_seed(); $\C{// get global seed}$
    8330 // SLOWER
    8331 uint32_t prng(); $\C{// [0,UINT\_MAX]}$
    8332 uint32_t prng( uint32_t u ); $\C{// [0,u)}$
    8333 uint32_t prng( uint32_t l, uint32_t u ); $\C{// [l,u]}$
    8334 // FASTER
    8335 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th );     $\C{// [0,UINT\_MAX]}$
    8336 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t u ); $\C{// [0,u)}$
    8337 uint32_t prng( $thread\LstStringStyle{\textdollar}$ & th, uint32_t l, uint32_t u );     $\C{// [l,u]}\CRT$
    8338 \end{cfa}
    8339 The slower ©prng© functions call ©active_thread© internally to access the thread-local PRNG-state, while the faster ©prng© functions are passed a pointer to the active thread.
    8340 If the thread pointer is known, \eg in a thread ©main©, eliminating the call to ©active_thread© significantly reduces the cost for accessing the thread's PRNG state.
    8341 \VRef[Figure]{f:ConcurrentPRNG} shows an example using the slower/faster concurrent PRNG in the program main and a thread.
    8342 
    8343 \begin{figure}
    8344 \begin{cfa}
    8345 thread T {};
    8346 void main( ®T & th® ) {  // thread address
    8347         for ( i; 10 ) {
    8348                 sout | nlOff | ®prng()®;  sout | ®prng( 5 )®;  sout | ®prng( 0, 5 )® | '\t';  // SLOWER
    8349                 sout | nlOff | ®prng( th )®;  sout | ®prng( th, 5 )®;  sout | ®prng( th, 0, 5 )® | nlOn;  // FASTER
    8350         }
    8351 }
    8352 int main() {
    8353         set_seed( 1009 );
    8354         $\R{thread\LstStringStyle{\textdollar}}$ ®& th = *active_thread()®;  // program-main thread-address
    8355         for ( i; 10 ) {
    8356                 sout | nlOff | ®prng()®; sout | ®prng( 5 )®; sout | ®prng( 0, 5 )® | '\t';  // SLOWER
    8357                 sout | nlOff | ®prng( th )®; sout | ®prng( th, 5 )®; sout | ®prng( th, 0, 5 )® | nlOn;  // FASTER
    8358         }
    8359         sout | nl;
    8360         T t; // run thread
    8361 }
    8362 \end{cfa}
    8363 \begin{cquote}
    8364 \begin{tabular}{@{}ll@{}}
    8365 \begin{cfa}
    8366 37301721 2 2
    8367 290112364 3 2
    8368 733221210 1 3
    8369 123981445 2 3
    8370 283934808 1 0
    8371 1414344101 1 3
    8372 871831898 3 4
    8373 2142057611 4 4
    8374 802117363 0 4
    8375 2346353643 1 3
    8376 \end{cfa}
    8377 &
    8378 \begin{cfa}
    8379 1681308562 1 3
    8380 1852700364 4 3
    8381 1775396023 2 3
    8382 2062557687 2 0
    8383 672325890 1 3
    8384 873424536 3 4
    8385 866783532 0 1
    8386 17310256 2 5
    8387 492964499 0 0
    8388 2143013105 3 2
    8389 \end{cfa}
    8390 \end{tabular}
    8391 \begin{cfa}
    8392 // same output as above from thread t
    8393 \end{cfa}
    8394 \end{cquote}
    8395 \caption{Concurrent PRNG}
    8396 \label{f:ConcurrentPRNG}
    8397 \end{figure}
    8398 \end{itemize}
    8399 
    8400 
    84018108\section{Multi-precision Integers}
    84028109\label{s:MultiPrecisionIntegers}
     
    86038310\end{tabular}
    86048311\end{cquote}
    8605 
     8312\small
    86068313\begin{cfa}
    86078314Factorial Numbers
  • libcfa/src/Makefile.am

    r9ef9644 ra556492  
    7272        common.hfa \
    7373        fstream.hfa \
     74        heap.hfa \
    7475        iostream.hfa \
    7576        iterator.hfa \
     
    101102        startup.hfa \
    102103        virtual.c \
    103         virtual.h \
    104         heap.cc \
    105         heap.h
     104        virtual.h
    106105
    107106# not all platforms support concurrency, add option do disable it
     
    173172
    174173-include $(libdeps)
    175 -include $(DEPDIR)/heap.Plo
    176174
    177175thread_libdeps = $(join \
  • libcfa/src/concurrency/coroutine.cfa

    r9ef9644 ra556492  
    8585// minimum feasible stack size in bytes
    8686static const size_t MinStackSize = 1000;
    87 
    88 extern "C" {
    89         extern size_t __cfa_page_size;                          // architecture pagesize HACK, should go in proper runtime singleton
    90         extern int __map_prot;
    91 }
     87extern size_t __page_size;                              // architecture pagesize HACK, should go in proper runtime singleton
     88extern int __map_prot;
    9289
    9390void __stack_prepare( __stack_info_t * this, size_t create_size );
     
    160157[void *, size_t] __stack_alloc( size_t storageSize ) {
    161158        const size_t stack_data_size = libCeiling( sizeof(__stack_t), 16 ); // minimum alignment
    162         assert(__cfa_page_size != 0l);
     159        assert(__page_size != 0l);
    163160        size_t size = libCeiling( storageSize, 16 ) + stack_data_size;
    164         size = ceiling(size, __cfa_page_size);
     161        size = ceiling(size, __page_size);
    165162
    166163        // If we are running debug, we also need to allocate a guardpage to catch stack overflows.
    167164        void * storage;
    168165        #if CFA_COROUTINE_USE_MMAP
    169                 storage = mmap(0p, size + __cfa_page_size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
     166                storage = mmap(0p, size + __page_size, PROT_EXEC | PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
    170167                if(storage == ((void*)-1)) {
    171168                        abort( "coroutine stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
    172169                }
    173                 if ( mprotect( storage, __cfa_page_size, PROT_NONE ) == -1 ) {
     170                if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
    174171                        abort( "coroutine stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
    175172                } // if
    176                 storage = (void *)(((intptr_t)storage) + __cfa_page_size);
     173                storage = (void *)(((intptr_t)storage) + __page_size);
    177174        #else
    178175                __cfaabi_dbg_debug_do(
    179                         storage = memalign( __cfa_page_size, size + __cfa_page_size );
     176                        storage = memalign( __page_size, size + __page_size );
    180177                );
    181178                __cfaabi_dbg_no_debug_do(
     
    184181
    185182                __cfaabi_dbg_debug_do(
    186                         if ( mprotect( storage, __cfa_page_size, PROT_NONE ) == -1 ) {
     183                        if ( mprotect( storage, __page_size, PROT_NONE ) == -1 ) {
    187184                                abort( "__stack_alloc : internal error, mprotect failure, error(%d) %s.", (int)errno, strerror( (int)errno ) );
    188185                        }
    189                         storage = (void *)(((intptr_t)storage) + __cfa_page_size);
     186                        storage = (void *)(((intptr_t)storage) + __page_size);
    190187                );
    191188        #endif
     
    201198        #if CFA_COROUTINE_USE_MMAP
    202199                size_t size = ((intptr_t)this->storage->base) - ((intptr_t)this->storage->limit) + sizeof(__stack_t);
    203                 storage = (void *)(((intptr_t)storage) - __cfa_page_size);
    204                 if(munmap(storage, size + __cfa_page_size) == -1) {
     200                storage = (void *)(((intptr_t)storage) - __page_size);
     201                if(munmap(storage, size + __page_size) == -1) {
    205202                        abort( "coroutine stack destruction : internal error, munmap failure, error(%d) %s.", errno, strerror( errno ) );
    206203                }
    207204        #else
    208205                __cfaabi_dbg_debug_do(
    209                         storage = (char*)(storage) - __cfa_page_size;
    210                         if ( mprotect( storage, __cfa_page_size, __map_prot ) == -1 ) {
     206                        storage = (char*)(storage) - __page_size;
     207                        if ( mprotect( storage, __page_size, __map_prot ) == -1 ) {
    211208                                abort( "(coStack_t *)%p.^?{}() : internal error, mprotect failure, error(%d) %s.", &this, errno, strerror( errno ) );
    212209                        }
  • libcfa/src/concurrency/kernel.hfa

    r9ef9644 ra556492  
    173173
    174174static inline void  ?{}(__timestamp_t & this) { this.tv = 0; this.ma = 0; }
    175 static inline void ^?{}(__timestamp_t &) {}
     175static inline void ^?{}(__timestamp_t & this) {}
    176176
    177177struct __attribute__((aligned(128))) __ready_queue_caches_t;
  • libcfa/src/concurrency/kernel/startup.cfa

    r9ef9644 ra556492  
    1818
    1919// C Includes
    20 #include <errno.h>                                                                              // errno
     20#include <errno.h>              // errno
    2121#include <signal.h>
    22 #include <string.h>                                                                             // strerror
    23 #include <unistd.h>                                                                             // sysconf
     22#include <string.h>             // strerror
     23#include <unistd.h>             // sysconf
    2424
    2525extern "C" {
    26         #include <limits.h>                                                                     // PTHREAD_STACK_MIN
    27         #include <unistd.h>                                                                     // syscall
    28         #include <sys/eventfd.h>                                                        // eventfd
    29         #include <sys/mman.h>                                                           // mprotect
    30         #include <sys/resource.h>                                                       // getrlimit
     26      #include <limits.h>       // PTHREAD_STACK_MIN
     27        #include <unistd.h>       // syscall
     28        #include <sys/eventfd.h>  // eventfd
     29      #include <sys/mman.h>     // mprotect
     30      #include <sys/resource.h> // getrlimit
    3131}
    3232
    3333// CFA Includes
    3434#include "kernel_private.hfa"
    35 #include "startup.hfa"                                                                  // STARTUP_PRIORITY_XXX
     35#include "startup.hfa"          // STARTUP_PRIORITY_XXX
    3636#include "limits.hfa"
    3737#include "math.hfa"
     
    102102extern void __wake_proc(processor *);
    103103extern int cfa_main_returned;                                                   // from interpose.cfa
    104 uint32_t __global_random_prime = 4_294_967_291u, __global_random_mask = false;
     104extern uint32_t __global_random_seed;
    105105
    106106//-----------------------------------------------------------------------------
     
    122122extern "C" {
    123123        struct { __dllist_t(cluster) list; __spinlock_t lock; } __cfa_dbg_global_clusters;
    124         extern size_t __cfa_page_size;
    125         extern int __map_prot;
    126 }
     124}
     125
     126extern size_t __page_size;
     127extern int __map_prot;
    127128
    128129//-----------------------------------------------------------------------------
     
    489490        preferred = ready_queue_new_preferred();
    490491        last_proc = 0p;
    491         random_state = __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl();
     492        random_state = __global_random_seed;
    492493        #if defined( __CFA_WITH_VERIFY__ )
    493494                canary = 0x0D15EA5E0D15EA5Ep;
     
    573574}
    574575
     576extern size_t __page_size;
    575577void ^?{}(processor & this) with( this ){
    576578        /* paranoid */ verify( !__atomic_load_n(&do_terminate, __ATOMIC_ACQUIRE) );
     
    738740        void * stack;
    739741        #if CFA_PROCESSOR_USE_MMAP
    740                 stacksize = ceiling( stacksize, __cfa_page_size ) + __cfa_page_size;
     742                stacksize = ceiling( stacksize, __page_size ) + __page_size;
    741743                stack = mmap(0p, stacksize, __map_prot, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
    742744                if(stack == ((void*)-1)) {
    743745                        abort( "pthread stack creation : internal error, mmap failure, error(%d) %s.", errno, strerror( errno ) );
    744746                }
    745                 if ( mprotect( stack, __cfa_page_size, PROT_NONE ) == -1 ) {
     747                if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
    746748                        abort( "pthread stack creation : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
    747749                } // if
    748750        #else
    749751                __cfaabi_dbg_debug_do(
    750                         stack = memalign( __cfa_page_size, stacksize + __cfa_page_size );
     752                        stack = memalign( __page_size, stacksize + __page_size );
    751753                        // pthread has no mechanism to create the guard page in user supplied stack.
    752                         if ( mprotect( stack, __cfa_page_size, PROT_NONE ) == -1 ) {
     754                        if ( mprotect( stack, __page_size, PROT_NONE ) == -1 ) {
    753755                                abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
    754756                        } // if
     
    777779                check( pthread_attr_getstacksize( &attr, &stacksize ), "pthread_attr_getstacksize" );
    778780                assert( stacksize >= PTHREAD_STACK_MIN );
    779                 stacksize += __cfa_page_size;
     781                stacksize += __page_size;
    780782
    781783                if(munmap(stack, stacksize) == -1) {
     
    785787                __cfaabi_dbg_debug_do(
    786788                        // pthread has no mechanism to create the guard page in user supplied stack.
    787                         if ( mprotect( stack, __cfa_page_size, __map_prot ) == -1 ) {
     789                        if ( mprotect( stack, __page_size, __map_prot ) == -1 ) {
    788790                                abort( "mprotect : internal error, mprotect failure, error(%d) %s.", errno, strerror( errno ) );
    789791                        } // if
  • libcfa/src/concurrency/thread.cfa

    r9ef9644 ra556492  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 12 15:24:18 2022
    13 // Update Count     : 66
     12// Last Modified On : Sat Jan 15 14:34:58 2022
     13// Update Count     : 45
    1414//
    1515
     
    2525#include "invoke.h"
    2626
    27 extern uint32_t __global_random_seed, __global_random_prime, __global_random_mask;
     27extern uint32_t __global_random_seed;
    2828
    2929//-----------------------------------------------------------------------------
     
    4545        preferred = ready_queue_new_preferred();
    4646        last_proc = 0p;
    47         random_state = __global_random_mask ? __global_random_prime : __global_random_prime ^ rdtscl();
     47        random_state = __global_random_seed;
    4848        #if defined( __CFA_WITH_VERIFY__ )
    4949                canary = 0x0D15EA5E0D15EA5Ep;
     
    176176
    177177void set_seed( uint32_t seed ) {
    178         uint32_t & state = active_thread()->random_state;
    179         state = __global_random_seed = seed;
    180         GENERATOR( state );
    181         __global_random_prime = state;
    182         __global_random_mask = true;
     178        active_thread()->random_state = __global_random_seed = seed;
     179        GENERATOR( active_thread()->random_state );
    183180} // set_seed
    184181
  • libcfa/src/concurrency/thread.hfa

    r9ef9644 ra556492  
    1010// Created On       : Tue Jan 17 12:27:26 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb 11 16:34:07 2022
    13 // Update Count     : 20
     12// Last Modified On : Wed Feb  9 22:10:14 2022
     13// Update Count     : 14
    1414//
    1515
     
    131131
    132132//----------
    133 // prng
    134133static inline {
    135134        uint32_t prng( thread$ & th ) __attribute__(( warn_unused_result )) { return LCG( th.random_state ); } // [0,UINT_MAX]
    136135        uint32_t prng( thread$ & th, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( th ) % u; } // [0,u)
    137136        uint32_t prng( thread$ & th, uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( th, u - l + 1 ) + l; } // [l,u]
    138         forall( T & | is_thread(T) ) {
    139                 uint32_t prng( T & th ) __attribute__(( warn_unused_result )) { return prng( (thread &)th ); } // [0,UINT_MAX]
    140                 uint32_t prng( T & th, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( th ) % u; } // [0,u)
    141                 uint32_t prng( T & th, uint32_t l, uint32_t u ) __attribute__(( warn_unused_result )) { return prng( th, u - l + 1 ) + l; } // [l,u]
    142         } // distribution
    143 } // distribution
     137} // prng
    144138
    145139// Local Variables: //
  • libcfa/src/startup.cfa

    r9ef9644 ra556492  
    2727        void __cfaabi_appready_startup( void ) {
    2828                tzset();                                                                                // initialize time global variables
    29                 #ifdef __CFA_DEBUG__FIXME
     29                #ifdef __CFA_DEBUG__
    3030                extern void heapAppStart();
    3131                heapAppStart();
    32                 #endif // __CFA_DEBUG__FIXME
     32                #endif // __CFA_DEBUG__
    3333        } // __cfaabi_appready_startup
    3434
    3535        void __cfaabi_appready_shutdown( void ) __attribute__(( destructor( STARTUP_PRIORITY_APPREADY ) ));
    3636        void __cfaabi_appready_shutdown( void ) {
    37                 #ifdef __CFA_DEBUG__FIXME
     37                #ifdef __CFA_DEBUG__
    3838                extern void heapAppStop();
    3939                heapAppStop();
    40                 #endif // __CFA_DEBUG__FIXME
     40                #endif // __CFA_DEBUG__
    4141        } // __cfaabi_appready_shutdown
    4242
  • libcfa/src/stdhdr/malloc.h

    r9ef9644 ra556492  
    1818} // extern "C"
    1919
    20 #include <heap.h>
     20#include <heap.hfa>
    2121
    2222// Local Variables: //
  • libcfa/src/stdlib.hfa

    r9ef9644 ra556492  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 12 17:22:25 2022
    13 // Update Count     : 643
     12// Last Modified On : Thu Feb 10 18:34:58 2022
     13// Update Count     : 641
    1414//
    1515
     
    2121
    2222#include <stdlib.h>                                                                             // *alloc, strto*, ato*
    23 #include <heap.h>
     23#include <heap.hfa>
    2424
    2525
     
    209209
    210210        forall( TT... | { T * alloc_internal$( void *, T *, size_t, size_t, S_fill(T), TT ); } ) {
    211                 T * alloc_internal$( void *       , T *        , size_t Align, size_t Dim, S_fill(T) Fill, T_resize Resize, TT rest) {
     211                T * alloc_internal$( void *       , T * Realloc, size_t Align, size_t Dim, S_fill(T) Fill, T_resize Resize, TT rest) {
    212212                return alloc_internal$( Resize, (T*)0p, Align, Dim, Fill, rest);
    213213                }
    214214
    215                 T * alloc_internal$( void *        , T *        , size_t Align, size_t Dim, S_fill(T) Fill, S_realloc(T) Realloc, TT rest) {
     215                T * alloc_internal$( void * Resize, T *        , size_t Align, size_t Dim, S_fill(T) Fill, S_realloc(T) Realloc, TT rest) {
    216216                return alloc_internal$( (void*)0p, Realloc, Align, Dim, Fill, rest);
    217217                }
     
    389389// Declaration :
    390390//   PRNG sprng = { 1009 } - set starting seed versus random seed
    391 //
     391//   
    392392// Interface :
    393393//   set_seed( sprng, 1009 ) - set starting seed for ALL kernel threads versus random seed
     
    412412void set_seed( PRNG & prng, uint32_t seed_ );
    413413static inline {
    414         void ?{}( PRNG & prng ) with( prng ) { callcnt = 0; set_seed( prng, rdtscl() ); } // random seed
    415         void ?{}( PRNG & prng, uint32_t seed ) with( prng ) { callcnt = 0; set_seed( prng, seed ); } // fixed seed
     414        void ?{}( PRNG & prng ) { set_seed( prng, rdtscl() ); } // random seed
     415        void ?{}( PRNG & prng, uint32_t seed ) { set_seed( prng, seed ); } // fixed seed
    416416        uint32_t get_seed( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { return seed; } // get seed
    417417        uint32_t prng( PRNG & prng ) __attribute__(( warn_unused_result )) with( prng ) { callcnt += 1; return LCG( state ); } // [0,UINT_MAX]
  • src/AST/Convert.hpp

    r9ef9644 ra556492  
    2020class Declaration;
    2121namespace ast {
    22         class TranslationUnit;
     22        struct TranslationUnit;
    2323};
    2424
  • src/AST/Fwd.hpp

    r9ef9644 ra556492  
    140140typedef unsigned int UniqueId;
    141141
    142 class TranslationUnit;
     142struct TranslationUnit;
    143143// TODO: Get from the TranslationUnit:
    144144extern ptr<Type> sizeType;
  • src/AST/Pass.hpp

    r9ef9644 ra556492  
    239239private:
    240240
    241         __pass::result1<ast::Stmt> call_accept( const ast::Stmt * );
    242         __pass::result1<ast::Expr> call_accept( const ast::Expr * );
    243 
    244         /// This has a `type` member that is the return type for the
    245         /// generic call_accept if the generic call_accept is defined.
     241        // Regular nodes
    246242        template< typename node_t >
    247         using generic_call_accept_result =
    248                 std::enable_if<
     243        struct result1 {
     244                bool differs;
     245                const node_t * value;
     246
     247                template< typename object_t, typename super_t, typename field_t >
     248                void apply(object_t *, field_t super_t::* field);
     249        };
     250
     251        result1<ast::Stmt> call_accept( const ast::Stmt * );
     252        result1<ast::Expr> call_accept( const ast::Expr * );
     253
     254        template< typename node_t >
     255        auto call_accept( const node_t * node )
     256                -> typename std::enable_if<
    249257                                !std::is_base_of<ast::Expr, node_t>::value &&
    250258                                !std::is_base_of<ast::Stmt, node_t>::value
    251                         , __pass::result1<
    252                                 typename std::remove_pointer< typename std::result_of<
    253                                         decltype(&node_t::accept)(node_t*, type&) >::type >::type
     259                        , result1<
     260                                typename std::remove_pointer< decltype( node->accept(*this) ) >::type
    254261                        >
    255                 >;
    256 
    257         template< typename node_t >
    258         auto call_accept( const node_t * node )
    259                 -> typename generic_call_accept_result<node_t>::type;
     262                >::type;
    260263
    261264        // requests WithStmtsToAdd directly add to this statement, as if it is a compound.
    262         __pass::result1<ast::Stmt> call_accept_as_compound(const ast::Stmt *);
    263 
     265        result1<ast::Stmt> call_accept_as_compound(const ast::Stmt *);
     266
     267        // Container of statements
    264268        template< template <class...> class container_t >
    265         __pass::resultNstmt<container_t> call_accept( const container_t< ptr<Stmt> > & );
    266 
     269        struct resultNstmt {
     270                struct delta {
     271                        ptr<Stmt> nval;
     272                        ssize_t old_idx;
     273                        bool is_old;
     274
     275                        delta(const Stmt * s, ssize_t i, bool old) : nval{s}, old_idx{i}, is_old{old} {}
     276                };
     277
     278                bool differs;
     279                container_t< delta > values;
     280
     281                resultNstmt() : differs(false), values{} {}
     282                resultNstmt(bool diff, container_t< delta > && vals) : differs(diff), values(vals) {}
     283
     284                template< typename object_t, typename super_t, typename field_t >
     285                void apply(object_t *, field_t super_t::* field);
     286
     287                template< template <class...> class incontainer_t >
     288                void take_all( incontainer_t<ast::ptr<ast::Stmt>> * stmts ) {
     289                        if(!stmts || stmts->empty()) return;
     290
     291                        std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ), [](ast::ptr<ast::Stmt>& decl) -> delta {
     292                                        return delta( decl.release(), -1, false );
     293                                });
     294                        stmts->clear();
     295                        differs = true;
     296                }
     297
     298                template< template <class...> class incontainer_t >
     299                void take_all( incontainer_t<ast::ptr<ast::Decl>> * decls ) {
     300                        if(!decls || decls->empty()) return;
     301
     302                        std::transform(decls->begin(), decls->end(), std::back_inserter( values ), [](ast::ptr<ast::Decl>& decl) -> auto {
     303                                        auto loc = decl->location;
     304                                        auto stmt = new DeclStmt( loc, decl.release() );
     305                                        return delta( stmt, -1, false );
     306                                });
     307                        decls->clear();
     308                        differs = true;
     309                }
     310        };
     311
     312        template< template <class...> class container_t >
     313        resultNstmt<container_t> call_accept( const container_t< ptr<Stmt> > & );
     314
     315        // Container of something
    267316        template< template <class...> class container_t, typename node_t >
    268         __pass::resultN< container_t, node_t > call_accept( const container_t< ptr<node_t> > & container );
     317        struct resultN {
     318                bool differs;
     319                container_t<ptr<node_t>> values;
     320
     321                template< typename object_t, typename super_t, typename field_t >
     322                void apply(object_t *, field_t super_t::* field);
     323        };
     324
     325        template< template <class...> class container_t, typename node_t >
     326        resultN< container_t, node_t > call_accept( const container_t< ptr<node_t> > & container );
    269327
    270328public:
  • src/AST/Pass.impl.hpp

    r9ef9644 ra556492  
    111111                }
    112112
     113
    113114                //------------------------------
    114115                /// Check if value was mutated, different for pointers and containers
     
    124125        }
    125126
     127
     128        template< typename core_t >
    126129        template< typename node_t >
    127130        template< typename object_t, typename super_t, typename field_t >
    128         void __pass::result1< node_t >::apply( object_t * object, field_t super_t::* field ) {
     131        void ast::Pass< core_t >::result1< node_t >::apply(object_t * object, field_t super_t::* field) {
    129132                object->*field = value;
    130133        }
     
    133136        template< typename node_t >
    134137        auto ast::Pass< core_t >::call_accept( const node_t * node )
    135                 -> typename ast::Pass< core_t >::template generic_call_accept_result<node_t>::type
     138                -> typename std::enable_if<
     139                                !std::is_base_of<ast::Expr, node_t>::value &&
     140                                !std::is_base_of<ast::Stmt, node_t>::value
     141                        , ast::Pass< core_t >::result1<
     142                                typename std::remove_pointer< decltype( node->accept(*this) ) >::type
     143                        >
     144                >::type
    136145        {
    137146                __pedantic_pass_assert( __visit_children() );
     
    142151
    143152                auto nval = node->accept( *this );
    144                 __pass::result1<
     153                ast::Pass< core_t >::result1<
    145154                        typename std::remove_pointer< decltype( node->accept(*this) ) >::type
    146155                > res;
     
    151160
    152161        template< typename core_t >
    153         __pass::template result1<ast::Expr> ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
     162        typename ast::Pass< core_t >::template result1<ast::Expr> ast::Pass< core_t >::call_accept( const ast::Expr * expr ) {
    154163                __pedantic_pass_assert( __visit_children() );
    155164                __pedantic_pass_assert( expr );
     
    165174
    166175        template< typename core_t >
    167         __pass::template result1<ast::Stmt> ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
     176        typename ast::Pass< core_t >::template result1<ast::Stmt> ast::Pass< core_t >::call_accept( const ast::Stmt * stmt ) {
    168177                __pedantic_pass_assert( __visit_children() );
    169178                __pedantic_pass_assert( stmt );
     
    174183
    175184        template< typename core_t >
    176         __pass::template result1<ast::Stmt> ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
     185        typename ast::Pass< core_t >::template result1<ast::Stmt> ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {
    177186                __pedantic_pass_assert( __visit_children() );
    178187                __pedantic_pass_assert( stmt );
     
    224233        }
    225234
     235        template< typename core_t >
    226236        template< template <class...> class container_t >
    227237        template< typename object_t, typename super_t, typename field_t >
    228         void __pass::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) {
     238        void ast::Pass< core_t >::resultNstmt<container_t>::apply(object_t * object, field_t super_t::* field) {
    229239                auto & container = object->*field;
    230240                __pedantic_pass_assert( container.size() <= values.size() );
     
    233243
    234244                container_t<ptr<Stmt>> nvals;
    235                 for (delta & d : values) {
    236                         if ( d.is_old ) {
     245                for(delta & d : values) {
     246                        if( d.is_old ) {
    237247                                __pedantic_pass_assert( cit.idx <= d.old_idx );
    238248                                std::advance( cit, d.old_idx - cit.idx );
    239249                                nvals.push_back( std::move( (*cit).val) );
    240250                        } else {
    241                                 nvals.push_back( std::move(d.new_val) );
     251                                nvals.push_back( std::move(d.nval) );
    242252                        }
    243253                }
    244254
    245                 container = std::move(nvals);
    246         }
    247 
    248         template< template <class...> class container_t >
    249         template< template <class...> class incontainer_t >
    250         void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Stmt>> * stmts ) {
    251                 if (!stmts || stmts->empty()) return;
    252 
    253                 std::transform(stmts->begin(), stmts->end(), std::back_inserter( values ),
    254                         [](ast::ptr<ast::Stmt>& stmt) -> delta {
    255                                 return delta( stmt.release(), -1, false );
    256                         });
    257                 stmts->clear();
    258                 differs = true;
    259         }
    260 
    261         template< template<class...> class container_t >
    262         template< template<class...> class incontainer_t >
    263         void __pass::resultNstmt< container_t >::take_all( incontainer_t<ptr<Decl>> * decls ) {
    264                 if (!decls || decls->empty()) return;
    265 
    266                 std::transform(decls->begin(), decls->end(), std::back_inserter( values ),
    267                         [](ast::ptr<ast::Decl>& decl) -> delta {
    268                                 auto loc = decl->location;
    269                                 auto stmt = new DeclStmt( loc, decl.release() );
    270                                 return delta( stmt, -1, false );
    271                         });
    272                 decls->clear();
    273                 differs = true;
     255                object->*field = std::move(nvals);
    274256        }
    275257
    276258        template< typename core_t >
    277259        template< template <class...> class container_t >
    278         __pass::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
     260        typename ast::Pass< core_t >::template resultNstmt<container_t> ast::Pass< core_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {
    279261                __pedantic_pass_assert( __visit_children() );
    280262                if( statements.empty() ) return {};
     
    303285                pass_visitor_stats.avg->push(pass_visitor_stats.depth);
    304286
    305                 __pass::resultNstmt<container_t> new_kids;
     287                resultNstmt<container_t> new_kids;
    306288                for( auto value : enumerate( statements ) ) {
    307289                        try {
     
    345327        }
    346328
     329        template< typename core_t >
    347330        template< template <class...> class container_t, typename node_t >
    348331        template< typename object_t, typename super_t, typename field_t >
    349         void __pass::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) {
     332        void ast::Pass< core_t >::resultN<container_t, node_t>::apply(object_t * object, field_t super_t::* field) {
    350333                auto & container = object->*field;
    351334                __pedantic_pass_assert( container.size() == values.size() );
     
    363346        template< typename core_t >
    364347        template< template <class...> class container_t, typename node_t >
    365         __pass::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
     348        typename ast::Pass< core_t >::template resultN<container_t, node_t> ast::Pass< core_t >::call_accept( const container_t< ast::ptr<node_t> > & container ) {
    366349                __pedantic_pass_assert( __visit_children() );
    367350                if( container.empty() ) return {};
     
    395378                if ( ! errors.isEmpty() ) { throw errors; }
    396379
    397                 return ast::__pass::resultN<container_t, node_t>{ mutated, new_kids };
     380                return ast::Pass< core_t >::resultN<container_t, node_t>{ mutated, new_kids };
    398381        }
    399382
  • src/AST/Pass.proto.hpp

    r9ef9644 ra556492  
    2323class Pass;
    2424
    25 class TranslationUnit;
     25struct TranslationUnit;
    2626
    2727struct PureVisitor;
     
    123123                static constexpr bool value = std::is_void< ret_t >::value ||
    124124                        std::is_base_of<const node_t, typename std::remove_pointer<ret_t>::type >::value;
    125         };
    126 
    127         /// The result is a single node.
    128         template< typename node_t >
    129         struct result1 {
    130                 bool differs;
    131                 const node_t * value;
    132 
    133                 template< typename object_t, typename super_t, typename field_t >
    134                 void apply( object_t *, field_t super_t::* field );
    135         };
    136 
    137         /// The result is a container of statements.
    138         template< template<class...> class container_t >
    139         struct resultNstmt {
    140                 /// The delta/change on a single node.
    141                 struct delta {
    142                         ptr<Stmt> new_val;
    143                         ssize_t old_idx;
    144                         bool is_old;
    145 
    146                         delta(const Stmt * s, ssize_t i, bool old) :
    147                                 new_val(s), old_idx(i), is_old(old) {}
    148                 };
    149 
    150                 bool differs;
    151                 container_t< delta > values;
    152 
    153                 template< typename object_t, typename super_t, typename field_t >
    154                 void apply( object_t *, field_t super_t::* field );
    155 
    156                 template< template<class...> class incontainer_t >
    157                 void take_all( incontainer_t<ptr<Stmt>> * stmts );
    158 
    159                 template< template<class...> class incontainer_t >
    160                 void take_all( incontainer_t<ptr<Decl>> * decls );
    161         };
    162 
    163         /// The result is a container of nodes.
    164         template< template<class...> class container_t, typename node_t >
    165         struct resultN {
    166                 bool differs;
    167                 container_t<ptr<node_t>> values;
    168 
    169                 template< typename object_t, typename super_t, typename field_t >
    170                 void apply( object_t *, field_t super_t::* field );
    171125        };
    172126
  • src/AST/TranslationUnit.hpp

    r9ef9644 ra556492  
    2323namespace ast {
    2424
    25 class TranslationUnit {
    26 public:
     25struct TranslationUnit {
    2726        std::list< ptr< Decl > > decls;
    2827
  • src/CodeGen/FixNames.h

    r9ef9644 ra556492  
    2020class Declaration;
    2121namespace ast {
    22         class TranslationUnit;
     22        struct TranslationUnit;
    2323}
    2424
  • src/Common/CodeLocation.h

    r9ef9644 ra556492  
    2525        /// Create a new unset CodeLocation.
    2626        CodeLocation() = default;
     27
    2728
    2829        /// Create a new CodeLocation with the given values.
  • src/Common/CodeLocationTools.hpp

    r9ef9644 ra556492  
    1717
    1818namespace ast {
    19         class TranslationUnit;
     19        struct TranslationUnit;
    2020}
    2121
  • src/Common/ResolvProtoDump.hpp

    r9ef9644 ra556492  
    1717
    1818namespace ast {
    19         class TranslationUnit;
     19        struct TranslationUnit;
    2020}
    2121
  • src/Concurrency/Waitfor.cc

    r9ef9644 ra556492  
    372372                        ),
    373373                        new ListInit(
    374                                 map_range < std::list<Initializer*> > ( clause.target.arguments, [](Expression * expr ){
    375                                         return new SingleInit( expr );
     374                                map_range < std::list<Initializer*> > ( clause.target.arguments, [this](Expression * expr ){
     375                                        Expression * init = new CastExpr(
     376                                                new UntypedExpr(
     377                                                        new NameExpr( "get_monitor" ),
     378                                                        { expr }
     379                                                ),
     380                                                new PointerType(
     381                                                        noQualifiers,
     382                                                        new StructInstType(
     383                                                                noQualifiers,
     384                                                                decl_monitor
     385                                                        )
     386                                                ),
     387                                                false
     388                                        );
     389
     390                                        ResolvExpr::findSingleExpression( init, indexer );
     391                                        return new SingleInit( init );
    376392                                })
    377393                        )
  • src/ControlStruct/MultiLevelExit.cpp

    r9ef9644 ra556492  
    176176        auto mutStmt = mutate( stmt );
    177177        // A child statement may set the break label.
    178         mutStmt->kids = fixBlock( stmt->kids, false );
     178        mutStmt->kids = move( fixBlock( stmt->kids, false ) );
    179179
    180180        if ( isLabeled ) {
  • src/InitTweak/FixInit.h

    r9ef9644 ra556492  
    2121class Declaration;
    2222namespace ast {
    23         class TranslationUnit;
     23        struct TranslationUnit;
    2424}
    2525
  • src/MakeLibCfa.h

    r9ef9644 ra556492  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // MakeLibCfa.h --
     7// MakeLibCfa.h -- 
    88//
    99// Author           : Richard C. Bilson
     
    2020class Declaration;
    2121namespace ast {
    22         class TranslationUnit;
     22        struct TranslationUnit;
    2323}
    2424
  • src/Parser/parser.yy

    r9ef9644 ra556492  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb 11 14:26:15 2022
    13 // Update Count     : 5174
     12// Last Modified On : Tue Feb  1 11:06:13 2022
     13// Update Count     : 5167
    1414//
    1515
     
    11971197                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
    11981198        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
     1199                // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }
    11991200                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
    12001201        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
     
    12031204                { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
    12041205        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
     1206                // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }
    12051207                { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
    12061208        | FOR '(' ')' statement                                                         // CFA => for ( ;; )
     
    12091211                { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
    12101212        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
     1213                // { SemanticError( yylloc, "Loop default block is currently unimplemented." ); $$ = nullptr; }
    12111214                { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
    12121215        ;
     
    27262729        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    27272730                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); }
    2728         | EXTERN STRINGliteral
    2729                 {
    2730                         linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    2731                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
    2732                 }
    2733           up external_definition down
    2734                 {
    2735                         linkage = linkageStack.top();
    2736                         linkageStack.pop();
    2737                         $$ = $5;
    2738                 }
    27392731        | EXTERN STRINGliteral                                                          // C++-style linkage specifier
    27402732                {
  • src/ResolvExpr/Resolver.cc

    r9ef9644 ra556492  
    11121112                }
    11131113
    1114 
     1114               
    11151115        } // anonymous namespace
    11161116/// Establish post-resolver invariants for expressions
     
    11581158
    11591159        namespace {
    1160 
     1160               
    11611161
    11621162                /// resolve `untyped` to the expression whose candidate satisfies `pred` with the
     
    19051905
    19061906                        clause2.target.args.reserve( clause.target.args.size() );
    1907                         const ast::StructDecl * decl_monitor = symtab.lookupStruct( "monitor$" );
    19081907                        for ( auto arg : argsCandidates.front() ) {
    1909                                 const auto & loc = stmt->location;
    1910 
    1911                                 ast::Expr * init = new ast::CastExpr( loc,
    1912                                         new ast::UntypedExpr( loc,
    1913                                                 new ast::NameExpr( loc, "get_monitor" ),
    1914                                                 { arg->expr }
    1915                                         ),
    1916                                         new ast::PointerType(
    1917                                                 new ast::StructInstType(
    1918                                                         decl_monitor
    1919                                                 )
    1920                                         )
    1921                                 );
    1922 
    1923                                 clause2.target.args.emplace_back( findSingleExpression( init, symtab ) );
     1908                                clause2.target.args.emplace_back( std::move( arg->expr ) );
    19241909                        }
    19251910
     
    20922077                if (auto functionDecl = decl.as<ast::FunctionDecl>()) {
    20932078                        // xxx - can intrinsic gen ever fail?
    2094                         if (functionDecl->linkage == ast::Linkage::AutoGen) {
     2079                        if (functionDecl->linkage == ast::Linkage::AutoGen) { 
    20952080                                auto mutDecl = mutate(functionDecl);
    20962081                                mutDecl->isDeleted = true;
  • src/ResolvExpr/Resolver.h

    r9ef9644 ra556492  
    3535        class StmtExpr;
    3636        class SymbolTable;
    37         class TranslationUnit;
     37        struct TranslationUnit;
    3838        class Type;
    3939        class TypeEnvironment;
     
    7272        ast::ptr< ast::Init > resolveCtorInit(
    7373                const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab );
    74         /// Resolves a statement expression
     74        /// Resolves a statement expression 
    7575        const ast::Expr * resolveStmtExpr(
    7676                const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab );
  • tests/PRNG.cfa

    r9ef9644 ra556492  
    88// Created On       : Wed Dec 29 09:38:12 2021
    99// Last Modified By : Peter A. Buhr
    10 // Last Modified On : Sat Feb 12 12:23:57 2022
    11 // Update Count     : 342
     10// Last Modified On : Fri Feb 11 08:16:43 2022
     11// Update Count     : 328
    1212//
    1313
     
    2020#include <malloc.h>                                                                             // malloc_stats
    2121#include <locale.h>                                                                             // setlocale
    22 #include <mutex_stmt.hfa>
    2322
    2423// FIX ME: spurious characters appear in output
     
    5150        } // for
    5251        double std = sqrt( sum / BUCKETS );
    53         mutex( sout ) sout | "trials"  | TRIALS | "buckets" | BUCKETS
    54                 | "min" | min | "max" | max
    55                 | "avg" | wd(0,1, avg) | "std" | wd(0,1, std) | "rstd" | wd(0,1, (avg == 0 ? 0.0 : std / avg * 100)) | "%";
     52        sout | "trials"  | TRIALS | "buckets" | BUCKETS
     53                 | "min" | min | "max" | max
     54                 | "avg" | wd(0,1, avg) | "std" | wd(0,1, std) | "rstd" | wd(0,1, (avg == 0 ? 0.0 : std / avg * 100)) | "%";
    5655} // avgstd
    5756
    58 
    5957uint32_t seed = 1009;
     58
    6059
    6160thread T1 {};
     
    9594        unsigned int * buckets = calloc( BUCKETS );                     // too big for task stack
    9695        for ( TRIALS ) {
    97                 buckets[prng( th ) % BUCKETS] += 1;     // concurrent
     96                buckets[prng( (thread$ &)th ) % BUCKETS] += 1;  // concurrent
    9897        } // for
    9998        avgstd( buckets );
  • tests/meta/dumpable.cfa

    r9ef9644 ra556492  
    7272        }
    7373
    74         uint64_t avail = buf.f_bavail;
    75         avail *= buf.f_bsize;
    76         if(avail < 536870912_l64u) {
    77                 serr | "Available diskspace is less than ~500Mb: " | avail;
     74        if((buf.f_bsize * buf.f_bavail) < 536870912) {
     75                serr | "Available diskspace is less than ~500Mb: " | (buf.f_bsize * buf.f_bavail);
    7876        }
    7977
Note: See TracChangeset for help on using the changeset viewer.