Index: src/AST/Decl.hpp
===================================================================
--- src/AST/Decl.hpp	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/AST/Decl.hpp	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -259,6 +259,7 @@
 
 	bool is_coroutine() { return kind == Coroutine; }
-	bool is_monitor() { return kind == Monitor; }
-	bool is_thread() { return kind == Thread; }
+	bool is_generator() { return kind == Generator; }
+	bool is_monitor  () { return kind == Monitor  ; }
+	bool is_thread   () { return kind == Thread   ; }
 
 	const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
Index: src/Concurrency/Keywords.cc
===================================================================
--- src/Concurrency/Keywords.cc	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/Concurrency/Keywords.cc	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -16,21 +16,22 @@
 #include "Concurrency/Keywords.h"
 
-#include <cassert>                 // for assert
-#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
-#include "CodeGen/OperatorTable.h" // for isConstructor
-#include "InitTweak/InitTweak.h"   // for getPointerBase
-#include "SynTree/LinkageSpec.h"   // for Cforall
-#include "SynTree/Constant.h"      // for Constant
-#include "SynTree/Declaration.h"   // for StructDecl, FunctionDecl, ObjectDecl
-#include "SynTree/Expression.h"    // for VariableExpr, ConstantExpr, Untype...
-#include "SynTree/Initializer.h"   // for SingleInit, ListInit, Initializer ...
-#include "SynTree/Label.h"         // for Label
-#include "SynTree/Statement.h"     // for CompoundStmt, DeclStmt, ExprStmt
-#include "SynTree/Type.h"          // for StructInstType, Type, PointerType
-#include "SynTree/Visitor.h"       // for Visitor, acceptAll
+#include <cassert>                        // for assert
+#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
+#include "CodeGen/OperatorTable.h"        // for isConstructor
+#include "ControlStruct/LabelGenerator.h" // for LebelGenerator
+#include "InitTweak/InitTweak.h"          // for getPointerBase
+#include "SynTree/LinkageSpec.h"          // for Cforall
+#include "SynTree/Constant.h"             // for Constant
+#include "SynTree/Declaration.h"          // for StructDecl, FunctionDecl, ObjectDecl
+#include "SynTree/Expression.h"           // for VariableExpr, ConstantExpr, Untype...
+#include "SynTree/Initializer.h"          // for SingleInit, ListInit, Initializer ...
+#include "SynTree/Label.h"                // for Label
+#include "SynTree/Statement.h"            // for CompoundStmt, DeclStmt, ExprStmt
+#include "SynTree/Type.h"                 // for StructInstType, Type, PointerType
+#include "SynTree/Visitor.h"              // for Visitor, acceptAll
 
 class Attribute;
@@ -147,4 +148,6 @@
 	};
 
+
+
 	//-----------------------------------------------------------------------------
 	//Handles monitor type declarations :
@@ -180,4 +183,75 @@
 
 	//-----------------------------------------------------------------------------
+	//Handles generator type declarations :
+	// generator MyGenerator {                   struct MyGenerator {
+	// 	int data;                                  int data;
+	// 	a_struct_t more_data;                      a_struct_t more_data;
+	//                                =>             int __gen_next;
+	// };                                        };
+	//
+	class GeneratorKeyword final : public ConcurrentSueKeyword {
+	  public:
+
+	  	GeneratorKeyword() : ConcurrentSueKeyword(
+			"$generator",
+			"__generator_state",
+			"get_generator",
+			"Unable to find builtin type $generator\n",
+			true,
+			AggregateDecl::Generator
+		)
+		{}
+
+		virtual ~GeneratorKeyword() {}
+
+		virtual bool is_target( StructDecl * decl ) override final { return decl->is_generator(); }
+
+		static void implement( std::list< Declaration * > & translationUnit ) {
+			PassVisitor< GeneratorKeyword > impl;
+			mutateAll( translationUnit, impl );
+		}
+	};
+
+
+	//-----------------------------------------------------------------------------
+	class SuspendKeyword final : public WithStmtsToAdd, public WithGuards {
+	public:
+		SuspendKeyword() = default;
+		virtual ~SuspendKeyword() = default;
+
+		void  premutate( FunctionDecl * );
+		DeclarationWithType * postmutate( FunctionDecl * );
+
+		Statement * postmutate( SuspendStmt * );
+
+		static void implement( std::list< Declaration * > & translationUnit ) {
+			PassVisitor< SuspendKeyword > impl;
+			mutateAll( translationUnit, impl );
+		}
+
+	private:
+		DeclarationWithType * is_main( FunctionDecl * );
+		bool is_real_suspend( FunctionDecl * );
+
+		Statement * make_generator_suspend( SuspendStmt * );
+		Statement * make_coroutine_suspend( SuspendStmt * );
+
+		struct LabelPair {
+			Label obj;
+			int   idx;
+		};
+
+		LabelPair make_label() {
+			labels.push_back( gen.newLabel("generator") );
+			return { labels.back(), int(labels.size()) };
+		}
+
+		DeclarationWithType * in_generator = nullptr;
+		FunctionDecl * decl_suspend = nullptr;
+		std::vector<Label> labels;
+		ControlStruct::LabelGenerator & gen = *ControlStruct::LabelGenerator::getGenerator();
+	};
+
+	//-----------------------------------------------------------------------------
 	//Handles mutex routines definitions :
 	// void foo( A * mutex a, B * mutex b,  int i ) {                  void foo( A * a, B * b,  int i ) {
@@ -251,4 +325,6 @@
 		CoroutineKeyword	::implement( translationUnit );
 		MonitorKeyword	::implement( translationUnit );
+		GeneratorKeyword  ::implement( translationUnit );
+		SuspendKeyword    ::implement( translationUnit );
 	}
 
@@ -446,7 +522,236 @@
 
 		declsToAddAfter.push_back( get_decl );
-
-		// get_decl->fixUniqueId();
-	}
+	}
+
+	//=============================================================================================
+	// Suspend keyword implementation
+	//=============================================================================================
+	DeclarationWithType * SuspendKeyword::is_main( FunctionDecl * func) {
+		if(func->name != "main") return nullptr;
+		if(func->type->parameters.size() != 1) return nullptr;
+
+		auto param = func->type->parameters.front();
+
+		auto type  = dynamic_cast<ReferenceType * >(param->get_type());
+		if(!type) return nullptr;
+
+		auto obj   = dynamic_cast<StructInstType *>(type->base);
+		if(!obj) return nullptr;
+
+		if(!obj->baseStruct->is_generator()) return nullptr;
+
+		return param;
+	}
+
+	bool SuspendKeyword::is_real_suspend( FunctionDecl * func ) {
+		if(isMangled(func->linkage)) return false; // the real suspend isn't mangled
+		if(func->name != "__cfactx_suspend") return false; // the real suspend has a specific name
+		if(func->type->parameters.size() != 0) return false; // Too many parameters
+		if(func->type->returnVals.size() != 0) return false; // Too many return values
+
+		return true;
+	}
+
+	void SuspendKeyword::premutate( FunctionDecl * func ) {
+		GuardValue(in_generator);
+		in_generator = nullptr;
+
+		// Is this the real suspend?
+		if(is_real_suspend(func)) {
+			decl_suspend = decl_suspend ? decl_suspend : func;
+			return;
+		}
+
+		// Is this the main of a generator?
+		auto param = is_main( func );
+		if(!param) return;
+
+		if(func->type->returnVals.size() != 0) SemanticError(func->location, "Generator main must return void");
+
+		in_generator = param;
+		GuardValue(labels);
+		labels.clear();
+	}
+
+	DeclarationWithType * SuspendKeyword::postmutate( FunctionDecl * func ) {
+		if( !func->statements ) return func; // Not the actual definition, don't do anything
+		if( !in_generator     ) return func; // Not in a generator, don't do anything
+		if( labels.empty()    ) return func; // Generator has no states, nothing to do, could throw a warning
+
+		// This is a generator main, we need to add the following code to the top
+		// static void * __generator_labels[] = {&&s0, &&s1, ...};
+		// goto * __generator_labels[gen.__generator_state];
+		const auto & loc = func->location;
+
+		const auto first_label = gen.newLabel("generator");
+
+		// for each label add to declaration
+		std::list<Initializer*> inits = { new SingleInit( new LabelAddressExpr( first_label ) ) };
+		for(const auto & label : labels) {
+			inits.push_back(
+				new SingleInit(
+					new LabelAddressExpr( label )
+				)
+			);
+		}
+		auto init = new ListInit(std::move(inits), noDesignators, true);
+		labels.clear();
+
+		// create decl
+		auto decl = new ObjectDecl(
+			"__generator_labels",
+			Type::StorageClasses( Type::Static ),
+			LinkageSpec::AutoGen,
+			nullptr,
+			new ArrayType(
+				Type::Qualifiers(),
+				new PointerType(
+					Type::Qualifiers(),
+					new VoidType( Type::Qualifiers() )
+				),
+				nullptr,
+				false, false
+			),
+			init
+		);
+
+		// create the goto
+		assert(in_generator);
+
+		auto go_decl = new ObjectDecl(
+			"__generator_label",
+			noStorageClasses,
+			LinkageSpec::AutoGen,
+			nullptr,
+			new PointerType(
+				Type::Qualifiers(),
+				new VoidType( Type::Qualifiers() )
+			),
+			new SingleInit(
+				new UntypedExpr(
+					new NameExpr("?[?]"),
+					{
+						new NameExpr("__generator_labels"),
+						new UntypedMemberExpr(
+							new NameExpr("__generator_state"),
+							new VariableExpr( in_generator )
+						)
+					}
+				)
+			)
+		);
+		go_decl->location = loc;
+
+		auto go = new BranchStmt(
+			new VariableExpr( go_decl ),
+			BranchStmt::Goto
+		);
+		go->location = loc;
+		go->computedTarget->location = loc;
+
+		auto noop = new NullStmt({ first_label });
+		noop->location = loc;
+
+		// wrap everything in a nice compound
+		auto body = new CompoundStmt({
+			new DeclStmt( decl ),
+			new DeclStmt( go_decl ),
+			go,
+			noop,
+			func->statements
+		});
+		body->location   = loc;
+		func->statements = body;
+
+		return func;
+	}
+
+	Statement * SuspendKeyword::postmutate( SuspendStmt * stmt ) {
+		SuspendStmt::Type type = stmt->type;
+		if(type == SuspendStmt::None) {
+			// This suspend has a implicit target, find it
+			type = in_generator ? SuspendStmt::Generator : SuspendStmt::Coroutine;
+		}
+
+		// Check that the target makes sense
+		if(!in_generator && type == SuspendStmt::Generator) SemanticError( stmt->location, "'suspend generator' must be used inside main of generator type.");
+
+		// Act appropriately
+		switch(type) {
+			case SuspendStmt::Generator: return make_generator_suspend(stmt);
+			case SuspendStmt::Coroutine: return make_coroutine_suspend(stmt);
+			default: abort();
+		}
+	}
+
+	Statement * SuspendKeyword::make_generator_suspend( SuspendStmt * stmt ) {
+		assert(in_generator);
+		// Target code is :
+		//   gen.__generator_state = X;
+		//   { THEN }
+		//   return;
+		//   __gen_X:;
+
+		// Save the location and delete the old statement, we only need the location from this point on
+		auto loc = stmt->location;
+
+		// Build the label and get its index
+		auto label = make_label();
+
+		// Create the context saving statement
+		auto save = new ExprStmt( new UntypedExpr(
+			new NameExpr( "?=?" ),
+			{
+				new UntypedMemberExpr(
+					new NameExpr("__generator_state"),
+					new VariableExpr( in_generator )
+				),
+				new ConstantExpr(
+					Constant::from_int( label.idx )
+				)
+			}
+		));
+		assert(save->expr);
+		save->location = loc;
+		stmtsToAddBefore.push_back( save );
+
+		// if we have a then add it here
+		auto then = stmt->then;
+		stmt->then = nullptr;
+		delete stmt;
+		if(then) stmtsToAddBefore.push_back( then );
+
+		// Create the return statement
+		auto ret = new ReturnStmt( nullptr );
+		ret->location = loc;
+		stmtsToAddBefore.push_back( ret );
+
+		// Create the null statement with the created label
+		auto noop = new NullStmt({ label.obj });
+		noop->location = loc;
+
+		// Return the null statement to take the place of the previous statement
+		return noop;
+	}
+
+	Statement * SuspendKeyword::make_coroutine_suspend( SuspendStmt * stmt ) {
+		if(stmt->then) SemanticError( stmt->location, "Compound statement following coroutines is not implemented.");
+
+		// Save the location and delete the old statement, we only need the location from this point on
+		auto loc = stmt->location;
+		delete stmt;
+
+		// Create the call expression
+		if(!decl_suspend) SemanticError( loc, "suspend keyword applied to coroutines requires coroutines to be in scope, add #include <coroutine.hfa>\n");
+		auto expr = new UntypedExpr( VariableExpr::functionPointer( decl_suspend ) );
+		expr->location = stmt->location;
+
+		// Change this statement into a regular expr
+		assert(expr);
+		auto nstmt = new ExprStmt( expr );
+		nstmt->location = stmt->location;
+		return nstmt;
+	}
+
 
 	//=============================================================================================
Index: src/GenPoly/Lvalue.cc
===================================================================
--- src/GenPoly/Lvalue.cc	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/GenPoly/Lvalue.cc	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -140,9 +140,15 @@
 		PassVisitor<FixIntrinsicResult> intrinsicResults;
 		mutateAll( translationUnit, intrinsicResults );
+		translationUnit.back()->print( std::cout );
 		mutateAll( translationUnit, addrRef );
+		translationUnit.back()->print( std::cout );
 		mutateAll( translationUnit, refCvt );
+		translationUnit.back()->print( std::cout );
 		mutateAll( translationUnit, fixer );
+		translationUnit.back()->print( std::cout );
 		mutateAll( translationUnit, collapser );
+		translationUnit.back()->print( std::cout );
 		mutateAll( translationUnit, genLval );
+		translationUnit.back()->print( std::cout );
 		mutateAll( translationUnit, elim );  // last because other passes need reference types to work
 
Index: src/Parser/ParseNode.h
===================================================================
--- src/Parser/ParseNode.h	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/Parser/ParseNode.h	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -428,4 +428,5 @@
 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
 Statement * build_directive( std::string * directive );
+SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when );
 WaitForStmt * build_waitfor( ExpressionNode * target, StatementNode * stmt, ExpressionNode * when, WaitForStmt * existing );
Index: src/Parser/StatementNode.cc
===================================================================
--- src/Parser/StatementNode.cc	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/Parser/StatementNode.cc	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -249,4 +249,19 @@
 } // build_finally
 
+SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) {
+	auto node = new SuspendStmt();
+
+	node->type = type;
+
+	std::list< Statement * > stmts;
+	buildMoveList< Statement, StatementNode >( then, stmts );
+	if(!stmts.empty()) {
+		assert( stmts.size() == 1 );
+		node->then = dynamic_cast< CompoundStmt * >( stmts.front() );
+	}
+
+	return node;
+}
+
 WaitForStmt * build_waitfor( ExpressionNode * targetExpr, StatementNode * stmt, ExpressionNode * when ) {
 	auto node = new WaitForStmt();
Index: src/Parser/TypeData.cc
===================================================================
--- src/Parser/TypeData.cc	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/Parser/TypeData.cc	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -769,4 +769,5 @@
 	  case AggregateDecl::Struct:
 	  case AggregateDecl::Coroutine:
+	  case AggregateDecl::Generator:
 	  case AggregateDecl::Monitor:
 	  case AggregateDecl::Thread:
Index: src/Parser/parser.yy
===================================================================
--- src/Parser/parser.yy	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/Parser/parser.yy	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -1261,15 +1261,15 @@
 		{ SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
 	| SUSPEND ';'
-	  	{ SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new StatementNode( build_suspend( nullptr ) ); }
 	| SUSPEND compound_statement ';'
-	  	{ SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new StatementNode( build_suspend( $2 ) ); }
 	| SUSPEND COROUTINE ';'
-	  	{ SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); }
 	| SUSPEND COROUTINE compound_statement
-	  	{ SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); }
 	| SUSPEND GENERATOR ';'
-	  	{ SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); }
 	| SUSPEND GENERATOR compound_statement
-	  	{ SemanticError( yylloc, "Suspend expression is currently unimplemented." ); $$ = nullptr; }
+		{ $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); }
 	| THROW assignment_expression_opt ';'				// handles rethrow
 		{ $$ = new StatementNode( build_throw( $2 ) ); }
@@ -2086,5 +2086,5 @@
 aggregate_control:										// CFA
 	GENERATOR
-		{ SemanticError( yylloc, "generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
+		{ yyy = true; $$ = AggregateDecl::Generator; }
 	| MONITOR GENERATOR
 		{ SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
Index: src/SynTree/Declaration.h
===================================================================
--- src/SynTree/Declaration.h	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/SynTree/Declaration.h	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -302,6 +302,7 @@
 
 	bool is_coroutine() { return kind == Coroutine; }
-	bool is_monitor() { return kind == Monitor; }
-	bool is_thread() { return kind == Thread; }
+	bool is_generator() { return kind == Generator; }
+	bool is_monitor  () { return kind == Monitor  ; }
+	bool is_thread   () { return kind == Thread   ; }
 
 	virtual StructDecl * clone() const override { return new StructDecl( *this ); }
Index: src/SynTree/Statement.h
===================================================================
--- src/SynTree/Statement.h	(revision 37cdd97f319c512b8374d214748e986930e2e8f8)
+++ src/SynTree/Statement.h	(revision dfa43602bd7af4000c92703f5f8bd89e83da1bab)
@@ -425,5 +425,5 @@
   public:
 	CompoundStmt * then = nullptr;
-	enum { None, Coroutine, Generator } type = None;
+	enum Type { None, Coroutine, Generator } type = None;
 
 	SuspendStmt() = default;
