•CurrentError

This commit is contained in:
dzaima 2022-01-08 21:55:19 +02:00
parent 588350d85b
commit 5cde913c78
11 changed files with 84 additions and 23 deletions

View File

@ -9,7 +9,7 @@
/* sort.c*/A(gradeUp,"") A(gradeDown,"") \
/* everything before the definition of •Type is defined to be pure, and everything after is not */ \
/* sysfn.c*/M(type,"•Type") M(decp,"•Decompose") M(primInd,"•PrimInd") M(glyph,"•Glyph") A(fill,"•FillFn") M(sys,"•getsys") A(grLen,"•GroupLen") D(grOrd,"•GroupOrd") \
/* sysfn.c*/M(repr,"•Repr") M(fmt,"•Fmt") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") A(bqn,"•BQN") A(sh,"•SH") M(fromUtf8,"•FromUTF8") \
/* sysfn.c*/M(repr,"•Repr") M(fmt,"•Fmt") A(asrt,"!") A(casrt,"!") M(out,"•Out") M(show,"•Show") A(bqn,"•BQN") A(sh,"•SH") M(fromUtf8,"•FromUTF8") M(currentError,"•CurrentError") \
/* sysfn.c*/D(cmp,"•Cmp") A(hash,"•Hash") M(unixTime,"•UnixTime") M(monoTime,"•MonoTime") M(delay,"•Delay") M(makeRand,"•MakeRand") M(reBQN,"•ReBQN") M(exit,"•Exit") M(getLine,"•GetLine") \
/* inverse.c*/M(setInvReg, "(SetInvReg)") M(setInvSwap, "(SetInvSwap)") M(nativeInvReg, "(NativeInvReg)") M(nativeInvSwap, "(NativeInvSwap)") \
/*internal.c*/M(itype,"•internal.Type") M(elType,"•internal.ElType") M(refc,"•internal.Refc") M(isPure,"•internal.IsPure") A(info,"•internal.Info") \

View File

@ -13,7 +13,7 @@ static B homFil1(B f, B r, B xf) {
if (f.u==bi_eq.u || f.u==bi_ne.u || f.u==bi_feq.u) { dec(xf); return toI32Any(r); } // ≠ may return ≥2⋆31, but whatever, this thing is stupid anyway
if (f.u==bi_fne.u) { dec(xf); return withFill(r, m_harrUv(0).b); }
if (!noFill(xf)) {
if (CATCH) { dec(catchMessage); return r; }
if (CATCH) { freeThrown(); return r; }
B rf = asFill(c1(f, xf));
popCatch();
return withFill(r, rf);
@ -27,7 +27,7 @@ static B homFil2(B f, B r, B wf, B xf) {
if (isPureFn(f)) {
if (f.u==bi_feq.u || f.u==bi_fne.u) { dec(wf); dec(xf); return toI32Any(r); }
if (!noFill(wf) && !noFill(xf)) {
if (CATCH) { dec(catchMessage); return r; }
if (CATCH) { freeThrown(); return r; }
B rf = asFill(c2(f, wf, xf));
popCatch();
return withFill(r, rf);

View File

@ -11,12 +11,30 @@ B val_c1(Md2D* d, B x) { return c1(d->f, x); }
B val_c2(Md2D* d, B w, B x) { return c2(d->g, w,x); }
typedef struct CustomObj {
struct Value;
V2v visit;
V2v freeO;
} CustomObj;
void* customObj(u64 size, V2v visit, V2v freeO) {
CustomObj* r = mm_alloc(size, t_customObj);
r->visit = visit;
r->freeO = freeO;
return r;
}
void customObj_visit(Value* v) { ((CustomObj*)v)->visit(v); }
void customObj_freeO(Value* v) { ((CustomObj*)v)->freeO(v); }
void customObj_freeF(Value* v) { ((CustomObj*)v)->freeO(v); mm_free(v); }
#if CATCH_ERRORS
extern B lastErrMsg; // sysfn.c
B fillBy_c1(Md2D* d, B x) {
B xf=getFillQ(x);
B r = c1(d->f, x);
if(isAtm(r) || noFill(xf)) { dec(xf); return r; }
if (CATCH) { dec(catchMessage); return r; }
if (CATCH) { freeThrown(); return r; }
B fill = asFill(c1(d->g, xf));
popCatch();
return withFill(r, fill);
@ -25,14 +43,29 @@ B fillBy_c2(Md2D* d, B w, B x) {
B wf=getFillQ(w); B xf=getFillQ(x);
B r = c2(d->f, w,x);
if(isAtm(r) || noFill(xf)) { dec(xf); dec(wf); return r; }
if (CATCH) { dec(catchMessage); return r; }
if (CATCH) { freeThrown(); return r; }
if (noFill(wf)) wf = incG(bi_asrt);
B fill = asFill(c2(d->g, wf, xf));
popCatch();
return withFill(r, fill);
}
B catch_c1(Md2D* d, B x) { if(CATCH) { dec(catchMessage); return c1(d->g, x); } inc(x); B r = c1(d->f, x); popCatch(); dec(x); return r; }
B catch_c2(Md2D* d, B w, B x) { if(CATCH) { dec(catchMessage); return c2(d->g, w,x); } inc(w); inc(x); B r = c2(d->f, w,x); popCatch(); dec(w); dec(x); return r; }
typedef struct ReObj {
struct CustomObj;
B msg;
} ReObj;
void re_visit(Value* v) { mm_visit(((ReObj*)v)->msg); }
void re_freeO(Value* v) { dec(lastErrMsg); lastErrMsg = ((ReObj*)v)->msg; }
void pushRe() {
ReObj* o = customObj(sizeof(ReObj), re_visit, re_freeO);
o->msg = lastErrMsg;
gsAdd(tag(o,OBJ_TAG));
lastErrMsg = inc(thrownMsg);
freeThrown();
}
B catch_c1(Md2D* d, B x) { if(CATCH) { pushRe(); B r = c1(d->g, x); dec(gsPop()); return r; } inc(x); B r = c1(d->f, x); popCatch(); dec(x); return r; }
B catch_c2(Md2D* d, B w, B x) { if(CATCH) { pushRe(); B r = c2(d->g, w,x); dec(gsPop()); return r; } inc(w); inc(x); B r = c2(d->f, w,x); popCatch(); dec(w); dec(x); return r; }
#else
B fillBy_c1(Md2D* d, B x) { return c1(d->f, x); }
B fillBy_c2(Md2D* d, B w, B x) { return c2(d->f, w,x); }
@ -265,5 +298,8 @@ void md2_init() {
TIi(t_md2BI,print) = print_md2BI;
TIi(t_md2BI,m2_uc1) = md2BI_uc1;
TIi(t_md2BI,m2_ucw) = md2BI_ucw;
TIi(t_customObj,freeO) = customObj_freeO;
TIi(t_customObj,freeF) = customObj_freeF;
TIi(t_customObj,visit) = customObj_visit;
c(BMd2,bi_before)->uc1 = before_uc1;
}

View File

@ -555,6 +555,17 @@ B repl_c1(B t, B x) {
return repl_c2(t, emptyHVec(), x);
}
#if CATCH_ERRORS
B lastErrMsg;
B currentError_c1(B t, B x) {
dec(x);
if (q_N(lastErrMsg)) thrM("•CurrentError: Not currently within any ⎊");
return inc(lastErrMsg);
}
#else
B currentError_c1(B t, B x) { thrM("•CurrentError: No errors as error catching has been disabled"); }
#endif
static NFnDesc* fileAtDesc;
B fileAt_c1(B d, B x) {
return path_rel(nfn_objU(d), x);
@ -654,6 +665,10 @@ B import_c1(B d, B x) {
static void sys_gcFn() {
mm_visit(importKeyList);
mm_visit(importValList);
mm_visit(thrownMsg);
#if CATCH_ERRORS
mm_visit(lastErrMsg);
#endif
}
@ -857,6 +872,7 @@ B sys_c1(B t, B x) {
else if (eqStr(c, U"fbytes")) cr = m_nfn(fBytesDesc, inc(REQ_PATH));
else if (eqStr(c, U"flines")) cr = m_nfn(fLinesDesc, inc(REQ_PATH));
else if (eqStr(c, U"import")) cr = m_nfn(importDesc, inc(REQ_PATH));
else if (eqStr(c, U"currenterror")) cr = inc(bi_currentError);
else if (eqStr(c, U"state")) {
if (q_N(comp_currArgs)) thrM("No arguments present for •state");
cr = m_hVec3(inc(REQ_PATH), inc(REQ_NAME), inc(comp_currArgs));
@ -876,6 +892,9 @@ B sys_c1(B t, B x) {
B cdPath;
void sysfn_init() {
#if CATCH_ERRORS
lastErrMsg = bi_N;
#endif
cdPath = m_str8(1, "."); gc_add(cdPath); gc_addFn(sys_gcFn);
fCharsDesc = registerNFn(m_str8l("(file).Chars"), fchars_c1, fchars_c2);
fileAtDesc = registerNFn(m_str8l("(file).At"), fileAt_c1, fileAt_c2);

13
src/h.h
View File

@ -203,11 +203,11 @@ typedef union B {
\
/*32*/ F(comp) F(block) F(body) F(scope) F(scopeExt) F(blBlocks) \
/*38*/ F(ns) F(nsDesc) F(fldAlias) F(vfyObj) F(hashmap) F(temp) F(nfn) F(nfnDesc) \
/*46*/ F(freed) F(harrPartial) \
/*48*/ F(fun_invReg ) F(md1_invReg ) F(md2_invReg ) \
/*51*/ F(fun_invSwap) F(md1_invSwap) F(md2_invSwap) \
/*46*/ F(freed) F(harrPartial) F(customObj) \
/*49*/ F(fun_invReg ) F(md1_invReg ) F(md2_invReg ) \
/*52*/ F(fun_invSwap) F(md1_invSwap) F(md2_invSwap) \
\
/*54*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap))
/*55*/ IF_WRAP(F(funWrap) F(md1Wrap) F(md2Wrap))
enum Type {
#define F(X) t_##X,
@ -332,12 +332,13 @@ NOINLINE NORETURN void thrF(char* s, ...);
NOINLINE NORETURN void thrOOM(void);
jmp_buf* prepareCatch(void);
#if CATCH_ERRORS
#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error*/ dec(catchMessage); return; } /*potentially erroring thing*/ popCatch(); /*no errors yay*/`
#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error*/ freeThrown(); return; } /*potentially erroring thing*/ popCatch(); /*no errors yay*/`
#else // note: popCatch() must always be called if no error was caught, so no returns before it!
#define CATCH false
#endif
void popCatch(void);
extern B catchMessage;
extern B thrownMsg;
void freeThrown(void);

View File

@ -152,9 +152,9 @@ int main(int argc, char* argv[]) {
if (startREPL) {
repl_init();
while (CATCH) {
printf("Error: "); printErrMsg(catchMessage); putchar('\n');
printf("Error: "); printErrMsg(thrownMsg); putchar('\n');
vm_pst(envCurr+1, envStart+envPrevHeight);
dec(catchMessage);
freeThrown();
#ifdef HEAP_VERIFY
heapVerify();
#endif

View File

@ -26,9 +26,9 @@ static void mm_visitP(void* x) { }
void gc_add(B x);
void gc_addFn(vfn f);
void gc_maybeGC();
void gc_forceGC();
void gc_visitRoots();
void gc_maybeGC(void);
void gc_forceGC(void);
void gc_visitRoots(void);
void mm_forHeap(V2v f);
static u64 mm_round(usz x) { return x; }

View File

@ -28,7 +28,7 @@ static inline B arith_recd(BBB2B f, B w, B x) {
B fw = getFillQ(w);
B r = eachd_fn(f, bi_N, w, x);
if (noFill(fw)) return r;
if (CATCH) { dec(catchMessage); return r; }
if (CATCH) { freeThrown(); return r; }
B fr = f(bi_N, fw, fx);
popCatch();
return withFill(r, asFill(fr));

View File

@ -11,7 +11,7 @@ I8Arr* file_bytes(B path); // consumes
B file_chars(B path); // consumes
B file_lines(B path); // consumes
I8Arr* stream_bytes();
I8Arr* stream_bytes(FILE* f);
void file_wChars(B path, B x); // consumes path
void file_wBytes(B path, B x); // consumes path

View File

@ -59,7 +59,7 @@ void print_BCStream(u32* p) {
}
B catchMessage;
B thrownMsg;
u64 envPrevHeight;
Env* envCurr; // pointer to current environment; included to make for simpler current position updating
@ -1217,7 +1217,7 @@ NOINLINE NORETURN void thr(B msg) {
// while (c>gStackStart) { print(*--c); putchar('\n'); } printf("gStack printed\n");
if (cf>cfStart) { // something wants to catch errors
catchMessage = msg;
thrownMsg = msg;
cf--;
B* gStackNew = gStackStart + cf->gsDepth;
@ -1244,6 +1244,11 @@ NOINLINE NORETURN void thr(B msg) {
}
}
NOINLINE void freeThrown() {
dec(thrownMsg);
thrownMsg = bi_N;
}
NOINLINE NORETURN void thrM(char* s) {
thr(fromUTF8(s, strlen(s)));
}

View File

@ -228,7 +228,7 @@ NOINLINE B vm_fmtPoint(B src, B prepend, B path, usz cs, usz ce); // consumes pr
NOINLINE void printErrMsg(B msg);
NOINLINE void unwindEnv(Env* envNew); // envNew==envStart-1 for emptying the env stack
NOINLINE void unwindCompiler(void); // unwind to the env of the invocation of the compiler; UB when not in compiler!
usz getPageSize();
usz getPageSize(void);