Index: doc/bibliography/pl.bib
===================================================================
--- doc/bibliography/pl.bib	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ doc/bibliography/pl.bib	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -377,4 +377,17 @@
 }
 
+@article{Hoare61,
+    keywords	= {quick sort},
+    contributer	= {pabuhr@plg},
+    author	= {C. A. R. Hoare},
+    title	= {Algorithms 63/64: Partition/Quicksort},
+    journal	= cacm,
+    volume	= 4,
+    number	= 7,
+    month	= jul,
+    year	= 1961,
+    pages	= {321},
+}
+
 @article{Cormack81,
     keywords	= {},
@@ -635,4 +648,15 @@
     year	= 2008,
     pages	= {8-15},
+}
+
+@article{Joung00,
+    author	= {Joung, Yuh-Jzer},
+    title	= {Asynchronous group mutual exclusion},
+    journal	= {Distributed Computing},
+    year	= {2000},
+    month	= {Nov},
+    volume	= {13},
+    number	= {4},
+    pages	= {189--206},
 }
 
@@ -5791,5 +5815,5 @@
 @manual{Python,
     keywords	= {Python},
-    contributer	= {pabuhr},
+    contributer	= {pabuhr@plg},
     title	= {Python Reference Manual, Release 2.5},
     author	= {Guido van Rossum},
@@ -5822,15 +5846,17 @@
 }
 
-@article{Hoare61,
-    keywords	= {quick sort},
-    contributer	= {pabuhr@plg},
-    author	= {C. A. R. Hoare},
-    title	= {Algorithms 63/64: Partition/Quicksort},
-    journal	= cacm,
-    volume	= 4,
-    number	= 7,
-    month	= jul,
-    year	= 1961,
-    pages	= {321},
+@article{Nakaike15,
+    keywords	= {hardware transactional memory},
+    contributer	= {pabuhr@plg},
+    author	= {Nakaike, Takuya and Odaira, Rei and Gaudet, Matthew and Michael, Maged M. and Tomari, Hisanobu},
+    title	= {Quantitative Comparison of Hardware Transactional Memory for Blue Gene/Q, zEnterprise {EC12}, {I}ntel Core, and {POWER8}},
+    journal	= {SIGARCH Comput. Archit. News},
+    volume	= {43},
+    number	= {3},
+    month	= jun,
+    year	= {2015},
+    pages	= {144--157},
+    publisher	= {ACM},
+    address	= {New York, NY, USA},
 }
 
Index: doc/papers/concurrency/Paper.tex
===================================================================
--- doc/papers/concurrency/Paper.tex	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ doc/papers/concurrency/Paper.tex	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -70,6 +70,4 @@
 %\DeclareTextCommandDefault{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}
 \renewcommand{\textunderscore}{\leavevmode\makebox[1.2ex][c]{\rule{1ex}{0.075ex}}}
-%\def\myCHarFont{\fontencoding{T1}\selectfont}%
-% \def\{{\ttfamily\upshape\myCHarFont \char`\}}}%
 
 \renewcommand*{\thefootnote}{\Alph{footnote}} % hack because fnsymbol does not work
@@ -741,12 +739,12 @@
 The coroutine main's stack holds the state for the next generation, @f1@ and @f2@, and the code has the three suspend points, representing the three states in the Fibonacci formula, to context switch back to the caller's resume.
 The interface function, @next@, takes a Fibonacci instance and context switches to it using @resume@;
-on return, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned.
+on restart, the Fibonacci field, @fn@, contains the next value in the sequence, which is returned.
 The first @resume@ is special because it cocalls the coroutine at its coroutine main and allocates the stack;
 when the coroutine main returns, its stack is deallocated.
 Hence, @Fib@ is an object at creation, transitions to a coroutine on its first resume, and transitions back to an object when the coroutine main finishes.
 Figure~\ref{f:Coroutine1State} shows the coroutine version of the C version in Figure~\ref{f:ExternalState}.
-Coroutine generators are called \newterm{output coroutines} because values are returned by the coroutine.
-
-Figure~\ref{f:CFAFmt} shows an \newterm{input coroutine}, @Format@, for restructuring text into groups of character blocks of fixed size.
+Coroutine generators are called \newterm{output coroutines} because values are only returned.
+
+Figure~\ref{f:CFAFmt} shows an \newterm{input coroutine}, @Format@, for restructuring text into groups of characters of fixed-size blocks.
 For example, the input of the left is reformatted into the output on the right.
 \begin{quote}
@@ -763,5 +761,5 @@
 \end{tabular}
 \end{quote}
-The example takes advantage of resuming coroutines in the constructor to prime the coroutine loops so the first character sent for formatting appears inside the nested loops.
+The example takes advantage of resuming a coroutine in the constructor to prime the loops so the first character sent for formatting appears inside the nested loops.
 The destruction provides a newline if formatted text ends with a full line.
 Figure~\ref{f:CFmt} shows the C equivalent formatter, where the loops of the coroutine are flatten (linearized) and rechecked on each call because execution location is not retained between calls.
@@ -778,5 +776,5 @@
 void main( Format & fmt ) with( fmt ) {
 	for ( ;; ) {	
-		for ( g = 0; g < 5; g += 1 ) {  // group
+		for ( g = 0; g < 5; g += 1 ) {      // group
 			for ( b = 0; b < 4; b += 1 ) { // block
 				`suspend();`
@@ -814,5 +812,5 @@
 };
 void format( struct Format * fmt ) {
-	if ( fmt->ch != -1 ) { // not EOF
+	if ( fmt->ch != -1 ) {      // not EOF ?
 		printf( "%c", fmt->ch );
 		fmt->b += 1;
@@ -823,5 +821,5 @@
 		}
 		if ( fmt->g == 5 ) {  // group
-			printf( "\n" );      // separator
+			printf( "\n" );     // separator
 			fmt->g = 0;
 		}
@@ -850,6 +848,6 @@
 
 The previous examples are \newterm{asymmetric (semi) coroutine}s because one coroutine always calls a resuming function for another coroutine, and the resumed coroutine always suspends back to its last resumer, similar to call/return for normal functions.
-However, there is no stack growth because @resume@/@suspend@ context switch to an existing stack frames rather than create a new one.
-\newterm{Symmetric (full) coroutine}s have a coroutine call a resuming function for another coroutine, which eventually forms a cycle.
+However, there is no stack growth because @resume@/@suspend@ context switch to existing stack-frames rather than create new ones.
+\newterm{Symmetric (full) coroutine}s have a coroutine call a resuming function for another coroutine, which eventually forms a resuming-call cycle.
 (The trivial cycle is a coroutine resuming itself.)
 This control flow is similar to recursion for normal routines, but again there is no stack growth from the context switch.
@@ -935,17 +933,17 @@
 The @start@ function communicates both the number of elements to be produced and the consumer into the producer's coroutine structure.
 Then the @resume@ to @prod@ creates @prod@'s stack with a frame for @prod@'s coroutine main at the top, and context switches to it.
-@prod@'s coroutine main starts, creates local variables that are retained between coroutine activations, and executes $N$ iterations, each generating two random vales, calling the consumer to deliver the values, and printing the status returned from the consumer.
+@prod@'s coroutine main starts, creates local variables that are retained between coroutine activations, and executes $N$ iterations, each generating two random values, calling the consumer to deliver the values, and printing the status returned from the consumer.
 
 The producer call to @delivery@ transfers values into the consumer's communication variables, resumes the consumer, and returns the consumer status.
 For the first resume, @cons@'s stack is initialized, creating local variables retained between subsequent activations of the coroutine.
-The consumer iterates until the @done@ flag is set, prints, increments status, and calls back to the producer's @payment@ member, and on return prints the receipt from the producer and increments the money for the next payment.
-The call from the consumer to the producer's @payment@ member introduces the cycle between producer and consumer.
+The consumer iterates until the @done@ flag is set, prints, increments status, and calls back to the producer via @payment@, and on return from @payment@, prints the receipt from the producer and increments @money@ (inflation).
+The call from the consumer to the @payment@ introduces the cycle between producer and consumer.
 When @payment@ is called, the consumer copies values into the producer's communication variable and a resume is executed.
-The context switch restarts the producer at the point where it was last context switched and it continues in member @delivery@ after the resume.
-
-The @delivery@ member returns the status value in @prod@'s @main@ member, where the status is printed.
+The context switch restarts the producer at the point where it was last context switched, so it continues in @delivery@ after the resume.
+
+@delivery@ returns the status value in @prod@'s coroutine main, where the status is printed.
 The loop then repeats calling @delivery@, where each call resumes the consumer coroutine.
 The context switch to the consumer continues in @payment@.
-The consumer increments and returns the receipt to the call in @cons@'s @main@ member.
+The consumer increments and returns the receipt to the call in @cons@'s coroutine main.
 The loop then repeats calling @payment@, where each call resumes the producer coroutine.
 
@@ -954,105 +952,34 @@
 The context switch restarts @cons@ in @payment@ and it returns with the last receipt.
 The consumer terminates its loops because @done@ is true, its @main@ terminates, so @cons@ transitions from a coroutine back to an object, and @prod@ reactivates after the resume in @stop@.
-The @stop@ member returns and @prod@'s @main@ member terminates.
+@stop@ returns and @prod@'s coroutine main terminates.
 The program main restarts after the resume in @start@.
-The @start@ member returns and the program main terminates.
-
-
-\subsubsection{Construction}
-
-One important design challenge for implementing coroutines and threads (shown in section \ref{threads}) is that the runtime system needs to run code after the user-constructor runs to connect the fully constructed object into the system.
-In the case of coroutines, this challenge is simpler since there is no non-determinism from preemption or scheduling.
-However, the underlying challenge remains the same for coroutines and threads.
-
-The runtime system needs to create the coroutine's stack and, more importantly, prepare it for the first resumption.
-The timing of the creation is non-trivial since users expect both to have fully constructed objects once execution enters the coroutine main and to be able to resume the coroutine from the constructor.
-There are several solutions to this problem but the chosen option effectively forces the design of the coroutine.
-
-Furthermore, \CFA faces an extra challenge as polymorphic routines create invisible thunks when cast to non-polymorphic routines and these thunks have function scope.
-For example, the following code, while looking benign, can run into undefined behaviour because of thunks:
-
-\begin{cfa}
-// async: Runs function asynchronously on another thread
-forall(otype T)
-extern void async(void (*func)(T*), T* obj);
-
-forall(otype T)
-void noop(T*) {}
-
-void bar() {
-	int a;
-	async(noop, &a); // start thread running noop with argument a
-}
-\end{cfa}
-
-The generated C code\footnote{Code trimmed down for brevity} creates a local thunk to hold type information:
-
-\begin{cfa}
-extern void async(/* omitted */, void (*func)(void*), void* obj);
-
-void noop(/* omitted */, void* obj){}
-
-void bar(){
-	int a;
-	void _thunk0(int* _p0){
-		/* omitted */
-		noop(/* omitted */, _p0);
-	}
-	/* omitted */
-	async(/* omitted */, ((void (*)(void*))(&_thunk0)), (&a));
-}
-\end{cfa}
-The problem in this example is a storage management issue, the function pointer @_thunk0@ is only valid until the end of the block, which limits the viable solutions because storing the function pointer for too long causes undefined behaviour; \ie the stack-based thunk being destroyed before it can be used.
-This challenge is an extension of challenges that come with second-class routines.
-Indeed, GCC nested routines also have the limitation that nested routine cannot be passed outside of the declaration scope.
-The case of coroutines and threads is simply an extension of this problem to multiple call stacks.
-
-
-\subsubsection{Alternative: Composition}
-
-One solution to this challenge is to use composition/containment, where coroutine fields are added to manage the coroutine.
-
-\begin{cfa}
-struct Fibonacci {
-	int fn; // used for communication
-	coroutine c; // composition
-};
-
-void FibMain(void*) {
-	//...
-}
-
-void ?{}(Fibonacci& this) {
-	this.fn = 0;
-	// Call constructor to initialize coroutine
-	(this.c){myMain};
-}
-\end{cfa}
-The downside of this approach is that users need to correctly construct the coroutine handle before using it.
-Like any other objects, the user must carefully choose construction order to prevent usage of objects not yet constructed.
-However, in the case of coroutines, users must also pass to the coroutine information about the coroutine main, like in the previous example.
-This opens the door for user errors and requires extra runtime storage to pass at runtime information that can be known statically.
-
-
-\subsubsection{Alternative: Reserved keyword}
-
-The next alternative is to use language support to annotate coroutines as follows:
-\begin{cfa}
-coroutine Fibonacci {
-	int fn; // used for communication
-};
-\end{cfa}
-The @coroutine@ keyword means the compiler can find and inject code where needed.
-The downside of this approach is that it makes coroutine a special case in the language.
-Users wanting to extend coroutines or build their own for various reasons can only do so in ways offered by the language.
-Furthermore, implementing coroutines without language supports also displays the power of the programming language used.
-While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can still be constructed by users without using the language support.
-The reserved keywords are only present to improve ease of use for the common cases.
-
-
-\subsubsection{Alternative: Lambda Objects}
+@start@ returns and the program main terminates.
+
+
+\subsection{Coroutine Implementation}
+
+A significant implementation challenge for coroutines (and threads, see section \ref{threads}) is adding extra fields and executing code after/before the coroutine constructor/destructor and coroutine main to create/initialize/de-initialize/destroy extra fields and the stack.
+There are several solutions to this problem and the chosen option forced the \CFA coroutine design.
+
+Object-oriented inheritance provides extra fields and code in a restricted context, but it requires programmers to explicitly perform the inheritance:
+\begin{cfa}
+struct mycoroutine $\textbf{\textsf{inherits}}$ baseCoroutine { ... }
+\end{cfa}
+and the programming language (and possibly its tool set, \eg debugger) may need to understand @baseCoroutine@ because of the stack.
+Furthermore, the execution of constructs/destructors is in the wrong order for certain operations, \eg for threads;
+\eg, if the thread is implicitly started, it must start \emph{after} all constructors, because the thread relies on a completely initialized object, but the inherited constructor runs \emph{before} the derived.
+
+An alternatively is composition:
+\begin{cfa}
+struct mycoroutine {
+	... // declarations
+	baseCoroutine dummy; // composition, last declaration
+}
+\end{cfa}
+which also requires an explicit declaration that must be the last one to ensure correct initialization order.
+However, there is nothing preventing wrong placement or multiple declarations.
 
 For coroutines as for threads, many implementations are based on routine pointers or function objects~\cite{Butenhof97, C++14, MS:VisualC++, BoostCoroutines15}.
-For example, Boost implements coroutines in terms of four functor object types:
+For example, Boost implements coroutines in terms of four functor object-types:
 \begin{cfa}
 asymmetric_coroutine<>::pull_type
@@ -1061,94 +988,115 @@
 symmetric_coroutine<>::yield_type
 \end{cfa}
-Often, the canonical threading paradigm in languages is based on function pointers, @pthread@ being one of the most well-known examples.
-The main problem of this approach is that the thread usage is limited to a generic handle that must otherwise be wrapped in a custom type.
-Since the custom type is simple to write in \CFA and solves several issues, added support for routine/lambda based coroutines adds very little.
-
-A variation of this would be to use a simple function pointer in the same way @pthread@ does for threads:
-\begin{cfa}
-void foo( coroutine_t cid, void* arg ) {
-	int* value = (int*)arg;
+Similarly, the canonical threading paradigm is often based on function pointers, \eg @pthread@~\cite{pthreads}, \Csharp~\cite{Csharp}, Go~\cite{Go}, and Scala~\cite{Scala}.
+However, the generic thread-handle (identifier) is limited (few operations), unless it is wrapped in a custom type.
+\begin{cfa}
+void mycor( coroutine_t cid, void * arg ) {
+	int * value = (int *)arg;				$\C{// type unsafe, pointer-size only}$
 	// Coroutine body
 }
-
 int main() {
-	int value = 0;
-	coroutine_t cid = coroutine_create( &foo, (void*)&value );
-	coroutine_resume( &cid );
-}
-\end{cfa}
-This semantics is more common for thread interfaces but coroutines work equally well.
-As discussed in section \ref{threads}, this approach is superseded by static approaches in terms of expressivity.
-
-
-\subsubsection{Alternative: Trait-Based Coroutines}
-
-Finally, the underlying approach, which is the one closest to \CFA idioms, is to use trait-based lazy coroutines.
-This approach defines a coroutine as anything that satisfies the trait @is_coroutine@ (as defined below) and is used as a coroutine.
-
-\begin{cfa}
-trait is_coroutine(dtype T) {
-      void main(T& this);
-      coroutine_desc* get_coroutine(T& this);
+	int input = 0, output;
+	coroutine_t cid = coroutine_create( &mycor, (void *)&input ); $\C{// type unsafe, pointer-size only}$
+	coroutine_resume( cid, (void *)input, (void **)&output ); $\C{// type unsafe, pointer-size only}$
+}
+\end{cfa}
+Since the custom type is simple to write in \CFA and solves several issues, added support for routine/lambda-based coroutines adds very little.
+
+The selected approach is to use language support by introducing a new kind of aggregate (structure):
+\begin{cfa}
+coroutine Fibonacci {
+	int fn; // communication variables
 };
-
-forall( dtype T | is_coroutine(T) ) void suspend(T&);
-forall( dtype T | is_coroutine(T) ) void resume (T&);
-\end{cfa}
-This ensures that an object is not a coroutine until @resume@ is called on the object.
-Correspondingly, any object that is passed to @resume@ is a coroutine since it must satisfy the @is_coroutine@ trait to compile.
+\end{cfa}
+The @coroutine@ keyword means the compiler (and tool set) can find and inject code where needed.
+The downside of this approach is that it makes coroutine a special case in the language.
+Users wanting to extend coroutines or build their own for various reasons can only do so in ways offered by the language.
+Furthermore, implementing coroutines without language supports also displays the power of a programming language.
+While this is ultimately the option used for idiomatic \CFA code, coroutines and threads can still be constructed without using the language support.
+The reserved keyword eases use for the common cases.
+
+Part of the mechanism to generalize coroutines is using a \CFA trait, which defines a coroutine as anything satisfying the trait @is_coroutine@, and this trait is used to restrict coroutine-manipulation functions:
+\begin{cfa}
+trait is_coroutine( dtype T ) {
+      void main( T & this );
+      coroutine_desc * get_coroutine( T & this );
+};
+forall( dtype T | is_coroutine(T) ) void get_coroutine( T & );
+forall( dtype T | is_coroutine(T) ) void suspend( T & );
+forall( dtype T | is_coroutine(T) ) void resume( T & );
+\end{cfa}
+This definition ensures there is a statically-typed @main@ function that is the starting point (first stack frame) of a coroutine.
+No return value or additional parameters are necessary for this function, because the coroutine type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values.
+As well, any object passed to @suspend@ and @resume@ is a coroutine since it must satisfy the @is_coroutine@ trait to compile.
 The advantage of this approach is that users can easily create different types of coroutines, for example, changing the memory layout of a coroutine is trivial when implementing the @get_coroutine@ routine.
-The \CFA keyword @coroutine@ simply has the effect of implementing the getter and forward declarations required for users to implement the main routine.
-
-\begin{center}
-\begin{tabular}{c c c}
-\begin{cfa}[tabsize=3]
-coroutine MyCoroutine {
-	int someValue;
+The \CFA keyword @coroutine@ implicitly implements the getter and forward declarations required for implementing the coroutine main:
+\begin{cquote}
+\begin{tabular}{@{}ccc@{}}
+\begin{cfa}
+coroutine MyCor {
+	int value;
+
 };
-\end{cfa} & == & \begin{cfa}[tabsize=3]
-struct MyCoroutine {
-	int someValue;
-	coroutine_desc __cor;
+\end{cfa}
+& {\Large $\Rightarrow$} &
+\begin{tabular}{@{}ccc@{}}
+\begin{cfa}
+struct MyCor {
+	int value;
+	coroutine_desc cor;
 };
-
-static inline
-coroutine_desc* get_coroutine(
-	struct MyCoroutine& this
-) {
-	return &this.__cor;
-}
-
-void main(struct MyCoroutine* this);
+\end{cfa}
+&
+\begin{cfa}
+static inline coroutine_desc *
+get_coroutine( MyCor & this ) {
+	return &this.cor;
+}
+\end{cfa}
+&
+\begin{cfa}
+void main( MyCor * this );
+
+
+
 \end{cfa}
 \end{tabular}
-\end{center}
-
-The combination of these two approaches allows users new to coroutining and concurrency to have an easy and concise specification, while more advanced users have tighter control on memory layout and initialization.
-
-\subsection{Thread Interface}\label{threads}
-The basic building blocks of multithreading in \CFA are \textbf{cfathread}.
-Both user and kernel threads are supported, where user threads are the concurrency mechanism and kernel threads are the parallel mechanism.
-User threads offer a flexible and lightweight interface.
-A thread can be declared using a struct declaration @thread@ as follows:
-
-\begin{cfa}
-thread foo {};
-\end{cfa}
-
-As for coroutines, the keyword is a thin wrapper around a \CFA trait:
-
-\begin{cfa}
-trait is_thread(dtype T) {
-      void ^?{}(T & mutex this);
-      void main(T & this);
-      thread_desc* get_thread(T & this);
+\end{tabular}
+\end{cquote}
+The combination of these two approaches allows an easy and concise specification to coroutining (and concurrency) for normal users, while more advanced users have tighter control on memory layout and initialization.
+
+
+\subsection{Thread Interface}
+\label{threads}
+
+Both user and kernel threads are supported, where user threads provide concurrency and kernel threads provide parallelism.
+Like coroutines and for the same design reasons, the selected approach for user threads is to use language support by introducing a new kind of aggregate (structure) and a \CFA trait:
+\begin{cquote}
+\begin{tabular}{@{}c@{\hspace{2\parindentlnth}}c@{}}
+\begin{cfa}
+thread myThread {
+	// communication variables
 };
-\end{cfa}
-
-Obviously, for this thread implementation to be useful it must run some user code.
-Several other threading interfaces use a function-pointer representation as the interface of threads (for example \Csharp~\cite{Csharp} and Scala~\cite{Scala}).
-However, this proposal considers that statically tying a @main@ routine to a thread supersedes this approach.
-Since the @main@ routine is already a special routine in \CFA (where the program begins), it is a natural extension of the semantics to use overloading to declare mains for different threads (the normal main being the main of the initial thread).
+
+
+\end{cfa}
+&
+\begin{cfa}
+trait is_thread( dtype T ) {
+      void main( T & this );
+      thread_desc * get_thread( T & this );
+      void ^?{}( T & `mutex` this );
+};
+\end{cfa}
+\end{tabular}
+\end{cquote}
+(The qualifier @mutex@ for the destructor parameter is discussed in Section~\ref{s:Monitors}.)
+Like a coroutine, the statically-typed @main@ function is the starting point (first stack frame) of a user thread.
+The difference is that a coroutine borrows a thread from its caller, so the first thread resuming a coroutine creates an instance of @main@;
+whereas, a user thread receives its own thread from the runtime system, which starts in @main@ as some point after the thread constructor is run.\footnote{
+The \lstinline@main@ function is already a special routine in C (where the program begins), so it is a natural extension of the semantics to use overloading to declare mains for different coroutines/threads (the normal main being the main of the initial thread).}
+No return value or additional parameters are necessary for this function, because the task type allows an arbitrary number of interface functions with corresponding arbitrary typed input/output values.
+
+\begin{comment} % put in appendix with coroutine version ???
 As such the @main@ routine of a thread can be defined as
 \begin{cfa}
@@ -1189,149 +1137,133 @@
 }
 \end{cfa}
-
 A consequence of the strongly typed approach to main is that memory layout of parameters and return values to/from a thread are now explicitly specified in the \textbf{api}.
-
-Of course, for threads to be useful, it must be possible to start and stop threads and wait for them to complete execution.
-While using an \textbf{api} such as @fork@ and @join@ is relatively common in the literature, such an interface is unnecessary.
-Indeed, the simplest approach is to use \textbf{raii} principles and have threads @fork@ after the constructor has completed and @join@ before the destructor runs.
-\begin{cfa}
-thread World;
-
-void main(World & this) {
+\end{comment}
+
+For user threads to be useful, it must be possible to start and stop the underlying thread, and wait for it to complete execution.
+While using an API such as @fork@ and @join@ is relatively common, such an interface is awkward and unnecessary.
+A simple approach is to use allocation/deallocation principles, and have threads implicitly @fork@ after construction and @join@ before destruction.
+\begin{cfa}
+thread World {};
+void main( World & this ) {
 	sout | "World!" | endl;
 }
-
-void main() {
-	World w;
-	// Thread forks here
-
-	// Printing "Hello " and "World!" are run concurrently
-	sout | "Hello " | endl;
-
-	// Implicit join at end of scope
-}
-\end{cfa}
-
-This semantic has several advantages over explicit semantics: a thread is always started and stopped exactly once, users cannot make any programming errors, and it naturally scales to multiple threads meaning basic synchronization is very simple.
-
-\begin{cfa}
-thread MyThread {
-	//...
+int main() {
+	World w`[10]`;							$\C{// implicit forks after creation}$
+	sout | "Hello " | endl;					$\C{// "Hello " and 10 "World!" printed concurrently}$
+}											$\C{// implicit joins before destruction}$
+\end{cfa}
+This semantics ensures a thread is started and stopped exactly once, eliminating some programming error, and scales to multiple threads for basic (termination) synchronization.
+This tree-structure (lattice) create/delete from C block-structure is generalized by using dynamic allocation, so threads can outlive the scope in which they are created, much like dynamically allocating memory lets objects outlive the scope in which they are created.
+\begin{cfa}
+int main() {
+	MyThread * heapLived;
+	{
+		MyThread blockLived;				$\C{// fork block-based thread}$
+		heapLived = `new`( MyThread );		$\C{// fork heap-based thread}$
+		...
+	}										$\C{// join block-based thread}$
+	...
+	`delete`( heapLived );					$\C{// join heap-based thread}$
+}
+\end{cfa}
+The heap-based approach allows arbitrary thread-creation topologies, with respect to fork/join-style concurrency.
+
+Figure~\ref{s:ConcurrentMatrixSummation} shows concurrently adding the rows of a matrix and then totalling the subtotals sequential, after all the row threads have terminated.
+The program uses heap-based threads because each thread needs different constructor values.
+(Python provides a simple iteration mechanism to initialize array elements to different values allowing stack allocation.)
+The allocation/deallocation pattern appears unusual because allocated objects are immediately deleted without any intervening code.
+However, for threads, the deletion provides implicit synchronization, which is the intervening code.
+While the subtotals are added in linear order rather than completion order, which slight inhibits concurrency, the computation is restricted by the critical-path thread (\ie the thread that takes the longest), and so any inhibited concurrency is very small as totalling the subtotals is trivial.
+
+\begin{figure}
+\begin{cfa}
+thread Adder {
+    int * row, cols, & subtotal;			$\C{// communication}$
 };
-
-// main
-void main(MyThread& this) {
-	//...
-}
-
-void foo() {
-	MyThread thrds[10];
-	// Start 10 threads at the beginning of the scope
-
-	DoStuff();
-
-	// Wait for the 10 threads to finish
-}
-\end{cfa}
-
-However, one of the drawbacks of this approach is that threads always form a tree where nodes must always outlive their children, \ie they are always destroyed in the opposite order of construction because of C scoping rules.
-This restriction is relaxed by using dynamic allocation, so threads can outlive the scope in which they are created, much like dynamically allocating memory lets objects outlive the scope in which they are created.
-
-\begin{cfa}
-thread MyThread {
-	//...
-};
-
-void main(MyThread& this) {
-	//...
-}
-
-void foo() {
-	MyThread* long_lived;
-	{
-		// Start a thread at the beginning of the scope
-		MyThread short_lived;
-
-		// create another thread that will outlive the thread in this scope
-		long_lived = new MyThread;
-
-		DoStuff();
-
-		// Wait for the thread short_lived to finish
-	}
-	DoMoreStuff();
-
-	// Now wait for the long_lived to finish
-	delete long_lived;
-}
-\end{cfa}
-
-
-% ======================================================================
-% ======================================================================
-\section{Concurrency}
-% ======================================================================
-% ======================================================================
-Several tools can be used to solve concurrency challenges.
-Since many of these challenges appear with the use of mutable shared state, some languages and libraries simply disallow mutable shared state (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka (Scala)~\cite{Akka}).
-In these paradigms, interaction among concurrent objects relies on message passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (channels~\cite{CSP,Go} for example).
-However, in languages that use routine calls as their core abstraction mechanism, these approaches force a clear distinction between concurrent and non-concurrent paradigms (\ie message passing versus routine calls).
-This distinction in turn means that, in order to be effective, programmers need to learn two sets of design patterns.
+void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
+    adder.[ row, cols, &subtotal ] = [ row, cols, &subtotal ];
+}
+void main( Adder & adder ) with( adder ) {
+    subtotal = 0;
+    for ( int c = 0; c < cols; c += 1 ) {
+		subtotal += row[c];
+    }
+}
+int main() {
+    const int rows = 10, cols = 1000;
+    int matrix[rows][cols], subtotals[rows], total = 0;
+    // read matrix
+    Adder * adders[rows];
+    for ( int r = 0; r < rows; r += 1 ) {	$\C{// start threads to sum rows}$
+		adders[r] = new( matrix[r], cols, &subtotals[r] );
+    }
+    for ( int r = 0; r < rows; r += 1 ) {	$\C{// wait for threads to finish}$
+		delete( adders[r] );				$\C{// termination join}$
+		total += subtotals[r];				$\C{// total subtotal}$
+    }
+    sout | total | endl;
+}
+\end{cfa}
+\caption{Concurrent Matrix Summation}
+\label{s:ConcurrentMatrixSummation}
+\end{figure}
+
+
+\section{Synchronization / Mutual Exclusion}
+
+Uncontrolled non-deterministic execution is meaningless.
+To reestablish meaningful execution requires mechanisms to reintroduce determinism (control non-determinism), called synchronization and mutual exclusion, where synchronization is a timing relationship among threads and mutual exclusion is an access-control mechanism on data shared by threads.
+Since many deterministic challenges appear with the use of mutable shared state, some languages/libraries disallow it (Erlang~\cite{Erlang}, Haskell~\cite{Haskell}, Akka~\cite{Akka} (Scala)).
+In these paradigms, interaction among concurrent objects is performed by stateless message-passing~\cite{Thoth,Harmony,V-Kernel} or other paradigms closely relate to networking concepts (\eg channels~\cite{CSP,Go}).
+However, in call/return-based languages, these approaches force a clear distinction (\ie introduce a new programming paradigm) between non-concurrent and concurrent computation (\ie function call versus message passing).
+This distinction means a programmers needs to learn two sets of design patterns.
 While this distinction can be hidden away in library code, effective use of the library still has to take both paradigms into account.
-
-Approaches based on shared memory are more closely related to non-concurrent paradigms since they often rely on basic constructs like routine calls and shared objects.
-At the lowest level, concurrent paradigms are implemented as atomic operations and locks.
-Many such mechanisms have been proposed, including semaphores~\cite{Dijkstra68b} and path expressions~\cite{Campbell74}.
-However, for productivity reasons it is desirable to have a higher-level construct be the core concurrency paradigm~\cite{Hochstein05}.
-
-An approach that is worth mentioning because it is gaining in popularity is transactional memory~\cite{Herlihy93}.
-While this approach is even pursued by system languages like \CC~\cite{Cpp-Transactions}, the performance and feature set is currently too restrictive to be the main concurrency paradigm for system languages, which is why it was rejected as the core paradigm for concurrency in \CFA.
-
-One of the most natural, elegant, and efficient mechanisms for synchronization and communication, especially for shared-memory systems, is the \emph{monitor}.
+In contrast, approaches based on statefull models more closely resemble the standard call/return programming-model, resulting in a single programming paradigm.
+
+At the lowest level, concurrent control is implemented as atomic operations, upon which different kinds of locks mechanism are constructed, \eg semaphores~\cite{Dijkstra68b} and path expressions~\cite{Campbell74}.
+However, for productivity it is always desirable to use the highest-level construct that provides the necessary efficiency~\cite{Hochstein05}.
+A newer approach is transactional memory~\cite{Herlihy93}.
+While this approach is pursued in hardware~\cite{Nakaike15} and system languages, like \CC~\cite{Cpp-Transactions}, the performance and feature set is still too restrictive to be the main concurrency paradigm for system languages, which is why it was rejected as the core paradigm for concurrency in \CFA.
+
+One of the most natural, elegant, and efficient mechanisms for synchronization and mutual exclusion for shared-memory systems is the \emph{monitor}.
 Monitors were first proposed by Brinch Hansen~\cite{Hansen73} and later described and extended by C.A.R.~Hoare~\cite{Hoare74}.
-Many programming languages---\eg Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java}---provide monitors as explicit language constructs.
+Many programming languages -- \eg Concurrent Pascal~\cite{ConcurrentPascal}, Mesa~\cite{Mesa}, Modula~\cite{Modula-2}, Turing~\cite{Turing:old}, Modula-3~\cite{Modula-3}, NeWS~\cite{NeWS}, Emerald~\cite{Emerald}, \uC~\cite{Buhr92a} and Java~\cite{Java} -- provide monitors as explicit language constructs.
 In addition, operating-system kernels and device drivers have a monitor-like structure, although they often use lower-level primitives such as semaphores or locks to simulate monitors.
-For these reasons, this project proposes monitors as the core concurrency construct.
-
-
-\subsection{Basics}
-
-Non-determinism requires concurrent systems to offer support for mutual-exclusion and synchronization.
-Mutual-exclusion is the concept that only a fixed number of threads can access a critical section at any given time, where a critical section is a group of instructions on an associated portion of data that requires the restricted access.
-On the other hand, synchronization enforces relative ordering of execution and synchronization tools provide numerous mechanisms to establish timing relationships among threads.
-
-
-\subsubsection{Mutual-Exclusion}
-
-As mentioned above, mutual-exclusion is the guarantee that only a fix number of threads can enter a critical section at once.
+For these reasons, this project proposes monitors as the core concurrency construct, upon which even higher-level approaches can be easily constructed..
+
+
+\subsection{Mutual Exclusion}
+
+A group of instructions manipulating a specific instance of shared data that must be performed atomically is called an (individual) \newterm{critical-section}~\cite{Dijkstra65}.
+A generalization is a \newterm{group critical-section}~\cite{Joung00}, where multiple tasks with the same session may use the resource simultaneously, but different sessions may not use the resource simultaneously.
+The readers/writer problem~\cite{Courtois71} is an instance of a group critical-section, where readers have the same session and all writers have a unique session.
+\newterm{Mutual exclusion} enforces the correction number of threads are using a critical section at the same time.
+
 However, many solutions exist for mutual exclusion, which vary in terms of performance, flexibility and ease of use.
-Methods range from low-level locks, which are fast and flexible but require significant attention to be correct, to  higher-level concurrency techniques, which sacrifice some performance in order to improve ease of use.
-Ease of use comes by either guaranteeing some problems cannot occur (\eg being deadlock free) or by offering a more explicit coupling between data and corresponding critical section.
+Methods range from low-level locks, which are fast and flexible but require significant attention for correctness, to higher-level concurrency techniques, which sacrifice some performance to improve ease of use.
+Ease of use comes by either guaranteeing some problems cannot occur (\eg deadlock free), or by offering a more explicit coupling between shared data and critical section.
 For example, the \CC @std::atomic<T>@ offers an easy way to express mutual-exclusion on a restricted set of operations (\eg reading/writing large types atomically).
-Another challenge with low-level locks is composability.
-Locks have restricted composability because it takes careful organizing for multiple locks to be used while preventing deadlocks.
-Easing composability is another feature higher-level mutual-exclusion mechanisms often offer.
-
-
-\subsubsection{Synchronization}
-
-As with mutual-exclusion, low-level synchronization primitives often offer good performance and good flexibility at the cost of ease of use.
-Again, higher-level mechanisms often simplify usage by adding either better coupling between synchronization and data (\eg message passing) or offering a simpler solution to otherwise involved challenges.
+However, a significant challenge with (low-level) locks is composability because it takes careful organization for multiple locks to be used while preventing deadlock.
+Easing composability is another feature higher-level mutual-exclusion mechanisms offer.
+
+
+\subsection{Synchronization}
+
+Synchronization enforces relative ordering of execution, and synchronization tools provide numerous mechanisms to establish these timing relationships.
+Low-level synchronization primitives offer good performance and flexibility at the cost of ease of use.
+Higher-level mechanisms often simplify usage by adding better coupling between synchronization and data (\eg message passing), or offering a simpler solution to otherwise involved challenges, \eg barrier lock.
 As mentioned above, synchronization can be expressed as guaranteeing that event \textit{X} always happens before \textit{Y}.
-Most of the time, synchronization happens within a critical section, where threads must acquire mutual-exclusion in a certain order.
-However, it may also be desirable to guarantee that event \textit{Z} does not occur between \textit{X} and \textit{Y}.
-Not satisfying this property is called \textbf{barging}.
-For example, where event \textit{X} tries to effect event \textit{Y} but another thread acquires the critical section and emits \textit{Z} before \textit{Y}.
-The classic example is the thread that finishes using a resource and unblocks a thread waiting to use the resource, but the unblocked thread must compete to acquire the resource.
+Often synchronization is used to order access to a critical section, \eg ensuring the next kind of thread to enter a critical section is a reader thread
+If a writer thread is scheduled for next access, but another reader thread acquires the critical section first, the reader has \newterm{barged}.
+Barging can result in staleness/freshness problems, where a reader barges ahead of a write and reads temporally stale data, or a writer barges ahead of another writer overwriting data with a fresh value preventing the previous value from having an opportunity to be read.
 Preventing or detecting barging is an involved challenge with low-level locks, which can be made much easier by higher-level constructs.
-This challenge is often split into two different methods, barging avoidance and barging prevention.
-Algorithms that use flag variables to detect barging threads are said to be using barging avoidance, while algorithms that baton-pass locks~\cite{Andrews89} between threads instead of releasing the locks are said to be using barging prevention.
-
-
-% ======================================================================
-% ======================================================================
+This challenge is often split into two different approaches, barging avoidance and barging prevention.
+Algorithms that allow a barger but divert it until later are avoiding the barger, while algorithms that preclude a barger from entering during synchronization in the critical section prevent the barger completely.
+baton-pass locks~\cite{Andrews89} between threads instead of releasing the locks are said to be using barging prevention.
+
+
 \section{Monitors}
-% ======================================================================
-% ======================================================================
+\label{s:Monitors}
+
 A \textbf{monitor} is a set of routines that ensure mutual-exclusion when accessing shared state.
 More precisely, a monitor is a programming technique that associates mutual-exclusion to routine scopes, as opposed to mutex locks, where mutual-exclusion is defined by lock/release calls independently of any scoping of the calling routine.
@@ -2501,5 +2433,5 @@
 Given these building blocks, it is possible to reproduce all three of the popular paradigms.
 Indeed, \textbf{uthread} is the default paradigm in \CFA.
-However, disabling \textbf{preemption} on the \textbf{cfacluster} means \textbf{cfathread} effectively become \textbf{fiber}.
+However, disabling \textbf{preemption} on a cluster means threads effectively become fibers.
 Since several \textbf{cfacluster} with different scheduling policy can coexist in the same application, this allows \textbf{fiber} and \textbf{uthread} to coexist in the runtime of an application.
 Finally, it is possible to build executors for thread pools from \textbf{uthread} or \textbf{fiber}, which includes specialized jobs like actors~\cite{Actors}.
Index: doc/papers/general/Paper.tex
===================================================================
--- doc/papers/general/Paper.tex	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ doc/papers/general/Paper.tex	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -243,5 +243,5 @@
 Nevertheless, C, first standardized almost forty years ago~\cite{ANSI89:C}, lacks many features that make programming in more modern languages safer and more productive.
 
-\CFA (pronounced ``C-for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that adds modern language-features to C, while maintaining both source and runtime compatibility with C and a familiar programming model for programmers.
+\CFA (pronounced ``C-for-all'', and written \CFA or Cforall) is an evolutionary extension of the C programming language that adds modern language-features to C, while maintaining source and runtime compatibility in the familiar C programming model.
 The four key design goals for \CFA~\cite{Bilson03} are:
 (1) The behaviour of standard C code must remain the same when translated by a \CFA compiler as when translated by a C compiler;
@@ -273,5 +273,5 @@
 Starting with a translator versus a compiler makes it easier and faster to generate and debug C object-code rather than intermediate, assembler or machine code.
 The translator design is based on the \emph{visitor pattern}, allowing multiple passes over the abstract code-tree, which works well for incrementally adding new feature through additional visitor passes.
-At the heart of the translator is the type resolver, which handles the polymorphic routine/type overload-resolution.
+At the heart of the translator is the type resolver, which handles the polymorphic function/type overload-resolution.
 % @plg2[8]% cd cfa-cc/src; cloc libcfa
 % -------------------------------------------------------------------------------
@@ -310,6 +310,6 @@
 
 Finally, it is impossible to describe a programming language without usages before definitions.
-Therefore, syntax and semantics appear before explanations;
-hence, patience is necessary until details are presented.
+Therefore, syntax and semantics appear before explanations, and related work (Section~\ref{s:RelatedWork}) is deferred until \CFA is presented;
+hence, patience is necessary until details are discussed.
 
 
@@ -329,5 +329,5 @@
 \end{quote}
 \vspace{-9pt}
-C already has a limited form of ad-hoc polymorphism in the form of its basic arithmetic operators, which apply to a variety of different types using identical syntax. 
+C already has a limited form of ad-hoc polymorphism in its basic arithmetic operators, which apply to a variety of different types using identical syntax. 
 \CFA extends the built-in operator overloading by allowing users to define overloads for any function, not just operators, and even any variable;
 Section~\ref{sec:libraries} includes a number of examples of how this overloading simplifies \CFA programming relative to C. 
@@ -653,5 +653,5 @@
 }
 \end{cfa}
-Since @pair( T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@, so the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type-checked to ensure the fields of both pairs and the arguments to the comparison function match in type.
+Since @pair( T *, T * )@ is a concrete type, there are no implicit parameters passed to @lexcmp@, so the generated code is identical to a function written in standard C using @void *@, yet the \CFA version is type-checked to ensure the members of both pairs and the arguments to the comparison function match in type.
 
 Another useful pattern enabled by reused dtype-static type instantiations is zero-cost \newterm{tag-structures}.
@@ -815,5 +815,5 @@
 \subsection{Member Access}
 
-It is also possible to access multiple fields from a single expression using a \newterm{member-access}.
+It is also possible to access multiple members from a single expression using a \newterm{member-access}.
 The result is a single tuple-valued expression whose type is the tuple of the types of the members, \eg:
 \begin{cfa}
@@ -1020,10 +1020,10 @@
 \begin{cfa}
 forall( dtype T0, dtype T1 | sized(T0) | sized(T1) ) struct _tuple2 {
-	T0 field_0;  T1 field_1;					$\C{// generated before the first 2-tuple}$
+	T0 member_0;  T1 member_1;					$\C{// generated before the first 2-tuple}$
 };
 _tuple2(int, int) f() {
 	_tuple2(double, double) x;
 	forall( dtype T0, dtype T1, dtype T2 | sized(T0) | sized(T1) | sized(T2) ) struct _tuple3 {
-		T0 field_0;  T1 field_1;  T2 field_2;	$\C{// generated before the first 3-tuple}$
+		T0 member_0;  T1 member_1;  T2 member_2;	$\C{// generated before the first 3-tuple}$
 	};
 	_tuple3(int, double, int) y;
@@ -1033,5 +1033,5 @@
 
 \begin{comment}
-Since tuples are essentially structures, tuple indexing expressions are just field accesses:
+Since tuples are essentially structures, tuple indexing expressions are just member accesses:
 \begin{cfa}
 void f(int, [double, char]);
@@ -1047,9 +1047,9 @@
 _tuple2(int, double) x;
 
-x.field_0+x.field_1;
-printf("%d %g\n", x.field_0, x.field_1);
-f(x.field_0, (_tuple2){ x.field_1, 'z' });
-\end{cfa}
-Note that due to flattening, @x@ used in the argument position is converted into the list of its fields.
+x.member_0+x.member_1;
+printf("%d %g\n", x.member_0, x.member_1);
+f(x.member_0, (_tuple2){ x.member_1, 'z' });
+\end{cfa}
+Note that due to flattening, @x@ used in the argument position is converted into the list of its members.
 In the call to @f@, the second and third argument components are structured into a tuple argument.
 Similarly, tuple member expressions are recursively expanded into a list of member access expressions.
@@ -1083,5 +1083,5 @@
 
 The various kinds of tuple assignment, constructors, and destructors generate GNU C statement expressions.
-A variable is generated to store the value produced by a statement expression, since its fields may need to be constructed with a non-trivial constructor and it may need to be referred to multiple time, \eg in a unique expression.
+A variable is generated to store the value produced by a statement expression, since its members may need to be constructed with a non-trivial constructor and it may need to be referred to multiple time, \eg in a unique expression.
 The use of statement expressions allows the translator to arbitrarily generate additional temporary variables as needed, but binds the implementation to a non-standard extension of the C language.
 However, there are other places where the \CFA translator makes use of GNU C extensions, such as its use of nested functions, so this restriction is not new.
@@ -1493,5 +1493,5 @@
 
 Heterogeneous data is often aggregated into a structure/union.
-To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate field-qualification by opening a scope containing the field identifiers.
+To reduce syntactic noise, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate member-qualification by opening a scope containing the member identifiers.
 \begin{cquote}
 \vspace*{-\baselineskip}%???
@@ -1530,12 +1530,12 @@
 The type must be an aggregate type.
 (Enumerations are already opened.)
-The object is the implicit qualifier for the open structure-fields.
+The object is the implicit qualifier for the open structure-members.
 
 All expressions in the expression list are open in parallel within the compound statement, which is different from Pascal, which nests the openings from left to right.
-The difference between parallel and nesting occurs for fields with the same name and type:
-\begin{cfa}
-struct S { int `i`; int j; double m; } s, w;
+The difference between parallel and nesting occurs for members with the same name and type:
+\begin{cfa}
+struct S { int `i`; int j; double m; } s, w;	$\C{// member i has same type in structure types S and T}$
 struct T { int `i`; int k; int m; } t, w;
-with ( s, t ) {
+with ( s, t ) {								$\C{// open structure variables s and t in parallel}$
 	j + k;									$\C{// unambiguous, s.j + t.k}$
 	m = 5.0;								$\C{// unambiguous, s.m = 5.0}$
@@ -1549,5 +1549,5 @@
 For parallel semantics, both @s.i@ and @t.i@ are visible, so @i@ is ambiguous without qualification;
 for nested semantics, @t.i@ hides @s.i@, so @i@ implies @t.i@.
-\CFA's ability to overload variables means fields with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates.
+\CFA's ability to overload variables means members with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates.
 Qualification or a cast is used to disambiguate.
 
@@ -1555,5 +1555,5 @@
 \begin{cfa}
 void ?{}( S & s, int i ) with ( s ) {		$\C{// constructor}$
-	`s.i = i;`  j = 3;  m = 5.5;			$\C{// initialize fields}$
+	`s.i = i;`  j = 3;  m = 5.5;			$\C{// initialize members}$
 }
 \end{cfa}
@@ -1659,5 +1659,5 @@
 \lstMakeShortInline@%
 \end{cquote}
-The only exception is bit field specification, which always appear to the right of the base type.
+The only exception is bit-field specification, which always appear to the right of the base type.
 % Specifically, the character @*@ is used to indicate a pointer, square brackets @[@\,@]@ are used to represent an array or function return value, and parentheses @()@ are used to indicate a function parameter.
 However, unlike C, \CFA type declaration tokens are distributed across all variables in the declaration list.
@@ -1715,5 +1715,5 @@
 // pointer to array of 5 doubles
 
-// common bit field syntax
+// common bit-field syntax
 
 
@@ -1911,8 +1911,8 @@
 \subsection{Type Nesting}
 
-Nested types provide a mechanism to organize associated types and refactor a subset of fields into a named aggregate (\eg sub-aggregates @name@, @address@, @department@, within aggregate @employe@).
+Nested types provide a mechanism to organize associated types and refactor a subset of members into a named aggregate (\eg sub-aggregates @name@, @address@, @department@, within aggregate @employe@).
 Java nested types are dynamic (apply to objects), \CC are static (apply to the \lstinline[language=C++]@class@), and C hoists (refactors) nested types into the enclosing scope, meaning there is no need for type qualification.
 Since \CFA in not object-oriented, adopting dynamic scoping does not make sense;
-instead \CFA adopts \CC static nesting, using the field-selection operator ``@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``@::@'' (see Figure~\ref{f:TypeNestingQualification}).
+instead \CFA adopts \CC static nesting, using the member-selection operator ``@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``@::@'' (see Figure~\ref{f:TypeNestingQualification}).
 \begin{figure}
 \centering
@@ -2005,6 +2005,6 @@
 Destruction parameters are useful for specifying storage-management actions, such as de-initialize but not deallocate.}.
 \begin{cfa}
-struct VLA { int len, * data; };			$\C{// variable length array of integers}$
-void ?{}( VLA & vla ) with ( vla ) { len = 10;  data = alloc( len ); }  $\C{// default constructor}$
+struct VLA { int size, * data; };			$\C{// variable length array of integers}$
+void ?{}( VLA & vla ) with ( vla ) { size = 10;  data = alloc( size ); }  $\C{// default constructor}$
 void ^?{}( VLA & vla ) with ( vla ) { free( data ); } $\C{// destructor}$
 {
@@ -2013,5 +2013,5 @@
 \end{cfa}
 @VLA@ is a \newterm{managed type}\footnote{
-A managed type affects the runtime environment versus a self-contained type.}: a type requiring a non-trivial constructor or destructor, or with a field of a managed type. 
+A managed type affects the runtime environment versus a self-contained type.}: a type requiring a non-trivial constructor or destructor, or with a member of a managed type. 
 A managed type is implicitly constructed at allocation and destructed at deallocation to ensure proper interaction with runtime resources, in this case, the @data@ array in the heap. 
 For details of the code-generation placement of implicit constructor and destructor calls among complex executable statements see~\cite[\S~2.2]{Schluntz17}.
@@ -2019,9 +2019,9 @@
 \CFA also provides syntax for \newterm{initialization} and \newterm{copy}:
 \begin{cfa}
-void ?{}( VLA & vla, int size, char fill ) with ( vla ) {  $\C{// initialization}$
-	len = size;  data = alloc( len, fill );
+void ?{}( VLA & vla, int size, char fill = '\0' ) {  $\C{// initialization}$
+	vla.[ size, data ] = [ size, alloc( size, fill ) ];
 }
 void ?{}( VLA & vla, VLA other ) {			$\C{// copy, shallow}$
-	vla.len = other.len;  vla.data = other.data;
+	vla = other;
 }
 \end{cfa}
@@ -2036,5 +2036,5 @@
 
 \CFA constructors may be explicitly called, like Java, and destructors may be explicitly called, like \CC.
-Explicit calls to constructors double as a \CC-style \emph{placement syntax}, useful for construction of member fields in user-defined constructors and reuse of existing storage allocations.
+Explicit calls to constructors double as a \CC-style \emph{placement syntax}, useful for construction of members in user-defined constructors and reuse of existing storage allocations.
 Like the other operators in \CFA, there is a concise syntax for constructor/destructor function calls:
 \begin{cfa}
@@ -2048,6 +2048,5 @@
 	y{ x };									$\C{// reallocate y, points to x}$
 	x{};									$\C{// reallocate x, not pointing to y}$
-	//  ^z{};  ^y{};  ^x{};
-}
+}	//  ^z{};  ^y{};  ^x{};
 \end{cfa}
 
@@ -2060,7 +2059,7 @@
 For compatibility with C, a copy constructor from the first union member type is also defined.
 For @struct@ types, each of the four functions are implicitly defined to call their corresponding functions on each member of the struct. 
-To better simulate the behaviour of C initializers, a set of \newterm{field constructors} is also generated for structures. 
+To better simulate the behaviour of C initializers, a set of \newterm{member constructors} is also generated for structures. 
 A constructor is generated for each non-empty prefix of a structure's member-list to copy-construct the members passed as parameters and default-construct the remaining members.
-To allow users to limit the set of constructors available for a type, when a user declares any constructor or destructor, the corresponding generated function and all field constructors for that type are hidden from expression resolution;
+To allow users to limit the set of constructors available for a type, when a user declares any constructor or destructor, the corresponding generated function and all member constructors for that type are hidden from expression resolution;
 similarly, the generated default constructor is hidden upon declaration of any constructor. 
 These semantics closely mirror the rule for implicit declaration of constructors in \CC\cite[p.~186]{ANSI98:C++}.
@@ -2740,4 +2739,5 @@
 
 \section{Related Work}
+\label{s:RelatedWork}
 
 
@@ -2793,5 +2793,5 @@
 C provides variadic functions through @va_list@ objects, but the programmer is responsible for managing the number of arguments and their types, so the mechanism is type unsafe.
 KW-C~\cite{Buhr94a}, a predecessor of \CFA, introduced tuples to C as an extension of the C syntax, taking much of its inspiration from SETL.
-The main contributions of that work were adding MRVF, tuple mass and multiple assignment, and record-field access.
+The main contributions of that work were adding MRVF, tuple mass and multiple assignment, and record-member access.
 \CCeleven introduced @std::tuple@ as a library variadic template structure.
 Tuples are a generalization of @std::pair@, in that they allow for arbitrary length, fixed-size aggregation of heterogeneous values.
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/Parser/parser.yy	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 22 08:41:57 2018
-// Update Count     : 3353
+// Last Modified On : Thu May 24 18:11:59 2018
+// Update Count     : 3369
 //
 
@@ -837,8 +837,8 @@
 //	'[' push assignment_expression pop ']'
 //		{ $$ = new ExpressionNode( build_tuple( $3 ) ); }
-	'[' ',' tuple_expression_list ']'
-		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
-	| '[' assignment_expression ',' tuple_expression_list ']'
-		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$2->set_last( $4 ) ) ); }
+	'[' push ',' tuple_expression_list pop ']'
+		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $4 ) ) ); }
+	| '[' push assignment_expression ',' tuple_expression_list pop ']'
+		{ $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $5 ) ) ); }
 	;
 
@@ -866,5 +866,5 @@
 	labeled_statement
 	| compound_statement
-	| expression_statement						{ $$ = $1; }
+	| expression_statement
 	| selection_statement
 	| iteration_statement
@@ -1183,13 +1183,9 @@
 	type_specifier_nobody
 	| type_specifier_nobody declarator
-		{
-			$$ = $2->addType( $1 );
-		}
+		{ $$ = $2->addType( $1 ); }
 	| type_specifier_nobody variable_abstract_declarator
 		{ $$ = $2->addType( $1 ); }
 	| cfa_abstract_declarator_tuple no_attr_identifier	// CFA
-		{
-			$$ = $1->addName( $2 );
-		}
+		{ $$ = $1->addName( $2 ); }
 	| cfa_abstract_declarator_tuple						// CFA
 	;
@@ -1269,5 +1265,5 @@
 
 declaration_list_opt:									// used at beginning of switch statement
-	pop
+	pop	// empty
 		{ $$ = nullptr; }
 	| declaration_list
@@ -1304,6 +1300,6 @@
 
 local_label_list:										// GCC, local label
-	no_attr_identifier_or_type_name				{}
-	| local_label_list ',' no_attr_identifier_or_type_name {}
+	no_attr_identifier_or_type_name
+	| local_label_list ',' no_attr_identifier_or_type_name
 	;
 
@@ -1400,18 +1396,17 @@
 		// type_specifier can resolve to just TYPEDEFname (e.g., typedef int T; int f( T );). Therefore this must be
 		// flattened to allow lookahead to the '(' without having to reduce identifier_or_type_name.
-	cfa_abstract_tuple identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
+	cfa_abstract_tuple identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
 		// To obtain LR(1 ), this rule must be factored out from function return type (see cfa_abstract_declarator).
-		{ $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
-	| cfa_function_return identifier_or_type_name '(' cfa_parameter_type_list_opt ')'
-		{ $$ = DeclarationNode::newFunction( $2, $1, $4, 0 ); }
+		{ $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
+	| cfa_function_return identifier_or_type_name '(' push cfa_parameter_type_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( $2, $1, $5, 0 ); }
 	;
 
 cfa_function_return:									// CFA
-	'[' cfa_parameter_list ']'
-		{ $$ = DeclarationNode::newTuple( $2 ); }
-	| '[' cfa_parameter_list ',' cfa_abstract_parameter_list ']'
-		// To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the
-		// ']'.
-		{ $$ = DeclarationNode::newTuple( $2->appendList( $4 ) ); }
+	'[' push cfa_parameter_list pop ']'
+		{ $$ = DeclarationNode::newTuple( $3 ); }
+	| '[' push cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ']'
+		// To obtain LR(1 ), the last cfa_abstract_parameter_list is added into this flattened rule to lookahead to the ']'.
+		{ $$ = DeclarationNode::newTuple( $3->appendList( $7 ) ); }
 	;
 
@@ -1587,13 +1582,6 @@
 
 forall:
-	FORALL '('
-		{
-			typedefTable.enterScope();
-		}
-	  type_parameter_list ')'							// CFA
-		{
-			typedefTable.leaveScope();
-			$$ = DeclarationNode::newForall( $4 );
-		}
+	FORALL '(' push type_parameter_list pop ')'					// CFA
+		{ $$ = DeclarationNode::newForall( $4 ); }
 	;
 
@@ -1970,9 +1958,9 @@
 	| cfa_abstract_parameter_list
 	| cfa_parameter_list
-	| cfa_parameter_list ',' cfa_abstract_parameter_list
-		{ $$ = $1->appendList( $3 ); }
-	| cfa_abstract_parameter_list ',' ELLIPSIS
+	| cfa_parameter_list pop ',' push cfa_abstract_parameter_list
+		{ $$ = $1->appendList( $5 ); }
+	| cfa_abstract_parameter_list pop ',' push ELLIPSIS
 		{ $$ = $1->addVarArgs(); }
-	| cfa_parameter_list ',' ELLIPSIS
+	| cfa_parameter_list pop ',' push ELLIPSIS
 		{ $$ = $1->addVarArgs(); }
 	;
@@ -1982,16 +1970,16 @@
 		// factored out from cfa_parameter_list, flattening the rules to get lookahead to the ']'.
 	cfa_parameter_declaration
-	| cfa_abstract_parameter_list ',' cfa_parameter_declaration
-		{ $$ = $1->appendList( $3 ); }
-	| cfa_parameter_list ',' cfa_parameter_declaration
-		{ $$ = $1->appendList( $3 ); }
-	| cfa_parameter_list ',' cfa_abstract_parameter_list ',' cfa_parameter_declaration
-		{ $$ = $1->appendList( $3 )->appendList( $5 ); }
+	| cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| cfa_parameter_list pop ',' push cfa_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
+	| cfa_parameter_list pop ',' push cfa_abstract_parameter_list pop ',' push cfa_parameter_declaration
+		{ $$ = $1->appendList( $5 )->appendList( $9 ); }
 	;
 
 cfa_abstract_parameter_list:							// CFA, new & old style abstract
 	cfa_abstract_parameter_declaration
-	| cfa_abstract_parameter_list ',' cfa_abstract_parameter_declaration
-		{ $$ = $1->appendList( $3 ); }
+	| cfa_abstract_parameter_list pop ',' push cfa_abstract_parameter_declaration
+		{ $$ = $1->appendList( $5 ); }
 	;
 
@@ -2142,13 +2130,13 @@
 	'.' no_attr_identifier								// C99, field name
 		{ $$ = new ExpressionNode( build_varref( $2 ) ); }
-	| '[' assignment_expression ']'						// C99, single array element
+	| '[' push assignment_expression pop ']'			// C99, single array element
 		// assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
-		{ $$ = $2; }
-	| '[' subrange ']'									// CFA, multiple array elements
-		{ $$ = $2; }
-	| '[' constant_expression ELLIPSIS constant_expression ']' // GCC, multiple array elements
-		{ $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $2 ), maybeMoveBuild< Expression >( $4 ) ) ); }
-	| '.' '[' field_list ']'							// CFA, tuple field selector
 		{ $$ = $3; }
+	| '[' push subrange pop ']'							// CFA, multiple array elements
+		{ $$ = $3; }
+	| '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
+		{ $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild< Expression >( $3 ), maybeMoveBuild< Expression >( $5 ) ) ); }
+	| '.' '[' push field_list pop ']'					// CFA, tuple field selector
+		{ $$ = $4; }
 	;
 
@@ -2269,7 +2257,5 @@
 	TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' '}'
 		{ $$ = DeclarationNode::newTrait( $2, $5, 0 ); }
-	| TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{'
-		{ typedefTable.enterScope(); }
-	  trait_declaration_list '}'
+	| TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' push trait_declaration_list '}'
 		{ $$ = DeclarationNode::newTrait( $2, $5, $10 ); }
 	;
@@ -2288,7 +2274,5 @@
 cfa_trait_declaring_list:								// CFA
 	cfa_variable_specifier
-		{ $$ = $1; }
 	| cfa_function_specifier
-		{ $$ = $1; }
 	| cfa_trait_declaring_list pop ',' push identifier_or_type_name
 		{ $$ = $1->appendList( $1->cloneType( $5 ) ); }
@@ -2349,7 +2333,5 @@
 		}
 	| type_qualifier_list
-		{
-			if ( $1->type->forall ) xxx = forall = true; // remember generic type
-		}
+		{ if ( $1->type->forall ) xxx = forall = true; } // remember generic type
 	  push '{' external_definition_list '}'				// CFA, namespace
 		{
@@ -2364,7 +2346,5 @@
 		}
 	| declaration_qualifier_list
-		{
-			if ( $1->type->forall ) xxx = forall = true; // remember generic type
-		}
+		{ if ( $1->type->forall ) xxx = forall = true; } // remember generic type
 	  push '{' external_definition_list '}'				// CFA, namespace
 		{
@@ -2406,13 +2386,7 @@
 		// declaration must still have a type_specifier.  OBSOLESCENT (see 1)
 	| function_declarator compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $1->addFunctionBody( $2 );
-		}
+		{ $$ = $1->addFunctionBody( $2 ); }
 	| KR_function_declarator KR_declaration_list_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 );
-		}
+		{ $$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 ); }
 	;
 
@@ -2427,5 +2401,4 @@
 	cfa_function_declaration with_clause_opt compound_statement	// CFA
 		{
-			typedefTable.leaveScope();
 			// Add the function body to the last identifier in the function definition list, i.e., foo3:
 			//   [const double] foo1(), foo2( int ), foo3( double ) { return 3.0; }
@@ -2436,5 +2409,4 @@
 		{
 			rebindForall( $1, $2 );
-			typedefTable.leaveScope();
 			$$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
 		}
@@ -2442,25 +2414,15 @@
 		{
 			rebindForall( $1, $2 );
-			typedefTable.leaveScope();
 			$$ = $2->addFunctionBody( $4, $3 )->addType( $1 );
 		}
 		// handles default int return type, OBSOLESCENT (see 1)
 	| type_qualifier_list function_declarator with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
-		}
+		{ $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); }
 		// handles default int return type, OBSOLESCENT (see 1)
 	| declaration_qualifier_list function_declarator with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 );
-		}
+		{ $$ = $2->addFunctionBody( $4, $3 )->addQualifiers( $1 ); }
 		// handles default int return type, OBSOLESCENT (see 1)
 	| declaration_qualifier_list type_qualifier_list function_declarator with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 );
-		}
+		{ $$ = $3->addFunctionBody( $5, $4 )->addQualifiers( $2 )->addQualifiers( $1 ); }
 
 		// Old-style K&R function definition, OBSOLESCENT (see 4)
@@ -2468,25 +2430,15 @@
 		{
 			rebindForall( $1, $2 );
-			typedefTable.leaveScope();
 			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addType( $1 );
 		}
 		// handles default int return type, OBSOLESCENT (see 1)
 	| type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
-		}
+		{ $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); }
 		// handles default int return type, OBSOLESCENT (see 1)
 	| declaration_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 );
-		}
+		{ $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); }
 		// handles default int return type, OBSOLESCENT (see 1)
 	| declaration_qualifier_list type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement
-		{
-			typedefTable.leaveScope();
-			$$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 );
-		}
+		{ $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 ); }
 	;
 
@@ -2685,6 +2637,6 @@
 	paren_identifier '(' identifier_list ')'			// function_declarator handles empty parameter
 		{ $$ = $1->addIdList( $3 ); }
-	| '(' KR_function_ptr ')' '(' parameter_type_list_opt ')'
-		{ $$ = $2->addParamList( $5 ); }
+	| '(' KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' KR_function_no_ptr ')'						// redundant parenthesis
 		{ $$ = $2; }
@@ -2804,8 +2756,8 @@
 
 identifier_parameter_function:
-	paren_identifier '(' parameter_type_list_opt ')'	// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $1->addParamList( $3 ); }
-	| '(' identifier_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' identifier_parameter_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -2857,8 +2809,8 @@
 
 type_parameter_function:
-	typedef '(' parameter_type_list_opt ')'				// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $1->addParamList( $3 ); }
-	| '(' type_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	typedef '(' push parameter_type_list_opt pop ')'	// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $1->addParamList( $4 ); }
+	| '(' type_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	;
 
@@ -2907,8 +2859,8 @@
 
 abstract_function:
-	'(' parameter_type_list_opt ')'						// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
-	| '(' abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	'(' push parameter_type_list_opt pop ')'			// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
+	| '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' abstract_function ')'							// redundant parenthesis
 		{ $$ = $2; }
@@ -2925,11 +2877,11 @@
 
 multi_array_dimension:
-	'[' assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $2, 0, false ); }
-	| '[' '*' ']'										// C99
+	'[' push assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $3, 0, false ); }
+	| '[' push '*' pop ']'								// C99
 		{ $$ = DeclarationNode::newVarArray( 0 ); }
-	| multi_array_dimension '[' assignment_expression ']'
-		{ $$ = $1->addArray( DeclarationNode::newArray( $3, 0, false ) ); }
-	| multi_array_dimension '[' '*' ']'					// C99
+	| multi_array_dimension '[' push assignment_expression pop ']'
+		{ $$ = $1->addArray( DeclarationNode::newArray( $4, 0, false ) ); }
+	| multi_array_dimension '[' push '*' pop ']'		// C99
 		{ $$ = $1->addArray( DeclarationNode::newVarArray( 0 ) ); }
 	;
@@ -2998,8 +2950,8 @@
 
 abstract_parameter_function:
-	'(' parameter_type_list_opt ')'						// empty parameter list OBSOLESCENT (see 3)
-		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
-	| '(' abstract_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	'(' push parameter_type_list_opt pop ')'			// empty parameter list OBSOLESCENT (see 3)
+		{ $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
+	| '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' abstract_parameter_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -3023,15 +2975,15 @@
 		{ $$ = DeclarationNode::newArray( 0, 0, false ); }
 	// multi_array_dimension handles the '[' '*' ']' case
-	| '[' type_qualifier_list '*' ']'					// remaining C99
-		{ $$ = DeclarationNode::newVarArray( $2 ); }
-	| '[' type_qualifier_list ']'
-		{ $$ = DeclarationNode::newArray( 0, $2, false ); }
+	| '[' push type_qualifier_list '*' pop ']'			// remaining C99
+		{ $$ = DeclarationNode::newVarArray( $3 ); }
+	| '[' push type_qualifier_list pop ']'
+		{ $$ = DeclarationNode::newArray( 0, $3, false ); }
 	// multi_array_dimension handles the '[' assignment_expression ']' case
-	| '[' type_qualifier_list assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $3, $2, false ); }
-	| '[' STATIC type_qualifier_list_opt assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $4, $3, true ); }
-	| '[' type_qualifier_list STATIC assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $4, $2, true ); }
+	| '[' push type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
+	| '[' push STATIC type_qualifier_list_opt assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $4, true ); }
+	| '[' push type_qualifier_list STATIC assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $3, true ); }
 	;
 
@@ -3077,6 +3029,6 @@
 
 variable_abstract_function:
-	'(' variable_abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
-		{ $$ = $2->addParamList( $5 ); }
+	'(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
+		{ $$ = $2->addParamList( $6 ); }
 	| '(' variable_abstract_function ')'				// redundant parenthesis
 		{ $$ = $2; }
@@ -3141,15 +3093,15 @@
 
 cfa_array_parameter_1st_dimension:
-	'[' type_qualifier_list '*' ']'						// remaining C99
-		{ $$ = DeclarationNode::newVarArray( $2 ); }
-	| '[' type_qualifier_list assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $3, $2, false ); }
-	| '[' declaration_qualifier_list assignment_expression ']'
+	'[' push type_qualifier_list '*' pop ']'			// remaining C99
+		{ $$ = DeclarationNode::newVarArray( $3 ); }
+	| '[' push type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $4, $3, false ); }
+	| '[' push declaration_qualifier_list assignment_expression pop ']'
 		// declaration_qualifier_list must be used because of shift/reduce conflict with
 		// assignment_expression, so a semantic check is necessary to preclude them as a type_qualifier cannot
 		// appear in this context.
-		{ $$ = DeclarationNode::newArray( $3, $2, true ); }
-	| '[' declaration_qualifier_list type_qualifier_list assignment_expression ']'
-		{ $$ = DeclarationNode::newArray( $4, $3->addQualifiers( $3 ), true ); }
+		{ $$ = DeclarationNode::newArray( $4, $3, true ); }
+	| '[' push declaration_qualifier_list type_qualifier_list assignment_expression pop ']'
+		{ $$ = DeclarationNode::newArray( $5, $4->addQualifiers( $3 ), true ); }
 	;
 
@@ -3220,6 +3172,6 @@
 
 cfa_abstract_tuple:										// CFA
-	'[' cfa_abstract_parameter_list ']'
-		{ $$ = DeclarationNode::newTuple( $2 ); }
+	'[' push cfa_abstract_parameter_list pop ']'
+		{ $$ = DeclarationNode::newTuple( $3 ); }
 	;
 
@@ -3227,8 +3179,8 @@
 //	'[' ']' '(' cfa_parameter_type_list_opt ')'
 //		{ $$ = DeclarationNode::newFunction( nullptr, DeclarationNode::newTuple( nullptr ), $4, nullptr ); }
-	cfa_abstract_tuple '(' cfa_parameter_type_list_opt ')'
-		{ $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
-	| cfa_function_return '(' cfa_parameter_type_list_opt ')'
-		{ $$ = DeclarationNode::newFunction( nullptr, $1, $3, nullptr ); }
+	cfa_abstract_tuple '(' push cfa_parameter_type_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
+	| cfa_function_return '(' push cfa_parameter_type_list_opt pop ')'
+		{ $$ = DeclarationNode::newFunction( nullptr, $1, $4, nullptr ); }
 	;
 
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -698,9 +698,10 @@
 			const ExplodedArgs& args, std::vector<ArgPack>& results, std::size_t& genStart,
 			const SymTab::Indexer& indexer, unsigned nTuples = 0 ) {
-		if ( TupleType* tupleType = dynamic_cast<TupleType*>( formalType ) ) {
+		if ( TupleType * tupleType = dynamic_cast<TupleType*>( formalType ) ) {
 			// formalType is a TupleType - group actuals into a TupleExpr
 			++nTuples;
 			for ( Type* type : *tupleType ) {
 				// xxx - dropping initializer changes behaviour from previous, but seems correct
+				// ^^^ need to handle the case where a tuple has a default argument
 				if ( ! instantiateArgument(
 						type, nullptr, args, results, genStart, indexer, nTuples ) )
@@ -713,5 +714,5 @@
 			}
 			return true;
-		} else if ( TypeInstType* ttype = Tuples::isTtype( formalType ) ) {
+		} else if ( TypeInstType * ttype = Tuples::isTtype( formalType ) ) {
 			// formalType is a ttype, consumes all remaining arguments
 			// xxx - mixing default arguments with variadic??
@@ -916,5 +917,5 @@
 				// consider only first exploded actual
 				Expression* expr = expl.exprs.front().get();
-				Type* actualType = expr->get_result()->clone();
+				Type* actualType = expr->result->clone();
 
 				PRINT(
@@ -947,5 +948,5 @@
 		ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() );
 		// sum cost and accumulate actuals
-		std::list<Expression*>& args = appExpr->get_args();
+		std::list<Expression*>& args = appExpr->args;
 		Cost cost = func.cost;
 		const ArgPack* pack = &result;
@@ -974,9 +975,9 @@
 		// add all type variables as open variables now so that those not used in the parameter
 		// list are still considered open.
-		funcEnv.add( funcType->get_forall() );
-
-		if ( targetType && ! targetType->isVoid() && ! funcType->get_returnVals().empty() ) {
+		funcEnv.add( funcType->forall );
+
+		if ( targetType && ! targetType->isVoid() && ! funcType->returnVals.empty() ) {
 			// attempt to narrow based on expected target type
-			Type * returnType = funcType->get_returnVals().front()->get_type();
+			Type * returnType = funcType->returnVals.front()->get_type();
 			if ( ! unify( returnType, targetType, funcEnv, funcNeed, funcHave, funcOpenVars,
 					indexer ) ) {
@@ -991,8 +992,8 @@
 		std::size_t genStart = 0;
 
-		for ( DeclarationWithType* formal : funcType->get_parameters() ) {
+		for ( DeclarationWithType* formal : funcType->parameters ) {
 			ObjectDecl* obj = strict_dynamic_cast< ObjectDecl* >( formal );
 			if ( ! instantiateArgument(
-					obj->get_type(), obj->get_init(), args, results, genStart, indexer ) )
+					obj->type, obj->init, args, results, genStart, indexer ) )
 				return;
 		}
@@ -1075,5 +1076,5 @@
 	void AlternativeFinder::Finder::postvisit( UntypedExpr *untypedExpr ) {
 		AlternativeFinder funcFinder( indexer, env );
-		funcFinder.findWithAdjustment( untypedExpr->get_function() );
+		funcFinder.findWithAdjustment( untypedExpr->function );
 		// if there are no function alternatives, then proceeding is a waste of time.
 		if ( funcFinder.alternatives.empty() ) return;
@@ -1120,6 +1121,6 @@
 				)
 				// check if the type is pointer to function
-				if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->get_result()->stripReferences() ) ) {
-					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->get_base() ) ) {
+				if ( PointerType *pointer = dynamic_cast< PointerType* >( func->expr->result->stripReferences() ) ) {
+					if ( FunctionType *function = dynamic_cast< FunctionType* >( pointer->base ) ) {
 						Alternative newFunc( *func );
 						referenceToRvalueConversion( newFunc.expr, newFunc.cost );
@@ -1127,7 +1128,7 @@
 							std::back_inserter( candidates ) );
 					}
-				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->get_result()->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
+				} else if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( func->expr->result->stripReferences() ) ) { // handle ftype (e.g. *? on function pointer)
 					EqvClass eqvClass;
-					if ( func->env.lookup( typeInst->get_name(), eqvClass ) && eqvClass.type ) {
+					if ( func->env.lookup( typeInst->name, eqvClass ) && eqvClass.type ) {
 						if ( FunctionType *function = dynamic_cast< FunctionType* >( eqvClass.type ) ) {
 							Alternative newFunc( *func );
@@ -1158,7 +1159,7 @@
 					// check if type is a pointer to function
 					if ( PointerType* pointer = dynamic_cast<PointerType*>(
-							funcOp->expr->get_result()->stripReferences() ) ) {
+							funcOp->expr->result->stripReferences() ) ) {
 						if ( FunctionType* function =
-								dynamic_cast<FunctionType*>( pointer->get_base() ) ) {
+								dynamic_cast<FunctionType*>( pointer->base ) ) {
 							Alternative newFunc( *funcOp );
 							referenceToRvalueConversion( newFunc.expr, newFunc.cost );
@@ -1182,11 +1183,11 @@
 			PRINT(
 				ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( withFunc.expr );
-				PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->get_function()->get_result() );
-				FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->get_base() );
-				std::cerr << "Case +++++++++++++ " << appExpr->get_function() << std::endl;
+				PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result );
+				FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base );
+				std::cerr << "Case +++++++++++++ " << appExpr->function << std::endl;
 				std::cerr << "formals are:" << std::endl;
-				printAll( function->get_parameters(), std::cerr, 8 );
+				printAll( function->parameters, std::cerr, 8 );
 				std::cerr << "actuals are:" << std::endl;
-				printAll( appExpr->get_args(), std::cerr, 8 );
+				printAll( appExpr->args, std::cerr, 8 );
 				std::cerr << "bindings are:" << std::endl;
 				withFunc.env.print( std::cerr, 8 );
@@ -1229,5 +1230,5 @@
 	bool isLvalue( Expression *expr ) {
 		// xxx - recurse into tuples?
-		return expr->result && ( expr->get_result()->get_lvalue() || dynamic_cast< ReferenceType * >( expr->get_result() ) );
+		return expr->result && ( expr->result->get_lvalue() || dynamic_cast< ReferenceType * >( expr->result ) );
 	}
 
@@ -1291,4 +1292,6 @@
 			AssertionSet needAssertions, haveAssertions;
 			OpenVarSet openVars;
+
+			alt.env.extractOpenVars( openVars );
 
 			// It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
@@ -1709,5 +1712,5 @@
 			AlternativeFinder finder( indexer, env );
 			finder.targetType = toType;
-			finder.findWithAdjustment( initExpr->get_expr() );
+			finder.findWithAdjustment( initExpr->expr );
 			for ( Alternative & alt : finder.get_alternatives() ) {
 				TypeEnvironment newEnv( alt.env );
@@ -1716,10 +1719,10 @@
 				PRINT(
 					std::cerr << "  @ " << toType << " " << initAlt.designation << std::endl;
-				 )
+				)
 				// It's possible that a cast can throw away some values in a multiply-valued expression.  (An example is a
 				// cast-to-void, which casts from one value to zero.)  Figure out the prefix of the subexpression results
 				// that are cast directly.  The candidate is invalid if it has fewer results than there are types to cast
 				// to.
-				int discardedValues = alt.expr->get_result()->size() - toType->size();
+				int discardedValues = alt.expr->result->size() - toType->size();
 				if ( discardedValues < 0 ) continue;
 				// xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not
@@ -1728,5 +1731,5 @@
 				unify( toType, alt.expr->result, newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type??
 
-				Cost thisCost = castCost( alt.expr->get_result(), toType, indexer, newEnv );
+				Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv );
 				if ( thisCost != Cost::infinity ) {
 					// count one safe conversion for each value that is thrown away
Index: src/Tuples/TupleAssignment.cc
===================================================================
--- src/Tuples/TupleAssignment.cc	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/Tuples/TupleAssignment.cc	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -231,5 +231,6 @@
 
 			ResolvExpr::AlternativeFinder finder{ currentFinder.get_indexer(),
-				currentFinder.get_environ() };
+				matcher->compositeEnv };
+
 			try {
 				finder.findWithAdjustment(*i);
@@ -349,4 +350,10 @@
 				ltmp.push_back( lobj );
 				rtmp.push_back( robj );
+
+				// resolve the cast expression so that rhsAlt return type is bound by the cast type as needed, and transfer the resulting environment
+				ResolvExpr::AlternativeFinder finder{ spotter.currentFinder.get_indexer(), compositeEnv };
+				finder.findWithAdjustment( rhsAlt.expr );
+				assert( finder.get_alternatives().size() == 1 );
+				compositeEnv = std::move( finder.get_alternatives().front().env );
 			}
 			tmpDecls.splice( tmpDecls.end(), ltmp );
Index: src/libcfa/concurrency/alarm.c
===================================================================
--- src/libcfa/concurrency/alarm.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/libcfa/concurrency/alarm.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -10,6 +10,6 @@
 // Created On       : Fri Jun 2 11:31:25 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Apr  9 13:36:18 2018
-// Update Count     : 61
+// Last Modified On : Fri May 25 06:25:47 2018
+// Update Count     : 67
 //
 
@@ -37,5 +37,5 @@
 
 void __kernel_set_timer( Duration alarm ) {
-	verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%luns)", alarm.tv);
+	verifyf(alarm >= 1`us || alarm == 0, "Setting timer to < 1us (%jins)", alarm.tv);
 	setitimer( ITIMER_REAL, &(itimerval){ alarm }, NULL );
 }
Index: c/tests/.expect/io.txt
===================================================================
--- src/tests/.expect/io.txt	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ 	(revision )
@@ -1,85 +1,0 @@
-9 6 28 0 7 1 2
-1 2 3
-123
-123
-
-opening delimiters
-x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
-
-closing delimiters
-1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
-
-opening/closing delimiters
-x`1`x'2'x"3"x:4:x 5 x	6	x
-7
-x
-8
-x
-9
-x
-10
-x
-
-override opening/closing delimiters
-x ( 1 ) x 2 , x 3 :x: 4
-
-input bacis types
-
-output basic types
-false
-A 23 93
-1 2 3 4 5 6 7 8
-1.1 1.2 1.3
-1.1+2.3i 1.1-2.3i 1.1-2.3i
-
-tuples
-1, 2, 3 4, 5, 6
-
-toggle separator
-1.11.21.3
-1.1+2.3i1.1-2.3i1.1-2.3i
-1.1+2.3i 1.1-2.3i1.1-2.3i
-1.1+2.3i 1.1-2.3i 1.1-2.3i
-1.1+2.3i1.1-2.3i 1.1-2.3i
-abcxyz
-abcxyz
-
-change separator
-from " " to ", $"
-1.1, $1.2, $1.3
-1.1+2.3i, $1.1-2.3i, $1.1-2.3i
-abc, $xyz
-1, 2, 3, $4, 5, 6
-
-from ", $" to " "
-1.1 1.2 1.3
-1.1+2.3i 1.1-2.3i 1.1-2.3i
-abc xyz
-1, 2, 3 4, 5, 6
-
-check sepOn/sepOff
-1 2 3
-12 3
-1 2 3
-1 2 3
-
-1 2 3
-
-check enable/disable
-123
-1 23
-1 2 3
-123
-1 2 3
-123
-1 2 3
-
-1 2 3 4 5 6 " "
-1, 2, 3 4, 5, 6 " "
-1, 2, 3 4, 5, 6
-
-3, 4, a, 7.2
-3, 4, a, 7.2
-3 4 a 7.2
-3 4 a 7.234a7.23 4 a 7.2
-3-4-a-7.2^3^4^3-4-a-7.2
Index: src/tests/.expect/io1.txt
===================================================================
--- src/tests/.expect/io1.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
+++ src/tests/.expect/io1.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -0,0 +1,25 @@
+9 6 28 0 7 1 2
+1 2 3
+123
+123
+
+opening delimiters
+x (1 x [2 x {3 x =4 x $5 x £6 x ¥7 x ¡8 x ¿9 x «10
+
+closing delimiters
+1, x 2. x 3; x 4! x 5? x 6% x 7¢ x 8» x 9) x 10] x 11} x
+
+opening/closing delimiters
+x`1`x'2'x"3"x:4:x 5 x	6	x
+7
+x
+8
+x
+9
+x
+10
+x
+
+override opening/closing delimiters
+x ( 1 ) x 2 , x 3 :x: 4
+
Index: src/tests/.expect/io2.txt
===================================================================
--- src/tests/.expect/io2.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
+++ src/tests/.expect/io2.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -0,0 +1,60 @@
+input bacis types
+
+output basic types
+false
+A 23 93
+1 2 3 4 5 6 7 8
+1.1 1.2 1.3
+1.1+2.3i 1.1-2.3i 1.1-2.3i
+
+tuples
+1, 2, 3 4, 5, 6
+
+toggle separator
+1.11.21.3
+1.1+2.3i1.1-2.3i1.1-2.3i
+1.1+2.3i 1.1-2.3i1.1-2.3i
+1.1+2.3i 1.1-2.3i 1.1-2.3i
+1.1+2.3i1.1-2.3i 1.1-2.3i
+abcxyz
+abcxyz
+
+change separator
+from " " to ", $"
+1.1, $1.2, $1.3
+1.1+2.3i, $1.1-2.3i, $1.1-2.3i
+abc, $xyz
+1, 2, 3, $4, 5, 6
+
+from ", $" to " "
+1.1 1.2 1.3
+1.1+2.3i 1.1-2.3i 1.1-2.3i
+abc xyz
+1, 2, 3 4, 5, 6
+
+check sepOn/sepOff
+1 2 3
+12 3
+1 2 3
+1 2 3
+
+1 2 3
+
+check enable/disable
+123
+1 23
+1 2 3
+123
+1 2 3
+123
+1 2 3
+
+1 2 3 4 5 6 " "
+1, 2, 3 4, 5, 6 " "
+1, 2, 3 4, 5, 6
+
+3, 4, a, 7.2
+3, 4, a, 7.2
+3 4 a 7.2
+3 4 a 7.234a7.23 4 a 7.2
+3-4-a-7.2^3^4^3-4-a-7.2
Index: src/tests/.expect/math1.x64.txt
===================================================================
--- src/tests/.expect/math1.x64.txt	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/.expect/math1.x64.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -12,11 +12,2 @@
 \ 16 256
 \ 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
-log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
-log2:3 3 3
-log10:2 2 2
-log1p:0.693147 0.693147180559945 0.693147180559945309
-ilogb:0 0 0
-logb:3 3 3
-sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
-cbrt:3 3 3
-hypot:1.41421 1.4142135623731 1.41421356237309505
Index: src/tests/.expect/math1.x86.txt
===================================================================
--- src/tests/.expect/math1.x86.txt	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/.expect/math1.x86.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -12,11 +12,2 @@
 \ 16 256
 \ 912673 256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
-log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
-log2:3 3 3
-log10:2 2 2
-log1p:0.693147 0.693147180559945 0.693147180559945309
-ilogb:0 0 0
-logb:3 3 3
-sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
-cbrt:3 3 3
-hypot:1.41421 1.4142135623731 1.41421356237309505
Index: src/tests/.expect/math2.x64.txt
===================================================================
--- src/tests/.expect/math2.x64.txt	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/.expect/math2.x64.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -1,2 +1,11 @@
+log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
+log2:3 3 3
+log10:2 2 2
+log1p:0.693147 0.693147180559945 0.693147180559945309
+ilogb:0 0 0
+logb:3 3 3
+sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
+cbrt:3 3 3
+hypot:1.41421 1.4142135623731 1.41421356237309505
 sin:0.841471 0.841470984807897 0.841470984807896507 1.29846+0.634964i 1.29845758141598+0.634963914784736i 1.29845758141597729+0.634963914784736108i
 cos:0.540302 0.54030230586814 0.540302305868139717 0.83373-0.988898i 0.833730025131149-0.988897705762865i 0.833730025131149049-0.988897705762865096i
@@ -6,13 +15,2 @@
 atan:0.785398 0.785398163397448 0.78539816339744831 1.01722+0.402359i 1.01722196789785+0.402359478108525i 1.01722196789785137+0.402359478108525094i
 atan2:0.785398 0.785398163397448 0.78539816339744831 atan:0.785398 0.785398163397448 0.78539816339744831
-sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
-cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
-tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
-acosh:0 0 0 1.06128+0.904557i 1.06127506190504+0.904556894302381i 1.06127506190503565+0.904556894302381364i
-asinh:0.881374 0.881373587019543 0.881373587019543025 1.06128+0.666239i 1.06127506190504+0.666239432492515i 1.06127506190503565+0.666239432492515255i
-atanh:inf inf inf 0.402359+1.01722i 0.402359478108525+1.01722196789785i 0.402359478108525094+1.01722196789785137i
-erf:0.842701 0.842700792949715 0.842700792949714869
-erfc:0.157299 0.157299207050285 0.157299207050285131
-lgamma:1.79176 1.79175946922805 1.791759469228055
-lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
-tgamma:6 6 6
Index: src/tests/.expect/math2.x86.txt
===================================================================
--- src/tests/.expect/math2.x86.txt	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/.expect/math2.x86.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -1,2 +1,11 @@
+log:0 0 0 0.346574+0.785398i 0.346573590279973+0.785398163397448i 0.346573590279972655+0.78539816339744831i
+log2:3 3 3
+log10:2 2 2
+log1p:0.693147 0.693147180559945 0.693147180559945309
+ilogb:0 0 0
+logb:3 3 3
+sqrt:1 1 1 1.09868+0.45509i 1.09868411346781+0.455089860562227i 1.09868411346780997+0.455089860562227341i
+cbrt:3 3 3
+hypot:1.41421 1.4142135623731 1.41421356237309505
 sin:0.841471 0.841470984807897 0.841470984807896507 1.29846+0.634964i 1.29845758141598+0.634963914784736i 1.29845758141597729+0.634963914784736108i
 cos:0.540302 0.54030230586814 0.540302305868139717 0.83373-0.988898i 0.833730025131149-0.988897705762865i 0.833730025131149049-0.988897705762865096i
@@ -6,13 +15,2 @@
 atan:0.785398 0.785398163397448 0.78539816339744831 1.01722+0.402359i 1.01722196789785+0.402359478108525i 1.01722196789785137+0.402359478108525094i
 atan2:0.785398 0.785398163397448 0.78539816339744831 atan:0.785398 0.785398163397448 0.78539816339744831
-sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
-cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
-tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
-acosh:0 0 0 1.06128+0.904557i 1.06127506190504+0.904556894302381i 1.06127506190503565+0.904556894302381364i
-asinh:0.881374 0.881373587019543 0.881373587019543025 1.06128+0.666239i 1.06127506190504+0.666239432492515i 1.06127506190503565+0.666239432492515255i
-atanh:inf inf inf 0.402359+1.01722i 0.402359478108525+1.01722196789785i 0.402359478108525094+1.01722196789785137i
-erf:0.842701 0.842700792949715 0.842700792949714869
-erfc:0.157299 0.157299207050285 0.157299207050285131
-lgamma:1.79176 1.79175946922805 1.791759469228055
-lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
-tgamma:6 6 6
Index: src/tests/.expect/math3.x64.txt
===================================================================
--- src/tests/.expect/math3.x64.txt	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/.expect/math3.x64.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -1,23 +1,11 @@
-floor:1 1 1
-ceil:2 2 2
-trunc:3 3 3
-rint:2 2 2
-rint:2 2 2
-rint:2 2 2
-lrint:2 2 2
-llrint:2 2 2
-nearbyint:4 4 4
-round:2 2 2
-round:2 2 2
-round:2 2 2
-lround:2 2 2
-llround:2 2 2
-copysign:-1 -1 -1
-frexp:0.5 3 0.5 3 0.5 3
-ldexp:8 8 8
-modf:2 0.3 2 0.3 2 0.3
-modf:2, 0.3 2, 0.3 2, 0.3
-nextafter:2 2 2
-nexttoward:2 2 2
-scalbn:16 16 16
-scalbln:16 16 16
+sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
+cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
+tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
+acosh:0 0 0 1.06128+0.904557i 1.06127506190504+0.904556894302381i 1.06127506190503565+0.904556894302381364i
+asinh:0.881374 0.881373587019543 0.881373587019543025 1.06128+0.666239i 1.06127506190504+0.666239432492515i 1.06127506190503565+0.666239432492515255i
+atanh:inf inf inf 0.402359+1.01722i 0.402359478108525+1.01722196789785i 0.402359478108525094+1.01722196789785137i
+erf:0.842701 0.842700792949715 0.842700792949714869
+erfc:0.157299 0.157299207050285 0.157299207050285131
+lgamma:1.79176 1.79175946922805 1.791759469228055
+lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
+tgamma:6 6 6
Index: src/tests/.expect/math3.x86.txt
===================================================================
--- src/tests/.expect/math3.x86.txt	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/.expect/math3.x86.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -1,23 +1,11 @@
-floor:1 1 1
-ceil:2 2 2
-trunc:3 3 3
-rint:2 2 2
-rint:2 2 2
-rint:2 2 2
-lrint:2 2 2
-llrint:2 2 2
-nearbyint:4 4 4
-round:2 2 2
-round:2 2 2
-round:2 2 2
-lround:2 2 2
-llround:2 2 2
-copysign:-1 -1 -1
-frexp:0.5 3 0.5 3 0.5 3
-ldexp:8 8 8
-modf:2 0.3 2 0.3 2 0.3
-modf:2, 0.3 2, 0.3 2, 0.3
-nextafter:2 2 2
-nexttoward:2 2 2
-scalbn:16 16 16
-scalbln:16 16 16
+sinh:1.1752 1.1752011936438 1.17520119364380146 0.634964+1.29846i 0.634963914784736+1.29845758141598i 0.634963914784736108+1.29845758141597729i
+cosh:1.54308 1.54308063481524 1.54308063481524378 0.83373+0.988898i 0.833730025131149+0.988897705762865i 0.833730025131149049+0.988897705762865096i
+tanh:0.761594 0.761594155955765 0.761594155955764888 1.08392+0.271753i 1.08392332733869+0.271752585319512i 1.08392332733869454+0.271752585319511717i
+acosh:0 0 0 1.06128+0.904557i 1.06127506190504+0.904556894302381i 1.06127506190503565+0.904556894302381364i
+asinh:0.881374 0.881373587019543 0.881373587019543025 1.06128+0.666239i 1.06127506190504+0.666239432492515i 1.06127506190503565+0.666239432492515255i
+atanh:inf inf inf 0.402359+1.01722i 0.402359478108525+1.01722196789785i 0.402359478108525094+1.01722196789785137i
+erf:0.842701 0.842700792949715 0.842700792949714869
+erfc:0.157299 0.157299207050285 0.157299207050285131
+lgamma:1.79176 1.79175946922805 1.791759469228055
+lgamma:1.79176 1 1.79175946922805 1 1.791759469228055 1
+tgamma:6 6 6
Index: src/tests/.expect/math4.x64.txt
===================================================================
--- src/tests/.expect/math4.x64.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
+++ src/tests/.expect/math4.x64.txt	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -0,0 +1,23 @@
+floor:1 1 1
+ceil:2 2 2
+trunc:3 3 3
+rint:2 2 2
+rint:2 2 2
+rint:2 2 2
+lrint:2 2 2
+llrint:2 2 2
+nearbyint:4 4 4
+round:2 2 2
+round:2 2 2
+round:2 2 2
+lround:2 2 2
+llround:2 2 2
+copysign:-1 -1 -1
+frexp:0.5 3 0.5 3 0.5 3
+ldexp:8 8 8
+modf:2 0.3 2 0.3 2 0.3
+modf:2, 0.3 2, 0.3 2, 0.3
+nextafter:2 2 2
+nexttoward:2 2 2
+scalbn:16 16 16
+scalbln:16 16 16
Index: src/tests/concurrent/coroutineYield.c
===================================================================
--- src/tests/concurrent/coroutineYield.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/concurrent/coroutineYield.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -3,4 +3,13 @@
 #include <stdlib>
 #include <thread>
+#include <time>
+
+#ifndef PREEMPTION_RATE
+#define PREEMPTION_RATE 10`ms
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
 
 #ifdef LONG_TEST
Index: src/tests/concurrent/examples/matrixSum.c
===================================================================
--- src/tests/concurrent/examples/matrixSum.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/concurrent/examples/matrixSum.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -11,6 +11,6 @@
 // Created On       : Mon Oct  9 08:29:28 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Dec  5 22:56:46 2017
-// Update Count     : 4
+// Last Modified On : Fri May 25 09:34:27 2018
+// Update Count     : 10
 // 
 
@@ -20,40 +20,39 @@
 
 thread Adder {
-    int * row, cols, * subtotal;						// communication
+	int * row, cols, & subtotal;						// communication
 };
 
 void ?{}( Adder & adder, int row[], int cols, int & subtotal ) {
-    adder.row = row;
-    adder.cols = cols;
-    adder.subtotal = &subtotal;
+	adder.[ row, cols ] = [ row, cols ];				// expression disallowed in multi-member access
+	&adder.subtotal = &subtotal;
 }
 
-void main( Adder & adder ) with( adder ) {
-    *subtotal = 0;
-    for ( int c = 0; c < cols; c += 1 ) {
-		*subtotal += row[c];
-    } // for
+void main( Adder & adder ) with( adder ) {				// thread starts here
+	subtotal = 0;
+	for ( int c = 0; c < cols; c += 1 ) {
+		subtotal += row[c];
+	} // for
 }
 
 int main() {
-    const int rows = 10, cols = 1000;
-    int matrix[rows][cols], subtotals[rows], total = 0;
-    processor p;										// extra kernel thread
+	const int rows = 10, cols = 1000;
+	int matrix[rows][cols], subtotals[rows], total = 0;
+	processor p;										// add kernel thread
 
-    for ( int r = 0; r < rows; r += 1 ) {
+	for ( int r = 0; r < rows; r += 1 ) {
 		for ( int c = 0; c < cols; c += 1 ) {
 			matrix[r][c] = 1;
 		} // for
-    } // for
-    Adder * adders[rows];
-    for ( int r = 0; r < rows; r += 1 ) {				// start threads to sum rows
+	} // for
+	Adder * adders[rows];
+	for ( int r = 0; r < rows; r += 1 ) {				// start threads to sum rows
 		adders[r] = &(*malloc()){ matrix[r], cols, subtotals[r] };
 //		adders[r] = new( matrix[r], cols, &subtotals[r] );
-    } // for
-    for ( int r = 0; r < rows; r += 1 ) {				// wait for threads to finish
+	} // for
+	for ( int r = 0; r < rows; r += 1 ) {				// wait for threads to finish
 		delete( adders[r] );
 		total += subtotals[r];							// total subtotals
-    } // for
-    sout | total | endl;
+	} // for
+	sout | total | endl;
 }
 
Index: src/tests/concurrent/signal/block.c
===================================================================
--- src/tests/concurrent/signal/block.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/concurrent/signal/block.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -14,10 +14,4 @@
 #include <time>
 
-#ifdef LONG_TEST
-static const unsigned long N = 150_000ul;
-#else
-static const unsigned long N = 5_000ul;
-#endif
-
 #ifndef PREEMPTION_RATE
 #define PREEMPTION_RATE 10`ms
@@ -27,4 +21,10 @@
 	return PREEMPTION_RATE;
 }
+
+#ifdef LONG_TEST
+static const unsigned long N = 150_000ul;
+#else
+static const unsigned long N = 5_000ul;
+#endif
 
 enum state_t { WAITED, SIGNAL, BARGE };
Index: src/tests/concurrent/signal/disjoint.c
===================================================================
--- src/tests/concurrent/signal/disjoint.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/concurrent/signal/disjoint.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -4,10 +4,4 @@
 #include <thread>
 #include <time>
-
-#ifdef LONG_TEST
-static const unsigned long N = 300_000ul;
-#else
-static const unsigned long N = 10_000ul;
-#endif
 
 #ifndef PREEMPTION_RATE
@@ -18,4 +12,10 @@
 	return PREEMPTION_RATE;
 }
+
+#ifdef LONG_TEST
+static const unsigned long N = 300_000ul;
+#else
+static const unsigned long N = 10_000ul;
+#endif
 
 enum state_t { WAIT, SIGNAL, BARGE };
Index: src/tests/concurrent/signal/wait.c
===================================================================
--- src/tests/concurrent/signal/wait.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/concurrent/signal/wait.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -12,10 +12,4 @@
 #include <time>
 
-#ifdef LONG_TEST
-static const unsigned long N = 375_000ul;
-#else
-static const unsigned long N = 2_500ul;
-#endif
-
 #ifndef PREEMPTION_RATE
 #define PREEMPTION_RATE 10`ms
@@ -25,4 +19,10 @@
 	return PREEMPTION_RATE;
 }
+
+#ifdef LONG_TEST
+static const unsigned long N = 375_000ul;
+#else
+static const unsigned long N = 2_500ul;
+#endif
 
 monitor global_t {};
Index: c/tests/io.c
===================================================================
--- src/tests/io.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ 	(revision )
@@ -1,184 +1,0 @@
-// 
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
-//
-// The contents of this file are covered under the licence agreement in the
-// file "LICENCE" distributed with Cforall.
-// 
-// io.c -- 
-// 
-// Author           : Peter A. Buhr
-// Created On       : Wed Mar  2 16:56:02 2016
-// Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Jan 26 15:19:34 2018
-// Update Count     : 100
-// 
-
-#include <fstream>
-
-int main() {
-	_Bool b;											// basic types
-	char c;
-	signed char sc;
-	unsigned char usc;
-	short int si;
-	unsigned short int usi;
-	int i;
-	unsigned int ui;
-	long int li;
-	unsigned long int uli;
-	long long int lli;
-	unsigned long long int ulli;
-	float f;
-	double d;
-	long double ld;
-	float _Complex fc;
-	double _Complex dc;
-	long double _Complex ldc;
-	enum { size = 10 };
-	char s1[size], s2[size];
-
-	int x = 3, y = 5, z = 7;
-	sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
-	sout | 1 | 2 | 3 | endl;
-	sout | '1' | '2' | '3' | endl;
-	sout | 1 | "" | 2 | "" | 3 | endl;
-	sout | endl;
-
-	sout | "opening delimiters" | endl;
-	sout
-		 | "x (" | 1
-		 | "x [" | 2
-		 | "x {" | 3
-		 | "x =" | 4
-		 | "x $" | 5
-		 | "x £" | 6
-		 | "x ¥" | 7
-		 | "x ¡" | 8
-		 | "x ¿" | 9
-		 | "x «" | 10
-		 | endl | endl;
-
-	sout | "closing delimiters" | endl;
-	sout
-		 | 1 | ", x"
-		 | 2 | ". x"
-		 | 3 | "; x"
-		 | 4 | "! x"
-		 | 5 | "? x"
-		 | 6 | "% x"
-		 | 7 | "¢ x"
-		 | 8 | "» x"
-		 | 9 | ") x"
-		 | 10 | "] x"
-		 | 11 | "} x"
-		 | endl | endl;
-
-	sout | "opening/closing delimiters" | endl;
-	sout
-		 | "x`" | 1 | "`x'" | 2
-		 | "'x\"" | 3 | "\"x:" | 4
-		 | ":x " | 5 | " x\t" | 6
-		 | "\tx\f" | 7 | "\fx\v" | 8
-		 | "\vx\n" | 9 | "\nx\r" | 10
-		 | "\rx"
-		 | endl | endl;
-
-	sout | "override opening/closing delimiters" | endl;
-	sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl;
-	sout | endl;
-
-	ifstream in = { "io.data" };						// create / open file
-
-	sout | "input bacis types" | endl;
-	in	 | b											// boolean
-		 | c | sc | usc									// character
-		 | si | usi | i | ui | li | uli | lli | ulli	// integral
-		 | f | d | ld									// floating point
-		 | fc | dc | ldc								// floating-point complex
-		 | cstr( s1 ) | cstr( s2, size );				// C string, length unchecked and checked
-	sout | endl;
-
-	sout | "output basic types" | endl;
-	sout | b | endl										// boolean
-		 | c | ' ' | sc | ' ' | usc | endl				// character
-		 | si | usi | i | ui | li | uli | lli | ulli | endl // integral
-		 | f | d | ld | endl							// floating point
-		 | fc | dc | ldc | endl;						// complex
-	sout | endl;
-
-	sout | "tuples" | endl;
-	[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
-	sout | t1 | t2 | endl;								// print tuple
-	sout | endl;
-
-	sout | "toggle separator" | endl;
-	sout | f | "" | d | "" | ld | endl					// floating point without separator
-		 | sepDisable | fc | dc | ldc | endl			// complex without separator
-		 | fc | sepOn | dc | ldc | endl					// local separator add
-		 | sepEnable | fc | dc | ldc | endl				// complex with separator
-		 | fc | sepOff | dc | ldc | endl				// local separator removal
-		 | s1 | sepOff | s2 | endl						// local separator removal
-		 | s1 | "" | s2 | endl;							// local separator removal
-	sout | endl;
-
-	sout | "change separator" | endl;
-	sout | "from \"" | sep | "\"";
-	sepSet( sout, ", $" );								// change separator, maximum of 15 characters
-	sout | " to \"" | sep | "\"" | endl;
-	sout | f | d | ld | endl
-		 | fc | dc | ldc | endl
-		 | s1 | s2 | endl
-		 | t1 | t2 | endl;								// print tuple
-	sout | endl;
-	sout | "from \"" | sep | "\" ";
-	sepSet( sout, " " );								// restore separator
-	sout | "to \"" | sep | "\"" | endl;
-	sout | f | d | ld | endl
-		 | fc | dc | ldc | endl
-		 | s1 | s2 | endl
-		 | t1 | t2 | endl;								// print tuple
-	sout | endl;
-
-	sout | "check sepOn/sepOff" | endl;
-	sout | sepOn | 1 | 2 | 3 | sepOn | endl;			// no separator at start/end of line
-	sout | 1 | sepOff | 2 | 3 | endl;					// locally turn off implicit separator
-	sout | sepOn | sepOn | 1 | 2 | 3 | sepOn | sepOff | sepOn | '\n'; // no separator at start/end of line
-	sout | 1 | 2 | 3 | "\n\n" | sepOn;					// no separator at start of next line
-	sout | 1 | 2 | 3 | endl;
-	sout | endl;
-
-	sout | "check enable/disable" | endl;
-	sout | sepDisable | 1 | 2 | 3 | endl;				// globally turn off implicit separation
-	sout | 1 | sepOn | 2 | 3 | endl;					// locally turn on implicit separator
-	sout | sepEnable | 1 | 2 | 3 | endl | sepDisable;	// globally turn on/off implicit separation
-	sout | 1 | 2 | 3 | endl | sepEnable;				// globally turn on implicit separation
-	sout | 1 | 2 | 3 | sepOn | sepDisable | endl;		// ignore seperate at end of line
-	sout | 1 | 2 | 3 | sepOn | sepEnable | endl;		// separator at end of line
-	sout | 1 | 2 | 3 | endl;
-	sout | endl;
-
-//	sout | fmt( d, "%8.3f" ) || endl;
-//	sout | endl;
-
-	sepSetTuple( sout, " " );							// set tuple separator from ", " to " "
-	sout | t1 | t2 | " \"" | sep | "\"" | endl;
-	sepSetTuple( sout, ", " );							// reset tuple separator to ", "
-	sout | t1 | t2 | " \"" | sep | "\"" | endl;
-	sout | t1 | t2 | endl;								// print tuple
-	sout | endl;
-
-	[int, int, const char *, double] t3 = { 3, 4, "a", 7.2 };
-	sout | [ 3, 4, "a", 7.2 ] | endl;
-	sout | t3 | endl;
-	sepSetTuple( sout, " " );
-	sout | t3 | endl;
-	sout | sepOn | t3 | sepDisable | t3 | sepEnable | t3 | endl;
-	sepSet( sout, "^" );
-	sepSetTuple( sout, "-" );
-	sout | t3 | 3 | 4 | t3 | endl;
-}
-
-// Local Variables: //
-// tab-width: 4 //
-// compile-command: "cfa io.c" //
-// End: //
Index: src/tests/io1.c
===================================================================
--- src/tests/io1.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
+++ src/tests/io1.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -0,0 +1,73 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// io1.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed Mar  2 16:56:02 2016
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu May 24 21:17:56 2018
+// Update Count     : 104
+// 
+
+#include <fstream>
+
+int main() {
+	int x = 3, y = 5, z = 7;
+	sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
+	sout | 1 | 2 | 3 | endl;
+	sout | '1' | '2' | '3' | endl;
+	sout | 1 | "" | 2 | "" | 3 | endl;
+	sout | endl;
+
+	sout | "opening delimiters" | endl;
+	sout
+		 | "x (" | 1
+		 | "x [" | 2
+		 | "x {" | 3
+		 | "x =" | 4
+		 | "x $" | 5
+		 | "x £" | 6
+		 | "x ¥" | 7
+		 | "x ¡" | 8
+		 | "x ¿" | 9
+		 | "x «" | 10
+		 | endl | endl;
+
+	sout | "closing delimiters" | endl;
+	sout
+		 | 1 | ", x"
+		 | 2 | ". x"
+		 | 3 | "; x"
+		 | 4 | "! x"
+		 | 5 | "? x"
+		 | 6 | "% x"
+		 | 7 | "¢ x"
+		 | 8 | "» x"
+		 | 9 | ") x"
+		 | 10 | "] x"
+		 | 11 | "} x"
+		 | endl | endl;
+
+	sout | "opening/closing delimiters" | endl;
+	sout
+		 | "x`" | 1 | "`x'" | 2
+		 | "'x\"" | 3 | "\"x:" | 4
+		 | ":x " | 5 | " x\t" | 6
+		 | "\tx\f" | 7 | "\fx\v" | 8
+		 | "\vx\n" | 9 | "\nx\r" | 10
+		 | "\rx"
+		 | endl | endl;
+
+	sout | "override opening/closing delimiters" | endl;
+	sout | "x ( " | 1 | " ) x" | 2 | " , x" | 3 | " :x: " | 4 | endl;
+	sout | endl;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa io1.c" //
+// End: //
Index: src/tests/io2.c
===================================================================
--- src/tests/io2.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
+++ src/tests/io2.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -0,0 +1,134 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// io2.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed Mar  2 16:56:02 2016
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu May 24 21:17:41 2018
+// Update Count     : 103
+// 
+
+#include <fstream>
+
+int main() {
+	_Bool b;											// basic types
+	char c;
+	signed char sc;
+	unsigned char usc;
+	short int si;
+	unsigned short int usi;
+	int i;
+	unsigned int ui;
+	long int li;
+	unsigned long int uli;
+	long long int lli;
+	unsigned long long int ulli;
+	float f;
+	double d;
+	long double ld;
+	float _Complex fc;
+	double _Complex dc;
+	long double _Complex ldc;
+	enum { size = 10 };
+	char s1[size], s2[size];
+
+	ifstream in = { "io.data" };						// create / open file
+
+	sout | "input bacis types" | endl;
+	in	 | b											// boolean
+		 | c | sc | usc									// character
+		 | si | usi | i | ui | li | uli | lli | ulli	// integral
+		 | f | d | ld									// floating point
+		 | fc | dc | ldc								// floating-point complex
+		 | cstr( s1 ) | cstr( s2, size );				// C string, length unchecked and checked
+	sout | endl;
+
+	sout | "output basic types" | endl;
+	sout | b | endl										// boolean
+		 | c | ' ' | sc | ' ' | usc | endl				// character
+		 | si | usi | i | ui | li | uli | lli | ulli | endl // integral
+		 | f | d | ld | endl							// floating point
+		 | fc | dc | ldc | endl;						// complex
+	sout | endl;
+
+	sout | "tuples" | endl;
+	[int, [ int, int ] ] t1 = [ 1, [ 2, 3 ] ], t2 = [ 4, [ 5, 6 ] ];
+	sout | t1 | t2 | endl;								// print tuple
+	sout | endl;
+
+	sout | "toggle separator" | endl;
+	sout | f | "" | d | "" | ld | endl					// floating point without separator
+		 | sepDisable | fc | dc | ldc | endl			// complex without separator
+		 | fc | sepOn | dc | ldc | endl					// local separator add
+		 | sepEnable | fc | dc | ldc | endl				// complex with separator
+		 | fc | sepOff | dc | ldc | endl				// local separator removal
+		 | s1 | sepOff | s2 | endl						// local separator removal
+		 | s1 | "" | s2 | endl;							// local separator removal
+	sout | endl;
+
+	sout | "change separator" | endl;
+	sout | "from \"" | sep | "\"";
+	sepSet( sout, ", $" );								// change separator, maximum of 15 characters
+	sout | " to \"" | sep | "\"" | endl;
+	sout | f | d | ld | endl
+		 | fc | dc | ldc | endl
+		 | s1 | s2 | endl
+		 | t1 | t2 | endl;								// print tuple
+	sout | endl;
+	sout | "from \"" | sep | "\" ";
+	sepSet( sout, " " );								// restore separator
+	sout | "to \"" | sep | "\"" | endl;
+	sout | f | d | ld | endl
+		 | fc | dc | ldc | endl
+		 | s1 | s2 | endl
+		 | t1 | t2 | endl;								// print tuple
+	sout | endl;
+
+	sout | "check sepOn/sepOff" | endl;
+	sout | sepOn | 1 | 2 | 3 | sepOn | endl;			// no separator at start/end of line
+	sout | 1 | sepOff | 2 | 3 | endl;					// locally turn off implicit separator
+	sout | sepOn | sepOn | 1 | 2 | 3 | sepOn | sepOff | sepOn | '\n'; // no separator at start/end of line
+	sout | 1 | 2 | 3 | "\n\n" | sepOn;					// no separator at start of next line
+	sout | 1 | 2 | 3 | endl;
+	sout | endl;
+
+	sout | "check enable/disable" | endl;
+	sout | sepDisable | 1 | 2 | 3 | endl;				// globally turn off implicit separation
+	sout | 1 | sepOn | 2 | 3 | endl;					// locally turn on implicit separator
+	sout | sepEnable | 1 | 2 | 3 | endl | sepDisable;	// globally turn on/off implicit separation
+	sout | 1 | 2 | 3 | endl | sepEnable;				// globally turn on implicit separation
+	sout | 1 | 2 | 3 | sepOn | sepDisable | endl;		// ignore seperate at end of line
+	sout | 1 | 2 | 3 | sepOn | sepEnable | endl;		// separator at end of line
+	sout | 1 | 2 | 3 | endl;
+	sout | endl;
+
+//	sout | fmt( d, "%8.3f" ) || endl;
+//	sout | endl;
+
+	sepSetTuple( sout, " " );							// set tuple separator from ", " to " "
+	sout | t1 | t2 | " \"" | sep | "\"" | endl;
+	sepSetTuple( sout, ", " );							// reset tuple separator to ", "
+	sout | t1 | t2 | " \"" | sep | "\"" | endl;
+	sout | t1 | t2 | endl;								// print tuple
+	sout | endl;
+
+	[int, int, const char *, double] t3 = { 3, 4, "a", 7.2 };
+	sout | [ 3, 4, "a", 7.2 ] | endl;
+	sout | t3 | endl;
+	sepSetTuple( sout, " " );
+	sout | t3 | endl;
+	sout | sepOn | t3 | sepDisable | t3 | sepEnable | t3 | endl;
+	sepSet( sout, "^" );
+	sepSetTuple( sout, "-" );
+	sout | t3 | 3 | 4 | t3 | endl;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa io2.c" //
+// End: //
Index: src/tests/math1.c
===================================================================
--- src/tests/math1.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/math1.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -10,6 +10,6 @@
 // Created On       : Fri Apr 22 14:59:21 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 11 15:16:41 2017
-// Update Count     : 84
+// Last Modified On : Thu May 24 21:01:15 2018
+// Update Count     : 85
 // 
 
@@ -48,17 +48,4 @@
     sout | "\\" | b | b \ e | endl;
     sout | "\\" | 'a' \ 3u | 2 \ 8u | 4 \ 3u | -4 \ 3u | 4 \ -3 | -4 \ -3 | 4.0 \ 2.1 | (1.0f+2.0fi) \ (3.0f+2.0fi) | endl;
-
-	//---------------------- Logarithm ----------------------
-
-	sout | "log:" | log( 1.0F ) | log( 1.0D ) | log( 1.0L ) | log( 1.0F+1.0FI ) | log( 1.0D+1.0DI ) | log( 1.0DL+1.0LI ) | endl;
-	sout | "log2:" | log2( 8.0F ) | log2( 8.0D ) | log2( 8.0L ) | endl;
-	sout | "log10:" | log10( 100.0F ) | log10( 100.0D ) | log10( 100.0L ) | endl;
-	sout | "log1p:" | log1p( 1.0F ) | log1p( 1.0D ) | log1p( 1.0L ) | endl;
-	sout | "ilogb:" | ilogb( 1.0F ) | ilogb( 1.0D ) | ilogb( 1.0L ) | endl;
-	sout | "logb:" | logb( 8.0F ) | logb( 8.0D ) | logb( 8.0L ) | endl;
-
-	sout | "sqrt:" | sqrt( 1.0F ) | sqrt( 1.0D ) | sqrt( 1.0L ) | sqrt( 1.0F+1.0FI ) | sqrt( 1.0D+1.0DI ) | sqrt( 1.0DL+1.0LI ) | endl;
-	sout | "cbrt:" | cbrt( 27.0F ) | cbrt( 27.0D ) | cbrt( 27.0L ) | endl;
-	sout | "hypot:" | hypot( 1.0F, -1.0F ) | hypot( 1.0D, -1.0D ) | hypot( 1.0L, -1.0L ) | endl;
 } // main
 
Index: src/tests/math2.c
===================================================================
--- src/tests/math2.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/math2.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -10,6 +10,6 @@
 // Created On       : Fri Apr 22 14:59:21 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 11 15:40:04 2017
-// Update Count     : 81
+// Last Modified On : Thu May 24 21:06:10 2018
+// Update Count     : 82
 // 
 
@@ -21,4 +21,17 @@
 	double d;
 	long double l;
+
+	//---------------------- Logarithm ----------------------
+
+	sout | "log:" | log( 1.0F ) | log( 1.0D ) | log( 1.0L ) | log( 1.0F+1.0FI ) | log( 1.0D+1.0DI ) | log( 1.0DL+1.0LI ) | endl;
+	sout | "log2:" | log2( 8.0F ) | log2( 8.0D ) | log2( 8.0L ) | endl;
+	sout | "log10:" | log10( 100.0F ) | log10( 100.0D ) | log10( 100.0L ) | endl;
+	sout | "log1p:" | log1p( 1.0F ) | log1p( 1.0D ) | log1p( 1.0L ) | endl;
+	sout | "ilogb:" | ilogb( 1.0F ) | ilogb( 1.0D ) | ilogb( 1.0L ) | endl;
+	sout | "logb:" | logb( 8.0F ) | logb( 8.0D ) | logb( 8.0L ) | endl;
+
+	sout | "sqrt:" | sqrt( 1.0F ) | sqrt( 1.0D ) | sqrt( 1.0L ) | sqrt( 1.0F+1.0FI ) | sqrt( 1.0D+1.0DI ) | sqrt( 1.0DL+1.0LI ) | endl;
+	sout | "cbrt:" | cbrt( 27.0F ) | cbrt( 27.0D ) | cbrt( 27.0L ) | endl;
+	sout | "hypot:" | hypot( 1.0F, -1.0F ) | hypot( 1.0D, -1.0D ) | hypot( 1.0L, -1.0L ) | endl;
 
 	//---------------------- Trigonometric ----------------------
@@ -32,27 +45,4 @@
 	sout | "atan2:" | atan2( 1.0F, 1.0F ) | atan2( 1.0D, 1.0D ) | atan2( 1.0L, 1.0L );
 	sout | "atan:" | atan( 1.0F, 1.0F ) | atan( 1.0D, 1.0D ) | atan( 1.0L, 1.0L ) | endl;
-
-	//---------------------- Hyperbolic ----------------------
-
-	sout | "sinh:" | sinh( 1.0F ) | sinh( 1.0D ) | sinh( 1.0L ) | sinh( 1.0F+1.0FI ) | sinh( 1.0D+1.0DI ) | sinh( 1.0DL+1.0LI ) | endl;
-	sout | "cosh:" | cosh( 1.0F ) | cosh( 1.0D ) | cosh( 1.0L ) | cosh( 1.0F+1.0FI ) | cosh( 1.0D+1.0DI ) | cosh( 1.0DL+1.0LI ) | endl;
-	sout | "tanh:" | tanh( 1.0F ) | tanh( 1.0D ) | tanh( 1.0L ) | tanh( 1.0F+1.0FI ) | tanh( 1.0D+1.0DI ) | tanh( 1.0DL+1.0LI ) | endl;
-	sout | "acosh:" | acosh( 1.0F ) | acosh( 1.0D ) | acosh( 1.0L ) | acosh( 1.0F+1.0FI ) | acosh( 1.0D+1.0DI ) | acosh( 1.0DL+1.0LI ) | endl;
-	sout | "asinh:" | asinh( 1.0F ) | asinh( 1.0D ) | asinh( 1.0L ) | asinh( 1.0F+1.0FI ) | asinh( 1.0D+1.0DI ) | asinh( 1.0DL+1.0LI ) | endl;
-	sout | "atanh:" | atanh( 1.0F ) | atanh( 1.0D ) | atanh( 1.0L ) | atanh( 1.0F+1.0FI ) | atanh( 1.0D+1.0DI ) | atanh( 1.0DL+1.0LI ) | endl;
-
-	//---------------------- Error / Gamma ----------------------
-
-	sout | "erf:" | erf( 1.0F ) | erf( 1.0D ) | erf( 1.0L ) | endl;
-	sout | "erfc:" | erfc( 1.0F ) | erfc( 1.0D ) | erfc( 1.0L ) | endl;
-	sout | "lgamma:" | lgamma( 4.0F ) | lgamma( 4.0D ) | lgamma( 4.0L ) | endl;
-	int sign;
-	f = lgamma( 4.0F, &sign );
-	sout | "lgamma:" | f | sign;
-	d = lgamma( 4.0D, &sign );
-	sout | d | sign;
-	l = lgamma( 4.0L, &sign );
-	sout | l | sign | endl;
-	sout | "tgamma:" | tgamma( 4.0F ) | tgamma( 4.0D ) | tgamma( 4.0L ) | endl;
 } // main
 
Index: src/tests/math3.c
===================================================================
--- src/tests/math3.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/math3.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -10,6 +10,6 @@
 // Created On       : Fri Apr 22 14:59:21 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 11 15:40:03 2017
-// Update Count     : 81
+// Last Modified On : Thu May 24 21:06:12 2018
+// Update Count     : 82
 // 
 
@@ -22,47 +22,26 @@
 	long double l;
 
-	//---------------------- Nearest Integer ----------------------
+	//---------------------- Hyperbolic ----------------------
 
-	sout | "floor:" | floor( 1.2F ) | floor( 1.2D ) | floor( 1.2L ) | endl;
-	sout | "ceil:" | ceil( 1.6F ) | ceil( 1.6D ) | ceil( 1.6L ) | endl;
-	sout | "trunc:" | trunc( 3.5F ) | trunc( 3.5D ) | trunc( 3.5L ) | endl;
-	sout | "rint:" | (float)rint( 1.5F ) | (double)rint( 1.5D ) | (long double)rint( 1.5L ) | endl;
-	sout | "rint:" | (long int)rint( 1.5F ) | (long int)rint( 1.5D ) | (long int)rint( 1.5L ) | endl;
-	sout | "rint:" | (long long int)rint( 1.5F ) | (long long int)rint( 1.5D ) | (long long int)rint( 1.5L ) | endl;
-	sout | "lrint:" | lrint( 1.5F ) | lrint( 1.5D ) | lrint( 1.5L ) | endl;
-	sout | "llrint:" | llrint( 1.5F ) | llrint( 1.5D ) | llrint( 1.5L ) | endl;
-	sout | "nearbyint:" | nearbyint( 3.5F ) | nearbyint( 3.5D ) | nearbyint( 3.5L ) | endl;
-	sout | "round:" | (float)round( 1.5F ) | (double)round( 1.5D ) | (long double)round( 1.5L ) | endl;
-	sout | "round:" | (long int)round( 1.5F ) | (long int)round( 1.5D ) | (long int)round( 1.5L ) | endl;
-	sout | "round:" | (long long int)round( 1.5F ) | (long long int)round( 1.5D ) | (long long int)round( 1.5L ) | endl;
-	sout | "lround:" | lround( 1.5F ) | lround( 1.5D ) | lround( 1.5L ) | endl;
-	sout | "llround:" | llround( 1.5F ) | llround( 1.5D ) | llround( 1.5L ) | endl;
+	sout | "sinh:" | sinh( 1.0F ) | sinh( 1.0D ) | sinh( 1.0L ) | sinh( 1.0F+1.0FI ) | sinh( 1.0D+1.0DI ) | sinh( 1.0DL+1.0LI ) | endl;
+	sout | "cosh:" | cosh( 1.0F ) | cosh( 1.0D ) | cosh( 1.0L ) | cosh( 1.0F+1.0FI ) | cosh( 1.0D+1.0DI ) | cosh( 1.0DL+1.0LI ) | endl;
+	sout | "tanh:" | tanh( 1.0F ) | tanh( 1.0D ) | tanh( 1.0L ) | tanh( 1.0F+1.0FI ) | tanh( 1.0D+1.0DI ) | tanh( 1.0DL+1.0LI ) | endl;
+	sout | "acosh:" | acosh( 1.0F ) | acosh( 1.0D ) | acosh( 1.0L ) | acosh( 1.0F+1.0FI ) | acosh( 1.0D+1.0DI ) | acosh( 1.0DL+1.0LI ) | endl;
+	sout | "asinh:" | asinh( 1.0F ) | asinh( 1.0D ) | asinh( 1.0L ) | asinh( 1.0F+1.0FI ) | asinh( 1.0D+1.0DI ) | asinh( 1.0DL+1.0LI ) | endl;
+	sout | "atanh:" | atanh( 1.0F ) | atanh( 1.0D ) | atanh( 1.0L ) | atanh( 1.0F+1.0FI ) | atanh( 1.0D+1.0DI ) | atanh( 1.0DL+1.0LI ) | endl;
 
-	//---------------------- Manipulation ----------------------
+	//---------------------- Error / Gamma ----------------------
 
-	sout | "copysign:" | copysign( 1.0F, -1.0F ) | copysign( 1.0D, -1.0D ) | copysign( 1.0L, -1.0L ) | endl;
-	int exp;
-	f = frexp( 4.0F, &exp );
-	sout | "frexp:" | f | exp;
-	d = frexp( 4.0D, &exp );
-	sout | d | exp;
-	l = frexp( 4.0L, &exp );
-	sout | l | exp | endl;
-	sout | "ldexp:" | ldexp( 2.0F, 2 ) | ldexp( 2.0D, 2 ) | ldexp( 2.0L, 2 ) | endl;
-	float fi;
-	double di;
-	long double ldi;
-	f = modf( 2.3F, &fi );
-	sout | "modf:" | fi | f;
-	d = modf( 2.3D, &di );
-	sout | di | d;
-	l = modf( 2.3L, &ldi );
-	sout | ldi | l | endl;
-	sout | "modf:" | modf( 2.3F ) | modf( 2.3D ) | modf( 2.3L ) | endl;
-	sout | "nextafter:" | nextafter( 2.0F, 3.0F ) | nextafter( 2.0D, 3.0D ) | nextafter( 2.0L, 3.0L ) | endl;
-	sout | "nexttoward:" | nexttoward( 2.0F, 3.0F ) | nexttoward( 2.0D, 3.0D ) | nexttoward( 2.0L, 3.0L ) | endl;
-
-	sout | "scalbn:" | scalbn( 2.0F, 3 ) | scalbn( 2.0D, 3 ) | scalbn( 2.0L, 3 ) | endl;
-	sout | "scalbln:" | scalbln( 2.0F, 3L ) | scalbln( 2.0D, 3L ) | scalbln( 2.0L, 3L ) | endl;
+	sout | "erf:" | erf( 1.0F ) | erf( 1.0D ) | erf( 1.0L ) | endl;
+	sout | "erfc:" | erfc( 1.0F ) | erfc( 1.0D ) | erfc( 1.0L ) | endl;
+	sout | "lgamma:" | lgamma( 4.0F ) | lgamma( 4.0D ) | lgamma( 4.0L ) | endl;
+	int sign;
+	f = lgamma( 4.0F, &sign );
+	sout | "lgamma:" | f | sign;
+	d = lgamma( 4.0D, &sign );
+	sout | d | sign;
+	l = lgamma( 4.0L, &sign );
+	sout | l | sign | endl;
+	sout | "tgamma:" | tgamma( 4.0F ) | tgamma( 4.0D ) | tgamma( 4.0L ) | endl;
 } // main
 
Index: src/tests/math4.c
===================================================================
--- src/tests/math4.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
+++ src/tests/math4.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -0,0 +1,72 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// math4.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Thu May 24 20:56:54 2018
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Thu May 24 20:58:06 2018
+// Update Count     : 2
+// 
+
+#include <fstream>
+#include <math>
+
+int main( void ) {
+	float f;
+	double d;
+	long double l;
+
+	//---------------------- Nearest Integer ----------------------
+
+	sout | "floor:" | floor( 1.2F ) | floor( 1.2D ) | floor( 1.2L ) | endl;
+	sout | "ceil:" | ceil( 1.6F ) | ceil( 1.6D ) | ceil( 1.6L ) | endl;
+	sout | "trunc:" | trunc( 3.5F ) | trunc( 3.5D ) | trunc( 3.5L ) | endl;
+	sout | "rint:" | (float)rint( 1.5F ) | (double)rint( 1.5D ) | (long double)rint( 1.5L ) | endl;
+	sout | "rint:" | (long int)rint( 1.5F ) | (long int)rint( 1.5D ) | (long int)rint( 1.5L ) | endl;
+	sout | "rint:" | (long long int)rint( 1.5F ) | (long long int)rint( 1.5D ) | (long long int)rint( 1.5L ) | endl;
+	sout | "lrint:" | lrint( 1.5F ) | lrint( 1.5D ) | lrint( 1.5L ) | endl;
+	sout | "llrint:" | llrint( 1.5F ) | llrint( 1.5D ) | llrint( 1.5L ) | endl;
+	sout | "nearbyint:" | nearbyint( 3.5F ) | nearbyint( 3.5D ) | nearbyint( 3.5L ) | endl;
+	sout | "round:" | (float)round( 1.5F ) | (double)round( 1.5D ) | (long double)round( 1.5L ) | endl;
+	sout | "round:" | (long int)round( 1.5F ) | (long int)round( 1.5D ) | (long int)round( 1.5L ) | endl;
+	sout | "round:" | (long long int)round( 1.5F ) | (long long int)round( 1.5D ) | (long long int)round( 1.5L ) | endl;
+	sout | "lround:" | lround( 1.5F ) | lround( 1.5D ) | lround( 1.5L ) | endl;
+	sout | "llround:" | llround( 1.5F ) | llround( 1.5D ) | llround( 1.5L ) | endl;
+
+	//---------------------- Manipulation ----------------------
+
+	sout | "copysign:" | copysign( 1.0F, -1.0F ) | copysign( 1.0D, -1.0D ) | copysign( 1.0L, -1.0L ) | endl;
+	int exp;
+	f = frexp( 4.0F, &exp );
+	sout | "frexp:" | f | exp;
+	d = frexp( 4.0D, &exp );
+	sout | d | exp;
+	l = frexp( 4.0L, &exp );
+	sout | l | exp | endl;
+	sout | "ldexp:" | ldexp( 2.0F, 2 ) | ldexp( 2.0D, 2 ) | ldexp( 2.0L, 2 ) | endl;
+	float fi;
+	double di;
+	long double ldi;
+	f = modf( 2.3F, &fi );
+	sout | "modf:" | fi | f;
+	d = modf( 2.3D, &di );
+	sout | di | d;
+	l = modf( 2.3L, &ldi );
+	sout | ldi | l | endl;
+	sout | "modf:" | modf( 2.3F ) | modf( 2.3D ) | modf( 2.3L ) | endl;
+	sout | "nextafter:" | nextafter( 2.0F, 3.0F ) | nextafter( 2.0D, 3.0D ) | nextafter( 2.0L, 3.0L ) | endl;
+	sout | "nexttoward:" | nexttoward( 2.0F, 3.0F ) | nexttoward( 2.0D, 3.0D ) | nexttoward( 2.0L, 3.0L ) | endl;
+
+	sout | "scalbn:" | scalbn( 2.0F, 3 ) | scalbn( 2.0D, 3 ) | scalbn( 2.0L, 3 ) | endl;
+	sout | "scalbln:" | scalbln( 2.0F, 3L ) | scalbln( 2.0D, 3L ) | scalbln( 2.0L, 3L ) | endl;
+} // main
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa math3.c" //
+// End: //
Index: src/tests/preempt_longrun/Makefile.am
===================================================================
--- src/tests/preempt_longrun/Makefile.am	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/preempt_longrun/Makefile.am	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -17,5 +17,5 @@
 repeats=10
 max_time=600
-preempt=1_000ul
+preempt=10ul\`ms
 debug=-debug
 
Index: src/tests/preempt_longrun/Makefile.in
===================================================================
--- src/tests/preempt_longrun/Makefile.in	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/preempt_longrun/Makefile.in	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -450,5 +450,5 @@
 repeats = 10
 max_time = 600
-preempt = 1_000ul
+preempt = 10ul\`ms
 debug = -debug
 REPEAT = ${abs_top_srcdir}/tools/repeat
Index: src/tests/preempt_longrun/create.c
===================================================================
--- src/tests/preempt_longrun/create.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/preempt_longrun/create.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -1,9 +1,8 @@
 #include <kernel>
 #include <thread>
-
-static const unsigned long N = 60_000ul;
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
@@ -11,4 +10,6 @@
 	return PREEMPTION_RATE;
 }
+
+static const unsigned long N = 60_000ul;
 
 thread worker_t {};
Index: src/tests/preempt_longrun/enter.c
===================================================================
--- src/tests/preempt_longrun/enter.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/preempt_longrun/enter.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -2,9 +2,8 @@
 #include <monitor>
 #include <thread>
-
-static const unsigned long N  = 2_100_000ul;
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
@@ -12,4 +11,6 @@
 	return PREEMPTION_RATE;
 }
+
+static const unsigned long N  = 2_100_000ul;
 
 monitor mon_t {};
Index: src/tests/preempt_longrun/enter3.c
===================================================================
--- src/tests/preempt_longrun/enter3.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/preempt_longrun/enter3.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -2,9 +2,8 @@
 #include <monitor>
 #include <thread>
-
-static const unsigned long N  = 500_000ul;
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
@@ -12,4 +11,6 @@
 	return PREEMPTION_RATE;
 }
+
+static const unsigned long N  = 500_000ul;
 
 monitor mon_t {};
Index: src/tests/preempt_longrun/processor.c
===================================================================
--- src/tests/preempt_longrun/processor.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/preempt_longrun/processor.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -1,9 +1,8 @@
 #include <kernel>
 #include <thread>
-
-static const unsigned long N = 5_000ul;
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
@@ -11,4 +10,6 @@
 	return PREEMPTION_RATE;
 }
+
+static const unsigned long N = 5_000ul;
 
 int main(int argc, char* argv[]) {
Index: src/tests/preempt_longrun/stack.c
===================================================================
--- src/tests/preempt_longrun/stack.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/preempt_longrun/stack.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -1,9 +1,9 @@
 #include <kernel>
+#include <math>
 #include <thread>
-
-#include <math>
+#include <time>
 
 #ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
+#error PREEMPTION_RATE not defined in makefile
 #endif
 
Index: src/tests/preempt_longrun/yield.c
===================================================================
--- src/tests/preempt_longrun/yield.c	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/preempt_longrun/yield.c	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -1,4 +1,13 @@
 #include <kernel>
 #include <thread>
+#include <time>
+
+#ifndef PREEMPTION_RATE
+#error PREEMPTION_RATE not defined in makefile
+#endif
+
+Duration default_preemption() {
+	return PREEMPTION_RATE;
+}
 
 #ifdef LONG_TEST
@@ -7,12 +16,4 @@
 static const unsigned long N = 325_000ul;
 #endif
-
-#ifndef PREEMPTION_RATE
-#define PREEMPTION_RATE 10`ms
-#endif
-
-Duration default_preemption() {
-	return PREEMPTION_RATE;
-}
 
 thread worker_t {};
Index: src/tests/test.py
===================================================================
--- src/tests/test.py	(revision 13073be42dba9d23e1eb3322d700f265381ae024)
+++ src/tests/test.py	(revision 8dbedfc9ed34c91b75dbb53a6977634c91f963be)
@@ -78,9 +78,4 @@
 			else :
 				print('ERROR: No expected file for test %s, ignoring it' % testname, file=sys.stderr)
-
-	# make sure we have at least some test to run
-	if not tests :
-		print('ERROR: No valid test to run', file=sys.stderr)
-		sys.exit(1)
 
 	return tests
@@ -266,4 +261,10 @@
 		tests = validTests( options )
 
+	# make sure we have at least some test to run
+	if not tests :
+		print('ERROR: No valid test to run', file=sys.stderr)
+		sys.exit(1)
+
+
 	# sort the test alphabetically for convenience
 	tests.sort(key=lambda t: (t.arch if t.arch else '') + t.target())
