Index: doc/working/exception/design.txt
===================================================================
--- doc/working/exception/design.txt	(revision 6b72040296be75249261867928ffda1eb2a66bd4)
+++ doc/working/exception/design.txt	(revision 465ed183eb041fa90a4d6647a205765d9d894c05)
@@ -1,123 +1,105 @@
 Design of Exceptions and EHM in Cforall:
 
-Currently this is a combination of ideas and big questions that still have to
-be addressed. It also includes some other error handling options, how they
-interact and compare to exceptions.
+
+Exception Instances:
+Currently, exceptions are integers (like errno).
+
+They are planned to be the new "tagged structures", which allows them to
+exist in a simple hierarchy which shared functionality throughout. However
+the tagged structures are not yet implemented so that will wait.
+
+A single built in exception is at the top of the hierarchy and all other
+exceptions are its children. When you match against an exception, you match
+for an exception and its children, so the top of the hierarchy is used as a
+catch-all option.
+
+The shared functionality across exceptions has not been finalized, but will
+probably include things like human readable descriptions and default handlers.
 
 
-What is an Exception:
+Throwing:
+There are currently two kinds of throws, "throw" for termination and
+"throwResume" for resumption. Both keywords can be used to create a throw
+statement. The kind of throw decides what handlers may catch the exception
+and weither control flow can return to the throw site.
 
-In other words what do we throw? What is matched against, how does it carry
-data with it? A very important question that has not been answered.
+Syntax
+"throw" exception ";"
+"throwResume" exception ";"
 
-Option 1: Strutures
+Non-local throws are allowed for resumption only. A target is an object with
+a stack, with which it may propagate and handle the exception.
 
-Considering the current state of Cforall the most natural form of the
-exception would likely be a struture, implementing a trait repersenting the
-minimum features of an exception. This has many advantages, including arbitray
-fields, some polymorphism and it matches exceptations of many current systems.
+Syntax
+"throwResume" exception "_At" target ";"
 
-The main issue with this is matching, without OOP inheritance there is no
-exception hierarchy. Meaning all handling has to happen on the exact exception
-without the ease of grouping parents. There are several ways to attempt to
-recover this.
-
-The first is with conditional matching (a check after the type has been
-matched) which allows for matching particular values of a known type. However
-this does not dynamically expand and requires an extra step (as opposed to
-mearly allowing one). I would not recomend this as the primary method.
-
-Second is to try and use type casts/conversions to create an implicate
-hierachy, so that a catch clause catches anything of the given type or
-anything that converts to the given type.
-
-Plan9 (from what I know of it) would be a powerful tool here. Even with it,
-creating a hierarchy of types at runtime might be too expencive. Esecially
-since they are less likely to be tree like at that point.
-
-Option 2: Tags
-
-The other option is to introduce a new construct into the language. A tag
-repersents a type of exception, it is not a structure or variable (or even
-a normal type). It may be usable in some of those contexts.
-
-Tags can declare an existing tag as its parent. Tags can be caught by handlers
-that catch their parents. (There is a single base_exception that all other
-exceptions are children of eventually.) This allows for grouping of exceptions
-that repersent similar errors.
-
-Tags should also have some assotiated data, where and on what did the error
-occur. Keeping with the otherness of exception tags and allowing them to be
-expanded, using a parameter list. Each exception can have a list of paramters
-given to it on a throw. Each tag would have a declared list of parameters
-(which could be treated more like a set of fields as well). Child tags must
-use their parent's list as a prefix to their own, so that the parameters can
-be accessed when the child tag is matched against the parent.
-
-Option N: ...
-
-This list is not complete.
+Termination throws unwind the stack until a handler is reached, control moves
+onwards from the end of the handler. Resumption throws do not unwind, if a
+handler is found and control will return to the throw after the exception is
+handled.
 
 
-Seperating Termination and Resumption:
+Catching:
+The catch and handle of an exception is preformed with a try statement, which
+also can have finally clauses to exceute on exit from the scope.
 
-Differentating the types of exceptions based on exception would be hard with
-exceptions as structures. It is possible with exceptions as tags by having
-two base exceptions, one for each type of throw. However recompining them
-to dual types would be harder.
+Syntax
+"try"
+	try-block
+( ("catch" | "catchResume")
+  "(" exception_type [identifier] [";" conditional_expression] ")"
+	catch-block
+)*
+("finally"
+	finally-block
+)?
 
-Reguardless, using different keywords would also be useful for clarity, even
-if it does not add functality. Using the C++ like keywords would be a good
-base. Resumption exceptions could use a different set (ex. raise->handle) or
-use resume as a qualifier on the existing statements.
+Either at least 1 handler clause or the finally clasue must be given on each
+try block. Each handler clause handles 1 of the two types of throws. Each
+handler also specifies a type of exception it handles, and will handle all
+children exceptions as well. In addition, a conditional expression which, if
+included, must be true for the handler to catch the exception.
+
+The two types of handlers may be intermixed. Multiple handlers catching the
+same type may also be used, to allow for fallbacks on false conditionals.
 
 
-Conditional Matching:
+Implementation Overview:
 
-A possible useful feature, it allows for arbitrary checks on a catch block
-instead of merely matching a type. However there are few use cases that
-cannot be avoided with proper use of a type hierarchy, and this shrinks even
-further with a good use of re-throws.
+The implementation has two main parts. The first is just a collection of the
+support definitions we need, the data types and functions used within the
+exception handling code. Second is a translation from Cforall code to C code
+that uses those definitions to throw, catch and handle exceptions.
 
-Also it assumes one sweep, that might also be a problem. But might also give
-it an advantage over re-throws.
+Termination handlers call a specially annotated function, passing it inner
+functions that act as the varius sub-blocks. Termination throws use the
+unwind library that checks the underlying code for those annotations. Each
+time one is found some magic is used to check for a matching handler, if one
+is found control goes to the special function which excecutes the handler and
+returns.
+
+Resumption handlers maintain a linked list of stack allocated nodes that have
+the handler functions attached. Throwing a resumption exception traverses this
+list, and calls each handler, the handlers handle the exception if they can
+and return if they did or not.
+
+Finally clauses just use stack cleanup to force a nested function, which has
+the code from the finally clause, to execute when we leave that section.
 
 
-Alternatives: Implicate Handlers & Return Unions
+Alternative Error Handling: Return Unions
 
-Both act as a kind of local version of an exception. Implicate handlers act as
-resumption exceptions and return unions like termination exceptions. By local
-I mean they work well at one or two levels of calls, but do not cover N levels
-as cleanly.
+Return unions (Maybe and Result), are types that can encode a success or
+other result in a single value. Maybe stores a value or nothing, Result stores
+a value or an error.
 
-Implicate handles require a growing number of function pointers (which should
-not be used very often) to be passed to functions, creating and additional
-preformance cost. Return unions have to be checked and handled at every level,
-which has some preformance cost, but also can significantly clutter code.
-Proper tools can help with the latter.
+For errors that are usually handled quite close to where they occur, these
+can replace exceptions.
 
-However, they may work better at that local level as they do not require stack
-walking or unwinding. In addition they are closer to regular control flow and
-are easier to staticly check. So even if they can't replace exceptions
-(directly) they may still be worth using together.
-
-For instance, consider the Python iterator interface. It uses a single
-function, __next__, to access the next value and to signal the end of the
-sequence. If a value is returned, it is the next value, if the StopIteration
-exception is thrown the sequence has finished.
-
-However almost every use of an iterator will add a try-except block around the
-call site (possibly through for or next) to catch and handle the exception
-immediately, ignoring the advantages of more distant exception handling.
-
-In this case it may be cleaner to use a Maybe for both cases (as in Rust)
-which gives similar results without having to jump to the exception handler.
-This will likely handle the error case more efficiently and the success case a
-bit less so.
-
-It also mixes the error and regular control flow, which can hurt readablity,
-but very little if the handling is simple, for instance providing a default
-value. Similarly, if the error (or alternate outcome) is common enough
-encoding it in the function signature may be good commuication.
+They tend to be faster and require similar or less amounts of code to handle.
+However they can slow down the normal path with some extra conditionals and
+can mix the normal and exceptional control flow path. If handling the error
+is simple, and happens relatively frequently, this might be prefered but in
+other cases it just hurts speed and readability.
 
 In short, these errors seem to be more effective when errors are likely and
@@ -125,16 +107,13 @@
 be handled locally, might be better off using these instead of exceptions.
 
-Also the implicate handlers and return unions could use exceptions as well.
-For instance, a useful default might handler might be to throw an exception,
-seaching up the stack for a solution if one is not locally provided.
-
-Or here is a possible helper for unpacking a Result value:
+Also the return unions could use exceptions as well. Getting the improper
+side of a return union might throw an exception. Or we can provide helpers
+for results withe exceptions as in:
 		forall(otype T, otype E | exception(E))
 		T get_or_throw (Result(T, E) * this) {
-			if (is_success(this)) {
-				return get_success(this);
+			if (has_value(this)) {
+				return get_value(this);
 			} else {
-				throw get_failure(this);
+				throw get_error(this);
 			}
 		}
-So they can feed off of each other.
Index: doc/working/exception/translate.c
===================================================================
--- doc/working/exception/translate.c	(revision 465ed183eb041fa90a4d6647a205765d9d894c05)
+++ doc/working/exception/translate.c	(revision 465ed183eb041fa90a4d6647a205765d9d894c05)
@@ -0,0 +1,248 @@
+/* Translation rules for exception handling code, from Cforall to C.
+ *
+ * Note that these are not final. Names, syntax and the exact translation
+ * will be updated. The first section is the shared definitions we will have
+ * to have access to where the translations are preformed.
+ */
+
+// Currently it is a typedef for int, but later it will be the root of the
+// hierarchy and so have to be public.
+typedef int exception;
+
+// These might be given simpler names and made public.
+void __throw_terminate(exception except) __attribute__((noreturn));
+void __throw_resume(exception except);
+
+void __try_terminate(void (*try_block)(),
+	void (*catch_block)(int index, exception except),
+	int (*match_block)(exception except));
+
+struct __try_resume_node {
+	struct __try_resume_node * next;
+	bool (*try_to_handle)(exception except);
+};
+
+struct __cleanup_hook {};
+
+// An instance of the following must be paired with every stack.
+struct stack_exception_data {
+	__try_resume_node * top_resume_data;
+	// Other pointers may be required for re-resume.
+
+	exception current_exception;
+	int handler_index;
+};
+
+
+// Translations:
+
+// Throws:
+"Cforall"
+
+throw exception_instance;
+
+resume exception_instance;
+
+"C"
+
+__throw_terminate(exception_instance);
+
+__throw_resume(exception_instance);
+
+
+// Termination Handlers:
+"Cforall"
+
+void try_terminate() {
+	try {
+		insideTry();
+	}
+	catch (SomeException) {
+		fiddleThing();
+	}
+	catch (OtherException err ; err.priority > 3) {
+		twiddleWidget();
+	}
+}
+
+"C"
+
+void try_terminate() {
+	{
+		void try1() {
+			insideTry();
+		}
+		// index is not nessasary, but should be much faster than going over
+		// all the checks in if we can find a way to pass it in.
+		void catch1(exception except, int index) {
+			switch (index) {
+			case 1:
+				// if it is referenced in the handler, cast except.
+				{
+					fiddleThing();
+				}
+				return;
+			case 2:
+				{
+					twiddleWidget();
+				}
+				return;
+			default:
+				// Error, should never be reached.
+			}
+		}
+		int match1(exception except) {
+			OtherException inner_except;
+			if (dynamic_cast__SomeException(except)) {
+				return 1;
+			}
+			else if ( (inner_except = dynamic_cast__OtherException(except)) &&
+					inner_except.priority > 3) {
+				return 2;
+			}
+			else return 0;
+		}
+		__try_terminate(try1, catch1, match1);
+	}
+}
+
+
+// Resumption Handlers:
+"Cforall"
+
+void try_resume() {
+	try {
+		insideTry();
+	}
+	catch resume (SomeException) {
+		fiddleThing();
+	}
+	catch resume (OtherException err ; err.priority > 3) {
+		twiddleWidget();
+	}
+}
+
+"C"
+
+void try_resume() {
+	{
+		bool catch1(exception except) {
+			OtherException inner_except;
+			if (dynamic_cast__SomeException(except)) {
+				fiddleThing();
+				return true;
+			} else if (dynamic_cast__OtherException(except) &&
+					inner_except.priority > 3) {
+				twiddleWidget();
+				return true;
+			} else {
+				return false;
+			}
+		}
+		struct __try_resume_node data =
+			{.next = stack.except.top_resume, .try_to_handle = catch1};
+		stack.except.top_resume = &data;
+
+		struct __cleanup_hook generated_name
+			__attribute__((cleanup(__try_resume_cleanup)));
+
+		{
+			insideTry();
+		}
+	}
+}
+
+
+// Finally Clause:
+"Cforall"
+
+void try_finally() {
+	try {
+		insideTry();
+	}
+	finally {
+		twiddleWidget();
+	}
+}
+
+"C"
+
+void try_finally() {
+	{
+		void finally1()	{
+			twiddleWidget();
+		}
+
+		struct __cleanup_hook generated_name
+			__attribute__((cleanup(finally1)));
+
+		{
+			insideTry();
+		}
+	}
+}
+
+
+// Combining the Above:
+"Cforall"
+
+void try_all() {
+	try {
+		insideTry();
+	}
+	catch (SomeException) {
+		fiddleThing();
+	}
+	catch resume (OtherException) {
+		twiddleWidget();
+	}
+	finally {
+		twiddleWidget();
+	}
+}
+
+"C"
+
+void try_all() {
+	{
+		void try1 () {
+			insideTry();
+		}
+		void catch1(exception except, int index) {
+			switch (index) {
+			case 1:
+				fiddleThing();
+				break;
+			default:
+				// Error if reached.
+			}
+		}
+		int match1(exception except) {
+			if (dynamic_cast__SomeException(except)) {
+				return 1;
+			}
+			return 0;
+		}
+		bool catch2() {
+			if (dynamic_cast__OtherException(except)) {
+				twiddleWidget();
+				return true;
+			}
+			return false;
+		}
+		void finally1() {
+			// (Finally, because of timing, also work for resume.)
+			__try_resume_cleanup();
+
+			twiddleWidget();
+		}
+
+		struct __try_resume_node generated_name =
+			{.next = stack.except.top_resume, .try_to_handle = catch2};
+		stack.except.top_resume = &data;
+		struct __cleanup_hook generated_name
+			__attribute__((cleanup(finally1)));
+
+		__try_terminate(try1, catch1, match1);
+	}
+}
