fancy error messages

This commit is contained in:
dzaima 2021-05-19 13:44:46 +03:00
parent 0b34c96a51
commit ffbb6ce601
10 changed files with 172 additions and 45 deletions

View File

@ -46,6 +46,13 @@ B m_str8(usz sz, char* s) {
for (u64 i = 0; i < sz; i++) rp[i] = (u32)s[i];
return r;
}
B m_str8l(char* s) {
usz sz = strlen(s);
u32* rp; B r = m_c32arrv(&rp, sz);
for (u64 i = 0; i < sz; i++) rp[i] = (u32)s[i];
return r;
}
NOINLINE B m_str32(u32* s) {
usz sz = 0; while(s[sz]) sz++;
u32* rp; B r = m_c32arrv(&rp, sz);
@ -93,4 +100,6 @@ static inline void c32arr_init() {
ti[t_i32arr].arrD1 = true; ti[t_i32slice].arrD1 = true;
ti[t_c32arr].elType = el_c32; ti[t_c32slice].elType = el_c32;
ti[t_c32arr].canStore = c32arr_canStore;
u32* tmp; bi_emptyCVec = m_c32arrv(&tmp, 0);
gc_add(bi_emptyCVec);
}

View File

@ -9,7 +9,7 @@ TmpFile* file_bytes(B path) { // consumes; may throw
toUTF8(path, p);
p[plen] = 0;
FILE* f = fopen(p, "r");
if (f==NULL) thrM("Couldn't read file");
if (f==NULL) thrF("Couldn't read file \"%R\"", path);
fseek(f, 0, SEEK_END);
u64 len = ftell(f);
fseek(f, 0, SEEK_SET);

View File

@ -41,8 +41,8 @@ B ud_c1(B t, B x) {
}
BS2B xgetU = TI(x).getU;
usz xia = a(x)->ia;
if (rnk(x)!=1) thrM("↕: Argument must be a vector");
if (xia>UR_MAX) thrM("↕: Result rank too large");
if (rnk(x)!=1) thrF("↕: Argument must be either an integer or integer list (had rank %i)", rnk(x));
if (xia>UR_MAX) thrF("↕: Result rank too large (%s≡≠𝕩)", xia);
usz sh[xia];
usz ria = 1;
for (usz i = 0; i < xia; i++) {

View File

@ -31,6 +31,7 @@
#define f64 double
#define I32_MAX ((i32)((1LL<<31)-1))
#define I32_MIN ((i32)(-(1LL<<31)))
#define I64_MIN ((i64)(-(1LL<<63)))
#define CHR_MAX 1114111
#define U16_MAX ((u16)~(u16)0)
#define U32_MAX ((u32)~(u32)0)
@ -231,6 +232,7 @@ void gsAdd(B x); // may throw
B gsPop();
// some primitive actions
B bi_N, bi_noVar, bi_badHdr, bi_optOut, bi_noFill, bi_emptyHVec, bi_emptyIVec, bi_emptyCVec;
void dec(B x);
B inc(B x);
void ptr_dec(void* x);
@ -248,6 +250,7 @@ bool atomEqual(B w, B x); // doesn't consume
B toCells(B x); // consumes
B toKCells(B x, ur k); // consumes
B withFill(B x, B f); // consumes both
B vec_join(B w, B x); // consumes both
bool eqShPrefix(usz* w, usz* x, ur len);
B m_v1(B a ); // consumes all
@ -263,10 +266,11 @@ B bqn_execFile(B path, B args); // consumes
NOINLINE NORETURN void thr(B b);
NOINLINE NORETURN void thrM(char* s);
#define thrF(...) thr(append_fmt(inc(bi_emptyCVec), __VA_ARGS__))
NOINLINE NORETURN void thrOOM();
jmp_buf* prepareCatch();
#ifdef CATCH_ERRORS
#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error; dec(catchMessage);*/ } /*potentially erroring thing*/ popCatch();`
#define CATCH setjmp(*prepareCatch()) // use as `if (CATCH) { /*handle error*/ dec(catchMessage); } /*potentially erroring thing*/ popCatch();`
#else // note: popCatch() must always be called if no error was caught, so no returns before it!
#define CATCH false
#endif
@ -448,8 +452,6 @@ TypeInfo ti[t_COUNT];
#define TI(x) (ti[v(x)->type])
B bi_N, bi_noVar, bi_badHdr, bi_optOut, bi_noFill, bi_emptyHVec, bi_emptyIVec;
bool isNothing(B b) { return b.u==bi_N.u; }
// refcount

View File

@ -157,6 +157,10 @@ int main(int argc, char* argv[]) {
printf("Error: "); print(catchMessage); putchar('\n');
vm_pst(envCurr, envStart+envPrevHeight);
dec(catchMessage);
#ifdef HEAP_VERIFY
heapVerify();
#endif
gc_maybeGC();
}
B replPath = m_str32(U"REPL"); gc_add(replPath);
while (true) { // exit by evaluating an empty expression
@ -187,11 +191,9 @@ int main(int argc, char* argv[]) {
#endif
#ifdef HEAP_VERIFY
heapVerify();
heapVerify();
#endif
gc_maybeGC();
#ifdef DEBUG
#endif
}
popCatch();
}

View File

@ -64,7 +64,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) thrM("⌜: Required result rank too large");
if (rr<xr) thrF("⌜: Required result rank too large (%i≡=𝕨, %i≡=𝕩)", wr, xr);
BS2B wgetU = TI(w).getU;
BS2B xget = TI(x).get;
@ -136,15 +136,14 @@ B scan_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
if (isArr(w)) {
ur wr = rnk(w); usz* wsh = a(w)->sh; BS2B wget = TI(w).get;
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 (wr+1!=xr || !eqShPrefix(wsh, xsh+1, wr)) thrF("`: Shape of 𝕨 must match the cell of 𝕩 (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);
if (ia==0) return x;
usz csz = arr_csz(x);
for (; i < csz; i++) r.a[i] = fc2(f, wget(w,i), xget(x,i));
for (; i < ia; i++) r.a[i] = fc2(f, inc(r.a[i-csz]), xget(x,i));
dec(w);
} else {
if (xr!=1) thrM("`: Shape of 𝕨 must match the cell of 𝕩");
if (xr!=1) thrF("`: Shape of 𝕨 must match the cell of 𝕩 (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);
if (ia==0) return x;
B pr = r.a[0] = fc2(f, w, xget(x,0)); i++;
for (; i < ia; i++) r.a[i] = pr = fc2(f, inc(pr), xget(x,i));
@ -153,7 +152,7 @@ B scan_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
}
B fold_c1(B d, B x) { B f = c(Md1D,d)->f;
if (isAtm(x) || rnk(x)!=1) thrM("´: argument must be a list");
if (isAtm(x) || rnk(x)!=1) thrF("´: Argument must be a list (%H ≡ ≢𝕩)", x);
usz ia = a(x)->ia;
if (ia==0) {
dec(x);
@ -178,7 +177,7 @@ B fold_c1(B d, B x) { B f = c(Md1D,d)->f;
return c;
}
B fold_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
if (isAtm(x) || rnk(x)!=1) thrM("´: 𝕩 must be a list");
if (isAtm(x) || rnk(x)!=1) thrF("´: 𝕩 must be a list (%H ≡ ≢𝕩)", x);
usz ia = a(x)->ia;
B c = w;
BS2B xget = TI(x).get;

View File

@ -35,8 +35,8 @@ B fillBy_c2(B d, B w, B x) {
popCatch();
return withFill(r, fill);
}
B catch_c1(B d, B x) { if(CATCH) return c1(c(Md2D,d)->g, x); inc(x); B r = c1(c(Md2D,d)->f, x); popCatch(); dec(x); return r; }
B catch_c2(B d, B w, B x) { if(CATCH) return c2(c(Md2D,d)->g, w,x); inc(w); inc(x); B r = c2(c(Md2D,d)->f, w,x); popCatch(); dec(w); dec(x); return r; }
B catch_c1(B d, B x) { if(CATCH) { dec(catchMessage); return c1(c(Md2D,d)->g, x); } inc(x); B r = c1(c(Md2D,d)->f, x); popCatch(); dec(x); return r; }
B catch_c2(B d, B w, B x) { if(CATCH) { dec(catchMessage); return c2(c(Md2D,d)->g, w,x); } inc(w); inc(x); B r = c2(c(Md2D,d)->f, w,x); popCatch(); dec(w); dec(x); return r; }
#else
B fillBy_c1(B d, B x) { return c1(c(Md2D,d)->f, x); }
B fillBy_c2(B d, B w, B x) { return c2(c(Md2D,d)->f, w,x); }

View File

@ -15,7 +15,7 @@ B eachd_fn(BBB2B f, B fo, B w, B x) { // consumes w,x; assumes at least one is a
dec(w); dec(x);
return m_hunit(r);
}
if (rm && !eqShPrefix(a(w)->sh, a(x)->sh, rm)) thrM("Mapping: Expected equal shape prefix");
if (rm && !eqShPrefix(a(w)->sh, a(x)->sh, rm)) thrF("Mapping: Expected equal shape prefix (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);
bool rw = rM==wr && ((v(w)->type==t_harr) & reusable(w)); // v(…) is safe as rank>0
bool rx = rM==xr && ((v(x)->type==t_harr) & reusable(x));
if (rw|rx && (wr==xr | rm==0)) {
@ -190,7 +190,7 @@ B pick_c2(B t, B w, B x) {
i64 p = o2i64(w);
usz xia = a(x)->ia;
if (p<0) p+= (i64)xia;
if ((u64)p >= xia) thrM("⊑: indexing out-of-bounds");
if ((u64)p >= xia) thrF("⊑: indexing out-of-bounds (𝕨≡%R, %s≡≠𝕩)", w, xia);
B r = TI(x).get(x, p);
dec(x);
return r;
@ -203,7 +203,7 @@ B select_c1(B t, B x) {
if (isAtm(x)) thrM("⊏: Argument cannot be an atom");
ur xr = rnk(x);
if (xr==0) thrM("⊏: Argument cannot be rank 0");
if (a(x)->sh[0]==0) thrM("⊏: Argument shape cannot start with 0");
if (a(x)->sh[0]==0) thrF("⊏: Argument shape cannot start with 0 (%H ≡ ≢𝕩)", x);
B r = TI(x).slice(inc(x),0);
usz* sh = arr_shAllocR(r, xr-1);
usz ia = 1;
@ -224,7 +224,7 @@ B select_c2(B t, B w, B x) {
usz cam = a(x)->sh[0];
i64 wi = o2i64(w);
if (wi<0) wi+= cam;
if ((usz)wi >= cam) thrM("⊏: Indexing out-of-bounds");
if ((usz)wi >= cam) thrF("⊏: Indexing out-of-bounds (𝕨≡%R, %s≡≠𝕩)", w, cam);
B r = TI(x).slice(inc(x), wi*csz);
usz* sh = arr_shAllocI(r, csz, xr-1);
if (sh) memcpy(sh, a(x)->sh+1, (xr-1)*sizeof(usz));
@ -245,7 +245,7 @@ B select_c2(B t, B w, B x) {
for (usz i = 0; i < wia; i++) {
i64 c = wp[i];
if (c<0) c+= xia;
if (c<0 | c>=xia) thrM("⊏: Indexing out-of-bounds");
if (c<0 | c>=xia) thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia);
rp[i] = xp[c];
}
dec(w); dec(x);
@ -255,7 +255,7 @@ B select_c2(B t, B w, B x) {
for (usz i = 0; i < wia; i++) {
i64 c = wp[i];
if (c<0) c+= xia;
if (c<0 | c>=xia) thrM("⊏: Indexing out-of-bounds");
if (c<0 | c>=xia) thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia);
r.a[i] = xget(x, c);
}
dec(w); dec(x);
@ -269,7 +269,7 @@ B select_c2(B t, B w, B x) {
if (!isNum(cw)) { harr_pfree(r.b, i); goto base; }
f64 c = o2f(cw);
if (c<0) c+= xia;
if ((usz)c >= xia) thrM("⊏: Indexing out-of-bounds");
if ((usz)c >= xia) thrF("⊏: Indexing out-of-bounds (%R∊𝕨, %s≡≠𝕩)", cw, xia);
r.a[i] = xget(x, c);
}
dec(w); dec(x);
@ -278,9 +278,9 @@ B select_c2(B t, B w, B x) {
} else {
BS2B wgetU = TI(w).getU;
ur wr = rnk(w);
ur rr = wr+xr-1;
i32 rr = wr+xr-1;
if (xr==0) thrM("⊏: 𝕩 cannot be a unit");
if (rr>UR_MAX) thrM("⊏: Result rank too large");
if (rr>UR_MAX) thrF("⊏: Result rank too large (%i≡=𝕨, %i≡=𝕩)", wr, xr);
usz csz = arr_csz(x);
usz cam = a(x)->sh[0];
MAKE_MUT(r, wia*csz);
@ -290,7 +290,7 @@ B select_c2(B t, B w, B x) {
if (!isNum(cw)) { mut_pfree(r, i*csz); goto base; }
f64 c = o2f(cw);
if (c<0) c+= cam;
if ((usz)c >= cam) thrM("⊏: Indexing out-of-bounds");
if ((usz)c >= cam) { mut_pfree(r, i*csz); thrF("⊏: Indexing out-of-bounds (%R∊𝕨, %s≡≠𝕩)", cw, cam); }
mut_copy(r, i*csz, x, csz*(usz)c, csz);
}
B rb = mut_fp(r);
@ -309,8 +309,7 @@ B select_c2(B t, B w, B x) {
B rt_slash;
B slash_c1(B t, B x) {
if (isAtm(x)) thrM("/: Argument must be a list");
if (rnk(x)!=1) thrM("/: Argument must have rank 1");
if (isAtm(x) || rnk(x)!=1) thrF("/: Argument must have rank 1 (%H ≡ ≢𝕩)", x);
i64 s = isum(x);
if(s<0) thrM("/: Argument must consist of natural numbers");
usz xia = a(x)->ia;
@ -338,7 +337,7 @@ B slash_c2(B t, B w, B x) {
usz wia = a(w)->ia;
usz xia = a(x)->ia;
B xf = getFillQ(x);
if (wia!=xia) thrM("/: Lengths of components of 𝕨 must match 𝕩");
if (wia!=xia) thrF("/: Lengths of components of 𝕨 must match 𝕩 (%s ≠ %s)", wia, xia);
i64 wsum = isum(w); if (wsum>USZ_MAX) thrOOM();
usz ria = wsum;
usz ri = 0;
@ -349,7 +348,7 @@ B slash_c2(B t, B w, B x) {
i32* rp; B r = m_i32arrv(&rp, ria);
for (usz i = 0; i < wia; i++) {
i32 c = wp[i];
if (c<0) thrM("/: 𝕨 must consist of natural numbers");
if (c<0) thrF("/: 𝕨 must consist of natural numbers (%i∊𝕨)", c);
i32 cx = xp[i];
for (usz j = 0; j < c; j++) *rp++ = cx;
}
@ -361,7 +360,7 @@ B slash_c2(B t, B w, B x) {
for (usz i = 0; i < wia; i++) {
i32 c = wp[i];
if (c==0) continue;
if (c<0) thrM("/: 𝕨 must consist of natural numbers");
if (c<0) thrF("/: 𝕨 must consist of natural numbers (%i∊𝕨)", c);
B cx = xgetU(x, i);
for (usz j = 0; j < c; j++) r.a[ri++] = inc(cx);
}
@ -468,9 +467,9 @@ B join_c1(B t, B x) {
usz cam = x0sh[0];
for (usz i = 1; i < xia; i++) {
B c = xgetU(x, i);
if (!isArr(c) || rnk(c)!=ir) thrM("∾: All items in argument should have same rank");
if (!isArr(c) || rnk(c)!=ir) thrF("∾: All items in argument should have same rank (contained items with ranks %i and %i)", ir, isArr(c)? rnk(c) : 0);
usz* csh = a(c)->sh;
if (ir>1) for (usz j = 1; j < ir; j++) if (csh[j]!=x0sh[j]) thrM("∾: Item trailing shapes must be equal");
if (ir>1) for (usz j = 1; j < ir; j++) if (csh[j]!=x0sh[j]) thrF("∾: Item trailing shapes must be equal (contained arrays with shapes %H and %H)", x0, c);
cam+= a(c)->sh[0];
if (SFNS_FILLS && !noFill(rf)) rf = fill_or(rf, getFillQ(c));
}
@ -506,7 +505,7 @@ B join_c2(B t, B w, B x) {
r.a[1] = TI(x).get(x,0); dec(x);
return withFill(r.b, f);
}
if (c-wr > 1 || c-xr > 1) thrM("∾: Argument ranks must differ by 1 or less");
if (c-wr > 1 || c-xr > 1) thrF("∾: Argument ranks must differ by 1 or less (%i≡=𝕨, %i≡=𝕩)", wr, xr);
if (c==1) {
B r = vec_join(w, x);
if (rnk(r)==0) srnk(r,1);
@ -521,7 +520,7 @@ B join_c2(B t, B w, B x) {
if (sh) {
for (i32 i = 1; i < c; i++) {
usz s = xsh[i+xr-c];
if (wsh[i+wr-c] != s) { mut_pfree(r, wia+xia); thrM("∾: Lengths not matchable"); }
if (wsh[i+wr-c] != s) { mut_pfree(r, wia+xia); thrF("∾: Lengths not matchable (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x); }
sh[i] = s;
}
sh[0] = (wr==c? wsh[0] : 1) + (xr==c? xsh[0] : 1);
@ -556,7 +555,7 @@ B couple_c2(B t, B w, B x) {
}
if (isAtm(w)) w = m_atomUnit(w);
if (isAtm(x)) x = m_atomUnit(x);
if (!eqShape(w, x)) thrM("≍: 𝕨 and 𝕩 must have equal shapes");
if (!eqShape(w, x)) thrF("≍: 𝕨 and 𝕩 must have equal shapes (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);
usz ia = a(w)->ia;
ur wr = rnk(w);
MAKE_MUT(r, ia*2);
@ -575,8 +574,8 @@ B couple_c2(B t, B w, B x) {
static void shift_check(B w, B x) {
ur wr = rnk(w); usz* wsh = a(w)->sh;
ur xr = rnk(x); usz* xsh = a(x)->sh;
if (wr+1!=xr & wr!=xr) thrM("shift: =𝕨 must be =𝕩 or ¯1+=𝕩");
for (i32 i = 1; i < xr; i++) if (wsh[i+wr-xr] != xsh[i]) thrM("shift: Lengths not matchable");
if (wr+1!=xr & wr!=xr) thrF("shift: =𝕨 must be =𝕩 or ¯1+=𝕩 (%i≡=𝕨, %i≡=𝕩)", wr, xr);
for (i32 i = 1; i < xr; i++) if (wsh[i+wr-xr] != xsh[i]) thrF("shift: Lengths not matchable (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);
}
B shiftb_c1(B t, B x) {
@ -644,7 +643,7 @@ B group_c2(B t, B w, B x) {
if (isArr(w)&isArr(x) && rnk(w)==1 && rnk(x)==1) {
usz wia = a(w)->ia;
usz xia = a(x)->ia;
if (wia-xia > 1) thrM("⊔: ≠𝕨 must be either ≠𝕩 or one bigger");
if (wia-xia > 1) thrF("⊔: ≠𝕨 must be either ≠𝕩 or one bigger (%s≡≠𝕨, %s≡≠𝕩)", wia, xia);
if (TI(w).elType==el_i32) {
i32* wp = i32any_ptr(w);
@ -757,7 +756,7 @@ B pick_ucw(B t, B o, B w, B x) {
usz xia = a(x)->ia;
i64 wi = o2i64(w);
if (wi<0) wi+= (i64)xia;
if ((u64)wi >= xia) thrM("⌾(n⊸⊑): reading out-of-bounds");
if ((u64)wi >= xia) thrF("𝔽⌾(n⊸⊑)𝕩: reading out-of-bounds (n≡%R, %s≡≠𝕩)", w, xia);
B arg = TI(x).get(x, wi);
B rep = c1(o, arg);
if (reusable(x) && TI(x).canStore(rep)) {
@ -796,7 +795,7 @@ B slash_ucw(B t, B o, B w, B x) {
B arg = slash_c2(t, inc(w), inc(x));
usz argIA = a(arg)->ia;
B rep = c1(o, arg);
if (isAtm(rep) || rnk(rep)!=1 || a(rep)->ia != argIA) thrM("𝔽⌾(a⊸/)𝕩: Result of 𝔽 must have the same shape as a/𝕩");
if (isAtm(rep) || rnk(rep)!=1 || a(rep)->ia != argIA) thrF("𝔽⌾(a⊸/)𝕩: Result of 𝔽 must have the same shape as a/𝕩 (expected ⟨%s⟩, got %H)", argIA, rep);
MAKE_MUT(r, ia); mut_to(r, el_or(TI(x).elType, TI(rep).elType));
BS2B xget = TI(x).get;
BS2B rgetU = TI(rep).getU;

View File

@ -29,6 +29,122 @@ B def_m2_d(B m, B f, B g) { thrM("cannot derive this"); }
B def_slice(B x, usz s) { thrM("cannot slice non-array!"); }
bool def_canStore(B x) { return false; }
B m_c32arrv(u32** p, usz ia);
B m_str8l(char* s);
B m_str32c(u32 c) {
u32* rp; B r = m_c32arrv(&rp, 1);
rp[0] = c;
return r;
}
B fromUTF8(char* x, i64 len);
B fromUTF8l(char* x);
#define A8(X) s = vec_join(s,m_str8l(X))
#define AU(X) s = vec_join(s,fromUTF8l(X))
#define AC(X) s = vec_join(s,m_str32c(X))
#define AFMT(...) s = append_fmt(s, __VA_ARGS__)
NOINLINE B append_fmt(B s, char* p, ...) {
va_list a;
va_start(a, p);
char buf[30];
char c;
char* lp = p;
while ((c = *p++) != 0) {
if (c!='%') continue;
if (lp!=p-1) s = vec_join(s, fromUTF8(lp, p-1-lp));
switch(c = *p++) { default: printf("Unknown format character '%c'", c); UD;
case 'R': { // TODO proper
B b = va_arg(a, B);
if (isNum(b)) {
AFMT("%f", o2f(b));
} else { assert(isArr(b) && rnk(b)==1);
s = vec_join(s, inc(b));
}
break;
}
case 'H': {
B o = va_arg(a, B);
ur r = isArr(o)? rnk(o) : 0;
usz* sh = isArr(o)? a(o)->sh : NULL;
if (r==0) AU("⟨⟩");
else if (r==1) AFMT("⟨%s⟩", sh[0]);
else {
for (i32 i = 0; i < r; i++) {
if(i) AU("");
AFMT("%s", sh[i]);
}
}
break;
}
case 'S': {
A8(va_arg(a, char*));
break;
}
case 'U': {
AU(va_arg(a, char*));
break;
}
case 'u': case 'x': case 'i': case 'l': {
i32 mode = c=='u'? 1 : c=='x'? 2 : 0;
if (mode) c = *p++;
assert(c);
if (mode) {
assert(c=='l'||c=='i');
if (c=='i') snprintf(buf, 30, mode==1? "%u" : "%x", va_arg(a, u32));
else snprintf(buf, 30, mode==1? "%lu" : "%lx", va_arg(a, u64));
} else {
if (c=='i') {
i32 v = va_arg(a, i32);
if (v<0) AU("¯");
snprintf(buf, 30, "%lu", (u64)(v<0?-v:v));
} else { assert(c=='l');
i64 v = va_arg(a, i64);
if (v<0) AU("¯");
if (v==I64_MIN) snprintf(buf, 30, "9223372036854775808");
else snprintf(buf, 30, "%lu", (u64)(v<0?-v:v));
}
}
A8(buf);
break;
}
case 's': {
usz v = va_arg(a, usz);
snprintf(buf, 30, sizeof(usz)==4? "%u" : "%lu", v);
A8(buf);
break;
}
case 'p': {
snprintf(buf, 30, "%p", va_arg(a, void*));
A8(buf);
break;
}
case 'f': {
f64 f = va_arg(a, f64);
if (f<0) {
AU("¯");
f=-f;
}
snprintf(buf, 30, "%g", f);
A8(buf);
break;
}
case 'c': {
buf[0] = va_arg(a, int); buf[1] = 0;
A8(buf);
break;
}
case '%': {
buf[0] = '%'; buf[1] = 0;
A8(buf);
break;
}
}
lp = p;
}
if (lp!=p) s = vec_join(s, fromUTF8(lp, p-lp));
va_end(a);
return s;
}
B rt_under, bi_before;
B rtUnder_c1(B f, B g, B x) { // consumes x
B fn = m2_d(inc(rt_under), inc(f), inc(g));

View File

@ -115,7 +115,7 @@ B asrt_c2(B t, B w, B x) {
bool isPureFn(B x);
B internal_c2(B t, B w, B x) {
B r;
u64 id = o2s(w);
i32 id = o2i(w);
if(id==0) {
if(isVal(x)) { char* c = format_type(v(x)->type); r = m_str8(strlen(c), c); }
else {
@ -130,7 +130,7 @@ B internal_c2(B t, B w, B x) {
else if(id==2) { r = isVal(x)? m_i32(v(x)->refc) : m_str32(U"(not heap-allocated)"); }
else if(id==3) { printf("%p\n", (void*)x.u); r = inc(x); }
else if(id==4) { r = m_f64(isPureFn(x)); }
else { dec(x); thrM("Bad 𝕨 argument for •Internal"); }
else { dec(x); thrF("•Internal: 𝕨≡%i is invalid", id); }
dec(x);
return r;
}
@ -189,7 +189,7 @@ B sys_c1(B t, B x) {
else if (eqStr(c, U"args")) {
if(isNothing(comp_currArgs)) thrM("No arguments present for •args");
r.a[i] = inc(comp_currArgs);
} else { dec(x); thrM("Unknown system function"); }
} else { dec(x); thrF("Unknown system function •%R", c); }
}
return harr_fcd(r, x);
}