Index: src/AST/Convert.cpp
===================================================================
--- src/AST/Convert.cpp	(revision 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/AST/Convert.cpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -650,4 +650,10 @@
 	}
 
+    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;
+	}
+
 	TypeSubstitution * convertTypeSubstitution(const ast::TypeSubstitution * src) {
 
Index: src/AST/Fwd.hpp
===================================================================
--- src/AST/Fwd.hpp	(revision 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/AST/Fwd.hpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -67,4 +67,5 @@
 class ImplicitCtorDtorStmt;
 class MutexStmt;
+class CorunStmt;
 
 class Expr;
Index: src/AST/Node.cpp
===================================================================
--- src/AST/Node.cpp	(revision 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/AST/Node.cpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/AST/Pass.hpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/AST/Pass.impl.hpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/AST/Print.cpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -922,4 +922,15 @@
 	}
 
+    virtual const ast::Stmt * visit( const ast::CorunStmt * node ) override final {
+		os << "Corun Statement" << endl;
+		os << indent << "... with Statement: ";
+		++indent;
+		safe_print( node->stmt );
+		--indent;
+		os << endl;
+
+		return node;
+	}
+
 	virtual const ast::Expr * visit( const ast::ApplicationExpr * node ) override final {
 		++indent;
Index: src/AST/Stmt.hpp
===================================================================
--- src/AST/Stmt.hpp	(revision 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/AST/Stmt.hpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/AST/Visitor.hpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/Common/CodeLocationTools.cpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 eb779d5ca94c2de1db899969438189f4b2c05b4b)
+++ src/Concurrency/Corun.cpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -0,0 +1,96 @@
+//
+// 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 ) {
+        assert( runnerBlockDecl );
+        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 eb779d5ca94c2de1db899969438189f4b2c05b4b)
+++ src/Concurrency/Corun.hpp	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -0,0 +1,32 @@
+//
+// 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
+
+
+class Declaration;
+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 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/Concurrency/module.mk	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -18,4 +18,6 @@
 	Concurrency/Actors.cpp \
 	Concurrency/Actors.hpp \
+	Concurrency/Corun.cpp \
+	Concurrency/Corun.hpp \
 	Concurrency/KeywordsNew.cpp \
 	Concurrency/Keywords.cc \
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/Parser/StatementNode.cc	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/Parser/StatementNode.h	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/Parser/parser.yy	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -1721,5 +1721,5 @@
 corun_statement:
 	CORUN statement
-		{ SemanticError( yylloc, "corun statement is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new StatementNode( build_corun( yylloc, $2 ) ); }
 	;
 
Index: src/main.cc
===================================================================
--- src/main.cc	(revision 0d49efb94c4526e735efdb8e90144d4d8dfbe53f)
+++ src/main.cc	(revision eb779d5ca94c2de1db899969438189f4b2c05b4b)
@@ -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 );
 
