random type changes

This commit is contained in:
dzaima 2021-04-30 20:38:48 +03:00
parent f36eddb01c
commit 755274ebb6
19 changed files with 105 additions and 87 deletions

View File

@ -37,17 +37,17 @@ static inline B arith_recd(BBB2B f, B w, B x) {
f64 pfmod(f64 a, f64 b) { f64 pfmod(f64 a, f64 b) {
f64 r = fmod(a, b); f64 r = fmod(a, b);
if (a<0 != b<0 && r) r+= b; if (a<0 != b<0 && r!=0) r+= b;
return r; return r;
} }
ffn(add, +, { ffn(add, +, {
if (isC32(w) & isF64(x)) { u64 r = (u64)(u32)w.u + o2i64(x); if(r>CHR_MAX)thrM("+: Invalid character"); return m_c32(r); } if (isC32(w) & isF64(x)) { u64 r = (u64)(o2cu(w)+o2i64(x)); if(r>CHR_MAX)thrM("+: Invalid character"); return m_c32((u32)r); }
if (isF64(w) & isC32(x)) { u64 r = (u64)(u32)x.u + o2i64(w); if(r>CHR_MAX)thrM("+: Invalid character"); return m_c32(r); } if (isF64(w) & isC32(x)) { u64 r = (u64)(o2cu(x)+o2i64(w)); if(r>CHR_MAX)thrM("+: Invalid character"); return m_c32((u32)r); }
}) })
ffn(sub, -, { ffn(sub, -, {
if (isC32(w) & isF64(x)) { u64 r = (u64)(u32)w.u - o2i64(x); if(r>CHR_MAX)thrM("-: Invalid character"); return m_c32(r); } if (isC32(w) & isF64(x)) { u64 r = (u64)(o2cu(w)-o2u64(x)); if(r>CHR_MAX)thrM("-: Invalid character"); return m_c32((u32)r); }
if (isC32(w) & isC32(x)) return m_f64((u32)w.u - (i64)(u32)x.u); if (isC32(w) & isC32(x)) return m_f64((i32)(u32)w.u - (i32)(u32)x.u);
}) })
ffn(mul, *, {}) ffn(mul, *, {})
ffn(and, *, {}) ffn(and, *, {})
@ -88,8 +88,8 @@ B eq_c2(B t, B w, B x) {
w=dcf(w); B* wp = harr_ptr(w); w=dcf(w); B* wp = harr_ptr(w);
x=dcf(x); B* xp = harr_ptr(x); x=dcf(x); B* xp = harr_ptr(x);
if (o2i(wp[0])<=1) { dec(w);dec(x); return m_i32(0); } if (o2i(wp[0])<=1) { dec(w);dec(x); return m_i32(0); }
i32 wia = a(w)->ia; usz wia = a(w)->ia;
i32 xia = a(x)->ia; usz xia = a(x)->ia;
if (wia != xia) { dec(w);dec(x); return m_i32(0); } if (wia != xia) { dec(w);dec(x); return m_i32(0); }
for (i32 i = 0; i<wia; i++) if(!equal(wp[i], xp[i])) for (i32 i = 0; i<wia; i++) if(!equal(wp[i], xp[i]))
{ dec(w);dec(x); return m_i32(0); } { dec(w);dec(x); return m_i32(0); }
@ -103,15 +103,15 @@ B ne_c2(B t, B w, B x) {
B add_c1(B t, B x) { return x; } B add_c1(B t, B x) { return x; }
B sub_c1(B t, B x) { if (isF64(x)) return m_f64( -x.f ); P1( sub); thrM("-: Negating non-number"); } B sub_c1(B t, B x) { if (isF64(x)) return m_f64( -x.f ); P1( sub); thrM("-: Negating non-number"); }
B not_c1(B t, B x) { if (isF64(x)) return m_f64( 1-x.f ); P1( not); thrM("¬: Argument was not a number"); } B not_c1(B t, B x) { if (isF64(x)) return m_f64( 1-x.f ); P1( not); thrM("¬: Argument was not a number"); }
B mul_c1(B t, B x) { if (isF64(x)) return m_f64(x.f?x.f>0?1:-1:0); P1( mul); thrM("×: Getting sign of non-number"); } B mul_c1(B t, B x) { if (isF64(x)) return m_f64(x.f==0?0:x.f>0?1:-1); P1(mul); thrM("×: Getting sign of non-number"); }
B div_c1(B t, B x) { if (isF64(x)) return m_f64( 1/x.f ); P1( div); thrM("÷: Getting reciprocal of non-number"); } B div_c1(B t, B x) { if (isF64(x)) return m_f64( 1/x.f ); P1( div); thrM("÷: Getting reciprocal of non-number"); }
B pow_c1(B t, B x) { if (isF64(x)) return m_f64( exp(x.f)); P1( pow); thrM("⋆: Getting exp of non-number"); } B pow_c1(B t, B x) { if (isF64(x)) return m_f64( exp(x.f)); P1( pow); thrM("⋆: Getting exp of non-number"); }
B floor_c1(B t, B x) { if (isF64(x)) return m_f64(floor(x.f)); P1(floor); thrM("⌊: Argument was not a number"); } B floor_c1(B t, B x) { if (isF64(x)) return m_f64(floor(x.f)); P1(floor); thrM("⌊: Argument was not a number"); }
B ceil_c1(B t, B x) { if (isF64(x)) return m_f64( ceil(x.f)); P1( ceil); thrM("⌈: Argument was not a number"); } B ceil_c1(B t, B x) { if (isF64(x)) return m_f64( ceil(x.f)); P1( ceil); thrM("⌈: Argument was not a number"); }
B stile_c1(B t, B x) { if (isF64(x)) return m_f64( fabs(x.f)); P1(stile); thrM("|: Argument was not a number"); } B stile_c1(B t, B x) { if (isF64(x)) return m_f64( fabs(x.f)); P1(stile); thrM("|: Argument was not a number"); }
B log_c1(B t, B x) { if (isF64(x)) return m_f64( log(x.f)); P1( log); thrM("⋆⁼: Getting log of non-number"); } B log_c1(B t, B x) { if (isF64(x)) return m_f64( log(x.f)); P1( log); thrM("⋆⁼: Getting log of non-number"); }
B lt_c1(B t, B x) { return m_unit(x); } B lt_c1(B t, B x) { return m_unit(x); }
B eq_c1(B t, B x) { B r = m_i32(isArr(x)? rnk(x) : 0); decR(x); return r; } B eq_c1(B t, B x) { B r = m_i32(isArr(x)? rnk(x) : 0); decR(x); return r; }

View File

@ -27,13 +27,13 @@ u32* c32arr_ptr(B x) { VT(x, t_c32arr); return c(C32Arr,x)->a; }
B m_str8(usz sz, char* s) { B m_str8(usz sz, char* s) {
B r = m_c32arrv(sz); u32* rp = c32arr_ptr(r); B r = m_c32arrv(sz); u32* rp = c32arr_ptr(r);
for (u64 i = 0; i < sz; i++) rp[i] = s[i]; for (u64 i = 0; i < sz; i++) rp[i] = (u32)s[i];
return r; return r;
} }
NOINLINE B m_str32(u32* s) { NOINLINE B m_str32(u32* s) {
u64 sz = 0; while(s[sz]) sz++; usz sz = 0; while(s[sz]) sz++;
B r = m_c32arrv(sz); u32* rp = c32arr_ptr(r); B r = m_c32arrv(sz); u32* rp = c32arr_ptr(r);
for (u64 i = 0; i < sz; i++) rp[i] = s[i]; for (usz i = 0; i < sz; i++) rp[i] = s[i];
return r; return r;
} }

View File

@ -140,4 +140,4 @@ B withFill(B x, B fill) { // consumes both
for (usz i = 0; i < ia; i++) a[i] = xget(x,i); for (usz i = 0; i < ia; i++) a[i] = xget(x,i);
dec(x); dec(x);
return r; return r;
} }

View File

@ -30,7 +30,7 @@ B rtack_c1(B t, B x) { return x; }
B rtack_c2(B t, B w, B x) { dec(w); return x; } B rtack_c2(B t, B w, B x) { dec(w); return x; }
B fmtN_c1(B t, B x) { B fmtN_c1(B t, B x) {
const u64 BL = 100; #define BL 100
char buf[BL]; char buf[BL];
if (isF64(x)) snprintf(buf, BL, "%g", x.f); if (isF64(x)) snprintf(buf, BL, "%g", x.f);
else snprintf(buf, BL, "(fmtN: not given a number?)"); else snprintf(buf, BL, "(fmtN: not given a number?)");
@ -48,7 +48,7 @@ i64 isum(B x) { // doesn't consume; assumes is array; may error
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
i64 r = 0; i64 r = 0;
usz xia = a(x)->ia; usz xia = a(x)->ia;
for (usz i = 0; i < xia; i++) r+= o2f(xgetU(x,i)); // TODO error on overflow and non-integers or something for (usz i = 0; i < xia; i++) r+= (i64)o2f(xgetU(x,i)); // TODO error on overflow and non-integers or something
return r; return r;
} }
@ -117,4 +117,4 @@ static inline void fns_init() { bm(ud) ba(fne) ba(feq) ba(ltack) ba(rtack) bm(fm
#undef ba #undef ba
#undef bd #undef bd
#undef bm #undef bm

View File

@ -100,4 +100,4 @@ void gc_forceGC() {
void gc_maybeGC() { void gc_maybeGC() {
if (!gc_depth) gc_forceGC(); if (!gc_depth) gc_forceGC();
} }

23
src/h.h
View File

@ -24,9 +24,10 @@
#define NOINLINE __attribute__ ((noinline)) #define NOINLINE __attribute__ ((noinline))
#define NORETURN __attribute__ ((noreturn)) #define NORETURN __attribute__ ((noreturn))
#define usz u32 typedef u32 usz;
#define ur u8 typedef u8 ur;
#define UR_MAX 255 #define USZ_MAX ((u32)((1LL<<32)-1))
#define UR_MAX 255
#define CTR_FOR(F) #define CTR_FOR(F)
#define CTR_DEF(N) u64 N; #define CTR_DEF(N) u64 N;
@ -322,21 +323,23 @@ void arr_shCopy(B n, B o) { // copy shape,rank,ia from o to n
// make objects // make objects
B m_arr(usz min, u8 type) { return mm_alloc(min, type, ftag(ARR_TAG)); } B m_arr(usz min, u8 type) { return mm_alloc(min, type, ftag(ARR_TAG)); }
B m_f64(f64 n) { assert(isF64(b(n))); return b(n); } // assert just to make sure we're actually creating a float B m_f64(f64 n) { assert(isF64(b(n))); return b(n); } // assert just to make sure we're actually creating a float
B m_c32(i32 n) { return tag(n, C32_TAG); } // TODO check validity? B m_c32(u32 n) { return tag(n, C32_TAG); } // TODO check validity?
#ifdef ATOM_I32 #ifdef ATOM_I32
B m_i32(i32 n) { return tag(n, I32_TAG); } B m_i32(i32 n) { return tag(n, I32_TAG); }
#else #else
B m_i32(i32 n) { return m_f64(n); } B m_i32(i32 n) { return m_f64(n); }
#endif #endif
B m_error() { return tag(4, TAG_TAG); } B m_error() { return tag(4, TAG_TAG); }
B m_usz(usz n) { return n==(i32)n? m_i32(n) : m_f64(n); } B m_usz(usz n) { return n<I32_MAX? m_i32((i32)n) : m_f64(n); }
i32 o2i (B x) { if ((i32)x.f!=x.f) thrM("Expected integer"); return (i32)x.f; } // i have no clue whether these consume or not, but it doesn't matter i32 o2i (B x) { if (x.f!=(f64)(i32)x.f) thrM("Expected integer"); return (i32)x.f; } // i have no clue whether these consume or not, but it doesn't matter
usz o2s (B x) { if ((usz)x.f!=x.f) thrM("Expected integer"); return (usz)x.f; } usz o2s (B x) { if (x.f!=(f64)(usz)x.f) thrM("Expected integer"); return (usz)x.f; }
i64 o2i64 (B x) { if ((i64)x.f!=x.f) thrM("Expected integer"); return (i64)x.f; } i64 o2i64 (B x) { if (x.f!=(f64)(i64)x.f) thrM("Expected integer"); return (i64)x.f; }
u64 o2u64 (B x) { if (x.f!=(f64)(u64)x.f) thrM("Expected integer"); return (u64)x.f; }
f64 o2f (B x) { if (!isNum(x)) thrM("Expected integer"); return x.f; } f64 o2f (B x) { if (!isNum(x)) thrM("Expected integer"); return x.f; }
i32 o2iu (B x) { return isI32(x)? (i32)(u32)x.u : (i32)x.f; } i32 o2iu (B x) { return isI32(x)? (i32)(u32)x.u : (i32)x.f; }
usz o2c (B x) { if (!isC32(x)) thrM("Expected character"); return (u32)x.u; } u32 o2c (B x) { if (!isC32(x)) thrM("Expected character"); return (u32)x.u; }
i32 o2cu (B x) { return (u32)x.u; }
usz o2su (B x) { return (usz)x.f; } usz o2su (B x) { return (usz)x.f; }
i64 o2i64u(B x) { return (i64)x.f; } i64 o2i64u(B x) { return (i64)x.f; }
bool q_i32(B x) { return isI32(x) || isF64(x)&(x.f==(i32)x.f); } bool q_i32(B x) { return isI32(x) || isF64(x)&(x.f==(i32)x.f); }
@ -477,4 +480,4 @@ static inline u64 nsTime() {
timespec_get(&t, TIME_UTC); timespec_get(&t, TIME_UTC);
// clock_gettime(CLOCK_REALTIME, &t); // clock_gettime(CLOCK_REALTIME, &t);
return t.tv_sec*1000000000ull + t.tv_nsec; return t.tv_sec*1000000000ull + t.tv_nsec;
} }

View File

@ -68,4 +68,4 @@ void heapVerify() {
heapVerify_mode=-1; heapVerify_mode=-1;
} }
#endif #endif

View File

@ -191,8 +191,9 @@ int main() {
#endif #endif
// uncomment to self-compile and use that for the REPL; expects a copy of mlochbaum/BQN/src/c.bqn to be at the execution directory // uncomment to self-compile and use that for the REPL
// char* c_src = 0; // expects a copy of mlochbaum/BQN/src/c.bqn to be at the execution directory (with •args replaced with the array in glyphs.bqn)
// char* c_src = NULL;
// u64 c_len; // u64 c_len;
// FILE* f = fopen("c.bqn", "rb"); // FILE* f = fopen("c.bqn", "rb");
// if (f) { // if (f) {
@ -207,11 +208,13 @@ int main() {
// exit(1); // exit(1);
// } // }
// if (c_src) { // if (c_src) {
// B cbc = c2(comp, inc(rtObj), fromUTF8(c_src, c_len)); // B cbc = c2(comp, inc(compArg), fromUTF8(c_src, c_len));
// Block* cbc_b = ca3(cbc); // Block* cbc_b = ca3(cbc);
// comp = m_funBlock(cbc_b, 0); // comp = m_funBlock(cbc_b, 0); ptr_dec(cbc_b);
// gc_add(comp);
// free(c_src); // free(c_src);
// } // }
while (CATCH) { while (CATCH) {
printf("caught: "); printf("caught: ");
print(catchMessage); print(catchMessage);

View File

@ -71,22 +71,22 @@ B repeat_replace(B g, B* q) { // doesn't consume
} \ } \
i64 bound[2] = {0,0}; \ i64 bound[2] = {0,0}; \
repeat_bounds(bound, g); \ repeat_bounds(bound, g); \
u64 min = -bound[0]; u64 max = bound[1]; \ u64 min=(u64)-bound[0]; u64 max=(u64)bound[1]; \
B all[min+max+1]; \ B all[min+max+1]; \
B* q = all+min; \ B* q = all+min; \
q[0] = inc(x); \ q[0] = inc(x); \
if (min) { \ if (min) { \
B x2 = inc(x); \ B x2 = inc(x); \
B fi = m1_d(inc(rt_undo), inc(f)); \ B fi = m1_d(inc(rt_undo), inc(f)); \
for (i64 i = 0; i < min; i++) q[-1-i] = inc(x2 = CN(fi, __VA_ARGS__ x2)); \ for (u64 i = 0; i < min; i++) q[-1-i] = inc(x2 = CN(fi, __VA_ARGS__ x2)); \
dec(x2); \ dec(x2); \
dec(fi); \ dec(fi); \
} \ } \
for (i64 i = 0; i < max; i++) q[i+1] = inc(x = CN(f, __VA_ARGS__ x)); \ for (u64 i = 0; i < max; i++) q[i+1] = inc(x = CN(f, __VA_ARGS__ x)); \
dec(x); \ dec(x); \
B r = repeat_replace(g, q); \ B r = repeat_replace(g, q); \
dec(g); \ dec(g); \
for (i64 i = 0; i < min+max+1; i++) dec(all[i]); \ for (u64 i = 0; i < min+max+1; i++) dec(all[i]); \
END; \ END; \
return r; return r;

View File

@ -13,7 +13,7 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
}; };
#define BSZ(X) (1ull<<(X)) #define BSZ(X) (1ull<<(X))
#define BSZI(X) (64-__builtin_clzl((X)-1ull)) #define BSZI(X) ((u8)(64-__builtin_clzl((X)-1ull)))
#define MMI(X) X #define MMI(X) X
#define BN(X) b1_##X #define BN(X) b1_##X
#define buckets b1_buckets #define buckets b1_buckets
@ -24,7 +24,7 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
#undef BSZI #undef BSZI
#define BSZ(X) (3ull<<(X)) #define BSZ(X) (3ull<<(X))
#define BSZI(X) (64-__builtin_clzl((X)/3-1ull)) #define BSZI(X) ((u8)(64-__builtin_clzl((X)/3-1ull)))
#define MMI(X) ((X)|64) #define MMI(X) ((X)|64)
#define BN(X) b3_##X #define BN(X) b3_##X
#define buckets b3_buckets #define buckets b3_buckets

View File

@ -13,7 +13,7 @@ struct EmptyValue { // needs set: mmInfo; type=t_empty; next; everything else ca
}; };
#define BSZ(X) (1ull<<(X)) #define BSZ(X) (1ull<<(X))
#define BSZI(X) (64-__builtin_clzl((X)-1ull)) #define BSZI(X) ((u8)(64-__builtin_clzl((X)-1ull)))
#define MMI(X) X #define MMI(X) X
#define BN(X) mm_##X #define BN(X) mm_##X
@ -40,4 +40,4 @@ u64 mm_size(Value* x) {
} }
#undef BSZ #undef BSZ
#undef BSZI #undef BSZI

View File

@ -45,7 +45,7 @@ static NOINLINE EmptyValue* BN(makeEmpty)(u8 bucket) { // result->next is garbag
c->mmInfo = MMI(bucket); c->mmInfo = MMI(bucket);
while (cb != bucket) { while (cb != bucket) {
cb--; cb--;
EmptyValue* b = (EmptyValue*) (BSZ(cb) + (char*)c); EmptyValue* b = (EmptyValue*) (BSZ(cb) + (u8*)c);
b->type = t_empty; b->type = t_empty;
b->mmInfo = MMI(cb); b->mmInfo = MMI(cb);
b->next = 0; assert(buckets[cb]==0); b->next = 0; assert(buckets[cb]==0);
@ -88,10 +88,10 @@ void BN(forHeap)(V2v f) {
for (u64 i = 0; i < alSize; i++) { for (u64 i = 0; i < alSize; i++) {
AllocInfo ci = al[i]; AllocInfo ci = al[i];
Value* s = ci.p; Value* s = ci.p;
Value* e = ci.sz + (void*)ci.p; Value* e = (Value*)(ci.sz + (u8*)ci.p);
while (s!=e) { while (s!=e) {
if (s->type!=t_empty) f(s); if (s->type!=t_empty) f(s);
s = BSZ(s->mmInfo&63) + (void*)s; s = (Value*)(BSZ(s->mmInfo&63) + (u8*)s);
} }
} }
} }
@ -105,4 +105,4 @@ u64 BN(heapAllocated)() {
#undef AllocInfo #undef AllocInfo
#undef al #undef al
#undef alSize #undef alSize
#undef alCap #undef alCap

View File

@ -110,4 +110,4 @@ void mut_copy(Mut* m, usz ms, B x, usz xs, usz l) {
} }
} }
#undef AGAIN #undef AGAIN
} }

View File

@ -197,4 +197,4 @@ static inline void rtPerf_init() {
static inline void rtPerf_init() { } static inline void rtPerf_init() { }
static inline B rtPerf_wrap(B f) { return f; } static inline B rtPerf_wrap(B f) { return f; }
static inline void rtPerf_print() { } static inline void rtPerf_print() { }
#endif #endif

View File

@ -154,7 +154,7 @@ B eachd(B f, B w, B x) { // complete w F¨ x
return r.b; return r.b;
} }
B shape_c1(B t, B x) { B shape_c1(B t, B x) {
if (!isArr(x)) thrM("reshaping non-array"); if (!isArr(x)) thrM("⥊: deshaping non-array");
usz ia = a(x)->ia; usz ia = a(x)->ia;
if (reusable(x)) { if (reusable(x)) {
decSh(x); decSh(x);
@ -166,16 +166,18 @@ B shape_c1(B t, B x) {
return r; return r;
} }
B shape_c2(B t, B w, B x) { B shape_c2(B t, B w, B x) {
if (!isArr(x)) { dec(x); dec(w); thrM("reshaping non-array"); } if (!isArr(x)) { dec(x); dec(w); thrM("⥊: Reshaping non-array"); }
if (!isArr(w)) return shape_c1(t, x); if (!isArr(w)) return shape_c1(t, x);
BS2B wget = TI(w).get; BS2B wget = TI(w).get;
ur nr = a(w)->ia; usz wia = a(w)->ia;
if (wia>UR_MAX) thrM("⥊: Result rank too large");
ur nr = (ur)wia;
usz nia = a(x)->ia; usz nia = a(x)->ia;
B r; B r;
if (reusable(x)) { r = x; decSh(x); } if (reusable(x)) { r = x; decSh(x); }
else r = TI(x).slice(x, 0); else r = TI(x).slice(x, 0);
usz* sh = arr_shAllocI(r, nia, nr); usz* sh = arr_shAllocI(r, nia, nr);
if (sh) for (i32 i = 0; i < nr; i++) sh[i] = o2s(wget(w,i)); if (sh) for (u32 i = 0; i < nr; i++) sh[i] = o2s(wget(w,i));
dec(w); dec(w);
return r; return r;
} }
@ -261,7 +263,7 @@ 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); usz wia = a(w)->ia; ur wr = rnk(w); usz wia = a(w)->ia;
u32 rr = wr+xr-1; ur 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) thrM("⊏: Result rank too large");
usz csz = arr_csz(x); usz csz = arr_csz(x);
@ -301,20 +303,20 @@ B slash_c1(B t, B x) {
usz ri = 0; usz ri = 0;
if (xia<I32_MAX) { if (xia<I32_MAX) {
B r = m_i32arrv(s); i32* rp = i32arr_ptr(r); B r = m_i32arrv(s); i32* rp = i32arr_ptr(r);
for (usz i = 0; i < xia; i++) { for (i32 i = 0; i < xia; i++) {
usz c = o2s(xgetU(x, i)); usz c = o2s(xgetU(x, i));
for (usz j = 0; j < c; j++) rp[ri++] = i; for (usz j = 0; j < c; j++) rp[ri++] = i;
} }
dec(x); dec(x);
return r; return r;
} }
HArr_p r = m_harrs(s, &ri); B r = m_f64arrv(s); f64* rp = f64arr_ptr(r);
for (usz i = 0; i < xia; i++) { for (usz i = 0; i < xia; i++) {
usz c = o2s(xgetU(x, i)); usz c = o2s(xgetU(x, i));
for (usz j = 0; j < c; j++) r.a[ri++] = m_i32(i); for (usz j = 0; j < c; j++) rp[ri++] = i;
} }
dec(x); dec(x);
return withFill(harr_fv(r),m_f64(0)); return r;
} }
B slash_c2(B t, B w, B x) { B slash_c2(B t, B w, B x) {
if (isArr(w) && isArr(x) && rnk(w)==1 && rnk(x)==1 && depth(w)==1) { if (isArr(w) && isArr(x) && rnk(w)==1 && rnk(x)==1 && depth(w)==1) {
@ -322,7 +324,8 @@ B slash_c2(B t, B w, B x) {
usz xia = a(x)->ia; usz xia = a(x)->ia;
B xf = getFill(inc(x)); B xf = getFill(inc(x));
if (wia!=xia) thrM("/: Lengths of components of 𝕨 must match 𝕩"); if (wia!=xia) thrM("/: Lengths of components of 𝕨 must match 𝕩");
usz ria = isum(w); i64 wsum = isum(w); if (wsum>USZ_MAX) thrM("/: Result too large");
usz ria = wsum;
usz ri = 0; usz ri = 0;
HArr_p r = m_harrs(ria, &ri); HArr_p r = m_harrs(ria, &ri);
BS2B wgetU = TI(w).getU; BS2B wgetU = TI(w).getU;

View File

@ -2,7 +2,7 @@
// a bunch of random things that don't really belong in any other file // a bunch of random things that don't really belong in any other file
void arr_print(B x) { // should accept refc=0 arguments for debugging purposes void arr_print(B x) { // should accept refc=0 arguments for debugging purposes
usz r = rnk(x); ur r = rnk(x);
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
usz ia = a(x)->ia; usz ia = a(x)->ia;
if (r!=1) { if (r!=1) {

View File

@ -60,8 +60,8 @@ B grLen_c1(B t, B x) { // assumes valid arguments
for (usz i = 0; i < ria; i++) rp[i] = 0; for (usz i = 0; i < ria; i++) rp[i] = 0;
for (usz i = 0; i < ia; i++) { for (usz i = 0; i < ia; i++) {
i64 n = o2i64u(xgetU(x, i)); i64 n = o2i64u(xgetU(x, i));
if (n==(usz)n) rp[n]++; if (n>USZ_MAX) thrM("grLen: Bad item in 𝕩");
else if (n!=-1) thrM("grLen: Too large"); else if (n>=0) rp[n]++;
} }
dec(x); dec(x);
return r; return r;
@ -95,7 +95,7 @@ B grOrd_c2(B t, B w, B x) { // assumes valid arguments
BS2B xgetU = TI(x).getU; BS2B xgetU = TI(x).getU;
usz tmp[wia]; usz tmp[wia];
tmp[0] = 0; tmp[0] = 0;
for (int i = 1; i < wia; i++) tmp[i] = tmp[i-1]+o2su(wgetU(w,i-1)); for (usz i = 1; i < wia; i++) tmp[i] = tmp[i-1]+o2su(wgetU(w,i-1));
usz ria = tmp[wia-1]+o2su(wgetU(w,wia-1)); usz ria = tmp[wia-1]+o2su(wgetU(w,wia-1));
B r = m_i32arrv(ria); i32* rp = i32arr_ptr(r); B r = m_i32arrv(ria); i32* rp = i32arr_ptr(r);
if (xia>=I32_MAX) thrM("grOrd: Too large"); if (xia>=I32_MAX) thrM("grOrd: Too large");
@ -174,4 +174,4 @@ B sys_c1(B t, B x) {
else thrM("Unknown system function"); else thrM("Unknown system function");
} }
return harr_fcd(r, x); return harr_fcd(r, x);
} }

View File

@ -1,4 +1,4 @@
i32 utf8_len(u8 ch) { i8 utf8_len(u8 ch) {
if (ch<128) return 1; if (ch<128) return 1;
if ((ch>>5)== 0b110) return 2; if ((ch>>5)== 0b110) return 2;
if ((ch>>4)== 0b1110) return 3; if ((ch>>4)== 0b1110) return 3;
@ -10,20 +10,29 @@ u32 utf8_p(u8* p) {
switch (len) { default: UD; switch (len) { default: UD;
case -1: return (u32)-1; case -1: return (u32)-1;
case 1: return *p; case 1: return *p;
case 2: return (0b11111&*p)<< 6 | (0b111111&p[1]); case 2: return (0b11111u&*p)<< 6 | (0b111111u&p[1]);
case 3: return (0b1111 &*p)<<12 | (0b111111&p[2]) | (0b111111&p[1])<<6; case 3: return (0b1111u &*p)<<12 | (0b111111u&p[2]) | (0b111111u&p[1])<<6;
case 4: return (0b111 &*p)<<18 | (0b111111&p[3]) | (0b111111&p[2])<<6 | (0b111111&p[1])<<12; case 4: return (0b111u &*p)<<18 | (0b111111u&p[3]) | (0b111111u&p[2])<<6 | (0b111111u&p[1])<<12;
} }
} }
B fromUTF8(char* s, u64 len) { B fromUTF8(char* s, i64 len) {
u64 sz = 0; u64 sz = 0;
u64 j; i64 j = 0;
for (j = 0; j < len; j+= utf8_len(s[j])) sz++; while (true) {
if (j!=len) return err("invalid UTF-8"); i8 l = utf8_len((u8)s[j]);
if (l==-1) thrM("Invalid UTF-8");
if (j>=len) {
if (j!=len) thrM("Invalid UTF-8");
break;
}
sz++;
j+= l;
}
B r = m_c32arrv(sz); B r = m_c32arrv(sz);
u32* rp = c32arr_ptr(r); u32* rp = c32arr_ptr(r);
u64 p = 0; u64 p = 0;
for (u64 i = 0; i < len; i+= utf8_len(s[i])) rp[p++] = utf8_p((u8*)s+i); // may read after end, eh // TODO verify
for (i64 i = 0; i < len; i+= utf8_len((u8)s[i])) rp[p++] = utf8_p((u8*)s+i); // may read after end, eh
return r; return r;
} }

View File

@ -83,9 +83,9 @@ void printBC(i32* p) {
printf("%s", nameBC(p)); printf("%s", nameBC(p));
i32* n = nextBC(p); i32* n = nextBC(p);
p++; p++;
i32 am = n-p; i64 am = n-p;
i32 len = 0; i32 len = 0;
for (i32 i = 0; i < am; i++) printf(" %d", p[i]); for (i64 i = 0; i < am; i++) printf(" %d", p[i]);
while(p!=n) { while(p!=n) {
i32 c = *p++; i32 c = *p++;
i32 pow = 10; i32 pow = 10;
@ -162,10 +162,10 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
B cbld = blockDefs[i]; B cbld = blockDefs[i];
if (a(cbld)->ia != 4) thrM("bad compile block"); if (a(cbld)->ia != 4) thrM("bad compile block");
BS2B bget = TI(cbld).get; BS2B bget = TI(cbld).get;
usz ty = o2s(bget(cbld,0)); if (ty<0|ty>2) thrM("bad block type"); usz ty = o2s(bget(cbld,0)); if (ty>2) thrM("bad block type");
bool imm = o2s(bget(cbld,1)); // todo o2b or something bool imm = o2s(bget(cbld,1)); // todo o2b or something
usz idx = o2s(bget(cbld,2)); if (idx>=bcl) thrM("oob bytecode index"); usz idx = o2s(bget(cbld,2)); if (idx>=bcl) thrM("oob bytecode index");
usz vam = o2s(bget(cbld,3)); usz vam = o2s(bget(cbld,3)); if (vam!=(u16)vam) thrM("too many variables");
i32* cbc = bc+idx; i32* cbc = bc+idx;
i32* scan = cbc; i32* scan = cbc;
@ -186,14 +186,14 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all
body->comp = comp; body->comp = comp;
body->bc = cbc; body->bc = cbc;
body->maxStack = mssz; body->maxStack = mssz;
body->maxPSC = mpsc; body->maxPSC = (u16)mpsc;
body->varAm = vam; body->varAm = (u16)vam;
ptr_inc(comp); ptr_inc(comp);
Block* bl = mm_allocN(sizeof(Block), t_block); Block* bl = mm_allocN(sizeof(Block), t_block);
bl->body = body; bl->body = body;
bl->imm = imm; bl->imm = imm;
bl->ty = ty; bl->ty = (u8)ty;
comp->blocks[i] = bl; comp->blocks[i] = bl;
} }
@ -356,7 +356,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
break; break;
} }
case LOCM: { i32 d = *bc++; i32 p = *bc++; case LOCM: { i32 d = *bc++; i32 p = *bc++;
ADD(tag((u64)d<<32 | p, VAR_TAG)); ADD(tag((u64)d<<32 | (u32)p, VAR_TAG));
break; break;
} }
case LOCO: { i32 d = *bc++; i32 p = *bc++; case LOCO: { i32 d = *bc++; i32 p = *bc++;
@ -403,7 +403,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume
#undef POP #undef POP
} }
B actualExec(Block* bl, Scope* psc, u32 ga, B* svar) { // consumes svar contents B actualExec(Block* bl, Scope* psc, i32 ga, B* svar) { // consumes svar contents
Body* bdy = bl->body; Body* bdy = bl->body;
Scope* sc = mm_allocN(fsizeof(Scope, vars, B, bdy->varAm), t_scope); Scope* sc = mm_allocN(fsizeof(Scope, vars, B, bdy->varAm), t_scope);
sc->psc = psc; if(psc) ptr_inc(psc); sc->psc = psc; if(psc) ptr_inc(psc);
@ -582,4 +582,4 @@ NOINLINE void thr(B msg) {
NOINLINE void thrM(char* s) { NOINLINE void thrM(char* s) {
thr(fromUTF8(s, strlen(s))); thr(fromUTF8(s, strlen(s)));
} }