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];
|
for (u64 i = 0; i < sz; i++) rp[i] = (u32)s[i];
|
||||||
return r;
|
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) {
|
NOINLINE B m_str32(u32* s) {
|
||||||
usz sz = 0; while(s[sz]) sz++;
|
usz sz = 0; while(s[sz]) sz++;
|
||||||
u32* rp; B r = m_c32arrv(&rp, 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_i32arr].arrD1 = true; ti[t_i32slice].arrD1 = true;
|
||||||
ti[t_c32arr].elType = el_c32; ti[t_c32slice].elType = el_c32;
|
ti[t_c32arr].elType = el_c32; ti[t_c32slice].elType = el_c32;
|
||||||
ti[t_c32arr].canStore = c32arr_canStore;
|
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);
|
toUTF8(path, p);
|
||||||
p[plen] = 0;
|
p[plen] = 0;
|
||||||
FILE* f = fopen(p, "r");
|
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);
|
fseek(f, 0, SEEK_END);
|
||||||
u64 len = ftell(f);
|
u64 len = ftell(f);
|
||||||
fseek(f, 0, SEEK_SET);
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|||||||
@ -41,8 +41,8 @@ B ud_c1(B t, B x) {
|
|||||||
}
|
}
|
||||||
BS2B xgetU = TI(x).getU;
|
BS2B xgetU = TI(x).getU;
|
||||||
usz xia = a(x)->ia;
|
usz xia = a(x)->ia;
|
||||||
if (rnk(x)!=1) thrM("↕: Argument must be a vector");
|
if (rnk(x)!=1) thrF("↕: Argument must be either an integer or integer list (had rank %i)", rnk(x));
|
||||||
if (xia>UR_MAX) thrM("↕: Result rank too large");
|
if (xia>UR_MAX) thrF("↕: Result rank too large (%s≡≠𝕩)", xia);
|
||||||
usz sh[xia];
|
usz sh[xia];
|
||||||
usz ria = 1;
|
usz ria = 1;
|
||||||
for (usz i = 0; i < xia; i++) {
|
for (usz i = 0; i < xia; i++) {
|
||||||
|
|||||||
8
src/h.h
8
src/h.h
@ -31,6 +31,7 @@
|
|||||||
#define f64 double
|
#define f64 double
|
||||||
#define I32_MAX ((i32)((1LL<<31)-1))
|
#define I32_MAX ((i32)((1LL<<31)-1))
|
||||||
#define I32_MIN ((i32)(-(1LL<<31)))
|
#define I32_MIN ((i32)(-(1LL<<31)))
|
||||||
|
#define I64_MIN ((i64)(-(1LL<<63)))
|
||||||
#define CHR_MAX 1114111
|
#define CHR_MAX 1114111
|
||||||
#define U16_MAX ((u16)~(u16)0)
|
#define U16_MAX ((u16)~(u16)0)
|
||||||
#define U32_MAX ((u32)~(u32)0)
|
#define U32_MAX ((u32)~(u32)0)
|
||||||
@ -231,6 +232,7 @@ void gsAdd(B x); // may throw
|
|||||||
B gsPop();
|
B gsPop();
|
||||||
|
|
||||||
// some primitive actions
|
// some primitive actions
|
||||||
|
B bi_N, bi_noVar, bi_badHdr, bi_optOut, bi_noFill, bi_emptyHVec, bi_emptyIVec, bi_emptyCVec;
|
||||||
void dec(B x);
|
void dec(B x);
|
||||||
B inc(B x);
|
B inc(B x);
|
||||||
void ptr_dec(void* 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 toCells(B x); // consumes
|
||||||
B toKCells(B x, ur k); // consumes
|
B toKCells(B x, ur k); // consumes
|
||||||
B withFill(B x, B f); // consumes both
|
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);
|
bool eqShPrefix(usz* w, usz* x, ur len);
|
||||||
|
|
||||||
B m_v1(B a ); // consumes all
|
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 thr(B b);
|
||||||
NOINLINE NORETURN void thrM(char* s);
|
NOINLINE NORETURN void thrM(char* s);
|
||||||
|
#define thrF(...) thr(append_fmt(inc(bi_emptyCVec), __VA_ARGS__))
|
||||||
NOINLINE NORETURN void thrOOM();
|
NOINLINE NORETURN void thrOOM();
|
||||||
jmp_buf* prepareCatch();
|
jmp_buf* prepareCatch();
|
||||||
#ifdef CATCH_ERRORS
|
#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!
|
#else // note: popCatch() must always be called if no error was caught, so no returns before it!
|
||||||
#define CATCH false
|
#define CATCH false
|
||||||
#endif
|
#endif
|
||||||
@ -448,8 +452,6 @@ TypeInfo ti[t_COUNT];
|
|||||||
#define TI(x) (ti[v(x)->type])
|
#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; }
|
bool isNothing(B b) { return b.u==bi_N.u; }
|
||||||
|
|
||||||
// refcount
|
// refcount
|
||||||
|
|||||||
@ -157,6 +157,10 @@ int main(int argc, char* argv[]) {
|
|||||||
printf("Error: "); print(catchMessage); putchar('\n');
|
printf("Error: "); print(catchMessage); putchar('\n');
|
||||||
vm_pst(envCurr, envStart+envPrevHeight);
|
vm_pst(envCurr, envStart+envPrevHeight);
|
||||||
dec(catchMessage);
|
dec(catchMessage);
|
||||||
|
#ifdef HEAP_VERIFY
|
||||||
|
heapVerify();
|
||||||
|
#endif
|
||||||
|
gc_maybeGC();
|
||||||
}
|
}
|
||||||
B replPath = m_str32(U"REPL"); gc_add(replPath);
|
B replPath = m_str32(U"REPL"); gc_add(replPath);
|
||||||
while (true) { // exit by evaluating an empty expression
|
while (true) { // exit by evaluating an empty expression
|
||||||
@ -187,11 +191,9 @@ int main(int argc, char* argv[]) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HEAP_VERIFY
|
#ifdef HEAP_VERIFY
|
||||||
heapVerify();
|
heapVerify();
|
||||||
#endif
|
#endif
|
||||||
gc_maybeGC();
|
gc_maybeGC();
|
||||||
#ifdef DEBUG
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
popCatch();
|
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 wia = a(w)->ia; ur wr = rnk(w);
|
||||||
usz xia = a(x)->ia; ur xr = rnk(x);
|
usz xia = a(x)->ia; ur xr = rnk(x);
|
||||||
usz ria = wia*xia; ur rr = wr+xr;
|
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 wgetU = TI(w).getU;
|
||||||
BS2B xget = TI(x).get;
|
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)) {
|
if (isArr(w)) {
|
||||||
ur wr = rnk(w); usz* wsh = a(w)->sh; BS2B wget = TI(w).get;
|
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 (wr+1!=xr || !eqShPrefix(wsh, xsh+1, wr)) thrF("`: Shape of 𝕨 must match the cell of 𝕩 (%H ≡ ≢𝕨, %H ≡ ≢𝕩)", w, x);
|
||||||
if (memcmp(wsh, xsh+1, wr)) thrM("`: Shape of 𝕨 must match the cell of 𝕩");
|
|
||||||
if (ia==0) return x;
|
if (ia==0) return x;
|
||||||
usz csz = arr_csz(x);
|
usz csz = arr_csz(x);
|
||||||
for (; i < csz; i++) r.a[i] = fc2(f, wget(w,i), xget(x,i));
|
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));
|
for (; i < ia; i++) r.a[i] = fc2(f, inc(r.a[i-csz]), xget(x,i));
|
||||||
dec(w);
|
dec(w);
|
||||||
} else {
|
} 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;
|
if (ia==0) return x;
|
||||||
B pr = r.a[0] = fc2(f, w, xget(x,0)); i++;
|
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));
|
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;
|
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;
|
usz ia = a(x)->ia;
|
||||||
if (ia==0) {
|
if (ia==0) {
|
||||||
dec(x);
|
dec(x);
|
||||||
@ -178,7 +177,7 @@ B fold_c1(B d, B x) { B f = c(Md1D,d)->f;
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
B fold_c2(B d, B w, B x) { B f = c(Md1D,d)->f;
|
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;
|
usz ia = a(x)->ia;
|
||||||
B c = w;
|
B c = w;
|
||||||
BS2B xget = TI(x).get;
|
BS2B xget = TI(x).get;
|
||||||
|
|||||||
@ -35,8 +35,8 @@ B fillBy_c2(B d, B w, B x) {
|
|||||||
popCatch();
|
popCatch();
|
||||||
return withFill(r, fill);
|
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_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) 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_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
|
#else
|
||||||
B fillBy_c1(B d, B x) { return c1(c(Md2D,d)->f, x); }
|
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); }
|
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);
|
dec(w); dec(x);
|
||||||
return m_hunit(r);
|
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 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));
|
bool rx = rM==xr && ((v(x)->type==t_harr) & reusable(x));
|
||||||
if (rw|rx && (wr==xr | rm==0)) {
|
if (rw|rx && (wr==xr | rm==0)) {
|
||||||
@ -190,7 +190,7 @@ B pick_c2(B t, B w, B x) {
|
|||||||
i64 p = o2i64(w);
|
i64 p = o2i64(w);
|
||||||
usz xia = a(x)->ia;
|
usz xia = a(x)->ia;
|
||||||
if (p<0) p+= (i64)xia;
|
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);
|
B r = TI(x).get(x, p);
|
||||||
dec(x);
|
dec(x);
|
||||||
return r;
|
return r;
|
||||||
@ -203,7 +203,7 @@ B select_c1(B t, B x) {
|
|||||||
if (isAtm(x)) thrM("⊏: Argument cannot be an atom");
|
if (isAtm(x)) thrM("⊏: Argument cannot be an atom");
|
||||||
ur xr = rnk(x);
|
ur xr = rnk(x);
|
||||||
if (xr==0) thrM("⊏: Argument cannot be rank 0");
|
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);
|
B r = TI(x).slice(inc(x),0);
|
||||||
usz* sh = arr_shAllocR(r, xr-1);
|
usz* sh = arr_shAllocR(r, xr-1);
|
||||||
usz ia = 1;
|
usz ia = 1;
|
||||||
@ -224,7 +224,7 @@ B select_c2(B t, B w, B x) {
|
|||||||
usz cam = a(x)->sh[0];
|
usz cam = a(x)->sh[0];
|
||||||
i64 wi = o2i64(w);
|
i64 wi = o2i64(w);
|
||||||
if (wi<0) wi+= cam;
|
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);
|
B r = TI(x).slice(inc(x), wi*csz);
|
||||||
usz* sh = arr_shAllocI(r, csz, xr-1);
|
usz* sh = arr_shAllocI(r, csz, xr-1);
|
||||||
if (sh) memcpy(sh, a(x)->sh+1, (xr-1)*sizeof(usz));
|
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++) {
|
for (usz i = 0; i < wia; i++) {
|
||||||
i64 c = wp[i];
|
i64 c = wp[i];
|
||||||
if (c<0) c+= xia;
|
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];
|
rp[i] = xp[c];
|
||||||
}
|
}
|
||||||
dec(w); dec(x);
|
dec(w); dec(x);
|
||||||
@ -255,7 +255,7 @@ B select_c2(B t, B w, B x) {
|
|||||||
for (usz i = 0; i < wia; i++) {
|
for (usz i = 0; i < wia; i++) {
|
||||||
i64 c = wp[i];
|
i64 c = wp[i];
|
||||||
if (c<0) c+= xia;
|
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);
|
r.a[i] = xget(x, c);
|
||||||
}
|
}
|
||||||
dec(w); dec(x);
|
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; }
|
if (!isNum(cw)) { harr_pfree(r.b, i); goto base; }
|
||||||
f64 c = o2f(cw);
|
f64 c = o2f(cw);
|
||||||
if (c<0) c+= xia;
|
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);
|
r.a[i] = xget(x, c);
|
||||||
}
|
}
|
||||||
dec(w); dec(x);
|
dec(w); dec(x);
|
||||||
@ -278,9 +278,9 @@ B select_c2(B t, B w, B x) {
|
|||||||
} else {
|
} else {
|
||||||
BS2B wgetU = TI(w).getU;
|
BS2B wgetU = TI(w).getU;
|
||||||
ur wr = rnk(w);
|
ur wr = rnk(w);
|
||||||
ur rr = wr+xr-1;
|
i32 rr = wr+xr-1;
|
||||||
if (xr==0) thrM("⊏: 𝕩 cannot be a unit");
|
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 csz = arr_csz(x);
|
||||||
usz cam = a(x)->sh[0];
|
usz cam = a(x)->sh[0];
|
||||||
MAKE_MUT(r, wia*csz);
|
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; }
|
if (!isNum(cw)) { mut_pfree(r, i*csz); goto base; }
|
||||||
f64 c = o2f(cw);
|
f64 c = o2f(cw);
|
||||||
if (c<0) c+= cam;
|
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);
|
mut_copy(r, i*csz, x, csz*(usz)c, csz);
|
||||||
}
|
}
|
||||||
B rb = mut_fp(r);
|
B rb = mut_fp(r);
|
||||||
@ -309,8 +309,7 @@ B select_c2(B t, B w, B x) {
|
|||||||
|
|
||||||
B rt_slash;
|
B rt_slash;
|
||||||
B slash_c1(B t, B x) {
|
B slash_c1(B t, B x) {
|
||||||
if (isAtm(x)) thrM("/: Argument must be a list");
|
if (isAtm(x) || rnk(x)!=1) thrF("/: Argument must have rank 1 (%H ≡ ≢𝕩)", x);
|
||||||
if (rnk(x)!=1) thrM("/: Argument must have rank 1");
|
|
||||||
i64 s = isum(x);
|
i64 s = isum(x);
|
||||||
if(s<0) thrM("/: Argument must consist of natural numbers");
|
if(s<0) thrM("/: Argument must consist of natural numbers");
|
||||||
usz xia = a(x)->ia;
|
usz xia = a(x)->ia;
|
||||||
@ -338,7 +337,7 @@ B slash_c2(B t, B w, B x) {
|
|||||||
usz wia = a(w)->ia;
|
usz wia = a(w)->ia;
|
||||||
usz xia = a(x)->ia;
|
usz xia = a(x)->ia;
|
||||||
B xf = getFillQ(x);
|
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();
|
i64 wsum = isum(w); if (wsum>USZ_MAX) thrOOM();
|
||||||
usz ria = wsum;
|
usz ria = wsum;
|
||||||
usz ri = 0;
|
usz ri = 0;
|
||||||
@ -349,7 +348,7 @@ B slash_c2(B t, B w, B x) {
|
|||||||
i32* rp; B r = m_i32arrv(&rp, ria);
|
i32* rp; B r = m_i32arrv(&rp, ria);
|
||||||
for (usz i = 0; i < wia; i++) {
|
for (usz i = 0; i < wia; i++) {
|
||||||
i32 c = wp[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];
|
i32 cx = xp[i];
|
||||||
for (usz j = 0; j < c; j++) *rp++ = cx;
|
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++) {
|
for (usz i = 0; i < wia; i++) {
|
||||||
i32 c = wp[i];
|
i32 c = wp[i];
|
||||||
if (c==0) continue;
|
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);
|
B cx = xgetU(x, i);
|
||||||
for (usz j = 0; j < c; j++) r.a[ri++] = inc(cx);
|
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];
|
usz cam = x0sh[0];
|
||||||
for (usz i = 1; i < xia; i++) {
|
for (usz i = 1; i < xia; i++) {
|
||||||
B c = xgetU(x, 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;
|
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];
|
cam+= a(c)->sh[0];
|
||||||
if (SFNS_FILLS && !noFill(rf)) rf = fill_or(rf, getFillQ(c));
|
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);
|
r.a[1] = TI(x).get(x,0); dec(x);
|
||||||
return withFill(r.b, f);
|
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) {
|
if (c==1) {
|
||||||
B r = vec_join(w, x);
|
B r = vec_join(w, x);
|
||||||
if (rnk(r)==0) srnk(r,1);
|
if (rnk(r)==0) srnk(r,1);
|
||||||
@ -521,7 +520,7 @@ B join_c2(B t, B w, B x) {
|
|||||||
if (sh) {
|
if (sh) {
|
||||||
for (i32 i = 1; i < c; i++) {
|
for (i32 i = 1; i < c; i++) {
|
||||||
usz s = xsh[i+xr-c];
|
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[i] = s;
|
||||||
}
|
}
|
||||||
sh[0] = (wr==c? wsh[0] : 1) + (xr==c? xsh[0] : 1);
|
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(w)) w = m_atomUnit(w);
|
||||||
if (isAtm(x)) x = m_atomUnit(x);
|
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;
|
usz ia = a(w)->ia;
|
||||||
ur wr = rnk(w);
|
ur wr = rnk(w);
|
||||||
MAKE_MUT(r, ia*2);
|
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) {
|
static void shift_check(B w, B x) {
|
||||||
ur wr = rnk(w); usz* wsh = a(w)->sh;
|
ur wr = rnk(w); usz* wsh = a(w)->sh;
|
||||||
ur xr = rnk(x); usz* xsh = a(x)->sh;
|
ur xr = rnk(x); usz* xsh = a(x)->sh;
|
||||||
if (wr+1!=xr & wr!=xr) thrM("shift: =𝕨 must be =𝕩 or ¯1+=𝕩");
|
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]) thrM("shift: Lengths not matchable");
|
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) {
|
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) {
|
if (isArr(w)&isArr(x) && rnk(w)==1 && rnk(x)==1) {
|
||||||
usz wia = a(w)->ia;
|
usz wia = a(w)->ia;
|
||||||
usz xia = a(x)->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) {
|
if (TI(w).elType==el_i32) {
|
||||||
i32* wp = i32any_ptr(w);
|
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;
|
usz xia = a(x)->ia;
|
||||||
i64 wi = o2i64(w);
|
i64 wi = o2i64(w);
|
||||||
if (wi<0) wi+= (i64)xia;
|
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 arg = TI(x).get(x, wi);
|
||||||
B rep = c1(o, arg);
|
B rep = c1(o, arg);
|
||||||
if (reusable(x) && TI(x).canStore(rep)) {
|
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));
|
B arg = slash_c2(t, inc(w), inc(x));
|
||||||
usz argIA = a(arg)->ia;
|
usz argIA = a(arg)->ia;
|
||||||
B rep = c1(o, arg);
|
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));
|
MAKE_MUT(r, ia); mut_to(r, el_or(TI(x).elType, TI(rep).elType));
|
||||||
BS2B xget = TI(x).get;
|
BS2B xget = TI(x).get;
|
||||||
BS2B rgetU = TI(rep).getU;
|
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!"); }
|
B def_slice(B x, usz s) { thrM("cannot slice non-array!"); }
|
||||||
bool def_canStore(B x) { return false; }
|
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 rt_under, bi_before;
|
||||||
B rtUnder_c1(B f, B g, B x) { // consumes x
|
B rtUnder_c1(B f, B g, B x) { // consumes x
|
||||||
B fn = m2_d(inc(rt_under), inc(f), inc(g));
|
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);
|
bool isPureFn(B x);
|
||||||
B internal_c2(B t, B w, B x) {
|
B internal_c2(B t, B w, B x) {
|
||||||
B r;
|
B r;
|
||||||
u64 id = o2s(w);
|
i32 id = o2i(w);
|
||||||
if(id==0) {
|
if(id==0) {
|
||||||
if(isVal(x)) { char* c = format_type(v(x)->type); r = m_str8(strlen(c), c); }
|
if(isVal(x)) { char* c = format_type(v(x)->type); r = m_str8(strlen(c), c); }
|
||||||
else {
|
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==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==3) { printf("%p\n", (void*)x.u); r = inc(x); }
|
||||||
else if(id==4) { r = m_f64(isPureFn(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);
|
dec(x);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ B sys_c1(B t, B x) {
|
|||||||
else if (eqStr(c, U"args")) {
|
else if (eqStr(c, U"args")) {
|
||||||
if(isNothing(comp_currArgs)) thrM("No arguments present for •args");
|
if(isNothing(comp_currArgs)) thrM("No arguments present for •args");
|
||||||
r.a[i] = inc(comp_currArgs);
|
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);
|
return harr_fcd(r, x);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user