Index: doc/theses/jiada_liang_MMath/main.tex
===================================================================
--- doc/theses/jiada_liang_MMath/main.tex	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
+++ doc/theses/jiada_liang_MMath/main.tex	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -0,0 +1,270 @@
+%%
+%% This is file `sample-manuscript.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% samples.dtx  (with options: `manuscript')
+%% 
+%% IMPORTANT NOTICE:
+%% 
+%% For the copyright see the source file.
+%% 
+%% Any modified versions of this file must be renamed
+%% with new filenames distinct from sample-manuscript.tex.
+%% 
+%% For distribution of the original source see the terms
+%% for copying and modification in the file samples.dtx.
+%% 
+%% This generated file may be distributed as long as the
+%% original source files, as listed above, are part of the
+%% same distribution. (The sources need not necessarily be
+%% in the same archive or directory.)
+%%
+%% Commands for TeXCount
+%TC:macro \cite [option:text,text]
+%TC:macro \citep [option:text,text]
+%TC:macro \citet [option:text,text]
+%TC:envir table 0 1
+%TC:envir table* 0 1
+%TC:envir tabular [ignore] word
+%TC:envir displaymath 0 word
+%TC:envir math 0 word
+%TC:envir comment 0 0
+%%
+%%
+%% The first command in your LaTeX source must be the \documentclass command.
+\documentclass[manuscript,screen,review]{acmart}
+\usepackage{xcolor}
+\usepackage{listings}
+\usepackage[ligature, inference]{semantic}
+\usepackage{array}
+
+\definecolor{mGreen}{rgb}{0,0.6,0}
+\definecolor{mGray}{rgb}{0.5,0.5,0.5}
+\definecolor{mPurple}{rgb}{0.58,0,0.82}
+\definecolor{backgroundColour}{rgb}{0.95,0.95,0.92}
+
+\lstdefinestyle{CStyle}{
+    backgroundcolor=\color{backgroundColour},   
+    commentstyle=\color{mGreen},
+    keywordstyle=\color{magenta},
+    numberstyle=\tiny\color{mGray},
+    stringstyle=\color{mPurple},
+    basicstyle=\footnotesize,
+    breakatwhitespace=false,         
+    breaklines=true,                 
+    captionpos=b,                    
+    keepspaces=true,                 
+    numbers=left,                    
+    numbersep=5pt,                  
+    showspaces=false,                
+    showstringspaces=false,
+    showtabs=false,                  
+    tabsize=2,
+    language=C
+}
+
+%%
+%% \BibTeX command to typeset BibTeX logo in the docs
+\AtBeginDocument{%
+  \providecommand\BibTeX{{%
+    \normalfont B\kern-0.5em{\scshape i\kern-0.25em b}\kern-0.8em\TeX}}}
+
+
+
+%%
+%% Submission ID.
+%% Use this when submitting an article to a sponsored event. You'll
+%% receive a unique submission ID from the organizers
+%% of the event, and this ID should be used as the parameter to this command.
+%%\acmSubmissionID{123-A56-BU3}
+
+%%
+%% For managing citations, it is recommended to use bibliography
+%% files in BibTeX format.
+%%
+%% You can then either use BibTeX with the ACM-Reference-Format style,
+%% or BibLaTeX with the acmnumeric or acmauthoryear sytles, that include
+%% support for advanced citation of software artefact from the
+%% biblatex-software package, also separately available on CTAN.
+%%
+%% Look at the sample-*-biblatex.tex files for templates showcasing
+%% the biblatex styles.
+%%
+
+%%
+%% The majority of ACM publications use numbered citations and
+%% references.  The command \citestyle{authoryear} switches to the
+%% "author year" style.
+%%
+%% If you are preparing content for an event
+%% sponsored by ACM SIGGRAPH, you must use the "author year" style of
+%% citations and references.
+%% Uncommenting
+%% the next command will enable that style.
+%%\citestyle{acmauthoryear}
+
+%%
+%% end of the preamble, start of the body of the document source.
+\begin{document}
+
+%%
+%% The "title" command has an optional parameter,
+%% allowing the author to define a "short title" to be used in page headers.
+\title{Enumeration in Cforall}
+
+%%
+%% The "author" command and its associated commands are used to define
+%% the authors and their affiliations.
+%% Of note is the shared affiliation of the first two authors, and the
+%% "authornote" and "authornotemark" commands
+%% used to denote shared contribution to the research.
+\author{Jiada Liang}
+
+
+%%
+%% The abstract is a short summary of the work to be presented in the
+%% article.
+\begin{abstract}
+    An enumeration, or enum in short, is a type that defines a list of named constant values in C. Cforall extends the enumeration with additional features.
+\end{abstract}
+
+%%
+%% The code below is generated by the tool at http://dl.acm.org/ccs.cfm.
+%% Please copy and paste the code instead of the example below.
+%%
+
+
+%%
+%% This command processes the author and affiliation and title
+%% information and builds the first part of the formatted document.
+\maketitle
+
+\section{C-Style Enum}
+\begin{lstlisting}[style=CStyle]
+enum Weekday { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday };
+\end{lstlisting}
+Cforall supports the classic C-Style enumeration (C-enum for short) and its syntax is consistent with C. No internal data structure is generated for C-enum, and C-enum does not provide the Cforall-enum interface methods.
+
+\section{Cforall Enum}
+\subsection{Enumerable Type}
+\begin{lstlisting}[style=CStyle]
+forall(T)
+trait enumerable {
+  void ?()( T & t, zero_t );
+  void ?()( T & t, one_t );
+  S& ?+=?( T & t, one_t );
+  void ?{}( T &, T ); 
+  T ?{}( T &, T ); 
+};
+\end{lstlisting}
+A type is enumerable in Cforall if it has defined 0, 1, increment operator, copy constructor, and copy assignment operator.
+
+(Should change the definition of enumerable to something else. Maybe auto-constructible. If a type is not auto-constructible, all enumeration must be explicitly initialized)
+\begin{lstlisting}[caption={An example enumerable type}, label{lst:sample_enumerable}, style=CStyle]
+struct Type { int i; };
+void ?()( Type & t, zero_t ) { t.i = 0; };
+void ?()( Type & t, one_t ) { t.i = 1; };
+int ?!=?( Type t, zero_t ) { return t.i != 0; };
+S& ?+=?( Type & t, one_t ) { t.i += 1; return t; };
+void ?()( Type & t, Type rhs ) { t.i = rhs.i; };
+Type ?()( Type & t, Type rhs ) { t.i = rhs.i; return t; };
+\end{lstlisting}
+
+A Cforall-enum is a C-enum parameterized by an enumerable type. For example,  $enum(int)$ turns a C-enum into a Cforall-enum.
+\begin{lstlisting}[caption={An example Cforall enum}, label{lst:sample_cforall_enum}, style=CStyle]
+enum Color(Type) { Red, Green, Blue };
+
+> Type Color.values[] = { 0, values[0]++, values[1]++ }; 
+> enum Color.Label { Red_Label, Green_Label, Blue_Label };
+\end{lstlisting}
+Declaring a Cforall-enum, the compiler defines a C-enum names every element in the Cforall-enum, and an array that stores Cforall enumeration values. 
+
+\subsection{Cforall Enumerations Behaviour}
+An instance of Cforall-enum (denoted as $<enum\_instance>$) has a label, the defined enum name. The label can be retrieved by calling the function $label()$ on a $<enum\_instance>$. The $value()$ function on the other hand returns the value used to initialize the Cforall-enum.
+
+Cforall-enum supports a qualified expression. The syntax of the qualified expression for Cforall-enum is $$<enum\_type\_name>.<enum\_instance\_name>$$. In the $Color$ example, $Color$ is a $<enum\_type\_name>$ and $Red$, $Green$, $Blue$ are $<enum\_instance\_name>$. 
+
+\begin{lstlisting}[caption={An example Cforall enum}, label{lst:sample_cforall_enum_usage}, style=CStyle]
+enum Color red = Color.Red;
+> enum Color.Label red = = Color.Label.Red_Label; 
+Type instance = Color.Red;
+> Type instance = Color.values[ Color.Label.Red_Label ];
+\end{lstlisting}
+
+The expression $Color.Red$ is overloaded to represent both $value(Color.Red)$ and $label(Color.Red)$. The expression returns the $label(Color.Red)$ by default but returns $value()$ whenever the $value()$ is a closer candidate in the context. [more explanation] In \ref{lst:sample_cforall_enum_usage}, when assigned to an enum variable, $Color.Red$ returns the label. This is to reduce the memory to store a Cforall-enum variable. In an assignment expression when the left-hand-side expects a $Type$, the resolution finds $value(Color.Red)$ is a better candidate than $label(Color.Red)$, and returns the value instead.
+
+\subsection{Enum Type Functions}
+\begin{lstlisting}[caption={Enum Type Functions}, label{lst:cforall_enum_functions}, style=CStyle]
+enum Color(string) { // assume String has been defined as an enumerable type
+    R = "Red", G = "Green", B = "Blue"
+};
+values( Color );
+> [ String("Red"), String("Green"), String("Blue") ];
+label_strings( Color );
+> [ "R", "G", "B" ];
+enum Color green = Color.G;
+
+label_string( Color, green );
+> "G"
+label( Color, green );
+> 1
+value( Color, green ) ;
+> "Green"
+value( Color, "G" );
+> "Green"
+label( Color, "G" );
+> 1
+value( Color, "DNE" );
+> (null)
+value( Color, 1 ); // "1" is the label "G"
+> "Green"
+\end{lstlisting}
+Names of labels are distinct in an enum declaration. Cforall therefore allows indexing an enum value with its string representation of a label.
+
+\subsection{Range Functions and Iteration (Placeholder)}
+\begin{lstlisting}[caption={Range Functions}, label{lst:range_functions}, style=CStyle]
+enum Weekday( 
+    Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
+};
+\end{lstlisting}
+
+\section{Implementation}
+
+\subsection{Companion Object}
+The intuition to create a companion object is that functions that support enumeration features need static information of an enumeration class. For example, values() returns an array of values defined for the enumeration. $label( Color, "G" )$ needs information about enum names defined for the enum class $Color$. Theoretically, enum-type functions can be defined as functions that take $TypeName$ expression as the first parameter. An alternative approach is to define that "companion object".
+
+\begin{lstlisting}[caption={Enum Type Functions}, label{lst:cforall_enum_functions}, style=CStyle]
+struct string;
+enum Color( string ) { 
+    R = "Red", G = "Green", B = "Blue"
+};
+
+forall( T | enumerable(T) )  {
+    struct Companion {
+        T* values;
+        char** labels;
+    };
+}
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+Companion( string ) Color = { 
+    .values = [ "Red", "Green", "Blue" ],
+    .labels = [ "R", "G", "B" ]
+};
+>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
+forall( T | enumerable(T) )
+T* value( Companion, int );
+char* label( Companion, int );
+\end{lstlisting}
+
+\subsection{TODO - Type trait for Cforall - Enum}
+%%
+%% If your work has an appendix, this is the place to put it.
+\appendix
+
+
+\end{document}
+\endinput
+%%
+%% End of file `sample-manuscript.tex'.
Index: libcfa/src/concurrency/channel.hfa
===================================================================
--- libcfa/src/concurrency/channel.hfa	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ libcfa/src/concurrency/channel.hfa	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -130,4 +130,5 @@
 static inline void __cons_handoff( channel(T) & chan, T & elem ) with(chan) {
     memcpy( cons`first.extra, (void *)&elem, sizeof(T) ); // do waiting consumer work
+    __atomic_thread_fence( __ATOMIC_SEQ_CST );
     wake_one( cons );
 }
@@ -136,4 +137,5 @@
 static inline void __prods_handoff( channel(T) & chan, T & retval ) with(chan) {
     memcpy( (void *)&retval, prods`first.extra, sizeof(T) );
+    __atomic_thread_fence( __ATOMIC_SEQ_CST );
     wake_one( prods );
 }
Index: libcfa/src/concurrency/cofor.cfa
===================================================================
--- libcfa/src/concurrency/cofor.cfa	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ libcfa/src/concurrency/cofor.cfa	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -4,10 +4,10 @@
 // cofor ( uC++ COFOR )
 
-thread co_runner {
+thread cofor_runner {
 	ssize_t low, high;
 	__cofor_body_t loop_body;
 };
 
-static void ?{}( co_runner & this, ssize_t low, ssize_t high, __cofor_body_t loop_body ) {
+static void ?{}( cofor_runner & this, ssize_t low, ssize_t high, __cofor_body_t loop_body ) {
 	this.low = low;
 	this.high = high;
@@ -15,5 +15,5 @@
 }
 
-void main( co_runner & this ) with( this ) {
+void main( cofor_runner & this ) with( this ) {
 	for ( ssize_t i = low; i < high; i++ )
 		loop_body(i);
@@ -29,5 +29,5 @@
 	ssize_t i = 0;
 	ssize_t stride_iter = low;
-	co_runner * runners[ threads ];
+	cofor_runner * runners[ threads ];
 	for ( i; threads ) {
 		runners[i] = alloc();
@@ -45,25 +45,3 @@
 }
 
-//////////////////////////////////////////////////////////////////////////////////////////
-// parallel (COBEGIN/COEND)
 
-thread para_runner {
-	parallel_stmt_t body;
-	void * arg;
-};
-
-static void ?{}( para_runner & this, parallel_stmt_t body, void * arg ) { 
-	this.body = body;
-	this.arg = arg;
-}
-
-void main( para_runner & this ) with( this ) { body( arg ); }
-
-void parallel( parallel_stmt_t * stmts, void ** args, size_t num ) libcfa_public {
-	para_runner * runners[ num ];
-	for ( i; num )
-		(*(runners[i] = malloc())){ stmts[i], args[i] };
-	for ( i; num )
-		delete( runners[i] );
-}
-
Index: libcfa/src/concurrency/cofor.hfa
===================================================================
--- libcfa/src/concurrency/cofor.hfa	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ libcfa/src/concurrency/cofor.hfa	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -16,6 +16,29 @@
 
 //////////////////////////////////////////////////////////////////////////////////////////
-// parallel (COBEGIN/COEND)
-typedef void (*parallel_stmt_t)( void * );
+// corun
 
-void parallel( parallel_stmt_t * stmts, void ** args, size_t num );
+// 
+typedef void (*__CFA_corun_lambda_t)( void );
+
+// used to run a corun statement in parallel
+thread co_runner {
+	__CFA_corun_lambda_t body;
+};
+
+// wraps a co_runner to provide RAII deallocation
+struct runner_block {
+    co_runner * runner;
+};
+static inline void ?{}( co_runner & this, __CFA_corun_lambda_t body ) { this.body = body; }
+
+void main( co_runner & this ) with( this ) { body(); }
+
+static inline void ?{}( runner_block & this ) {}
+static inline void ?{}( runner_block & this, __CFA_corun_lambda_t body ) {
+    (*(this.runner = malloc())){ body };
+}
+
+static inline void ^?{}( runner_block & this ) {
+    delete( this.runner );
+}
+
Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/AST/Convert.cpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -269,5 +269,5 @@
 			node->location,
 			Type::StorageClasses( node->storage.val ),
-            get<Type>().accept1( node->base ),
+			get<Type>().accept1( node->base ),
 			LinkageSpec::Spec( node->linkage.val )
 		);
@@ -567,5 +567,5 @@
 	}
 
-    const ast::WhenClause * visit( const ast::WhenClause * node ) override final {
+	const ast::WhenClause * visit( const ast::WhenClause * node ) override final {
 		// There is no old-AST WhenClause, so this should never be called.
 		assert( !node );
@@ -604,6 +604,6 @@
 	}
 
-    const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
-        // There is no old-AST WaitUntilStmt, so this should never be called.
+	const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
+		// There is no old-AST WaitUntilStmt, so this should never be called.
 		assert( !node );
 		return nullptr;
@@ -648,4 +648,10 @@
 		);
 		return stmtPostamble( stmt, node );
+	}
+
+	const ast::Stmt * visit( const ast::CorunStmt * node ) override final {
+		// There is no old-AST CorunStmt, so this should never be called.
+		assert( !node );
+		return nullptr;
 	}
 
@@ -853,5 +859,5 @@
 		// New workd:   one public type: node->result, plus node->underlyer only to support roundtrip conversion
 		//              preserving underlyer because the correct type for string literals is complicated to construct,
-	    //              and distinguishing a string from other literals using the type is hard to do accurately
+		//              and distinguishing a string from other literals using the type is hard to do accurately
 		// Both worlds: the outer, expression-level type can change during resolution
 		//              for a string, that's char[k] before-resolve and char * after
@@ -859,5 +865,5 @@
 		//              for a string, that's char[k] always
 		// Both worlds: the "rep" field of a constant is the C source file fragment that compiles to the desired value
-        //              for a string, that includes outer quotes, backslashes, et al cases from the Literals test
+		//              for a string, that includes outer quotes, backslashes, et al cases from the Literals test
 		ConstantExpr *rslt = new ConstantExpr(Constant(
 			get<Type>().accept1(node->underlyer),
@@ -1518,5 +1524,5 @@
 		return strict_dynamic_cast< ast::Decl * >( node );
 	}
-	
+
 	ConverterOldToNew() = default;
 	ConverterOldToNew(const ConverterOldToNew &) = delete;
@@ -1581,5 +1587,5 @@
 	ast::Label make_label(const Label* old) {
 		CodeLocation const & location =
-		    ( old->labelled ) ? old->labelled->location : CodeLocation();
+			( old->labelled ) ? old->labelled->location : CodeLocation();
 		return ast::Label(
 			location,
@@ -2240,5 +2246,4 @@
 	// TypeSubstitution shouldn't exist yet in old.
 	ast::TypeSubstitution * convertTypeSubstitution(const TypeSubstitution * old) {
-		
 		if (!old) return nullptr;
 		if (old->empty()) return nullptr;
@@ -2285,5 +2290,5 @@
 	ast::Expr * visitBaseExpr_SkipResultType( const Expression * old, ast::Expr * nw) {
 
-		nw->env    = convertTypeSubstitution(old->env);
+		nw->env = convertTypeSubstitution(old->env);
 
 		nw->extension = old->extension;
@@ -2856,5 +2861,5 @@
 
 	virtual void visit( const EnumInstType * old ) override final {
-		ast::EnumInstType * ty; 
+		ast::EnumInstType * ty;
 		if ( old->baseEnum ) {
 			ty = new ast::EnumInstType{
Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/AST/Fwd.hpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -67,4 +67,5 @@
 class ImplicitCtorDtorStmt;
 class MutexStmt;
+class CorunStmt;
 
 class Expr;
Index: src/AST/Node.cpp
===================================================================
--- src/AST/Node.cpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/AST/Node.cpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -192,4 +192,6 @@
 template class ast::ptr_base< ast::MutexStmt, ast::Node::ref_type::weak >;
 template class ast::ptr_base< ast::MutexStmt, ast::Node::ref_type::strong >;
+template class ast::ptr_base< ast::CorunStmt, ast::Node::ref_type::weak >;
+template class ast::ptr_base< ast::CorunStmt, ast::Node::ref_type::strong >;
 template class ast::ptr_base< ast::Expr, ast::Node::ref_type::weak >;
 template class ast::ptr_base< ast::Expr, ast::Node::ref_type::strong >;
Index: src/AST/Pass.hpp
===================================================================
--- src/AST/Pass.hpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/AST/Pass.hpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -162,8 +162,8 @@
 	const ast::FinallyClause *    visit( const ast::FinallyClause        * ) override final;
 	const ast::Stmt *             visit( const ast::SuspendStmt          * ) override final;
-    const ast::WhenClause *       visit( const ast::WhenClause           * ) override final;
+	const ast::WhenClause *       visit( const ast::WhenClause           * ) override final;
 	const ast::Stmt *             visit( const ast::WaitForStmt          * ) override final;
 	const ast::WaitForClause *    visit( const ast::WaitForClause        * ) override final;
-    const ast::Stmt *             visit( const ast::WaitUntilStmt        * ) override final;
+	const ast::Stmt *             visit( const ast::WaitUntilStmt        * ) override final;
 	const ast::Decl *             visit( const ast::WithStmt             * ) override final;
 	const ast::NullStmt *         visit( const ast::NullStmt             * ) override final;
@@ -171,4 +171,5 @@
 	const ast::Stmt *             visit( const ast::ImplicitCtorDtorStmt * ) override final;
 	const ast::Stmt *             visit( const ast::MutexStmt            * ) override final;
+	const ast::Stmt *             visit( const ast::CorunStmt            * ) override final;
 	const ast::Expr *             visit( const ast::ApplicationExpr      * ) override final;
 	const ast::Expr *             visit( const ast::UntypedExpr          * ) override final;
Index: src/AST/Pass.impl.hpp
===================================================================
--- src/AST/Pass.impl.hpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/AST/Pass.impl.hpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -1121,4 +1121,17 @@
 
 //--------------------------------------------------------------------------
+// CorunStmt
+template< typename core_t >
+const ast::Stmt * ast::Pass< core_t >::visit( const ast::CorunStmt * node ) {
+	VISIT_START( node );
+
+	if ( __visit_children() ) {
+		maybe_accept( node, &CorunStmt::stmt );
+	}
+
+	VISIT_END( Stmt, node );
+}
+
+//--------------------------------------------------------------------------
 // ApplicationExpr
 template< typename core_t >
Index: src/AST/Print.cpp
===================================================================
--- src/AST/Print.cpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/AST/Print.cpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -209,5 +209,5 @@
 	}
 
-    void print( const ast::WaitStmt * node ) {
+	void print( const ast::WaitStmt * node ) {
 		if ( node->timeout_time ) {
 			os << indent-1 << "timeout of:" << endl;
@@ -860,5 +860,5 @@
 	}
 
-    virtual const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
+	virtual const ast::Stmt * visit( const ast::WaitUntilStmt * node ) override final {
 		os << "Waituntil Statement" << endl;
 		indent += 2;
@@ -866,5 +866,6 @@
 			clause->accept( *this );
 		}
-        print(node);    // calls print( const ast::WaitStmt * node )
+		// calls print( const ast::WaitStmt * node )
+		print(node);
 		return node;
 	}
@@ -913,4 +914,15 @@
 		printAll( node->mutexObjs );
 		--indent;
+		os << indent << "... with Statement: ";
+		++indent;
+		safe_print( node->stmt );
+		--indent;
+		os << endl;
+
+		return node;
+	}
+
+	virtual const ast::Stmt * visit( const ast::CorunStmt * node ) override final {
+		os << "Corun Statement" << endl;
 		os << indent << "... with Statement: ";
 		++indent;
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/AST/Stmt.hpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -532,4 +532,18 @@
 };
 
+// Corun Statement
+class CorunStmt final : public Stmt {
+  public:
+	ptr<Stmt> stmt;
+
+	CorunStmt( const CodeLocation & loc, const Stmt * stmt, const std::vector<Label> && labels = {} )
+		: Stmt(loc, std::move(labels)), stmt(stmt) {}
+
+	const Stmt * accept( Visitor & v ) const override { return v.visit( this ); }
+  private:
+	CorunStmt * clone() const override { return new CorunStmt{ *this }; }
+	MUTATE_FRIEND
+};
+
 } // namespace ast
 
Index: src/AST/Visitor.hpp
===================================================================
--- src/AST/Visitor.hpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/AST/Visitor.hpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -59,4 +59,5 @@
     virtual const ast::Stmt *             visit( const ast::ImplicitCtorDtorStmt * ) = 0;
     virtual const ast::Stmt *             visit( const ast::MutexStmt            * ) = 0;
+    virtual const ast::Stmt *             visit( const ast::CorunStmt            * ) = 0;
     virtual const ast::Expr *             visit( const ast::ApplicationExpr      * ) = 0;
     virtual const ast::Expr *             visit( const ast::UntypedExpr          * ) = 0;
Index: src/Common/CodeLocationTools.cpp
===================================================================
--- src/Common/CodeLocationTools.cpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/Common/CodeLocationTools.cpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -137,4 +137,5 @@
     macro(ImplicitCtorDtorStmt, Stmt) \
     macro(MutexStmt, Stmt) \
+    macro(CorunStmt, Stmt) \
     macro(ApplicationExpr, Expr) \
     macro(UntypedExpr, Expr) \
Index: src/Concurrency/Corun.cpp
===================================================================
--- src/Concurrency/Corun.cpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
+++ src/Concurrency/Corun.cpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -0,0 +1,98 @@
+//
+// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
+//
+// The contents of this file are covered under the licence agreement in the
+// file "LICENCE" distributed with Cforall.
+//
+// Corun.cpp -- generate code needed by the actor system
+//
+// Author           : Colby Parsons
+// Created On       : Monday October 9 15:16:42 2023
+// Last Modified By : Colby Parsons
+// Last Modified On : Monday October 9 15:16:42 2023
+// Update Count     : 0
+//
+
+#include "AST/Decl.hpp"
+#include "AST/Expr.hpp"
+#include "AST/Pass.hpp"
+#include "AST/Stmt.hpp"
+#include "AST/TranslationUnit.hpp"
+#include "Common/UniqueName.h"
+using namespace ast;
+using namespace std;
+
+namespace Concurrency {
+
+struct CorunKeyword : public WithDeclsToAdd<>, public WithStmtsToAdd<> {
+    UniqueName CorunFnNamer = "__CFA_corun_lambda_"s;
+    UniqueName RunnerBlockNamer = "__CFA_corun_block_"s;
+
+    const StructDecl * runnerBlockDecl = nullptr;
+
+    // Finds select_node decl
+    void previsit( const StructDecl * decl ) {
+        if ( !decl->body ) {
+            return;
+        } else if ( "runner_block" == decl->name ) {
+            assert( !runnerBlockDecl );
+            runnerBlockDecl = decl;
+        }
+    }
+
+    Stmt * postvisit( const CorunStmt * stmt ) {
+        if ( !runnerBlockDecl )
+            SemanticError( stmt->location, "To use corun statements add #include <cofor.hfa>\n" );
+
+        if ( !stmt->stmt )
+            return nullptr;
+
+        const CodeLocation & loc = stmt->location;
+        const string fnName = CorunFnNamer.newName();
+        const string objName = RunnerBlockNamer.newName();
+
+        // Generates:
+        // void __CFA_corun_lambda_() { ... stmt->stmt ... }
+        Stmt * runnerLambda = new DeclStmt( loc,
+            new FunctionDecl( loc,
+                fnName,                                             // name
+                {},                                                 // forall
+                {},                                                 // params
+                {},                                                 // return
+                new CompoundStmt( loc, { deepCopy(stmt->stmt) } )   // body
+            )
+        );
+
+        // Generates:
+        // runner_block __CFA_corun_block_;
+        Stmt * objDecl = new DeclStmt( loc,
+            new ObjectDecl( loc,
+                objName,
+                new StructInstType( runnerBlockDecl )
+            )
+        );
+
+        // Generates:
+        // __CFA_corun_block_{ __CFA_corun_lambda_ };
+        Stmt * threadStart = new ExprStmt( loc,
+            new UntypedExpr ( loc,
+                new NameExpr( loc, "?{}" ),
+                {
+                    new NameExpr( loc, objName ),
+                    new NameExpr( loc, fnName )
+                }
+            )
+        );
+
+        stmtsToAddBefore.push_back( runnerLambda );
+        stmtsToAddBefore.push_back( objDecl );
+
+        return threadStart;
+    }
+};
+
+void implementCorun( TranslationUnit & translationUnit ) {
+    Pass<CorunKeyword>::run( translationUnit );
+}
+
+} // namespace Concurrency
Index: src/Concurrency/Corun.hpp
===================================================================
--- src/Concurrency/Corun.hpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
+++ src/Concurrency/Corun.hpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -0,0 +1,30 @@
+//
+// 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.
+//
+// Corun.hpp -- Implement concurrency constructs from their keywords.
+//
+// Author           : Colby Parsons
+// Created On       : Monday October 9 15:16:42 2023
+// Last Modified By :
+// Last Modified On :
+// Update Count     : 1
+//
+
+#pragma once
+
+namespace ast {
+	class TranslationUnit;
+}
+
+namespace Concurrency {
+	void implementCorun( ast::TranslationUnit & translationUnit );
+};
+
+// Local Variables: //
+// tab-width: 4 //
+// mode: c++ //
+// compile-command: "make install" //
+// End: //
Index: src/Concurrency/module.mk
===================================================================
--- src/Concurrency/module.mk	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/Concurrency/module.mk	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -18,4 +18,6 @@
 	Concurrency/Actors.cpp \
 	Concurrency/Actors.hpp \
+	Concurrency/Corun.cpp \
+	Concurrency/Corun.hpp \
 	Concurrency/KeywordsNew.cpp \
 	Concurrency/Keywords.cc \
Index: src/GenPoly/BoxNew.cpp
===================================================================
--- src/GenPoly/BoxNew.cpp	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/GenPoly/BoxNew.cpp	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -94,26 +94,21 @@
 
 /// Adds parameters for otype size and alignment to a function type.
-void addOTypeParams(
-		ast::FunctionDecl * decl,
+void addSTypeParams(
+		ast::vector<ast::DeclWithType> & params,
 		ast::vector<ast::TypeDecl> const & sizedParams ) {
-	// TODO: Can we fold this into buildLayoutFunction to avoid rebuilding?
-	ast::FunctionType * type = ast::mutate( decl->type.get() );
 	for ( ast::ptr<ast::TypeDecl> const & sizedParam : sizedParams ) {
 		ast::TypeInstType inst( sizedParam );
 		std::string paramName = Mangle::mangleType( &inst );
-		decl->params.emplace_back( new ast::ObjectDecl(
+		params.emplace_back( new ast::ObjectDecl(
 			sizedParam->location,
 			sizeofName( paramName ),
 			makeSizeAlignType()
 		) );
-		type->params.emplace_back( makeSizeAlignType() );
-		decl->params.emplace_back( new ast::ObjectDecl(
+		params.emplace_back( new ast::ObjectDecl(
 			sizedParam->location,
 			alignofName( paramName ),
 			makeSizeAlignType()
 		) );
-		type->params.emplace_back( makeSizeAlignType() );
-	}
-	decl->type = type;
+	}
 }
 
@@ -129,7 +124,7 @@
 };
 
-// TODO: Is there a better way to handle the different besides a flag?
 LayoutData buildLayoutFunction(
 		CodeLocation const & location, ast::AggregateDecl const * aggr,
+		ast::vector<ast::TypeDecl> const & sizedParams,
 		bool isInFunction, bool isStruct ) {
 	ast::ObjectDecl * sizeParam = new ast::ObjectDecl(
@@ -153,4 +148,5 @@
 		params.push_back( offsetParam );
 	}
+	addSTypeParams( params, sizedParams );
 
 	// Routines at global scope marked "static" to prevent multiple
@@ -238,6 +234,6 @@
 
 	// Build layout function signature.
-	LayoutData layout =
-		buildLayoutFunction( location, decl, isInFunction(), true );
+	LayoutData layout = buildLayoutFunction(
+		location, decl, sizedParams, isInFunction(), true );
 	ast::FunctionDecl * layoutDecl = layout.function;
 	// Also return these or extract them from the parameter list?
@@ -246,5 +242,4 @@
 	ast::ObjectDecl const * offsetofParam = layout.offsetofParam;
 	assert( nullptr != layout.offsetofParam );
-	addOTypeParams( layoutDecl, sizedParams );
 
 	// Calculate structure layout in function body.
@@ -313,6 +308,6 @@
 
 	// Build layout function signature.
-	LayoutData layout =
-		buildLayoutFunction( location, decl, isInFunction(), false );
+	LayoutData layout = buildLayoutFunction(
+		location, decl, sizedParams, isInFunction(), false );
 	ast::FunctionDecl * layoutDecl = layout.function;
 	// Also return these or extract them from the parameter list?
@@ -320,5 +315,4 @@
 	ast::ObjectDecl const * alignofParam = layout.alignofParam;
 	assert( nullptr == layout.offsetofParam );
-	addOTypeParams( layoutDecl, sizedParams );
 
 	// Calculate union layout in function body.
@@ -641,8 +635,6 @@
 	// the variable can be reused as a parameter to the call rather than
 	// creating a new temporary variable. Previously this step was an
-	// optimization, but
-	// ...
-	// with the introduction of tuples and UniqueExprs, it is necessary to
-	// ensure that they use the same variable.
+	// optimization, but with the introduction of tuples and UniqueExprs,
+	// it is necessary to ensure that they use the same variable.
 	// Essentially, looking for pattern:
 	// (x=f(...), x)
@@ -689,5 +681,4 @@
 	// the distinction between _conc_T30 and T3(int)) concRetType may not be
 	// a good name in one or both of these places.
-	// TODO A more appropriate name change is welcome.
 	if ( dynRetType ) {
 		ast::Type const * result = mutExpr->result;
@@ -698,9 +689,4 @@
 	} else if ( needsAdapter( function, scopeTypeVars )
 			&& !needsAdapter( function, exprTypeVars ) ) {
-		// TODO:
-		// The !needsAdapter check may be incorrect. It seems there is some
-		// situation where an adapter is applied where it shouldn't be,
-		// and this fixes it for some case. More investigation is needed.
-
 		// Change the application so it calls the adapter rather than the
 		// passed function.
@@ -1774,5 +1760,5 @@
 	/// Adds type parameters to the layout call; will generate the
 	/// appropriate parameters if needed.
-	void addOTypeParamsToLayoutCall(
+	void addSTypeParamsToLayoutCall(
 		ast::UntypedExpr * layoutCall,
 		const ast::vector<ast::Type> & otypeParams );
@@ -2014,7 +2000,6 @@
 		ast::MemberExpr const * expr ) {
 	// Only mutate member expressions for polymorphic types.
-	int typeDepth;
 	ast::Type const * objectType = hasPolyBase(
-		expr->aggregate->result, scopeTypeVars, &typeDepth
+		expr->aggregate->result, scopeTypeVars
 	);
 	if ( !objectType ) return expr;
@@ -2094,5 +2079,5 @@
 	}
 	// MemberExpr was converted to pointer + offset; and it is not valid C to
-	// take the address of an addition, so stript the address-of.
+	// take the address of an addition, so strip away the address-of.
 	// It also preserves the env value.
 	return ast::mutate_field( expr->arg.get(), &ast::Expr::env, expr->env );
@@ -2295,5 +2280,5 @@
 				} );
 
-			addOTypeParamsToLayoutCall( layoutCall, sizedParams );
+			addSTypeParamsToLayoutCall( layoutCall, sizedParams );
 
 			stmtsToAddBefore.emplace_back(
@@ -2336,5 +2321,5 @@
 			} );
 
-		addOTypeParamsToLayoutCall( layoutCall, sizedParams );
+		addSTypeParamsToLayoutCall( layoutCall, sizedParams );
 
 		stmtsToAddBefore.emplace_back(
@@ -2346,5 +2331,5 @@
 }
 
-void PolyGenericCalculator::addOTypeParamsToLayoutCall(
+void PolyGenericCalculator::addSTypeParamsToLayoutCall(
 		ast::UntypedExpr * layoutCall,
 		const ast::vector<ast::Type> & otypeParams ) {
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/Parser/StatementNode.cc	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -498,4 +498,9 @@
 } // build_mutex
 
+ast::Stmt * build_corun( const CodeLocation & location, StatementNode * stmt ) {
+	ast::Stmt * body = maybeMoveBuild( stmt );
+	return new ast::CorunStmt( location, body );
+} // build_corun
+
 // Local Variables: //
 // tab-width: 4 //
Index: src/Parser/StatementNode.h
===================================================================
--- src/Parser/StatementNode.h	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/Parser/StatementNode.h	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -105,2 +105,3 @@
 ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
 ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
+ast::Stmt * build_corun( const CodeLocation &, StatementNode * stmt );
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/Parser/parser.yy	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -1721,5 +1721,5 @@
 corun_statement:
 	CORUN statement
-		{ SemanticError( yylloc, "corun statement is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new StatementNode( build_corun( yylloc, $2 ) ); }
 	;
 
Index: src/ResolvExpr/ResolveTypeof.cc
===================================================================
--- src/ResolvExpr/ResolveTypeof.cc	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/ResolvExpr/ResolveTypeof.cc	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -231,5 +231,5 @@
             const ast::Designation *des = mutListInit->designations[k].get();
             // Desination here
-            ast::Designation * newDesination = new ast::Designation(des->location);
+            ast::Designation * newDesignation = new ast::Designation(des->location);
             std::deque<ast::ptr<ast::Expr>> newDesignators;
 
@@ -265,6 +265,6 @@
             }            
             
-            newDesination->designators = newDesignators;
-            mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesination);
+            newDesignation->designators = newDesignators;
+            mutListInit = ast::mutate_field_index(mutListInit, &ast::ListInit::designations, k, newDesignation);
             
         }
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ src/main.cc	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -46,4 +46,5 @@
 #include "Common/utility.h"                 // for deleteAll, filter, printAll
 #include "Concurrency/Actors.hpp"           // for implementActors
+#include "Concurrency/Corun.hpp"            // for implementCorun
 #include "Concurrency/Keywords.h"           // for implementMutex, implement...
 #include "Concurrency/Waitfor.h"            // for generateWaitfor
@@ -345,4 +346,5 @@
 		PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords, transUnit );
 		PASS( "Fix Unique Ids", Validate::fixUniqueIds, transUnit );
+		PASS( "Implement Corun", Concurrency::implementCorun, transUnit );
 		PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls, transUnit );
 
Index: tests/.expect/linkonce.txt
===================================================================
--- tests/.expect/linkonce.txt	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ tests/.expect/linkonce.txt	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -1,1 +1,1 @@
-signed=-7 unsigned=12
+signed=7 unsigned=12
Index: tests/concurrency/cofor.cfa
===================================================================
--- tests/concurrency/cofor.cfa	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ tests/concurrency/cofor.cfa	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -1,14 +1,21 @@
 #include <cofor.hfa>
 
-long total = 0;
-void add_num( void * arg ) { __atomic_fetch_add( &total, (long)arg, __ATOMIC_SEQ_CST ); }
+
+void add_num( long * total, long val ) { __atomic_fetch_add( total, (long)val, __ATOMIC_SEQ_CST ); }
 
 int main() {
     printf("start\n");
     processor p[4];
+    long total = 0;
     COFOR( i, 0, 10, __atomic_fetch_add( &total, i, __ATOMIC_SEQ_CST ); );
-    parallel_stmt_t stmts[5] = { add_num, add_num, add_num, add_num, add_num };
-    void * nums[5] = { (void *)11, (void *)12, (void *)13, (void *)14, (void *)15 };
-    parallel( stmts, nums, 5 );
+    {
+        corun;      // does nothing
+        corun{};    // does nothing
+        corun add_num( &total, 11 );
+        corun { add_num( &total, 12 ); }
+        corun __atomic_fetch_add( &total, 13, __ATOMIC_SEQ_CST );
+        corun { __atomic_fetch_add( &total, 14, __ATOMIC_SEQ_CST ); }
+        __atomic_fetch_add( &total, 15, __ATOMIC_SEQ_CST ); // run by main thd
+    }
     printf("total: %ld\n", total);
     printf("done\n");
Index: tests/link-once/main.cfa
===================================================================
--- tests/link-once/main.cfa	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ tests/link-once/main.cfa	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -1,5 +1,5 @@
 // Test our new cfa_linkonce attribute:
 
-__attribute__(( cfa_linkonce )) signed int example = -7;
+__attribute__(( cfa_linkonce )) signed int example = 7;
 __attribute__(( cfa_linkonce )) unsigned int example = 12;
 
Index: tests/link-once/partner.cfa
===================================================================
--- tests/link-once/partner.cfa	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ tests/link-once/partner.cfa	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -1,5 +1,5 @@
 // Side file for the link-once test.
 
-__attribute__(( cfa_linkonce )) signed int example = -7;
+__attribute__(( cfa_linkonce )) signed int example = 7;
 __attribute__(( cfa_linkonce )) unsigned int example = 12;
 
Index: tests/test.py
===================================================================
--- tests/test.py	(revision 946a6e4d6e22aa9ec049796a1ac9b96286d7e852)
+++ tests/test.py	(revision a97b9ed3c1ef2940db3bc2e85497a8b1a674d78d)
@@ -125,5 +125,5 @@
 	parser.add_argument('--archive-errors', help='If called with a valid path, on test crashes the test script will copy the core dump and the executable to the specified path.', type=str, default='')
 	parser.add_argument('-j', '--jobs', help='Number of tests to run simultaneously, 0 (default) for unlimited', nargs='?', const=0, type=int)
-	parser.add_argument('--list-comp', help='List all valide arguments', action='store_true')
+	parser.add_argument('--list-comp', help='List all valid arguments', action='store_true')
 	parser.add_argument('--list-dist', help='List all tests for distribution', action='store_true')
 	parser.add_argument('-I','--include', help='Directory of test to include, can be used multiple time, All  if omitted', action='append')
