diff --git a/src/arith.c b/src/arith.c index afab9d62..8537a49f 100644 --- a/src/arith.c +++ b/src/arith.c @@ -37,17 +37,17 @@ static inline B arith_recd(BBB2B f, B w, B x) { f64 pfmod(f64 a, f64 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; } 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 (isF64(w) & isC32(x)) { u64 r = (u64)(u32)x.u + o2i64(w); 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)(o2cu(x)+o2i64(w)); if(r>CHR_MAX)thrM("+: Invalid character"); return m_c32((u32)r); } }) 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) & isC32(x)) return m_f64((u32)w.u - (i64)(u32)x.u); + 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((i32)(u32)w.u - (i32)(u32)x.u); }) ffn(mul, *, {}) ffn(and, *, {}) @@ -88,8 +88,8 @@ B eq_c2(B t, B w, B x) { w=dcf(w); B* wp = harr_ptr(w); x=dcf(x); B* xp = harr_ptr(x); if (o2i(wp[0])<=1) { dec(w);dec(x); return m_i32(0); } - i32 wia = a(w)->ia; - i32 xia = a(x)->ia; + usz wia = a(w)->ia; + usz xia = a(x)->ia; if (wia != xia) { dec(w);dec(x); return m_i32(0); } for (i32 i = 0; i0?1:-1:0); 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 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 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 log_c1(B t, B x) { if (isF64(x)) return m_f64( log(x.f)); P1( log); thrM("⋆⁼: Getting log of 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 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 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 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 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 eq_c1(B t, B x) { B r = m_i32(isArr(x)? rnk(x) : 0); decR(x); return r; } diff --git a/src/c32arr.c b/src/c32arr.c index 70c65b7c..235e02d0 100644 --- a/src/c32arr.c +++ b/src/c32arr.c @@ -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 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; } 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); - for (u64 i = 0; i < sz; i++) rp[i] = s[i]; + for (usz i = 0; i < sz; i++) rp[i] = s[i]; return r; } diff --git a/src/fillarr.c b/src/fillarr.c index 505afbc3..68b0e669 100644 --- a/src/fillarr.c +++ b/src/fillarr.c @@ -140,4 +140,4 @@ B withFill(B x, B fill) { // consumes both for (usz i = 0; i < ia; i++) a[i] = xget(x,i); dec(x); return r; -} \ No newline at end of file +} diff --git a/src/fns.c b/src/fns.c index d35b7f16..76edec2a 100644 --- a/src/fns.c +++ b/src/fns.c @@ -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 fmtN_c1(B t, B x) { - const u64 BL = 100; + #define BL 100 char buf[BL]; if (isF64(x)) snprintf(buf, BL, "%g", x.f); 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; i64 r = 0; 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; } @@ -117,4 +117,4 @@ static inline void fns_init() { bm(ud) ba(fne) ba(feq) ba(ltack) ba(rtack) bm(fm #undef ba #undef bd -#undef bm \ No newline at end of file +#undef bm diff --git a/src/gc.c b/src/gc.c index 2eccc3f6..491de0dc 100644 --- a/src/gc.c +++ b/src/gc.c @@ -100,4 +100,4 @@ void gc_forceGC() { void gc_maybeGC() { if (!gc_depth) gc_forceGC(); -} \ No newline at end of file +} diff --git a/src/h.h b/src/h.h index 2d9c3edd..61c0416d 100644 --- a/src/h.h +++ b/src/h.h @@ -24,9 +24,10 @@ #define NOINLINE __attribute__ ((noinline)) #define NORETURN __attribute__ ((noreturn)) -#define usz u32 -#define ur u8 -#define UR_MAX 255 +typedef u32 usz; +typedef u8 ur; +#define USZ_MAX ((u32)((1LL<<32)-1)) +#define UR_MAX 255 #define CTR_FOR(F) #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 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_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 B m_i32(i32 n) { return tag(n, I32_TAG); } #else B m_i32(i32 n) { return m_f64(n); } #endif 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 nnext is garbag c->mmInfo = MMI(bucket); while (cb != bucket) { cb--; - EmptyValue* b = (EmptyValue*) (BSZ(cb) + (char*)c); + EmptyValue* b = (EmptyValue*) (BSZ(cb) + (u8*)c); b->type = t_empty; b->mmInfo = MMI(cb); b->next = 0; assert(buckets[cb]==0); @@ -88,10 +88,10 @@ void BN(forHeap)(V2v f) { for (u64 i = 0; i < alSize; i++) { AllocInfo ci = al[i]; Value* s = ci.p; - Value* e = ci.sz + (void*)ci.p; + Value* e = (Value*)(ci.sz + (u8*)ci.p); while (s!=e) { 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 al #undef alSize -#undef alCap \ No newline at end of file +#undef alCap diff --git a/src/mut.c b/src/mut.c index f1988245..bf003969 100644 --- a/src/mut.c +++ b/src/mut.c @@ -110,4 +110,4 @@ void mut_copy(Mut* m, usz ms, B x, usz xs, usz l) { } } #undef AGAIN -} \ No newline at end of file +} diff --git a/src/rtPerf.c b/src/rtPerf.c index b1c2882a..456d55ec 100644 --- a/src/rtPerf.c +++ b/src/rtPerf.c @@ -197,4 +197,4 @@ static inline void rtPerf_init() { static inline void rtPerf_init() { } static inline B rtPerf_wrap(B f) { return f; } static inline void rtPerf_print() { } -#endif \ No newline at end of file +#endif diff --git a/src/sfns.c b/src/sfns.c index ffbf7c2f..8b63c86b 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -154,7 +154,7 @@ B eachd(B f, B w, B x) { // complete w F¨ x return r.b; } 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; if (reusable(x)) { decSh(x); @@ -166,16 +166,18 @@ B shape_c1(B t, B x) { return r; } 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); 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; B r; if (reusable(x)) { r = x; decSh(x); } else r = TI(x).slice(x, 0); 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); return r; } @@ -261,7 +263,7 @@ B select_c2(B t, B w, B x) { } else { BS2B wgetU = TI(w).getU; 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 (rr>UR_MAX) thrM("⊏: Result rank too large"); usz csz = arr_csz(x); @@ -301,20 +303,20 @@ B slash_c1(B t, B x) { usz ri = 0; if (xiaia; B xf = getFill(inc(x)); 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; HArr_p r = m_harrs(ria, &ri); BS2B wgetU = TI(w).getU; diff --git a/src/stuff.c b/src/stuff.c index 9d4650b7..ec63a732 100644 --- a/src/stuff.c +++ b/src/stuff.c @@ -2,7 +2,7 @@ // 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 - usz r = rnk(x); + ur r = rnk(x); BS2B xgetU = TI(x).getU; usz ia = a(x)->ia; if (r!=1) { diff --git a/src/sysfn.c b/src/sysfn.c index 9b3139fd..b648b16c 100644 --- a/src/sysfn.c +++ b/src/sysfn.c @@ -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 < ia; i++) { i64 n = o2i64u(xgetU(x, i)); - if (n==(usz)n) rp[n]++; - else if (n!=-1) thrM("grLen: Too large"); + if (n>USZ_MAX) thrM("grLen: Bad item in 𝕩"); + else if (n>=0) rp[n]++; } dec(x); return r; @@ -95,7 +95,7 @@ B grOrd_c2(B t, B w, B x) { // assumes valid arguments BS2B xgetU = TI(x).getU; usz tmp[wia]; 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)); B r = m_i32arrv(ria); i32* rp = i32arr_ptr(r); if (xia>=I32_MAX) thrM("grOrd: Too large"); @@ -174,4 +174,4 @@ B sys_c1(B t, B x) { else thrM("Unknown system function"); } return harr_fcd(r, x); -} \ No newline at end of file +} diff --git a/src/utf.c b/src/utf.c index 80a7a9c0..977dec3c 100644 --- a/src/utf.c +++ b/src/utf.c @@ -1,4 +1,4 @@ -i32 utf8_len(u8 ch) { +i8 utf8_len(u8 ch) { if (ch<128) return 1; if ((ch>>5)== 0b110) return 2; if ((ch>>4)== 0b1110) return 3; @@ -10,20 +10,29 @@ u32 utf8_p(u8* p) { switch (len) { default: UD; case -1: return (u32)-1; case 1: return *p; - case 2: return (0b11111&*p)<< 6 | (0b111111&p[1]); - case 3: return (0b1111 &*p)<<12 | (0b111111&p[2]) | (0b111111&p[1])<<6; - case 4: return (0b111 &*p)<<18 | (0b111111&p[3]) | (0b111111&p[2])<<6 | (0b111111&p[1])<<12; + case 2: return (0b11111u&*p)<< 6 | (0b111111u&p[1]); + case 3: return (0b1111u &*p)<<12 | (0b111111u&p[2]) | (0b111111u&p[1])<<6; + 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 j; - for (j = 0; j < len; j+= utf8_len(s[j])) sz++; - if (j!=len) return err("invalid UTF-8"); + i64 j = 0; + while (true) { + 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); u32* rp = c32arr_ptr(r); 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; } diff --git a/src/vm.c b/src/vm.c index 5f5c7e6d..26cd3749 100644 --- a/src/vm.c +++ b/src/vm.c @@ -83,9 +83,9 @@ void printBC(i32* p) { printf("%s", nameBC(p)); i32* n = nextBC(p); p++; - i32 am = n-p; + i64 am = n-p; 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) { i32 c = *p++; i32 pow = 10; @@ -162,10 +162,10 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all B cbld = blockDefs[i]; if (a(cbld)->ia != 4) thrM("bad compile block"); 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 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* scan = cbc; @@ -186,14 +186,14 @@ Block* compile(B bcq, B objs, B blocksq) { // consumes all body->comp = comp; body->bc = cbc; body->maxStack = mssz; - body->maxPSC = mpsc; - body->varAm = vam; + body->maxPSC = (u16)mpsc; + body->varAm = (u16)vam; ptr_inc(comp); Block* bl = mm_allocN(sizeof(Block), t_block); bl->body = body; bl->imm = imm; - bl->ty = ty; + bl->ty = (u8)ty; comp->blocks[i] = bl; } @@ -356,7 +356,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume break; } 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; } case LOCO: { i32 d = *bc++; i32 p = *bc++; @@ -403,7 +403,7 @@ B evalBC(Body* b, Scope* sc) { // doesn't consume #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; Scope* sc = mm_allocN(fsizeof(Scope, vars, B, bdy->varAm), t_scope); sc->psc = psc; if(psc) ptr_inc(psc); @@ -582,4 +582,4 @@ NOINLINE void thr(B msg) { NOINLINE void thrM(char* s) { thr(fromUTF8(s, strlen(s))); -} \ No newline at end of file +}