Index: doc/LaTeXmacros/common.tex
===================================================================
--- doc/LaTeXmacros/common.tex	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ doc/LaTeXmacros/common.tex	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -11,6 +11,6 @@
 %% Created On       : Sat Apr  9 10:06:17 2016
 %% Last Modified By : Peter A. Buhr
-%% Last Modified On : Mon Jul 24 21:02:14 2017
-%% Update Count     : 352
+%% Last Modified On : Mon Aug 28 20:18:42 2017
+%% Update Count     : 355
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -148,21 +148,30 @@
 % Latin abbreviation
 \newcommand{\abbrevFont}{\textit}	% set empty for no italics
+\newcommand{\EG}{\abbrevFont{e}.\abbrevFont{g}.}
 \newcommand*{\eg}{%
-	\@ifnextchar{,}{\abbrevFont{e}.\abbrevFont{g}.}%
-		{\@ifnextchar{:}{\abbrevFont{e}.\abbrevFont{g}.}%
-			{\abbrevFont{e}.\abbrevFont{g}.,\xspace}}%
-}%
+	\@ifnextchar{,}{\EG}%
+		{\@ifnextchar{:}{\EG}%
+			{\EG,\xspace}}%
+}%
+\newcommand{\IE}{\abbrevFont{i}.\abbrevFont{e}.}
 \newcommand*{\ie}{%
-	\@ifnextchar{,}{\abbrevFont{i}.\abbrevFont{e}.}%
-		{\@ifnextchar{:}{\abbrevFont{i}.\abbrevFont{e}.}%
-			{\abbrevFont{i}.\abbrevFont{e}.,\xspace}}%
-}%
+	\@ifnextchar{,}{\IE}%
+		{\@ifnextchar{:}{\IE}%
+			{\IE,\xspace}}%
+}%
+\newcommand{\ETC}{\abbrevFont{etc}}
 \newcommand*{\etc}{%
-	\@ifnextchar{.}{\abbrevFont{etc}}%
-        {\abbrevFont{etc}.\xspace}%
-}%
+	\@ifnextchar{.}{\ETC}%
+        {\ETC\xspace}%
+}%
+\newcommand{\ETAL}{\abbrevFont{et\:al}}
 \newcommand{\etal}{%
-	\@ifnextchar{.}{\abbrevFont{et~al}}%
-	        {\abbrevFont{et al}.\xspace}%
+	\@ifnextchar{.}{\ETAL}%
+		{\abbrevFont{\ETAL}.\xspace}%
+}%
+\newcommand{\VIZ}{\abbrevFont{viz}}
+\newcommand{\viz}{%
+	\@ifnextchar{.}{\VIZ}%
+		{\abbrevFont{\VIZ}.\xspace}%
 }%
 \makeatother
Index: doc/LaTeXmacros/lstlang.sty
===================================================================
--- doc/LaTeXmacros/lstlang.sty	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ doc/LaTeXmacros/lstlang.sty	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -8,6 +8,6 @@
 %% Created On       : Sat May 13 16:34:42 2017
 %% Last Modified By : Peter A. Buhr
-%% Last Modified On : Mon Jul 24 20:40:37 2017
-%% Update Count     : 13
+%% Last Modified On : Wed Aug 30 22:11:14 2017
+%% Update Count     : 14
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
@@ -112,5 +112,5 @@
 		finally, forall, ftype, _Generic, _Imaginary, inline, __label__, lvalue, _Noreturn, one_t, 
 		otype, restrict, _Static_assert, throw, throwResume, trait, try, ttype, typeof, __typeof, 
-		__typeof__, virtual, with, zero_t},
+		__typeof__, virtual, waitfor, when, with, zero_t},
 	morekeywords=[2]{
 		_Atomic, coroutine, is_coroutine, is_monitor, is_thread, monitor, mutex, nomutex, 
Index: doc/refrat/keywords.tex
===================================================================
--- doc/refrat/keywords.tex	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ doc/refrat/keywords.tex	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -11,6 +11,6 @@
 %% Created On       : Sun Aug  6 08:17:27 2017
 %% Last Modified By : Peter A. Buhr
-%% Last Modified On : Sun Aug  6 08:31:42 2017
-%% Update Count     : 4
+%% Last Modified On : Wed Aug 30 22:10:10 2017
+%% Update Count     : 5
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \begin{tabular}{@{}llllll@{}}
@@ -52,11 +52,11 @@
 ©ttype©			\\
 ©virtual©		\\
-©with©			\\
+©waitfor©		\\
 \end{tabular}
 &
 \begin{tabular}{@{}l@{}}
+©when©			\\
+©with©			\\
 ©zero_t©		\\
-				\\
-				\\
 				\\
 				\\
Index: src/Common/CodeLocation.h
===================================================================
--- src/Common/CodeLocation.h	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Common/CodeLocation.h	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -9,7 +9,7 @@
 // Author           : Andrew Beach
 // Created On       : Thr Aug 17 11:23:00 2017
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 17 14:07:00 2017
-// Update Count     : 0
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Aug 28 12:46:01 2017
+// Update Count     : 2
 //
 
@@ -66,5 +66,6 @@
 
 inline std::string to_string( const CodeLocation& location ) {
-    return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + " " : "";
+    // Column number ":1" allows IDEs to parse the error message and position the cursor in the source text.
+    return location.isSet() ? location.filename + ":" + std::to_string(location.linenumber) + ":1 " : "";
 }
 
Index: src/Common/PassVisitor.h
===================================================================
--- src/Common/PassVisitor.h	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Common/PassVisitor.h	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -75,4 +75,5 @@
 	virtual void visit( CatchStmt *catchStmt ) override final;
 	virtual void visit( FinallyStmt *finallyStmt ) override final;
+	virtual void visit( WaitForStmt *waitforStmt ) override final;
 	virtual void visit( NullStmt *nullStmt ) override final;
 	virtual void visit( DeclStmt *declStmt ) override final;
@@ -159,7 +160,8 @@
 	virtual Statement* mutate( ReturnStmt *returnStmt ) override final;
 	virtual Statement* mutate( ThrowStmt *throwStmt ) override final;
-	virtual Statement* mutate( TryStmt *returnStmt ) override final;
+	virtual Statement* mutate( TryStmt *tryStmt ) override final;
 	virtual Statement* mutate( CatchStmt *catchStmt ) override final;
-	virtual Statement* mutate( FinallyStmt *catchStmt ) override final;
+	virtual Statement* mutate( FinallyStmt *finallyStmt ) override final;
+	virtual Statement* mutate( WaitForStmt *waitforStmt ) override final;
 	virtual NullStmt* mutate( NullStmt *nullStmt ) override final;
 	virtual Statement* mutate( DeclStmt *declStmt ) override final;
Index: src/Common/PassVisitor.impl.h
===================================================================
--- src/Common/PassVisitor.impl.h	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Common/PassVisitor.impl.h	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -541,4 +541,6 @@
 }
 
+//--------------------------------------------------------------------------
+// FinallyStmt
 template< typename pass_type >
 void PassVisitor< pass_type >::visit( FinallyStmt * node ) {
@@ -547,4 +549,23 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
+	MUTATE_BODY( Statement, node );
+}
+
+//--------------------------------------------------------------------------
+// WaitForStmt
+template< typename pass_type >
+void PassVisitor< pass_type >::visit( WaitForStmt * node ) {
+	VISIT_BODY( node );
+}
+
+template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( WaitForStmt * node ) {
+	MUTATE_BODY( Statement, node );
+}
+
+//--------------------------------------------------------------------------
+// NullStmt
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( NullStmt * node ) {
 	VISIT_BODY( node );
@@ -552,4 +573,11 @@
 
 template< typename pass_type >
+NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
+	MUTATE_BODY( NullStmt, node );
+}
+
+//--------------------------------------------------------------------------
+// DeclStmt
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( DeclStmt * node ) {
 	VISIT_BODY( node );
@@ -557,4 +585,11 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
+	MUTATE_BODY( Statement, node );
+}
+
+//--------------------------------------------------------------------------
+// ImplicitCtorDtorStmt
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( ImplicitCtorDtorStmt * node ) {
 	VISIT_BODY( node );
@@ -562,6 +597,18 @@
 
 template< typename pass_type >
+Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
+	MUTATE_BODY( Statement, node );
+}
+
+//--------------------------------------------------------------------------
+// ApplicationExpr
+template< typename pass_type >
 void PassVisitor< pass_type >::visit( ApplicationExpr * node ) {
 	VISIT_BODY( node );
+}
+
+template< typename pass_type >
+Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
+	MUTATE_BODY( Expression, node );
 }
 
@@ -944,29 +991,4 @@
 
 template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( FinallyStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-NullStmt * PassVisitor< pass_type >::mutate( NullStmt * node ) {
-	MUTATE_BODY( NullStmt, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( DeclStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-Statement * PassVisitor< pass_type >::mutate( ImplicitCtorDtorStmt * node ) {
-	MUTATE_BODY( Statement, node );
-}
-
-template< typename pass_type >
-Expression * PassVisitor< pass_type >::mutate( ApplicationExpr * node ) {
-	MUTATE_BODY( Expression, node );
-}
-
-template< typename pass_type >
 Expression * PassVisitor< pass_type >::mutate( NameExpr * node ) {
 	MUTATE_BODY( Expression, node );
Index: src/Common/SemanticError.cc
===================================================================
--- src/Common/SemanticError.cc	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Common/SemanticError.cc	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -10,21 +10,16 @@
 // Created On       : Mon May 18 07:44:20 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue May 19 07:21:25 2015
-// Update Count     : 1
+// Last Modified On : Tue Aug 29 18:17:35 2017
+// Update Count     : 3
 //
 
-#include <cstdio>            // for fileno, stderr
-#include <unistd.h>          // for isatty
-#include <iostream>          // for basic_ostream, operator<<, ostream
-#include <list>              // for list, _List_iterator
-#include <string>            // for string, operator<<, operator+, to_string
+#include <cstdio>										// for fileno, stderr
+#include <unistd.h>										// for isatty
+#include <iostream>										// for basic_ostream, operator<<, ostream
+#include <list>											// for list, _List_iterator
+#include <string>										// for string, operator<<, operator+, to_string
 
-#include "Common/utility.h"  // for to_string, CodeLocation (ptr only)
+#include "Common/utility.h"								// for to_string, CodeLocation (ptr only)
 #include "SemanticError.h"
-
-inline const std::string& error_str() {
-	static std::string str = isatty( fileno(stderr) ) ? "\e[31merror:\e[39m " : "error: ";
-	return str;
-}
 
 SemanticError::SemanticError() {
@@ -49,6 +44,6 @@
 void SemanticError::print( std::ostream &os ) {
 	using std::to_string;
-	for(auto err : errors) {
-		os << to_string( err.location ) << err.description << '\n';
+	for( auto err : errors ) {
+		os << to_string( err.location ) << err.description << std::endl;
 	}
 }
Index: src/Common/SemanticError.h
===================================================================
--- src/Common/SemanticError.h	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Common/SemanticError.h	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -9,17 +9,18 @@
 // Author           : Richard C. Bilson
 // Created On       : Mon May 18 07:44:20 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Thr Aug 17 14:01:00 2017
-// Update Count     : 7
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Tue Aug 29 22:03:36 2017
+// Update Count     : 17
 //
 
 #pragma once
 
-#include <exception>  // for exception
-#include <iostream>   // for ostream
-#include <list>       // for list
-#include <string>     // for string
+#include <exception>									// for exception
+#include <iostream>										// for ostream
+#include <list>											// for list
+#include <string>										// for string
+#include <unistd.h>										// for isatty
 
-#include "CodeLocation.h"  // for CodeLocation, toString
+#include "CodeLocation.h"								// for CodeLocation, toString
 
 struct error {
@@ -28,7 +29,7 @@
 
 	error() = default;
-	error( const std::string& str ) : description( str ) {}
+	error( const std::string & str ) : description( str ) {}
 
-	void maybeSet( const CodeLocation& location ) {
+	void maybeSet( const CodeLocation & location ) {
 		if( this->location.linenumber < 0 ) {
 			this->location = location;
@@ -41,15 +42,20 @@
 	SemanticError();
 	SemanticError( std::string error );
-	template< typename T > SemanticError( const std::string &error, const T *obj );
+	template< typename T > SemanticError( const std::string & error, const T * obj );
 	~SemanticError() throw() {}
 
-	void append( SemanticError &other );
+	static inline const std::string & error_str() {
+		static std::string str = isatty( STDERR_FILENO ) ? "\e[31merror:\e[39m " : "error: ";
+		return str;
+	}
+
+	void append( SemanticError & other );
 	void append( const std::string & );
 	bool isEmpty() const;
-	void print( std::ostream &os );
+	void print( std::ostream & os );
 
-	void set_location( const CodeLocation& location );
-	// constructs an exception using the given message and the printed
-	// representation of the obj (T must have a print method)
+	void set_location( const CodeLocation & location );
+	// constructs an exception using the given message and the printed representation of the obj (T must have a print
+	// method)
   private:
 	std::list< error > errors;
@@ -57,5 +63,5 @@
 
 template< typename T >
-SemanticError::SemanticError( const std::string &error, const T *obj ) {
+SemanticError::SemanticError( const std::string & error, const T * obj ) {
 	append( toString( error, obj ) );
 }
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Concurrency/Keywords.cc	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -19,4 +19,5 @@
 #include <string>                  // for string, operator==
 
+#include "Common/PassVisitor.h"    // for PassVisitor
 #include "Common/SemanticError.h"  // for SemanticError
 #include "Common/utility.h"        // for deleteAll, map_range
@@ -46,5 +47,5 @@
 
 	//=============================================================================================
-	// Visitors declaration
+	// Pass declarations
 	//=============================================================================================
 
@@ -58,8 +59,5 @@
 	//                                           static inline NewField_t * getter_name( MyType * this ) { return &this->newField; }
 	//
-	class ConcurrentSueKeyword : public Visitor {
-	  protected:
-	    template< typename Visitor >
-	    friend void SymTab::acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor );
+	class ConcurrentSueKeyword : public WithDeclsToAdd {
 	  public:
 
@@ -69,6 +67,5 @@
 		virtual ~ConcurrentSueKeyword() {}
 
-		using Visitor::visit;
-		virtual void visit( StructDecl * decl ) override final;
+		void postvisit( StructDecl * decl );
 
 		void handle( StructDecl * );
@@ -86,5 +83,4 @@
 		bool needs_main;
 
-		std::list< Declaration * > declsToAdd, declsToAddAfter;
 		StructDecl* type_decl = nullptr;
 	};
@@ -117,6 +113,6 @@
 
 		static void implement( std::list< Declaration * > & translationUnit ) {
-			ThreadKeyword impl;
-			SymTab::acceptAndAdd( translationUnit, impl );
+			PassVisitor< ThreadKeyword > impl;
+			acceptAll( translationUnit, impl );
 		}
 	};
@@ -148,6 +144,6 @@
 
 		static void implement( std::list< Declaration * > & translationUnit ) {
-			CoroutineKeyword impl;
-			SymTab::acceptAndAdd( translationUnit, impl );
+			PassVisitor< CoroutineKeyword > impl;
+			acceptAll( translationUnit, impl );
 		}
 	};
@@ -179,6 +175,6 @@
 
 		static void implement( std::list< Declaration * > & translationUnit ) {
-			MonitorKeyword impl;
-			SymTab::acceptAndAdd( translationUnit, impl );
+			PassVisitor< MonitorKeyword > impl;
+			acceptAll( translationUnit, impl );
 		}
 	};
@@ -192,10 +188,9 @@
 	// }                                                               }
 	//
-	class MutexKeyword final : public Visitor {
+	class MutexKeyword final {
 	  public:
 
-		using Visitor::visit;
-		virtual void visit( FunctionDecl * decl ) override final;
-		virtual void visit(   StructDecl * decl ) override final;
+		void postvisit( FunctionDecl * decl );
+		void postvisit(   StructDecl * decl );
 
 		std::list<DeclarationWithType*> findMutexArgs( FunctionDecl* );
@@ -204,5 +199,5 @@
 
 		static void implement( std::list< Declaration * > & translationUnit ) {
-			MutexKeyword impl;
+			PassVisitor< MutexKeyword > impl;
 			acceptAll( translationUnit, impl );
 		}
@@ -230,14 +225,13 @@
 	// }                                                               }
 	//
-	class ThreadStarter final : public Visitor {
+	class ThreadStarter final {
 	  public:
 
-		using Visitor::visit;
-		virtual void visit( FunctionDecl * decl ) override final;
+		void postvisit( FunctionDecl * decl );
 
 		void addStartStatement( FunctionDecl * decl, DeclarationWithType * param );
 
 		static void implement( std::list< Declaration * > & translationUnit ) {
-			ThreadStarter impl;
+			PassVisitor< ThreadStarter > impl;
 			acceptAll( translationUnit, impl );
 		}
@@ -264,6 +258,5 @@
 	// Generic keyword implementation
 	//=============================================================================================
-	void ConcurrentSueKeyword::visit(StructDecl * decl) {
-		Visitor::visit(decl);
+	void ConcurrentSueKeyword::postvisit(StructDecl * decl) {
 		if( decl->get_name() == type_name && decl->has_body() ) {
 			assert( !type_decl );
@@ -353,7 +346,7 @@
 		}
 
-		declsToAdd.push_back( forward );
-		if( needs_main ) declsToAdd.push_back( main_decl );
-		declsToAdd.push_back( get_decl );
+		declsToAddBefore.push_back( forward );
+		if( needs_main ) declsToAddBefore.push_back( main_decl );
+		declsToAddBefore.push_back( get_decl );
 
 		return get_decl;
@@ -405,6 +398,5 @@
 	//=============================================================================================
 
-	void MutexKeyword::visit(FunctionDecl* decl) {
-		Visitor::visit(decl);
+	void MutexKeyword::postvisit(FunctionDecl* decl) {
 
 		std::list<DeclarationWithType*> mutexArgs = findMutexArgs( decl );
@@ -424,6 +416,5 @@
 	}
 
-	void MutexKeyword::visit(StructDecl* decl) {
-		Visitor::visit(decl);
+	void MutexKeyword::postvisit(StructDecl* decl) {
 
 		if( decl->get_name() == "monitor_desc" ) {
@@ -532,7 +523,5 @@
 	// General entry routine
 	//=============================================================================================
-	void ThreadStarter::visit(FunctionDecl * decl) {
-		Visitor::visit(decl);
-
+	void ThreadStarter::postvisit(FunctionDecl * decl) {
 		if( ! CodeGen::isConstructor(decl->get_name()) ) return;
 
Index: src/InitTweak/InitTweak.cc
===================================================================
--- src/InitTweak/InitTweak.cc	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/InitTweak/InitTweak.cc	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -325,5 +325,5 @@
 			std::string name = getFunctionName( expr );
 			assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
-			assertf( ! expr->get_args().empty(), "Can't get called function from dereference with no arguments" );
+			assertf( ! expr->get_args().empty(), "Cannot get called function from dereference with no arguments" );
 			return getCalledFunction( expr->get_args().front() );
 		}
@@ -433,5 +433,5 @@
 			std::string name = getFunctionName( expr );
 			assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );
-			assertf( ! expr->get_args().empty(), "Can't get function name from dereference with no arguments" );
+			assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" );
 			return funcName( expr->get_args().front() );
 		}
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Parser/StatementNode.cc	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -212,5 +212,9 @@
 	WaitForStmt::Target target;
 	target.function = maybeBuild<Expression>( targetExpr );
-	buildMoveList< Expression >( targetExpr, target.arguments );
+
+	ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
+	targetExpr->set_next( nullptr );
+	buildMoveList< Expression >( next, target.arguments );
+
 	delete targetExpr;
 
@@ -226,7 +230,10 @@
 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when, WaitForStmt * node ) {
 	WaitForStmt::Target target;
-
 	target.function = maybeBuild<Expression>( targetExpr );
-	buildMoveList< Expression >( targetExpr, target.arguments );
+
+	ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
+	targetExpr->set_next( nullptr );
+	buildMoveList< Expression >( next, target.arguments );
+
 	delete targetExpr;
 
Index: src/Parser/lex.ll
===================================================================
--- src/Parser/lex.ll	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Parser/lex.ll	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -10,6 +10,6 @@
  * Created On       : Sat Sep 22 08:58:10 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Tue Aug 22 22:43:39 2017
- * Update Count     : 558
+ * Last Modified On : Wed Aug 30 17:35:21 2017
+ * Update Count     : 584
  */
 
@@ -19,5 +19,5 @@
 
 %{
-// This lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor directive have been
+// The lexer assumes the program has been preprocessed by cpp. Hence, all user level preprocessor directive have been
 // performed and removed from the source. The only exceptions are preprocessor directives passed to the compiler (e.g.,
 // line-number directives) and C/C++ style comments, which are ignored.
@@ -25,6 +25,10 @@
 //**************************** Includes and Defines ****************************
 
+unsigned int column = 0;								// position of the end of the last token parsed
+#define YY_USER_ACTION column += yyleng;				// trigger before each matching rule's action
+
 #include <string>
 #include <cstdio>										// FILENAME_MAX
+using namespace std;
 
 #include "ParseNode.h"
@@ -32,13 +36,13 @@
 
 char *yyfilename;
-std::string *strtext;									// accumulate parts of character and string constant value
+string *strtext;										// accumulate parts of character and string constant value
 
 #define RETURN_LOCN(x)		yylval.tok.loc.file = yyfilename; yylval.tok.loc.line = yylineno; return( x )
-#define RETURN_VAL(x)		yylval.tok.str = new std::string( yytext ); RETURN_LOCN( x )
+#define RETURN_VAL(x)		yylval.tok.str = new string( yytext ); RETURN_LOCN( x )
 #define RETURN_CHAR(x)		yylval.tok.str = nullptr; RETURN_LOCN( x )
 #define RETURN_STR(x)		yylval.tok.str = strtext; RETURN_LOCN( x )
 
 #define WHITE_RETURN(x)		// do nothing
-#define NEWLINE_RETURN()	WHITE_RETURN( '\n' )
+#define NEWLINE_RETURN()	column = 0; WHITE_RETURN( '\n' )
 #define ASCIIOP_RETURN()	RETURN_CHAR( (int)yytext[0] ) // single character operator
 #define NAMEDOP_RETURN(x)	RETURN_CHAR( x )			// multichar operator, with a name
@@ -154,5 +158,5 @@
 		memcpy( &filename, begin_string + 1, length );	// copy file name from yytext
 		filename[ length ] = '\0';						// terminate string with sentinel
-		//std::cout << "file " << filename << " line " << lineno << std::endl;
+		//cout << "file " << filename << " line " << lineno << endl;
 		yylineno = lineno;
 		yyfilename = filename;
@@ -302,5 +306,5 @@
 
 				/* character constant, allows empty value */
-({cwide_prefix}[_]?)?['] { BEGIN QUOTE; rm_underscore(); strtext = new std::string( yytext, yyleng ); }
+({cwide_prefix}[_]?)?['] { BEGIN QUOTE; rm_underscore(); strtext = new string( yytext, yyleng ); }
 <QUOTE>[^'\\\n]* { strtext->append( yytext, yyleng ); }
 <QUOTE>['\n]	{ BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(CHARACTERconstant); }
@@ -308,5 +312,5 @@
 
 				/* string constant */
-({swide_prefix}[_]?)?["] { BEGIN STRING; rm_underscore(); strtext = new std::string( yytext, yyleng ); }
+({swide_prefix}[_]?)?["] { BEGIN STRING; rm_underscore(); strtext = new string( yytext, yyleng ); }
 <STRING>[^"\\\n]* { strtext->append( yytext, yyleng ); }
 <STRING>["\n]	{ BEGIN 0; strtext->append( yytext, yyleng ); RETURN_STR(STRINGliteral); }
@@ -422,8 +426,14 @@
 }
 
-				/* unknown characters */
-.				{ printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno); }
+				/* unknown character */
+.				{ yyerror( "unknown character" ); }
 
 %%
+// ----end of lexer----
+
+void yyerror( const char * errmsg ) {
+	cout << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
+		 << ": " << SemanticError::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;
+}
 
 // Local Variables: //
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/Parser/parser.yy	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -10,6 +10,6 @@
 // Created On       : Sat Sep  1 20:22:55 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Aug 26 17:50:19 2017
-// Update Count     : 2712
+// Last Modified On : Wed Aug 30 07:04:19 2017
+// Update Count     : 2740
 //
 
@@ -48,9 +48,11 @@
 #include <cstdio>
 #include <stack>
+using namespace std;
+
 #include "ParseNode.h"
 #include "TypedefTable.h"
 #include "TypeData.h"
 #include "LinkageSpec.h"
-using namespace std;
+#include "Common/SemanticError.h"						// error_str
 
 extern DeclarationNode * parseTree;
@@ -3133,14 +3135,4 @@
 // ----end of grammar----
 
-extern char *yytext;
-
-void yyerror( const char * ) {
-	cout << "Error ";
-	if ( yyfilename ) {
-		cout << "in file " << yyfilename << " ";
-	} // if
-	cout << "at line " << yylineno << " reading token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << "\"" << endl;
-}
-
 // Local Variables: //
 // mode: c++ //
Index: src/ResolvExpr/AlternativeFinder.cc
===================================================================
--- src/ResolvExpr/AlternativeFinder.cc	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/ResolvExpr/AlternativeFinder.cc	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sat May 16 23:52:08 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Wed Jul 26 11:33:00 2017
-// Update Count     : 31
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Aug 28 13:47:24 2017
+// Update Count     : 32
 //
 
@@ -195,5 +195,5 @@
 				AltList winners;
 				findMinCost( alternatives.begin(), alternatives.end(), back_inserter( winners ) );
-				stream << "Can't choose between " << winners.size() << " alternatives for expression ";
+				stream << "Cannot choose between " << winners.size() << " alternatives for expression ";
 				expr->print( stream );
 				stream << "Alternatives are:";
Index: src/SymTab/Validate.cc
===================================================================
--- src/SymTab/Validate.cc	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/SymTab/Validate.cc	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -9,7 +9,7 @@
 // Author           : Richard C. Bilson
 // Created On       : Sun May 17 21:50:04 2015
-// Last Modified By : Andrew Beach
-// Last Modified On : Tus Aug  8 13:27:00 2017
-// Update Count     : 358
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Mon Aug 28 13:47:23 2017
+// Update Count     : 359
 //
 
@@ -709,5 +709,5 @@
 		} else {
 			TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
-			assertf( base != typedeclNames.end(), "Can't find typedecl name %s", typeInst->get_name().c_str() );
+			assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->get_name().c_str() );
 			typeInst->set_baseType( base->second );
 		} // if
Index: src/libcfa/concurrency/coroutine
===================================================================
--- src/libcfa/concurrency/coroutine	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/libcfa/concurrency/coroutine	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,3 +1,2 @@
-//                              - *- Mode: CFA - *-
 //
 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
@@ -11,6 +10,6 @@
 // Created On       : Mon Nov 28 12:27:26 2016
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Jul 22 09:57:17 2017
-// Update Count     : 2
+// Last Modified On : Wed Aug 30 07:58:29 2017
+// Update Count     : 3
 //
 
Index: src/prelude/prelude.cf
===================================================================
--- src/prelude/prelude.cf	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/prelude/prelude.cf	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,3 +1,2 @@
-//                               -*- Mode: C -*-
 //
 // Copyright (C) Glen Ditchfield 1994, 1999
@@ -8,6 +7,6 @@
 // Created On       : Sat Nov 29 07:23:41 2014
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Tue Jul  5 18:04:40 2016
-// Update Count     : 92
+// Last Modified On : Wed Aug 30 07:56:07 2017
+// Update Count     : 93
 //
 
Index: src/tests/.expect/castError.txt
===================================================================
--- src/tests/.expect/castError.txt	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/.expect/castError.txt	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,3 +1,3 @@
-castError.c:7 error: Can't choose between 3 alternatives for expression Cast of:
+castError.c:7:1 error: Cannot choose between 3 alternatives for expression Cast of:
   Name: f
 
Index: src/tests/.expect/completeTypeError.txt
===================================================================
--- src/tests/.expect/completeTypeError.txt	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/.expect/completeTypeError.txt	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,3 +1,3 @@
-completeTypeError.c:34 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:34:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: *?
 ...to: 
@@ -5,5 +5,5 @@
 
 
-completeTypeError.c:36 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:36:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: baz
 ...to: 
@@ -11,5 +11,5 @@
 
 
-completeTypeError.c:37 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:37:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: quux
 ...to: 
@@ -17,5 +17,5 @@
 
 
-completeTypeError.c:58 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:58:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: baz
 ...to: 
@@ -23,5 +23,5 @@
 
 
-completeTypeError.c:59 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:59:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: quux
 ...to: 
@@ -29,5 +29,5 @@
 
 
-completeTypeError.c:60 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:60:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: *?
 ...to: 
@@ -35,5 +35,5 @@
 
 
-completeTypeError.c:72 error: No reasonable alternatives for expression Applying untyped: 
+completeTypeError.c:72:1 error: No reasonable alternatives for expression Applying untyped: 
   Name: baz
 ...to: 
Index: src/tests/.expect/declarationErrors.txt
===================================================================
--- src/tests/.expect/declarationErrors.txt	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/.expect/declarationErrors.txt	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,66 +1,66 @@
-declarationErrors.c:16 error: duplicate static in declaration of x1: static const volatile short int 
+declarationErrors.c:16:1 error: duplicate static in declaration of x1: static const volatile short int 
 
-declarationErrors.c:17 error: conflicting extern & static in declaration of x2: extern const volatile short int 
+declarationErrors.c:17:1 error: conflicting extern & static in declaration of x2: extern const volatile short int 
 
-declarationErrors.c:18 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int 
+declarationErrors.c:18:1 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int 
 
-declarationErrors.c:19 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
+declarationErrors.c:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
   with members 
    with body 
 
 
-declarationErrors.c:20 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
+declarationErrors.c:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
   with members 
    with body 
 
 
-declarationErrors.c:22 error: duplicate static in declaration of x6: static const volatile instance of type Int
+declarationErrors.c:22:1 error: duplicate static in declaration of x6: static const volatile instance of type Int
 
-declarationErrors.c:24 error: duplicate const in declaration of f01: static inline function
+declarationErrors.c:24:1 error: duplicate const in declaration of f01: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:25 error: duplicate volatile in declaration of f02: static inline function
+declarationErrors.c:25:1 error: duplicate volatile in declaration of f02: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:26 error: duplicate const in declaration of f03: static inline function
+declarationErrors.c:26:1 error: duplicate const in declaration of f03: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:27 error: duplicate volatile in declaration of f04: static inline function
+declarationErrors.c:27:1 error: duplicate volatile in declaration of f04: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:28 error: duplicate const in declaration of f05: static inline function
+declarationErrors.c:28:1 error: duplicate const in declaration of f05: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:29 error: duplicate volatile in declaration of f06: static inline function
+declarationErrors.c:29:1 error: duplicate volatile in declaration of f06: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:30 error: duplicate const in declaration of f07: static inline function
+declarationErrors.c:30:1 error: duplicate const in declaration of f07: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:31 error: duplicate const, duplicate volatile in declaration of f08: static inline function
+declarationErrors.c:31:1 error: duplicate const, duplicate volatile in declaration of f08: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:33 error: duplicate const, duplicate volatile in declaration of f09: static inline function
+declarationErrors.c:33:1 error: duplicate const, duplicate volatile in declaration of f09: static inline function
   with no parameters 
   returning const volatile int 
 
 
-declarationErrors.c:34 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function
+declarationErrors.c:34:1 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function
   with no parameters 
   returning const restrict volatile _Atomic int 
Index: src/tests/.expect/dtor-early-exit-ERR1.txt
===================================================================
--- src/tests/.expect/dtor-early-exit-ERR1.txt	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/.expect/dtor-early-exit-ERR1.txt	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,1 +1,2 @@
-dtor-early-exit.c:142 error: jump to label 'L1' crosses initialization of y Branch (Goto)
+dtor-early-exit.c:142:1 error: jump to label 'L1' crosses initialization of y Branch (Goto)
+
Index: src/tests/.expect/dtor-early-exit-ERR2.txt
===================================================================
--- src/tests/.expect/dtor-early-exit-ERR2.txt	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/.expect/dtor-early-exit-ERR2.txt	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,1 +1,2 @@
-dtor-early-exit.c:142 error: jump to label 'L2' crosses initialization of y Branch (Goto)
+dtor-early-exit.c:142:1 error: jump to label 'L2' crosses initialization of y Branch (Goto)
+
Index: src/tests/.expect/memberCtors-ERR1.txt
===================================================================
--- src/tests/.expect/memberCtors-ERR1.txt	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/.expect/memberCtors-ERR1.txt	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,1 +1,1 @@
-memberCtors.c:71 error: in void ?{}(B &b), field a2 used before being constructed
+memberCtors.c:71:1 error: in void ?{}(B &b), field a2 used before being constructed
Index: src/tests/.expect/scopeErrors.txt
===================================================================
--- src/tests/.expect/scopeErrors.txt	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/.expect/scopeErrors.txt	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,9 +1,10 @@
-scopeErrors.c:2 error: duplicate object definition for thisIsAnError: signed int
-scopeErrors.c:20 error: duplicate function definition for butThisIsAnError: function
+scopeErrors.c:2:1 error: duplicate object definition for thisIsAnError: signed int
+scopeErrors.c:20:1 error: duplicate function definition for butThisIsAnError: function
   with parameters
     double
-  returning
+  returning 
     _retval_butThisIsAnError:       Attribute with name: unused
 double
-  with body
+  with body 
     CompoundStmt
+
Index: src/tests/div.c
===================================================================
--- src/tests/div.c	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/div.c	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,3 +1,2 @@
-//                               -*- Mode: C -*- 
 // 
 // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
@@ -11,6 +10,6 @@
 // Created On       : Tue Aug  8 16:28:43 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Wed Aug  9 17:09:40 2017
-// Update Count     : 16
+// Last Modified On : Wed Aug 30 07:56:28 2017
+// Update Count     : 17
 // 
 
Index: src/tests/ifcond.c
===================================================================
--- src/tests/ifcond.c	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ src/tests/ifcond.c	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -1,5 +1,4 @@
-//                               -*- Mode: C -*- 
 // 
-// Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
 //
 // The contents of this file are covered under the licence agreement in the
@@ -11,6 +10,6 @@
 // Created On       : Sat Aug 26 10:13:11 2017
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Aug 26 11:13:00 2017
-// Update Count     : 11
+// Last Modified On : Wed Aug 30 07:55:24 2017
+// Update Count     : 13
 // 
 
Index: src/tests/stdincludes.c
===================================================================
--- src/tests/stdincludes.c	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
+++ src/tests/stdincludes.c	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -0,0 +1,54 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// stdincludes.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Tue Aug 29 08:26:14 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Aug 30 07:56:39 2017
+// Update Count     : 5
+// 
+
+// C11 standard headers
+
+#include <assert.h>
+#include <complex.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fenv.h>
+#include <float.h>
+#include <inttypes.h>
+//#include <iso646.h>										// does not exist on linux
+#include <limits.h>
+#include <locale.h>
+#include <malloc.h>										// extra
+#include <math.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdalign.h>
+#include <stdarg.h>
+#include <stdatomic.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdnoreturn.h>
+#include <string.h>
+#include <tgmath.h>
+#include <time.h>
+#include <uchar.h>
+#include <unistd.h>										// extra
+#include <wchar.h>
+#include <wctype.h>
+
+int main() {}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa stdincludes.c" //
+// End: //
Index: src/tests/waitfor.c
===================================================================
--- src/tests/waitfor.c	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
+++ src/tests/waitfor.c	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -0,0 +1,249 @@
+// 
+// Cforall Version 1.0.0 Copyright (C) 2017 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+// 
+// waitfor.c -- 
+// 
+// Author           : Peter A. Buhr
+// Created On       : Wed Aug 30 17:53:29 2017
+// Last Modified By : Peter A. Buhr
+// Last Modified On : Wed Aug 30 17:55:17 2017
+// Update Count     : 2
+// 
+
+#include <stdbool.h>
+
+int fred() {
+	int x, z;
+
+	// test waitfor and when
+
+	waitfor( x );
+
+	waitfor( x ) {
+	}
+
+	waitfor( x, z ) {
+	}
+
+	when( true ) waitfor( x );
+
+	when( true ) waitfor( x ) {
+	}
+
+	waitfor( x );
+	or waitfor( y );
+
+	waitfor( x, z );
+	or waitfor( y );
+
+	when( true ) waitfor( x );
+	or when( true ) waitfor( y );
+
+	when( true ) waitfor( x, z );
+	or when( true ) waitfor( y );
+
+	waitfor( x ) {
+	} or waitfor( y ) {
+	}
+
+	waitfor( x, z ) {
+	} or waitfor( y ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) waitfor( y ) {
+	}
+
+	waitfor( x );
+	or waitfor( y ) {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) waitfor( y ) {
+	}
+
+	waitfor( x ) {
+	} or waitfor( y );
+
+	when( true ) waitfor( x ) {
+	} or when( true ) waitfor( y );
+
+	// test when, waitfor and else
+
+	waitfor( x );
+	or else;
+
+	when( true ) waitfor( x );
+	or else;
+
+	when( true ) waitfor( x, z );
+	or else;
+
+	waitfor( x ) {
+	} or else {
+	}
+
+	when( true ) waitfor( x ) {
+	} or else {
+	}
+
+	waitfor( x );
+	or else {
+	}
+
+	when( true ) waitfor( x );
+	or else {
+	}
+
+	when( true ) waitfor( x, z );
+	or else {
+	}
+
+	waitfor( x ) {
+	} or else;
+
+	when( true ) waitfor( x ) {
+	} or else;
+
+	waitfor( x );
+	or when( true ) else;
+
+	when( true ) waitfor( x );
+	or when( true ) else;
+
+	when( true ) waitfor( x, z );
+	or when( true ) else;
+
+	waitfor( x ) {
+	} or when( true ) else {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) else {
+	}
+
+	waitfor( x );
+	or when( true ) else {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) else {
+	}
+
+	when( true ) waitfor( x, z );
+	or when( true ) else {
+	}
+
+	waitfor( x ) {
+	} or when( true ) else;
+
+	when( true ) waitfor( x ) {
+	} or when( true ) else;
+
+	// test when, waitfor and timeout
+
+	waitfor( x );
+	or timeout( 3 );
+
+	waitfor( x, z );
+	or timeout( 3 );
+
+	when( true ) waitfor( x );
+	or timeout( 3 );
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x, z ) {
+	} or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x ) {
+	} or when ( true ) timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x, z ) {
+	} or when ( true ) timeout( 3 ) {
+	}
+
+	waitfor( x );
+	or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x );
+	or timeout( 3 ) {
+	}
+
+	when( true ) waitfor( x );
+	or when( true ) timeout( 3 ) {
+	}
+
+	waitfor( x ) {
+	} or timeout( 3 );
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 );
+
+	when( true ) waitfor( x ) {
+	} or when( true ) timeout( 3 );
+
+	// test when, waitfor, timeout and else
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or timeout( 3 ) {
+	} or when( true ) else {}
+
+	waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	when( true ) waitfor( x ) {
+	} or when( true ) timeout( 3 ) {
+	} or when( true ) else {}
+
+	// test quasi-keywords "or" and "timeout"
+
+	int or, timeout;
+	waitfor( timeout, 7 ) 3;
+	waitfor( timeout, 7 ) 3; or waitfor( timeout, 7 ) 3;
+	when( or ) waitfor( or, ) { 4; } or timeout( 1 ) 3;
+	when( 3 ) waitfor( or, 2 ) 4; or else 4;
+	when( 3 ) waitfor( or, 3 ) 4; or when( or ) timeout( or ) 4; or when( or ) else timeout;
+	when( 3 ) waitfor( or, or ) 3; or when( or ) waitfor( or, timeout ) 4; or else 4;
+	when( 3 ) waitfor( or, or ) 3; or waitfor( or, 9 ) 4; or when( or ) timeout( timeout ) 4;
+	when( 3 ) waitfor( or, 3 ) 3; or waitfor( or, 7 ) or; or timeout( 1 ) or; or when( 3 ) else or;
+
+	// test else selection
+
+	if ( or > timeout ) waitfor( or ) 3;
+	else waitfor( timeout ) 4;
+}
+
+// Local Variables: //
+// tab-width: 4 //
+// compile-command: "cfa waitfor.c" //
+// End: //
Index: tools/prettyprinter/lex.ll
===================================================================
--- tools/prettyprinter/lex.ll	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ tools/prettyprinter/lex.ll	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -7,13 +7,14 @@
  * lex.ll --
  * 
- * Author           : Rodolfo Gabriel Esteves
+ * Author           : Peter A. Buhr
  * Created On       : Sat Dec 15 11:45:59 2001
  * Last Modified By : Peter A. Buhr
- * Last Modified On : Fri Jul 21 23:06:16 2017
- * Update Count     : 254
+ * Last Modified On : Tue Aug 29 17:33:36 2017
+ * Update Count     : 268
  */
 
 %option stack
 %option yylineno
+%option nounput
 
 %{
@@ -30,4 +31,7 @@
 string comment_str;
 string code_str;
+
+// Stop warning due to incorrectly generated flex code.
+#pragma GCC diagnostic ignored "-Wsign-compare"
 %}
 
@@ -44,111 +48,114 @@
 /* ---------------------------- Token Section ---------------------------- */
 %%
-<INITIAL,C_CODE>"/*"	{				/* C style comments */
-			#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
-    			    cerr << "\"/*\" : " << yytext << endl;
-			#endif
-			    if ( YYSTATE == C_CODE ) code_str += yytext;
-			    else comment_str += yytext;
-			    yy_push_state(C_COMMENT);
-			}
-<C_COMMENT>(.|"\n")	{				/* C style comments */
-			#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
-    			    cerr << "<C_COMMENT>(.|\\n) : " << yytext << endl;
-			#endif
-			    if ( yy_top_state() == C_CODE ) code_str += yytext;
-			    else comment_str += yytext;
-			}
-<C_COMMENT>"*/"		{				/* C style comments */
-			#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
-    			    cerr << "<C_COMMENT>\"*/\" : " << yytext << endl;
-			#endif
-			    if ( yy_top_state() == C_CODE ) code_str += yytext;
-			    else {
-				comment_str += yytext;
-				//cerr << "C COMMENT : " << endl << comment_str << endl;
-				ws_list.push_back( comment_str );
-				comment_str = "";
-			    }
-			    yy_pop_state();
-			}
-<INITIAL,C_CODE>"//"[^\n]*"\n" {			/* C++ style comments */
-			#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
-    			    cerr << "\"//\"[^\\n]*\"\n\" : " << yytext << endl;
-			#endif
-			    if ( YYSTATE == C_CODE ) code_str += yytext;
-			    else {
-				comment_str += yytext;
-				//cerr << "C++ COMMENT : " << endl << comment_str << endl;
-				ws_list.push_back( comment_str );
-				comment_str = "";
-			    }
-			}
+<INITIAL,C_CODE>"/*" {									// C style comments */
+#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
+    cerr << "\"/*\" : " << yytext << endl;
+#endif
+    if ( YYSTATE == C_CODE ) code_str += yytext;
+    else comment_str += yytext;
+    yy_push_state(C_COMMENT);
+}
+<C_COMMENT>(.|"\n")	{									// C style comments
+#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
+    cerr << "<C_COMMENT>(.|\\n) : " << yytext << endl;
+#endif
+    if ( yy_top_state() == C_CODE ) code_str += yytext;
+    else comment_str += yytext;
+}
+<C_COMMENT>"*/"	{										// C style comments
+#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
+	cerr << "<C_COMMENT>\"*/\" : " << yytext << endl;
+#endif
+	if ( yy_top_state() == C_CODE ) code_str += yytext;
+	else {
+		comment_str += yytext;
+		//cerr << "C COMMENT : " << endl << comment_str << endl;
+		ws_list.push_back( comment_str );
+		comment_str = "";
+	}
+	yy_pop_state();
+}
 
-";"			{ RETURN_TOKEN( ';' ) }
-":"			{ RETURN_TOKEN( ':' ) }
-"|"			{ RETURN_TOKEN( '|' ) }
-","			{ RETURN_TOKEN( ',' ) }
-"<"			{ RETURN_TOKEN( '<' ) }
-">"			{ RETURN_TOKEN( '>' ) }
+<INITIAL,C_CODE>"//"[^\n]*"\n" {						// C++ style comments
+#if defined(DEBUG_ALL) | defined(DEBUG_COMMENT)
+	cerr << "\"//\"[^\\n]*\"\n\" : " << yytext << endl;
+#endif
+	if ( YYSTATE == C_CODE ) code_str += yytext;
+	else {
+		comment_str += yytext;
+		//cerr << "C++ COMMENT : " << endl << comment_str << endl;
+		ws_list.push_back( comment_str );
+		comment_str = "";
+	}
+}
 
-[[:space:]]+		{				/* [ \t\n]+ */
-			    ws_list.push_back( yytext );
-			    //cerr << "WS : " << "\"" << yytext << "\"" << endl;
-			}
+";"				{ RETURN_TOKEN( ';' ) }
+":"				{ RETURN_TOKEN( ':' ) }
+"|"				{ RETURN_TOKEN( '|' ) }
+","				{ RETURN_TOKEN( ',' ) }
+"<"				{ RETURN_TOKEN( '<' ) }
+">"				{ RETURN_TOKEN( '>' ) }
 
-<INITIAL>"{"		{ RETURN_TOKEN( '{' ) }
-<INITIAL>"}"		{ RETURN_TOKEN( '}' ) }
-<C_CODE>"{"		{
-			#if defined(DEBUG_ALL) | defined(DEBUG_C)
-			    cerr << "<C_CODE>. : " << yytext << endl;
-			#endif
-			    code_str += yytext;
-			    RETURN_TOKEN( '{' )
-			}
-<C_CODE>"}"		{
-			#if defined(DEBUG_ALL) | defined(DEBUG_C)
-			    cerr << "<C_CODE>. : " << yytext << endl;
-			#endif
-			    code_str += yytext;
-			    RETURN_TOKEN( '}' )
-			}
+[[:space:]]+ {											// [ \t\n]+
+	ws_list.push_back( yytext );
+	//cerr << "WS : " << "\"" << yytext << "\"" << endl;
+}
+
+<INITIAL>"{"	{ RETURN_TOKEN( '{' ) }
+<INITIAL>"}"	{ RETURN_TOKEN( '}' ) }
+<C_CODE>"{"	{
+#if defined(DEBUG_ALL) | defined(DEBUG_C)
+	cerr << "<C_CODE>. : " << yytext << endl;
+#endif
+	code_str += yytext;
+	RETURN_TOKEN( '{' )
+}
+<C_CODE>"}"	{
+#if defined(DEBUG_ALL) | defined(DEBUG_C)
+	cerr << "<C_CODE>. : " << yytext << endl;
+#endif
+	code_str += yytext;
+	RETURN_TOKEN( '}' )
+}
 
 "%%"			{ RETURN_TOKEN( MARK ) }
 "%{"			{ RETURN_TOKEN( LCURL ) }
-<C_CODE>"%}"		{ RETURN_TOKEN( RCURL ) }
+<C_CODE>"%}"	{ RETURN_TOKEN( RCURL ) }
 
-^"%union"       	{ RETURN_TOKEN( UNION ) }
-^"%start"       	{ RETURN_TOKEN( START ) }
-^"%token"       	{ RETURN_TOKEN( TOKEN ) }
-^"%type"	       	{ RETURN_TOKEN( TYPE ) }
-^"%left"	       	{ RETURN_TOKEN( LEFT ) }
-^"%right"	       	{ RETURN_TOKEN( RIGHT ) }
-^"%nonassoc"    	{ RETURN_TOKEN( NONASSOC ) }
-^"%pure_parser"    	{ RETURN_TOKEN( PURE_PARSER ) }
-^"%semantic_parser"    	{ RETURN_TOKEN( SEMANTIC_PARSER ) }
-^"%expect"  	  	{ RETURN_TOKEN( EXPECT ) }
+^"%union"       { RETURN_TOKEN( UNION ) }
+^"%start"       { RETURN_TOKEN( START ) }
+^"%token"       { RETURN_TOKEN( TOKEN ) }
+^"%type"	    { RETURN_TOKEN( TYPE ) }
+^"%left"	    { RETURN_TOKEN( LEFT ) }
+^"%right"	    { RETURN_TOKEN( RIGHT ) }
+^"%nonassoc"    { RETURN_TOKEN( NONASSOC ) }
+^"%precedence"  { RETURN_TOKEN( PRECEDENCE ) }
+^"%pure_parser" { RETURN_TOKEN( PURE_PARSER ) }
+^"%semantic_parser"	{ RETURN_TOKEN( SEMANTIC_PARSER ) }
+^"%expect"  	{ RETURN_TOKEN( EXPECT ) }
 ^"%thong" 	   	{ RETURN_TOKEN( THONG ) }
 
 "%prec" 	   	{ RETURN_TOKEN( PREC ) }
 
-{integer}	    	{ RETURN_TOKEN( INTEGER ); }
-[']{c_char}[']    	{ RETURN_TOKEN( CHARACTER ); }
-{identifier}    	{ RETURN_TOKEN( IDENTIFIER ); }
+{integer}	    { RETURN_TOKEN( INTEGER ); }
+[']{c_char}[']  { RETURN_TOKEN( CHARACTER ); }
+{identifier}    { RETURN_TOKEN( IDENTIFIER ); }
 
-<C_CODE>["]{s_char}*["]	{				/* hide braces "{}" in strings */
-			#if defined(DEBUG_ALL) | defined(DEBUG_C)
-			    cerr << "<C_CODE>. : " << yytext << endl;
-			#endif
-			    code_str += yytext;
-			}
+<C_CODE>["]{s_char}*["]	{								// hide braces "{}" in strings
+#if defined(DEBUG_ALL) | defined(DEBUG_C)
+	cerr << "<C_CODE>. : " << yytext << endl;
+#endif
+	code_str += yytext;
+}
 
-<C_CODE>(.|\n)		{				/* must be last rule of C_CODE */
-			#if defined(DEBUG_ALL) | defined(DEBUG_C)
-			    cerr << "<C_CODE>. : " << yytext << endl;
-			#endif
-			    code_str += yytext;
-			}
+<C_CODE>(.|\n) {										// must be last rule of C_CODE
+#if defined(DEBUG_ALL) | defined(DEBUG_C)
+	cerr << "<C_CODE>. : " << yytext << endl;
+#endif
+	code_str += yytext;
+}
 
-.			{ printf("UNKNOWN CHARACTER:%s\n", yytext); } /* unknown characters */
+				/* unknown characters */
+.				{ printf("unknown character(s):\"%s\" on line %d\n", yytext, yylineno); }
 %%
 void lexC(void) {
Index: tools/prettyprinter/parser.hh
===================================================================
--- tools/prettyprinter/parser.hh	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ tools/prettyprinter/parser.hh	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -59,26 +59,27 @@
     RIGHT = 269,
     NONASSOC = 270,
-    TYPE = 271,
-    PURE_PARSER = 272,
-    SEMANTIC_PARSER = 273,
-    EXPECT = 274,
-    THONG = 275,
-    PREC = 276,
-    END_TERMINALS = 277,
-    _SECTIONS = 278,
-    _DEFSECTION_OPT = 279,
-    _LITERALBLOCK = 280,
-    _DECLARATION = 281,
-    _TAG_OPT = 282,
-    _NAMENOLIST = 283,
-    _NAMENO = 284,
-    _NAMELIST = 285,
-    _RULESECTION = 286,
-    _RULE = 287,
-    _LHS = 288,
-    _RHS = 289,
-    _PREC = 290,
-    _ACTION = 291,
-    _USERSECTION_OPT = 292
+    PRECEDENCE = 271,
+    TYPE = 272,
+    PURE_PARSER = 273,
+    SEMANTIC_PARSER = 274,
+    EXPECT = 275,
+    THONG = 276,
+    PREC = 277,
+    END_TERMINALS = 278,
+    _SECTIONS = 279,
+    _DEFSECTION_OPT = 280,
+    _LITERALBLOCK = 281,
+    _DECLARATION = 282,
+    _TAG_OPT = 283,
+    _NAMENOLIST = 284,
+    _NAMENO = 285,
+    _NAMELIST = 286,
+    _RULESECTION = 287,
+    _RULE = 288,
+    _LHS = 289,
+    _RHS = 290,
+    _PREC = 291,
+    _ACTION = 292,
+    _USERSECTION_OPT = 293
   };
 #endif
@@ -97,26 +98,27 @@
 #define RIGHT 269
 #define NONASSOC 270
-#define TYPE 271
-#define PURE_PARSER 272
-#define SEMANTIC_PARSER 273
-#define EXPECT 274
-#define THONG 275
-#define PREC 276
-#define END_TERMINALS 277
-#define _SECTIONS 278
-#define _DEFSECTION_OPT 279
-#define _LITERALBLOCK 280
-#define _DECLARATION 281
-#define _TAG_OPT 282
-#define _NAMENOLIST 283
-#define _NAMENO 284
-#define _NAMELIST 285
-#define _RULESECTION 286
-#define _RULE 287
-#define _LHS 288
-#define _RHS 289
-#define _PREC 290
-#define _ACTION 291
-#define _USERSECTION_OPT 292
+#define PRECEDENCE 271
+#define TYPE 272
+#define PURE_PARSER 273
+#define SEMANTIC_PARSER 274
+#define EXPECT 275
+#define THONG 276
+#define PREC 277
+#define END_TERMINALS 278
+#define _SECTIONS 279
+#define _DEFSECTION_OPT 280
+#define _LITERALBLOCK 281
+#define _DECLARATION 282
+#define _TAG_OPT 283
+#define _NAMENOLIST 284
+#define _NAMENO 285
+#define _NAMELIST 286
+#define _RULESECTION 287
+#define _RULE 288
+#define _LHS 289
+#define _RHS 290
+#define _PREC 291
+#define _ACTION 292
+#define _USERSECTION_OPT 293
 
 /* Value type.  */
@@ -129,5 +131,5 @@
 	Token *tokenp;
 
-#line 132 "parser.hh" /* yacc.c:1909  */
+#line 134 "parser.hh" /* yacc.c:1909  */
 };
 
Index: tools/prettyprinter/parser.yy
===================================================================
--- tools/prettyprinter/parser.yy	(revision 326338aec9e5906b6b09c788119731fd8edfeb42)
+++ tools/prettyprinter/parser.yy	(revision fbcb35488c190b8e3845a1a9572c9c931586897f)
@@ -10,6 +10,6 @@
 // Created On       : Sat Dec 15 13:44:21 2001
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Thu Jun 29 09:26:47 2017
-// Update Count     : 1045
+// Last Modified On : Tue Aug 29 16:34:10 2017
+// Update Count     : 1047
 // 
 
@@ -67,4 +67,5 @@
 %token<tokenp>	RIGHT									// %right
 %token<tokenp>	NONASSOC								// %nonassoc
+%token<tokenp>	PRECEDENCE								// %precedence
 %token<tokenp>	TYPE									// %type
 %token<tokenp>	PURE_PARSER								// %pure_parser
@@ -259,4 +260,5 @@
 	| RIGHT
 	| NONASSOC
+	| PRECEDENCE
 	;
 
