-
Notifications
You must be signed in to change notification settings - Fork 11
/
Exception.HC
89 lines (73 loc) · 1.85 KB
/
Exception.HC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#ifndef EXCEPTION_H
#define EXCEPTION_H
#include "PrimitiveTypes.HC"
#define EXCEPTION_CSTRING 0
#define EXCEPTION_MALVAL 1
// Forward declarations
extern class Malval;
extern class String;
extern Malval *MalStringMk(String *s);
extern String *StringMk(CHAR *c);
extern String *PrintMalval(Malval *m, BOOL print_readably, BOOL print_quotes);
// Exceptions are not garbage-collected even though they may contain
// Malvals which *are* GCed. So, the inner Malval isn't considered
// reachable by the GC and would be collected if the GC were to run
// during the lifetime of the exception, but I don't think it's possible
// for that to happen. The GC should never run while an exception is
// being propagated, and we shouldn't depend on the existence of the
// exception after catching it and continuing with evaluation.
class Exception
{
Malval *_malval;
};
Exception *GetException()
{
return Fs->except_ch;
}
VOID CatchException()
{
Fs->catch_except = TRUE;
}
VOID RethrowException()
{
Fs->catch_except = FALSE;
}
String *ExceptionString(Exception *e)
{
return PrintMalval(e->_malval, TRUE, FALSE);
}
Malval *ExceptionMalval(Exception *e)
{
return e->_malval;
}
Exception *ExceptionCStringMk(CHAR *c)
{
Exception *e = MAlloc(sizeof(Exception));
e->_malval = MalStringMk(StringMk(c));
return e;
}
Exception *ExceptionMalvalMk(Malval *v)
{
Exception *e = MAlloc(sizeof(Exception));
e->_malval = v;
return e;
}
CHAR *throws(CHAR *str)
{
Exception *e = ExceptionCStringMk(str);
// throw with no_log=TRUE. It seems to hang up sometimes otherwise,
// presumably somehow due to treating bytes of the pointer as chars.
throw(e, TRUE);
return 0; // make compiler stfu
}
CHAR *throwval(Malval *val)
{
Exception *e = ExceptionMalvalMk(val);
throw(e, TRUE);
return 0; // make compiler stfu
}
VOID ExceptionDelete(Exception *e)
{
Free(e);
}
#endif