00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <basix/mmx_syntax.hpp>
00014 namespace mmx {
00015
00016 exception::exception (const string& msg, const generic& where):
00017 rep (gen (GEN_EXCEPTION, msg, where)) {}
00018
00019 generic
00020 std_exception (const string& msg, const generic& where) {
00021 return as<generic> (exception (gen (GEN_EXCEPTION, msg, where)));
00022 }
00023
00024 generic
00025 std_exception (const string& msg, const generic& a, const generic& where) {
00026 exception exc (gen (GEN_EXCEPTION, msg * flatten_as_mmx (a), where));
00027 return as<generic> (exc);
00028 }
00029
00030 generic
00031 user_exception (const vector<generic>& msg, const generic& w) {
00032 return as<generic> (exception (gen (GEN_EXCEPTION, as<generic> (msg), w)));
00033 }
00034
00035 generic
00036 wrong_nr_args (const generic& where) {
00037 return std_exception ("wrong number of arguments", where);
00038 }
00039
00040 generic
00041 type_mismatch (const generic& expect, const generic& where) {
00042 return std_exception ("expected ", expect, where);
00043 }
00044
00045 generic
00046 trace_push (const generic& exc, const generic& where) {
00047 generic msg= *as<exception> (exc);
00048 ASSERT (is_func (msg, GEN_EXCEPTION, 2), "invalid exception");
00049 generic w= gen (GEN_BACKTRACE, where, msg[2]);
00050 return as<generic> (exception (gen (msg[0], msg[1], w)));
00051 }
00052
00053 generic
00054 trace_pull (const generic& exc) {
00055 generic msg= *as<exception> (exc);
00056 ASSERT (is_func (msg, GEN_EXCEPTION, 2), "invalid exception");
00057 ASSERT (is_func (msg[2], GEN_BACKTRACE, 2), "backtrace expected");
00058 return as<generic> (exception (gen (msg[0], msg[1], msg[2][2])));
00059 }
00060
00061 generic
00062 trace_top (const generic& exc) {
00063 generic msg= *as<exception> (exc);
00064 ASSERT (is_func (msg, GEN_EXCEPTION, 2), "invalid exception");
00065 ASSERT (is_func (msg[2], GEN_BACKTRACE, 2), "backtrace expected");
00066 return as<generic> (exception (gen (msg[0], "backtrace", msg[2][1])));
00067 }
00068
00069 nat
00070 trace_depth (const generic& exc) {
00071 if (has_trace (exc)) return trace_depth (trace_pull (exc)) + 1;
00072 else return 1;
00073 }
00074
00075 generic
00076 trace_bottom (const generic& exc, nat n) {
00077 generic g= exc;
00078 nat d= trace_depth (exc);
00079 for (nat i=n; i<d; i++) g= trace_pull (g);
00080 return g;
00081 }
00082
00083 bool
00084 has_trace (const generic& exc) {
00085 if (!is<exception> (exc)) return false;
00086 generic msg= *as<exception> (exc);
00087 return
00088 is_func (msg, GEN_EXCEPTION, 2) &&
00089 is_func (msg[2], GEN_BACKTRACE, 2);
00090 }
00091
00092 }