Index: src/tests/except-2.c
===================================================================
--- src/tests/except-2.c	(revision 0ec92299f0bd3358cab9ec5e092ffa1fb4c73302)
+++ src/tests/except-2.c	(revision 0ec92299f0bd3358cab9ec5e092ffa1fb4c73302)
@@ -0,0 +1,120 @@
+// New draft of exception tests.
+
+
+#include <string.h>
+
+// Local Exception Types and manual vtable types.
+#define BASE_EXCEPT __cfaehm__base_exception_t
+#define TABLE(name) name##_vtable
+#define INSTANCE(name) _##name##_vtable_instance
+#define TRIVIAL_EXCEPTION(name) \
+struct name; \
+struct TABLE(name) { \
+	struct __cfaehm__base_exception_t_vtable const * parent; \
+	size_t size; \
+	void (*copy)(name *this, name * other); \
+	void (*free)(name *this); \
+	const char * (*msg)(name *this); \
+}; \
+extern TABLE(name) INSTANCE(name); \
+struct name { \
+	struct TABLE(name) const * virtual_table; \
+}; \
+const char * name##_msg(name * this) { \
+	return #name; \
+} \
+void name##_copy(name * this, name * other) { \
+	this->virtual_table = other->virtual_table; \
+} \
+TABLE(name) INSTANCE(name) @= { \
+	.parent : &INSTANCE(__cfaehm__base_exception_t), \
+	.size : sizeof(name), .copy : name##_copy, \
+	.free : ^?{}, .msg : name##_msg \
+}; \
+void ?{}(name * this) { \
+	this->virtual_table = &INSTANCE(name); \
+}
+TRIVIAL_EXCEPTION(yin)
+TRIVIAL_EXCEPTION(yang)
+
+struct num_error;
+struct num_error_vtable {
+	struct exception_t_vtable 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 ) {
+		const char * base = "Num Error with code: X";
+		this->msg = strdup( base );
+	}
+	this->msg[21] = '0' + this->num;
+	return this->msg;
+}
+void ?{}(num_error * this, int num) {
+	this->virtual_table = &_num_error_vtable_instance;
+	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 @= {
+	&___cfaehm__base_exception_t_vtable_instance,
+	sizeof(num_error), ?{}, ^?{},
+	num_error_msg, num_error_code
+};
+
+
+// Test simple throwing, matching and catching.
+void throw_catch() {
+	try {
+		yin black;
+		throw (BASE_EXCEPT *)&black;
+	} catch( yin * error ) {
+		printf("throw yin caught.\n");
+	}
+
+	try {
+		yang white;
+		throwResume (BASE_EXCEPT *)&white;
+		printf("> throwResume returned.\n");
+	} catchResume( yang * error ) {
+		printf("throwResume yang caught <");
+	}
+
+	/* Conditional catches are still a work in progress.
+	try {
+		num_error x = { 2 };
+		throw (struct exception_t *)&x;
+	}
+	catch (num_error * error0 ; 3 == error0->virtual_table->code( error0 ) ) {
+		printf("exception at %p\n", error0 );
+		printf("Should not be printed.\n");
+	}
+	catch (num_error * error1 ; 2 == error1->virtual_table->code( error1 ) ) {
+		printf("Should be printed.\n");
+	}*/
+}
+
+int main (int argc, char * argv[]) {
+	throw_catch();
+	return 0;
+}
