fancy error messages
This commit is contained in:
parent
0b34c96a51
commit
ffbb6ce601
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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++) {
|
||||
|
||||
8
src/h.h
8
src/h.h
@ -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
|
||||
|
||||
@ -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
|
||||
@ -190,8 +194,6 @@ int main(int argc, char* argv[]) {
|
||||
heapVerify();
|
||||
#endif
|
||||
gc_maybeGC();
|
||||
#ifdef DEBUG
|
||||
#endif
|
||||
}
|
||||
popCatch();
|
||||
}
|
||||
|
||||
11
src/md1.c
11
src/md1.c
@ -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;
|
||||
|
||||
@ -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); }
|
||||
|
||||
49
src/sfns.c
49
src/sfns.c
@ -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;
|
||||
|
||||
116
src/stuff.c
116
src/stuff.c
@ -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));
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user