•CurrentError
This commit is contained in:
parent
588350d85b
commit
5cde913c78
@ -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") \
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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
13
src/h.h
@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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; }
|
||||
|
||||
@ -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));
|
||||
|
||||
@ -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
|
||||
|
||||
9
src/vm.c
9
src/vm.c
@ -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)));
|
||||
}
|
||||
|
||||
2
src/vm.h
2
src/vm.h
@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user