catch errors
This commit is contained in:
parent
2d43489cd2
commit
889f633bd3
14
src/arith.c
14
src/arith.c
@ -4,7 +4,7 @@
|
||||
#define ffnx(name, expr, extra) B name(B t, B w, B x) { \
|
||||
if (isF64(w) & isF64(x)) return m_f64(expr); \
|
||||
extra \
|
||||
return err(#name ": invalid arithmetic"); \
|
||||
thrM(#name ": invalid arithmetic"); \
|
||||
}
|
||||
#define ffn(name, op, extra) ffnx(name, w.f op x.f, extra)
|
||||
|
||||
@ -51,12 +51,12 @@ B eq_c2(B t, B w, B x) {
|
||||
|
||||
|
||||
B add_c1(B t, B x) { return x; }
|
||||
B sub_c1(B t, B x) { if (isF64(x)) return m_f64( -x.f ); return err("negating non-number"); }
|
||||
B mul_c1(B t, B x) { if (isF64(x)) return m_f64(x.f?x.f>0?1:-1:0); return err("getting sign of non-number"); }
|
||||
B div_c1(B t, B x) { if (isF64(x)) return m_f64( 1/x.f ); return err("getting reciprocal of non-number"); }
|
||||
B pow_c1(B t, B x) { if (isF64(x)) return m_f64( exp(x.f)); return err("getting exp of non-number"); }
|
||||
B floor_c1(B t, B x) { if (isF64(x)) return m_f64(floor(x.f)); return err("getting floor of non-number"); }
|
||||
B log_c1(B t, B x) { if (isF64(x)) return m_f64( log(x.f)); return err("getting log of non-number"); }
|
||||
B sub_c1(B t, B x) { if (isF64(x)) return m_f64( -x.f ); thrM("negating non-number"); }
|
||||
B mul_c1(B t, B x) { if (isF64(x)) return m_f64(x.f?x.f>0?1:-1:0); thrM("getting sign of non-number"); }
|
||||
B div_c1(B t, B x) { if (isF64(x)) return m_f64( 1/x.f ); thrM("getting reciprocal of non-number"); }
|
||||
B pow_c1(B t, B x) { if (isF64(x)) return m_f64( exp(x.f)); thrM("getting exp of non-number"); }
|
||||
B floor_c1(B t, B x) { if (isF64(x)) return m_f64(floor(x.f)); thrM("getting floor of non-number"); }
|
||||
B log_c1(B t, B x) { if (isF64(x)) return m_f64( log(x.f)); thrM("getting log of non-number"); }
|
||||
B eq_c1(B t, B x) { B r = m_i32(isArr(x)? rnk(x) : 0); decR(x); return r; }
|
||||
|
||||
|
||||
|
||||
10
src/h.h
10
src/h.h
@ -6,6 +6,7 @@
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
#define i8 int8_t
|
||||
#define u8 uint8_t
|
||||
@ -20,6 +21,7 @@
|
||||
#define U16_MAX ((u16)-1)
|
||||
#define UD __builtin_unreachable();
|
||||
#define NOINLINE __attribute__ ((noinline))
|
||||
#define NORETURN __attribute__ ((noreturn))
|
||||
|
||||
#define usz u32
|
||||
#define ur u8
|
||||
@ -180,7 +182,6 @@ u64 mm_size(Value* x);
|
||||
|
||||
u64 mm_heapAllocated();
|
||||
u64 mm_heapUsed();
|
||||
|
||||
void mm_forHeap(V2v f);
|
||||
B mm_alloc(usz sz, u8 type, u64 tag) {
|
||||
assert(tag>1LL<<16 || tag==0); // make sure it's `ftag`ged :|
|
||||
@ -198,6 +199,13 @@ B m_v1(B a );
|
||||
B m_v2(B a, B b );
|
||||
B m_v3(B a, B b, B c );
|
||||
B m_v4(B a, B b, B c, B d);
|
||||
B m_str32(u32* s);
|
||||
NORETURN void thr(B b);
|
||||
NORETURN void thrM(char* s);
|
||||
jmp_buf* prepareCatch(); // use with `if (setjmp(prepareCatch())) { /*catch*/ } /*regular execution*/`
|
||||
void popCatch();
|
||||
B catchMessage;
|
||||
|
||||
|
||||
#define c(T,x) ((T*)((x).u&0xFFFFFFFFFFFFull))
|
||||
#define v(x) c(Value, x)
|
||||
|
||||
@ -167,6 +167,12 @@ int main() {
|
||||
// comp = m_funBlock(cbc_b, 0);
|
||||
// free(c_src);
|
||||
// }
|
||||
while (setjmp(*prepareCatch())) {
|
||||
printf("caught: ");
|
||||
print(catchMessage);
|
||||
puts("");
|
||||
dec(catchMessage);
|
||||
}
|
||||
while (true) { // exit by evaluating an empty expression
|
||||
char* ln = NULL;
|
||||
size_t gl = 0;
|
||||
|
||||
18
src/md1.c
18
src/md1.c
@ -1,7 +1,7 @@
|
||||
#include "h.h"
|
||||
|
||||
B tbl_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
if (!isArr(x)) return err("⌜: argument was atom");
|
||||
if (!isArr(x)) thrM("⌜: argument cannot be an atom");
|
||||
usz ia = a(x)->ia;
|
||||
if (ia==0) return x;
|
||||
BS2B xget = TI(x).get;
|
||||
@ -70,7 +70,7 @@ B tbl_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
|
||||
usz wia = a(w)->ia; ur wr = rnk(w);
|
||||
usz xia = a(x)->ia; ur xr = rnk(x);
|
||||
usz ria = wia*xia; ur rr = wr+xr;
|
||||
if (rr<xr) return err("⌜: result rank too large");
|
||||
if (rr<xr) thrM("⌜: required result rank too large");
|
||||
HArr_p r = m_harrp(ria);
|
||||
usz* rsh = arr_shAlloc(r.b, ria, rr);
|
||||
if (rsh) {
|
||||
@ -90,15 +90,14 @@ B tbl_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
|
||||
}
|
||||
dec(w); dec(x);
|
||||
return r.b;
|
||||
} else return err("⌜: one argument was an atom");
|
||||
} else thrM("⌜: 𝕨 and 𝕩 must be arrays");
|
||||
}
|
||||
|
||||
|
||||
B scan_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
if (!isArr(x)) return err("`: argument cannot be a scalar");
|
||||
if (!isArr(x) || rnk(x)==0) thrM("`: argument cannot have rank 0");
|
||||
ur xr = rnk(x);
|
||||
usz ia = a(x)->ia;
|
||||
if (xr==0) return err("`: argument cannot be a scalar");
|
||||
if (ia==0) return x;
|
||||
bool reuse = v(x)->type==t_harr && reusable(x);
|
||||
HArr_p r = reuse? harr_parts(inc(x)) : m_harrc(x);
|
||||
@ -115,23 +114,22 @@ B scan_c1(B d, B x) { B f = c(Md1D,d)->f;
|
||||
return r.b;
|
||||
}
|
||||
B scan_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
|
||||
if (!isArr(x)) return err("`: 𝕩 cannot be a scalar");
|
||||
if (!isArr(x) || rnk(x)==0) thrM("`: 𝕩 cannot have rank 0");
|
||||
ur xr = rnk(x); usz* xsh = a(x)->sh; usz ia = a(x)->ia;
|
||||
bool reuse = v(x)->type==t_harr && reusable(x);
|
||||
HArr_p r = reuse? harr_parts(inc(x)) : m_harrc(x);
|
||||
BS2B xget = reuse? TI(x).getU : TI(x).get;
|
||||
if (isArr(w)) {
|
||||
ur wr = rnk(w); usz* wsh = a(w)->sh; BS2B wget = TI(w).get;
|
||||
if (xr==0) return err("`: 𝕩 cannot be a scalar");
|
||||
if (wr+1 != xr) return err("`: shape of 𝕨 must match the cell of 𝕩");
|
||||
if (memcmp(wsh, xsh+1, wr)) return err("`: shape of 𝕨 must match the cell of 𝕩");
|
||||
if (wr+1 != xr) thrM("`: shape of 𝕨 must match the cell of 𝕩");
|
||||
if (memcmp(wsh, xsh+1, wr)) thrM("`: shape of 𝕨 must match the cell of 𝕩");
|
||||
if (ia==0) { ptr_dec(r.c); return x; } // only safe as r would have 0 items too
|
||||
usz csz = arr_csz(x);
|
||||
for (usz i = 0; i < csz; i++) r.a[i] = c2(f, wget(w,i), xget(x,i));
|
||||
for (usz i = csz; i < ia; i++) r.a[i] = c2(f, inc(r.a[i-csz]), xget(x,i));
|
||||
dec(w);
|
||||
} else {
|
||||
if (xr!=1) return err("`: if 𝕨 is scalar, 𝕩 must be a vector");
|
||||
if (xr!=1) thrM("`: shape of 𝕨 must match the cell of 𝕩");
|
||||
if (ia==0) { ptr_dec(r.c); return x; }
|
||||
B pr = r.a[0] = c2(f, w, xget(x,0));
|
||||
for (usz i = 1; i < ia; i++) r.a[i] = pr = c2(f, inc(pr), xget(x,i));
|
||||
|
||||
@ -37,7 +37,7 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
|
||||
u64 currObjCounter;
|
||||
#endif
|
||||
void* mm_allocN(usz sz, u8 type) {
|
||||
assert(sz>12);
|
||||
assert(sz>=16);
|
||||
onAlloc(sz, type);
|
||||
u8 b1 = 64-__builtin_clzl(sz-1ull);
|
||||
Value* r;
|
||||
|
||||
@ -23,7 +23,7 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
|
||||
u64 currObjCounter;
|
||||
#endif
|
||||
void* mm_allocN(usz sz, u8 type) {
|
||||
assert(sz>8);
|
||||
assert(sz>=16);
|
||||
onAlloc(sz, type);
|
||||
Value* r = mm_allocL(BSZI(sz), type);
|
||||
#ifdef OBJ_COUNTER
|
||||
|
||||
@ -56,20 +56,18 @@ static NOINLINE EmptyValue* BN(makeEmpty)(u8 bucket) { // result->next is garbag
|
||||
|
||||
void BN(free)(Value* x) {
|
||||
onFree(x);
|
||||
EmptyValue* c = (EmptyValue*) x;
|
||||
#ifdef DONT_FREE
|
||||
if (c->type!=t_freed) c->flags = c->type;
|
||||
#else
|
||||
u8 b = c->mmInfo&63;
|
||||
c->next = buckets[b];
|
||||
buckets[b] = c;
|
||||
#endif
|
||||
c->type = t_empty;
|
||||
#ifdef USE_VALGRIND
|
||||
VALGRIND_MAKE_MEM_NOACCESS(x, BSZ(c->mmInfo&63));
|
||||
VALGRIND_MAKE_MEM_DEFINED(&x->type, 1);
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(x, BSZ(x->mmInfo&63));
|
||||
VALGRIND_MAKE_MEM_DEFINED(&x->mmInfo, 1);
|
||||
#endif
|
||||
#ifdef DONT_FREE
|
||||
if (x->type!=t_freed) x->flags = x->type;
|
||||
#else
|
||||
u8 b = x->mmInfo&63;
|
||||
((EmptyValue*)x)->next = buckets[b];
|
||||
buckets[b] = (EmptyValue*)x;
|
||||
#endif
|
||||
x->type = t_empty;
|
||||
}
|
||||
|
||||
void* BN(allocL)(u8 bucket, u8 type) {
|
||||
|
||||
@ -107,15 +107,13 @@ B asrt_c1(B t, B x) {
|
||||
if (isI32(x) && 1==(i32)x.u) return x;
|
||||
if (isF64(x) && 1==x.f) return x;
|
||||
dec(x);
|
||||
return err("assertion error");
|
||||
thrM("assertion error");
|
||||
}
|
||||
B asrt_c2(B t, B w, B x) {
|
||||
if (isI32(x) && 1==(u32)x.u) { dec(w); return x; }
|
||||
if (isF64(x) && 1==x.f) { dec(w); return x; }
|
||||
dec(x);
|
||||
printf("Assertion error: "); fflush(stdout); print(w); printf("\n");
|
||||
dec(w);
|
||||
return err("assertion error with message");
|
||||
thr(w);
|
||||
}
|
||||
|
||||
B internal_c2(B t, B w, B x) {
|
||||
|
||||
57
src/vm.c
57
src/vm.c
@ -257,7 +257,7 @@ i32* vmStack;
|
||||
i32 bcCtr = 0;
|
||||
#endif
|
||||
|
||||
B* gStack;
|
||||
B* gStack; // points to after end
|
||||
B* gStackStart;
|
||||
B* gStackEnd;
|
||||
|
||||
@ -518,3 +518,58 @@ void print_vmStack() {
|
||||
printf("\n"); fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef struct CatchFrame {
|
||||
jmp_buf jmp;
|
||||
u64 gStackDepth;
|
||||
u64 cfDepth;
|
||||
} CatchFrame;
|
||||
CatchFrame* cf; // points to after end
|
||||
CatchFrame* cfStart;
|
||||
CatchFrame* cfEnd;
|
||||
|
||||
jmp_buf* prepareCatch() { // in the case of returning false, must call popCatch();
|
||||
if (cf==cfEnd) {
|
||||
u64 n = cfEnd-cfStart;
|
||||
n = n<8? 8 : n*2;
|
||||
u64 d = cfStart-cf;
|
||||
cfStart = realloc(cfStart, n*sizeof(CatchFrame));
|
||||
cf = cfStart+d;
|
||||
cfEnd = cfStart+n;
|
||||
}
|
||||
cf->cfDepth = cf-cfStart;
|
||||
cf->gStackDepth = gStack-gStackStart;
|
||||
return &(cf++)->jmp;
|
||||
}
|
||||
void popCatch() {
|
||||
assert(cf>cfStart);
|
||||
cf--;
|
||||
}
|
||||
|
||||
NORETURN void thr(B msg) {
|
||||
if (cf>cfStart) {
|
||||
catchMessage = msg;
|
||||
cf--;
|
||||
|
||||
B* gStackNew = gStackStart + cf->gStackDepth;
|
||||
if (gStackNew>gStack) err("bad catch gStack");
|
||||
// while (gStack!=gStackNew) dec(*--gStack);
|
||||
gStack = gStackNew;
|
||||
|
||||
cf = cfStart + cf->cfDepth;
|
||||
longjmp(cf->jmp, 1);
|
||||
printf("wat\n");
|
||||
}
|
||||
assert(cf==cfStart);
|
||||
printf("Error: ");
|
||||
print(msg);
|
||||
puts("");
|
||||
// exit(1);
|
||||
__builtin_trap();
|
||||
}
|
||||
|
||||
NORETURN void thrM(char* s) {
|
||||
thr(fromUTF8(s, strlen(s)));
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user