Index: sts/.expect/except-finally-error.txt
===================================================================
--- tests/.expect/except-finally-error.txt	(revision 8b16980c32b666a9179e12e780d2eb89df7d5941)
+++ 	(revision )
@@ -1,15 +1,0 @@
-except-finally-error.cfa:7:1 error: 'break' outside a loop, 'switch', or labelled block
-except-finally-error.cfa:15:1 error: 'break' outside a loop, 'switch', or labelled block
-except-finally-error.cfa:23:1 error: 'break' outside a loop, 'switch', or labelled block
-except-finally-error.cfa:31:1 error: 'continue' target must be an enclosing loop: 
-except-finally-error.cfa:48:1 error: 'break' target must be an enclosing control structure: mainLoop
-except-finally-error.cfa:56:1 error: 'continue' target must be an enclosing loop: mainLoop
-except-finally-error.cfa:65:1 error: 'break' outside a loop, 'switch', or labelled block
-except-finally-error.cfa:76:1 error: 'break' outside a loop, 'switch', or labelled block
-except-finally-error.cfa:87:1 error: 'fallthrough' must be enclosed in a 'switch' or 'choose'
-except-finally-error.cfa:98:1 error: 'break' target must be an enclosing control structure: mainBlock
-except-finally-error.cfa:111:1 error: 'fallthrough' must be enclosed in a 'switch' or 'choose'
-except-finally-error.cfa:124:1 error: 'fallthrough' must be enclosed in a 'switch' or 'choose'
-except-finally-error.cfa:133:1 error: 'return' may not appear in a finally clause
-except-finally-error.cfa:139:1 error: 'return' may not appear in a finally clause
-except-finally-error.cfa:148:1 error: 'break' outside a loop, 'switch', or labelled block
Index: sts/except-0.cfa
===================================================================
--- tests/except-0.cfa	(revision 8b16980c32b666a9179e12e780d2eb89df7d5941)
+++ 	(revision )
@@ -1,247 +1,0 @@
-// Draft of tests for exception handling.
-// Outdated: The integer constant exceptions need to be replaced with virtual
-// exceptions for the new system.
-
-// ERROR: exceptions do not interact with ^?{} properly.
-
-#include <stdio.h>
-#include <stdbool.h>
-
-#include "except-mac.hfa"
-TRIVIAL_EXCEPTION(yin)
-TRIVIAL_EXCEPTION(yang)
-TRIVIAL_EXCEPTION(zen)
-
-
-// Local type to mark exits from scopes. (see ERROR)
-struct signal_exit {
-	const char * area;
-};
-
-void ?{}(signal_exit * this, const char * area) {
-	this->area = area;
-}
-
-void ^?{}(signal_exit * this) {
-	printf("Exiting: %s\n", this->area);
-//	sout | "Exiting:" | this->area;
-}
-
-
-// Mark throws: make sure to only pass in exception types.
-forall(dtype T)
-void terminate(T * except_value) {
-	signal_exit a = {"terminate function"};
-	THROW(except_value);
-	printf("terminate returned\n");
-}
-
-forall(dtype T)
-void resume(T * except_value) {
-	signal_exit a = {"resume function"};
-	THROW_RESUME(except_value);
-	printf("resume returned\n");
-}
-
-// Termination Test: Two handlers: no catch, catch
-void bar() {
-	signal_exit a = {"bar function"};
-	try {
-		terminate(&(zen){});
-	} catch (yin * error) {
-		printf("bar caught exception yin.\n");
-	}
-}
-
-void foo() {
-	signal_exit a = {"foo function"};
-	try {
-		bar();
-	} catch (yang * error) {
-		printf("foo caught exception yang.\n");
-	} catch (zen * error) {
-		printf("foo caught exception zen.\n");
-	}
-}
-
-// Resumption Two Handler Test: no catch, catch.
-void beta() {
-	signal_exit a = {"beta function"};
-	try {
-		zen x;
-		resume(&x);
-	} catchResume (yin * error) {
-		printf("beta caught exception yin\n");
-	}
-}
-
-void alpha() {
-	signal_exit a = {"alpha function"};
-	try {
-		beta();
-	} catchResume (yang * error) {
-		printf("alpha caught exception yang\n");
-	} catchResume (zen * error) {
-		printf("alpha caught exception zen\n");
-	}
-}
-
-// Finally Test:
-void farewell(bool jump) {
-	try {
-		if (jump) {
-			printf("jump out of farewell\n");
-			goto endoffunction;
-		} else {
-			printf("walk out of farewell\n");
-		}
-	} finally {
-		printf("See you next time\n");
-	}
-	endoffunction:
-	printf("leaving farewell\n");
-}
-
-// Resume-to-Terminate Test:
-void fallback() {
-	try {
-		zen x;
-		resume(&x);
-	} catch (zen * error) {
-		printf("fallback caught termination zen\n");
-	}
-}
-
-// Terminate Throw New Exception:
-void terminate_swap() {
-	signal_exit a = {"terminate_swap"};
-	try {
-		yin x;
-		terminate(&x);
-	} catch (yin * error) {
-		yang y;
-		terminate(&y);
-	}
-}
-
-void terminate_swapped() {
-	signal_exit a = {"terminate_swapped"};
-	try {
-		terminate_swap();
-	} catch (yang * error) {
-		printf("terminate_swapped caught exception yang\n");
-	}
-}
-
-// Resume Throw New Exception:
-void resume_swap() {
-	signal_exit a = {"resume_swap"};
-	try {
-		yin x;
-		resume(&x);
-	} catchResume (yin * error) {
-		yang y;
-		resume(&y);
-	}
-}
-
-void resume_swapped() {
-	try {
-		resume_swap();
-	} catchResume (yang * error) {
-		printf("resume_swapped caught exception yang\n");
-	}
-}
-
-// Terminate Rethrow:
-void reterminate() {
-	try {
-		try {
-			zen x;
-			terminate(&x);
-		} catch (zen * error) {
-			printf("reterminate zen caught and "
-			       "will rethrow exception zen\n");
-			throw;
-		}
-	} catch (zen * error) {
-		printf("reterminate 1 caught exception zen\n");
-	}
-}
-
-// Resume Rethrow:
-void reresume() {
-	try {
-		try {
-			zen x;
-			resume(&x);
-		} catchResume (zen * error) {
-			printf("reresume zen caught and rethrows exception zen\n");
-			throwResume;
-		}
-	} catchResume (zen * error) {
-		printf("reresume 1 caught exception zen\n");
-	}
-}
-
-// Terminate-Resume interaction:
-void fum() {
-	// terminate block, call resume
-	try {
-		zen x;
-		resume(&x);
-	} catch (zen * error) {
-		printf("fum caught exception zen\n");
-	}
-}
-
-void foe() {
-	// resume block, call terminate
-	try {
-		zen y;
-		terminate(&y);
-	} catchResume (zen * error) {
-		printf("foe caught exception zen\n");
-	}
-}
-
-void fy() {
-	// terminate block calls fum, call foe
-	try {
-		foe();
-	} catch (zen * error) {
-		printf("fy caught exception zen\n");
-		fum();
-	}
-}
-
-void fee() {
-	// resume block, call fy
-	try {
-		fy();
-	} catchResume (zen * error) {
-		printf("fee caught exception zen\n");
-	}
-}
-
-
-// main: choose which tests to run
-int main(int argc, char * argv[]) {
-	signal_exit a = {"main function"};
-
-	foo(); printf("\n");
-	alpha(); printf("\n");
-	farewell(false); printf("\n");
-	farewell(true); printf("\n");
-	fallback(); printf("\n");
-	terminate_swapped(); printf("\n");
-	resume_swapped(); printf("\n");
-	reterminate(); printf("\n");
-	reresume(); printf("\n");
-	fee(); printf("\n");
-
-	// Uncaught termination test.
-	printf("Throw uncaught.\n");
-	yang z;
-	terminate(&z);
-}
Index: sts/except-1.cfa
===================================================================
--- tests/except-1.cfa	(revision 8b16980c32b666a9179e12e780d2eb89df7d5941)
+++ 	(revision )
@@ -1,81 +1,0 @@
-// Draft memory management test. (remember -fexceptions)
-// Outdated: The integer constant exceptions need to be replaced with virtual
-// exceptions for the new system.
-
-#include <stdio.h>
-
-#include "except-mac.hfa"
-TRIVIAL_EXCEPTION(yin)
-TRIVIAL_EXCEPTION(yang)
-
-int main()
-{
-	try {
-		yin a;
-		THROW(&a);
-	}
-	catch( yin * err ) {
-		printf("First Caught\n");
-		try {
-			yang b;
-			THROW(&b);
-		}
-		catch( yang * err ) {
-			printf("Both Caught\n");
-		}
-	}
-	printf("Part A Complete\n");
-
-	try {
-		try {
-			yang c;
-			THROW(&c);
-		}
-		catch( yang * err ) {
-			printf("First Catch and rethrow\n");
-			throw;
-		}
-	}
-	catch( yang * err ) {
-		printf("Second Catch\n");
-	}
-	printf("Part B Complete\n");
-
-	try {
-		try {
-			yin d;
-			THROW(&d);
-		}
-		catch( yin * err ) {
-			printf("Throw before cleanup\n");
-			yang e;
-			THROW(&e);
-		}
-	}
-	catch( yang * err ) {
-		printf("Catch after cleanup\n");
-	}
-	printf("Part C Complete\n");
-
-	try {
-		try {
-			yin f;
-			THROW(&f);
-		}
-		catch( yin * err ) {
-			printf("Caught initial throw.\n");
-			try {
-				yang g;
-				THROW(&g);
-			}
-			catch( yang * err ) {
-				printf("Caught intermediate throw.\n");
-			}
-			throw;
-		}
-	}
-	catch( yin * err ) {
-		printf("Caught final throw.\n");
-	}
-	printf("Part D Complete\n");
-}
Index: sts/except-2.cfa
===================================================================
--- tests/except-2.cfa	(revision 8b16980c32b666a9179e12e780d2eb89df7d5941)
+++ 	(revision )
@@ -1,92 +1,0 @@
-// New draft of exception tests.
-
-
-#include <stdlib.hfa>
-#include "except-mac.hfa"
-
-TRIVIAL_EXCEPTION(yin)
-TRIVIAL_EXCEPTION(yang)
-
-struct num_error;
-struct num_error_vtable {
-	struct TABLE(BASE_EXCEPT) const * parent;
-	size_t size;
-	void (*copy)(num_error *this, num_error * other);
-	void (*free)(num_error *this);
-	const char * (*msg)(num_error *this);
-	int (*code)(num_error *this);
-};
-extern num_error_vtable INSTANCE(num_error);
-
-struct num_error {
-	struct num_error_vtable const * virtual_table;
-	char * msg;
-	int num;
-};
-
-void num_error_msg(num_error * this) {
-	if ( ! this->msg ) {
-		static const char * base = "Num Error with code: X";
-		this->msg = malloc(22);
-		for (int i = 0 ; (this->msg[i] = base[i]) ; ++i);
-	}
-	this->msg[21] = '0' + this->num;
-	return this->msg;
-}
-void ?{}(num_error * this, int num) {
-	this->virtual_table = &INSTANCE(num_error);
-	this->msg = 0;
-	this->num = num;
-}
-void ?{}(num_error * this, num_error * other) {
-	this->virtual_table = other->virtual_table;
-	this->msg = 0;
-	this->num = other->num;
-}
-void ^?{}(num_error * this) {
-	if( this->msg ) free( this->msg );
-}
-int num_error_code( num_error * this ) {
-	return this->num;
-}
-num_error_vtable _num_error_vtable_instance @= {
-	&INSTANCE(BASE_EXCEPT),
-	sizeof(num_error), ?{}, ^?{},
-	num_error_msg, num_error_code
-};
-
-
-// Test simple throwing, matching and catching.
-void throw_catch() {
-	try {
-		yin black;
-		THROW(&black);
-	} catch ( yin * error ) {
-		printf("throw yin caught.\n");
-	}
-
-	try {
-		yang white;
-		THROW_RESUME(&white);
-		printf("> throwResume returned.\n");
-	} catchResume ( yang * error ) {
-		printf("throwResume yang caught <");
-	}
-
-	try {
-		num_error x = { 2 };
-		THROW(&x);
-	}
-	catch (num_error * error ; 3 == error->virtual_table->code( error ) ) {
-		printf("exception at %p\n", error );
-		printf("Should not be printed.\n");
-	}
-	catch (num_error * error ; 2 == error->virtual_table->code( error ) ) {
-		printf("Should be printed.\n");
-	}
-}
-
-int main (int argc, char * argv[]) {
-	throw_catch();
-	return 0;
-}
Index: sts/except-3.cfa
===================================================================
--- tests/except-3.cfa	(revision 8b16980c32b666a9179e12e780d2eb89df7d5941)
+++ 	(revision )
@@ -1,18 +1,0 @@
-// Test that __attribute__((cleanup(...))) is working.
-
-#include <stdio.h>
-#include "except-mac.hfa"
-TRIVIAL_EXCEPTION(myth)
-
-int main (int argc, char * argv[]) {
-	try {
-		try {
-			printf("throw [");
-			THROW(&(myth){});
-		} finally {
-			printf("] unwind <");
-		}
-	} catch (myth * error) {
-		printf("> catch\n");
-	}
-}
Index: sts/except-finally-error.cfa
===================================================================
--- tests/except-finally-error.cfa	(revision 8b16980c32b666a9179e12e780d2eb89df7d5941)
+++ 	(revision )
@@ -1,156 +1,0 @@
-// All of these should be caught as long as the check remains in the same
-// pass. (Although not even all of the checks are in place yet.)
-
-void break_in_finally() {
-	while (true) {
-		try {} finally {
-			break;
-		}
-	}
-}
-
-void for_break_in_finally() {
-	for (10) {
-		try {} finally {
-			break;
-		}
-	}
-}
-
-void do_while_break_in_finally() {
-	do {
-		try {} finally {
-			break;
-		}
-	} while (false);
-}
-
-void continue_in_finally() {
-	while (true) {
-		try {} finally {
-			continue;
-		}
-	}
-}
-
-void goto_in_finally() {
-	while (true) {
-		try {} finally {
-			goto end_of_function;
-		}
-	}
-	end_of_function: {}
-}
-
-void labelled_break_in_finally() {
-	mainLoop: while (true) {
-		try {} finally {
-			break mainLoop;
-		}
-	}
-}
-
-void labelled_continue_in_finally() {
-	mainLoop: while (true) {
-		try {} finally {
-			continue mainLoop;
-		}
-	}
-}
-
-void switch_break_in_finally() {
-	switch (1) {
-	case 1:
-		try {} finally {
-			break;
-		}
-	default:
-		break;
-	}
-}
-
-void choose_break_in_finally() {
-	choose (1) {
-	case 1:
-		try {} finally {
-			break;
-		}
-	default:
-		break;
-	}
-}
-
-void choose_fallthru_in_finally() {
-	choose (1) {
-	case 1:
-		try {} finally {
-			fallthru;
-		}
-	default:
-		break;
-	}
-}
-
-void labelled_choose_break_in_finally() {
-	mainBlock: choose (1) {
-	case 1:
-		try {} finally {
-			break mainBlock;
-		}
-	case 2:
-		break;
-	default:
-		break;
-	}
-}
-
-void labelled_choose_fallthru_in_finally() {
-	mainBlock: choose (1) {
-	case 1:
-		try {} finally {
-			fallthru mainBlock;
-		}
-	case 2:
-		break;
-	default:
-		break;
-	}
-}
-
-void choose_fallthru_default_in_finally() {
-	choose (1) {
-	case 1:
-		try {} finally {
-			fallthru default;
-		}
-	default:
-		break;
-	}
-}
-
-void void_return_in_finally() {
-	try {} finally {
-		return;
-	}
-}
-
-int value_return_in_finally() {
-	try {} finally {
-		return -7;
-	}
-
-}
-
-// Checked in the same place, make sure it does't break.
-void break_in_function() {
-	while (true) {
-		void inner() {
-			break;
-		}
-	}
-}
-
-void main() {
-	// Should not compile.
-	return 1;
-}
Index: sts/except-mac.hfa
===================================================================
--- tests/except-mac.hfa	(revision 8b16980c32b666a9179e12e780d2eb89df7d5941)
+++ 	(revision )
@@ -1,78 +1,0 @@
-// Macros to try and make declaring and using exceptions easier
-// No, these are not part of the language, they replace the virtual system.
-
-// Internal use:
-#define GLUE2(left, right) left##right
-#define GLUE3(left, middle, right) left##middle##right
-
-// The fully (perhaps overly) qualified name of the base exception type:
-#define BASE_EXCEPT __cfaabi_ehm__base_exception_t
-
-// Get the name of the vtable type and vtable instance for an exception type:
-#define TABLE(name) GLUE2(name,_vtable)
-#define INSTANCE(name) GLUE3(_,name,_vtable_instance)
-
-// Throws and the bit of overhead:
-#define THROW(expr) throw ((BASE_EXCEPT *)(expr))
-#define THROW_RESUME(expr) throwResume ((BASE_EXCEPT *)(expr))
-
-
-
-// The following macros are for defining your own new exception types.
-
-// Declare vtable and forward declare the exception type and vtable instance.
-// This should start a new exception declaration.
-// ... argument is the additional vtable fields.
-#define DECLARE_EXCEPT(except_name,parent_name,...) \
-struct except_name; \
-struct TABLE(except_name) { \
-	struct TABLE(parent_name) const * parent; \
-	size_t size; \
-	void (*copy)(except_name *this, except_name * other); \
-	void (*free)(except_name &this); \
-	const char * (*msg)(except_name *this); \
-	__VA_ARGS__ \
-}; \
-extern TABLE(except_name) INSTANCE(except_name);
-
-// The first field of the exception structure should be created with this.
-#define VTABLE_FIELD(except_name) \
-struct TABLE(except_name) const * virtual_table
-
-// In each constructor the vtable must be initialized.
-#define VTABLE_INIT(this_name,except_name) \
-this_name.virtual_table = &INSTANCE(except_name)
-
-// Declare the vtable instance. This should end an exception declaration.
-// ... argument is the remaining vtable field values.
-#define VTABLE_INSTANCE(except_name,parent_name,copy,free,msg,...) \
-TABLE(except_name) INSTANCE(except_name) @= { \
-	&INSTANCE(parent_name), sizeof(except_name), \
-	copy, free, msg, ## __VA_ARGS__ \
-};
-
-// Same, but used declarators for arguments.
-#define VTABLE_INSTANCE_KEY(except_name,parent_name,copy,free,msg,...) \
-TABLE(except_name) INSTANCE(except_name) @= { \
-	.parent : &INSTANCE(parent_name), .size : sizeof(except_name), \
-	.copy : copy, .free : free, .msg : msg, ## __VA_ARGS__ \
-};
-
-
-
-// Declare a trivial exception, one that adds no features:
-#define TRIVIAL_EXCEPTION(name) \
-DECLARE_EXCEPT(name,BASE_EXCEPT,) \
-struct name { \
-	VTABLE_FIELD(name); \
-}; \
-const char * GLUE2(name,_msg)(name * this) { \
-    return #name; \
-} \
-void GLUE2(name,_copy)(name * this, name * other) { \
-    this->virtual_table = other->virtual_table; \
-} \
-void ?{}(name & this) { \
-	VTABLE_INIT(this,name); \
-} \
-VTABLE_INSTANCE(name,BASE_EXCEPT,GLUE2(name,_copy),^?{},GLUE2(name,_msg),)
Index: tests/exceptions/.expect/finally-error.txt
===================================================================
--- tests/exceptions/.expect/finally-error.txt	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
+++ tests/exceptions/.expect/finally-error.txt	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
@@ -0,0 +1,15 @@
+exceptions/finally-error.cfa:7:1 error: 'break' outside a loop, 'switch', or labelled block
+exceptions/finally-error.cfa:15:1 error: 'break' outside a loop, 'switch', or labelled block
+exceptions/finally-error.cfa:23:1 error: 'break' outside a loop, 'switch', or labelled block
+exceptions/finally-error.cfa:31:1 error: 'continue' target must be an enclosing loop: 
+exceptions/finally-error.cfa:48:1 error: 'break' target must be an enclosing control structure: mainLoop
+exceptions/finally-error.cfa:56:1 error: 'continue' target must be an enclosing loop: mainLoop
+exceptions/finally-error.cfa:65:1 error: 'break' outside a loop, 'switch', or labelled block
+exceptions/finally-error.cfa:76:1 error: 'break' outside a loop, 'switch', or labelled block
+exceptions/finally-error.cfa:87:1 error: 'fallthrough' must be enclosed in a 'switch' or 'choose'
+exceptions/finally-error.cfa:98:1 error: 'break' target must be an enclosing control structure: mainBlock
+exceptions/finally-error.cfa:111:1 error: 'fallthrough' must be enclosed in a 'switch' or 'choose'
+exceptions/finally-error.cfa:124:1 error: 'fallthrough' must be enclosed in a 'switch' or 'choose'
+exceptions/finally-error.cfa:133:1 error: 'return' may not appear in a finally clause
+exceptions/finally-error.cfa:139:1 error: 'return' may not appear in a finally clause
+exceptions/finally-error.cfa:148:1 error: 'break' outside a loop, 'switch', or labelled block
Index: tests/exceptions/except-0.cfa
===================================================================
--- tests/exceptions/except-0.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
+++ tests/exceptions/except-0.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
@@ -0,0 +1,247 @@
+// Draft of tests for exception handling.
+// Outdated: The integer constant exceptions need to be replaced with virtual
+// exceptions for the new system.
+
+// ERROR: exceptions do not interact with ^?{} properly.
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "except-mac.hfa"
+TRIVIAL_EXCEPTION(yin)
+TRIVIAL_EXCEPTION(yang)
+TRIVIAL_EXCEPTION(zen)
+
+
+// Local type to mark exits from scopes. (see ERROR)
+struct signal_exit {
+	const char * area;
+};
+
+void ?{}(signal_exit * this, const char * area) {
+	this->area = area;
+}
+
+void ^?{}(signal_exit * this) {
+	printf("Exiting: %s\n", this->area);
+//	sout | "Exiting:" | this->area;
+}
+
+
+// Mark throws: make sure to only pass in exception types.
+forall(dtype T)
+void terminate(T * except_value) {
+	signal_exit a = {"terminate function"};
+	THROW(except_value);
+	printf("terminate returned\n");
+}
+
+forall(dtype T)
+void resume(T * except_value) {
+	signal_exit a = {"resume function"};
+	THROW_RESUME(except_value);
+	printf("resume returned\n");
+}
+
+// Termination Test: Two handlers: no catch, catch
+void bar() {
+	signal_exit a = {"bar function"};
+	try {
+		terminate(&(zen){});
+	} catch (yin * error) {
+		printf("bar caught exception yin.\n");
+	}
+}
+
+void foo() {
+	signal_exit a = {"foo function"};
+	try {
+		bar();
+	} catch (yang * error) {
+		printf("foo caught exception yang.\n");
+	} catch (zen * error) {
+		printf("foo caught exception zen.\n");
+	}
+}
+
+// Resumption Two Handler Test: no catch, catch.
+void beta() {
+	signal_exit a = {"beta function"};
+	try {
+		zen x;
+		resume(&x);
+	} catchResume (yin * error) {
+		printf("beta caught exception yin\n");
+	}
+}
+
+void alpha() {
+	signal_exit a = {"alpha function"};
+	try {
+		beta();
+	} catchResume (yang * error) {
+		printf("alpha caught exception yang\n");
+	} catchResume (zen * error) {
+		printf("alpha caught exception zen\n");
+	}
+}
+
+// Finally Test:
+void farewell(bool jump) {
+	try {
+		if (jump) {
+			printf("jump out of farewell\n");
+			goto endoffunction;
+		} else {
+			printf("walk out of farewell\n");
+		}
+	} finally {
+		printf("See you next time\n");
+	}
+	endoffunction:
+	printf("leaving farewell\n");
+}
+
+// Resume-to-Terminate Test:
+void fallback() {
+	try {
+		zen x;
+		resume(&x);
+	} catch (zen * error) {
+		printf("fallback caught termination zen\n");
+	}
+}
+
+// Terminate Throw New Exception:
+void terminate_swap() {
+	signal_exit a = {"terminate_swap"};
+	try {
+		yin x;
+		terminate(&x);
+	} catch (yin * error) {
+		yang y;
+		terminate(&y);
+	}
+}
+
+void terminate_swapped() {
+	signal_exit a = {"terminate_swapped"};
+	try {
+		terminate_swap();
+	} catch (yang * error) {
+		printf("terminate_swapped caught exception yang\n");
+	}
+}
+
+// Resume Throw New Exception:
+void resume_swap() {
+	signal_exit a = {"resume_swap"};
+	try {
+		yin x;
+		resume(&x);
+	} catchResume (yin * error) {
+		yang y;
+		resume(&y);
+	}
+}
+
+void resume_swapped() {
+	try {
+		resume_swap();
+	} catchResume (yang * error) {
+		printf("resume_swapped caught exception yang\n");
+	}
+}
+
+// Terminate Rethrow:
+void reterminate() {
+	try {
+		try {
+			zen x;
+			terminate(&x);
+		} catch (zen * error) {
+			printf("reterminate zen caught and "
+			       "will rethrow exception zen\n");
+			throw;
+		}
+	} catch (zen * error) {
+		printf("reterminate 1 caught exception zen\n");
+	}
+}
+
+// Resume Rethrow:
+void reresume() {
+	try {
+		try {
+			zen x;
+			resume(&x);
+		} catchResume (zen * error) {
+			printf("reresume zen caught and rethrows exception zen\n");
+			throwResume;
+		}
+	} catchResume (zen * error) {
+		printf("reresume 1 caught exception zen\n");
+	}
+}
+
+// Terminate-Resume interaction:
+void fum() {
+	// terminate block, call resume
+	try {
+		zen x;
+		resume(&x);
+	} catch (zen * error) {
+		printf("fum caught exception zen\n");
+	}
+}
+
+void foe() {
+	// resume block, call terminate
+	try {
+		zen y;
+		terminate(&y);
+	} catchResume (zen * error) {
+		printf("foe caught exception zen\n");
+	}
+}
+
+void fy() {
+	// terminate block calls fum, call foe
+	try {
+		foe();
+	} catch (zen * error) {
+		printf("fy caught exception zen\n");
+		fum();
+	}
+}
+
+void fee() {
+	// resume block, call fy
+	try {
+		fy();
+	} catchResume (zen * error) {
+		printf("fee caught exception zen\n");
+	}
+}
+
+
+// main: choose which tests to run
+int main(int argc, char * argv[]) {
+	signal_exit a = {"main function"};
+
+	foo(); printf("\n");
+	alpha(); printf("\n");
+	farewell(false); printf("\n");
+	farewell(true); printf("\n");
+	fallback(); printf("\n");
+	terminate_swapped(); printf("\n");
+	resume_swapped(); printf("\n");
+	reterminate(); printf("\n");
+	reresume(); printf("\n");
+	fee(); printf("\n");
+
+	// Uncaught termination test.
+	printf("Throw uncaught.\n");
+	yang z;
+	terminate(&z);
+}
Index: tests/exceptions/except-1.cfa
===================================================================
--- tests/exceptions/except-1.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
+++ tests/exceptions/except-1.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
@@ -0,0 +1,81 @@
+// Draft memory management test. (remember -fexceptions)
+// Outdated: The integer constant exceptions need to be replaced with virtual
+// exceptions for the new system.
+
+#include <stdio.h>
+
+#include "except-mac.hfa"
+TRIVIAL_EXCEPTION(yin)
+TRIVIAL_EXCEPTION(yang)
+
+int main()
+{
+	try {
+		yin a;
+		THROW(&a);
+	}
+	catch( yin * err ) {
+		printf("First Caught\n");
+		try {
+			yang b;
+			THROW(&b);
+		}
+		catch( yang * err ) {
+			printf("Both Caught\n");
+		}
+	}
+	printf("Part A Complete\n");
+
+	try {
+		try {
+			yang c;
+			THROW(&c);
+		}
+		catch( yang * err ) {
+			printf("First Catch and rethrow\n");
+			throw;
+		}
+	}
+	catch( yang * err ) {
+		printf("Second Catch\n");
+	}
+	printf("Part B Complete\n");
+
+	try {
+		try {
+			yin d;
+			THROW(&d);
+		}
+		catch( yin * err ) {
+			printf("Throw before cleanup\n");
+			yang e;
+			THROW(&e);
+		}
+	}
+	catch( yang * err ) {
+		printf("Catch after cleanup\n");
+	}
+	printf("Part C Complete\n");
+
+	try {
+		try {
+			yin f;
+			THROW(&f);
+		}
+		catch( yin * err ) {
+			printf("Caught initial throw.\n");
+			try {
+				yang g;
+				THROW(&g);
+			}
+			catch( yang * err ) {
+				printf("Caught intermediate throw.\n");
+			}
+			throw;
+		}
+	}
+	catch( yin * err ) {
+		printf("Caught final throw.\n");
+	}
+	printf("Part D Complete\n");
+}
Index: tests/exceptions/except-2.cfa
===================================================================
--- tests/exceptions/except-2.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
+++ tests/exceptions/except-2.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
@@ -0,0 +1,92 @@
+// New draft of exception tests.
+
+
+#include <stdlib.hfa>
+#include "except-mac.hfa"
+
+TRIVIAL_EXCEPTION(yin)
+TRIVIAL_EXCEPTION(yang)
+
+struct num_error;
+struct num_error_vtable {
+	struct TABLE(BASE_EXCEPT) const * parent;
+	size_t size;
+	void (*copy)(num_error *this, num_error * other);
+	void (*free)(num_error *this);
+	const char * (*msg)(num_error *this);
+	int (*code)(num_error *this);
+};
+extern num_error_vtable INSTANCE(num_error);
+
+struct num_error {
+	struct num_error_vtable const * virtual_table;
+	char * msg;
+	int num;
+};
+
+void num_error_msg(num_error * this) {
+	if ( ! this->msg ) {
+		static const char * base = "Num Error with code: X";
+		this->msg = malloc(22);
+		for (int i = 0 ; (this->msg[i] = base[i]) ; ++i);
+	}
+	this->msg[21] = '0' + this->num;
+	return this->msg;
+}
+void ?{}(num_error * this, int num) {
+	this->virtual_table = &INSTANCE(num_error);
+	this->msg = 0;
+	this->num = num;
+}
+void ?{}(num_error * this, num_error * other) {
+	this->virtual_table = other->virtual_table;
+	this->msg = 0;
+	this->num = other->num;
+}
+void ^?{}(num_error * this) {
+	if( this->msg ) free( this->msg );
+}
+int num_error_code( num_error * this ) {
+	return this->num;
+}
+num_error_vtable _num_error_vtable_instance @= {
+	&INSTANCE(BASE_EXCEPT),
+	sizeof(num_error), ?{}, ^?{},
+	num_error_msg, num_error_code
+};
+
+
+// Test simple throwing, matching and catching.
+void throw_catch() {
+	try {
+		yin black;
+		THROW(&black);
+	} catch ( yin * error ) {
+		printf("throw yin caught.\n");
+	}
+
+	try {
+		yang white;
+		THROW_RESUME(&white);
+		printf("> throwResume returned.\n");
+	} catchResume ( yang * error ) {
+		printf("throwResume yang caught <");
+	}
+
+	try {
+		num_error x = { 2 };
+		THROW(&x);
+	}
+	catch (num_error * error ; 3 == error->virtual_table->code( error ) ) {
+		printf("exception at %p\n", error );
+		printf("Should not be printed.\n");
+	}
+	catch (num_error * error ; 2 == error->virtual_table->code( error ) ) {
+		printf("Should be printed.\n");
+	}
+}
+
+int main (int argc, char * argv[]) {
+	throw_catch();
+	return 0;
+}
Index: tests/exceptions/except-3.cfa
===================================================================
--- tests/exceptions/except-3.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
+++ tests/exceptions/except-3.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
@@ -0,0 +1,18 @@
+// Test that __attribute__((cleanup(...))) is working.
+
+#include <stdio.h>
+#include "except-mac.hfa"
+TRIVIAL_EXCEPTION(myth)
+
+int main (int argc, char * argv[]) {
+	try {
+		try {
+			printf("throw [");
+			THROW(&(myth){});
+		} finally {
+			printf("] unwind <");
+		}
+	} catch (myth * error) {
+		printf("> catch\n");
+	}
+}
Index: tests/exceptions/except-mac.hfa
===================================================================
--- tests/exceptions/except-mac.hfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
+++ tests/exceptions/except-mac.hfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
@@ -0,0 +1,78 @@
+// Macros to try and make declaring and using exceptions easier
+// No, these are not part of the language, they replace the virtual system.
+
+// Internal use:
+#define GLUE2(left, right) left##right
+#define GLUE3(left, middle, right) left##middle##right
+
+// The fully (perhaps overly) qualified name of the base exception type:
+#define BASE_EXCEPT __cfaabi_ehm__base_exception_t
+
+// Get the name of the vtable type and vtable instance for an exception type:
+#define TABLE(name) GLUE2(name,_vtable)
+#define INSTANCE(name) GLUE3(_,name,_vtable_instance)
+
+// Throws and the bit of overhead:
+#define THROW(expr) throw ((BASE_EXCEPT *)(expr))
+#define THROW_RESUME(expr) throwResume ((BASE_EXCEPT *)(expr))
+
+
+
+// The following macros are for defining your own new exception types.
+
+// Declare vtable and forward declare the exception type and vtable instance.
+// This should start a new exception declaration.
+// ... argument is the additional vtable fields.
+#define DECLARE_EXCEPT(except_name,parent_name,...) \
+struct except_name; \
+struct TABLE(except_name) { \
+	struct TABLE(parent_name) const * parent; \
+	size_t size; \
+	void (*copy)(except_name *this, except_name * other); \
+	void (*free)(except_name &this); \
+	const char * (*msg)(except_name *this); \
+	__VA_ARGS__ \
+}; \
+extern TABLE(except_name) INSTANCE(except_name);
+
+// The first field of the exception structure should be created with this.
+#define VTABLE_FIELD(except_name) \
+struct TABLE(except_name) const * virtual_table
+
+// In each constructor the vtable must be initialized.
+#define VTABLE_INIT(this_name,except_name) \
+this_name.virtual_table = &INSTANCE(except_name)
+
+// Declare the vtable instance. This should end an exception declaration.
+// ... argument is the remaining vtable field values.
+#define VTABLE_INSTANCE(except_name,parent_name,copy,free,msg,...) \
+TABLE(except_name) INSTANCE(except_name) @= { \
+	&INSTANCE(parent_name), sizeof(except_name), \
+	copy, free, msg, ## __VA_ARGS__ \
+};
+
+// Same, but used declarators for arguments.
+#define VTABLE_INSTANCE_KEY(except_name,parent_name,copy,free,msg,...) \
+TABLE(except_name) INSTANCE(except_name) @= { \
+	.parent : &INSTANCE(parent_name), .size : sizeof(except_name), \
+	.copy : copy, .free : free, .msg : msg, ## __VA_ARGS__ \
+};
+
+
+
+// Declare a trivial exception, one that adds no features:
+#define TRIVIAL_EXCEPTION(name) \
+DECLARE_EXCEPT(name,BASE_EXCEPT,) \
+struct name { \
+	VTABLE_FIELD(name); \
+}; \
+const char * GLUE2(name,_msg)(name * this) { \
+    return #name; \
+} \
+void GLUE2(name,_copy)(name * this, name * other) { \
+    this->virtual_table = other->virtual_table; \
+} \
+void ?{}(name & this) { \
+	VTABLE_INIT(this,name); \
+} \
+VTABLE_INSTANCE(name,BASE_EXCEPT,GLUE2(name,_copy),^?{},GLUE2(name,_msg),)
Index: tests/exceptions/finally-error.cfa
===================================================================
--- tests/exceptions/finally-error.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
+++ tests/exceptions/finally-error.cfa	(revision c0b2a6314000bebfc39c3c79a8e2942349724804)
@@ -0,0 +1,156 @@
+// All of these should be caught as long as the check remains in the same
+// pass. (Although not even all of the checks are in place yet.)
+
+void break_in_finally() {
+	while (true) {
+		try {} finally {
+			break;
+		}
+	}
+}
+
+void for_break_in_finally() {
+	for (10) {
+		try {} finally {
+			break;
+		}
+	}
+}
+
+void do_while_break_in_finally() {
+	do {
+		try {} finally {
+			break;
+		}
+	} while (false);
+}
+
+void continue_in_finally() {
+	while (true) {
+		try {} finally {
+			continue;
+		}
+	}
+}
+
+void goto_in_finally() {
+	while (true) {
+		try {} finally {
+			goto end_of_function;
+		}
+	}
+	end_of_function: {}
+}
+
+void labelled_break_in_finally() {
+	mainLoop: while (true) {
+		try {} finally {
+			break mainLoop;
+		}
+	}
+}
+
+void labelled_continue_in_finally() {
+	mainLoop: while (true) {
+		try {} finally {
+			continue mainLoop;
+		}
+	}
+}
+
+void switch_break_in_finally() {
+	switch (1) {
+	case 1:
+		try {} finally {
+			break;
+		}
+	default:
+		break;
+	}
+}
+
+void choose_break_in_finally() {
+	choose (1) {
+	case 1:
+		try {} finally {
+			break;
+		}
+	default:
+		break;
+	}
+}
+
+void choose_fallthru_in_finally() {
+	choose (1) {
+	case 1:
+		try {} finally {
+			fallthru;
+		}
+	default:
+		break;
+	}
+}
+
+void labelled_choose_break_in_finally() {
+	mainBlock: choose (1) {
+	case 1:
+		try {} finally {
+			break mainBlock;
+		}
+	case 2:
+		break;
+	default:
+		break;
+	}
+}
+
+void labelled_choose_fallthru_in_finally() {
+	mainBlock: choose (1) {
+	case 1:
+		try {} finally {
+			fallthru mainBlock;
+		}
+	case 2:
+		break;
+	default:
+		break;
+	}
+}
+
+void choose_fallthru_default_in_finally() {
+	choose (1) {
+	case 1:
+		try {} finally {
+			fallthru default;
+		}
+	default:
+		break;
+	}
+}
+
+void void_return_in_finally() {
+	try {} finally {
+		return;
+	}
+}
+
+int value_return_in_finally() {
+	try {} finally {
+		return -7;
+	}
+
+}
+
+// Checked in the same place, make sure it does't break.
+void break_in_function() {
+	while (true) {
+		void inner() {
+			break;
+		}
+	}
+}
+
+void main() {
+	// Should not compile.
+	return 1;
+}
