From d0f835aa2ea4959fece313ee052bda14ba521013 Mon Sep 17 00:00:00 2001 From: dzaima Date: Sun, 4 Apr 2021 18:18:47 +0300 Subject: [PATCH] fill --- src/c32arr.c | 62 +++++++++++++++++++++++++++++++++++++++++ src/fillarr.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/h.h | 12 ++++---- src/harr.c | 12 -------- src/main.c | 7 +++-- src/mm_buddy.c | 4 +-- src/sfns.c | 6 +++- src/sysfn.c | 14 ++++++++-- src/vm.c | 3 ++ 9 files changed, 170 insertions(+), 25 deletions(-) create mode 100644 src/c32arr.c create mode 100644 src/fillarr.c diff --git a/src/c32arr.c b/src/c32arr.c new file mode 100644 index 00000000..6b5e6cd3 --- /dev/null +++ b/src/c32arr.c @@ -0,0 +1,62 @@ +#include "h.h" + +typedef struct C32Arr { + struct Arr; + u32 a[]; +} C32Arr; + + +B m_c32arrv(usz ia) { + B r = m_arr(fsizeof(C32Arr,a,u32,ia), t_c32arr); + arr_shVec(r, ia); + return r; +} +B m_c32arrc(B x) { assert(isArr(x)); + B r = m_arr(fsizeof(C32Arr,a,B,a(x)->ia), t_c32arr); + arr_shCopy(r, x); + return r; +} +B m_c32arrp(usz ia) { // doesn't write any shape/size info! be careful! + return m_arr(fsizeof(C32Arr,a,u32,ia), t_c32arr); +} + + +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* p = c32arr_ptr(r); + for (u64 i = 0; i < sz; i++) p[i] = s[i]; + return r; +} +B m_str32(u32* s) { // meant to be used as m_str32(U"{𝕨‿𝕩}") + u64 sz = 0; while(s[sz]) sz++; + B r = m_c32arrv(sz); u32* p = c32arr_ptr(r); + for (u64 i = 0; i < sz; i++) p[i] = s[i]; + return r; +} + +typedef struct C32Slice { + struct Slice; + u32* a; +} C32Slice; +B m_c32slice(B p, u32* ptr) { + C32Slice* r = mm_allocN(sizeof(C32Slice), t_c32slice); + r->p = p; + r->a = ptr; + return tag(r, ARR_TAG); +} + +B c32arr_slice (B x, usz s) {return m_c32slice(x , c(C32Arr ,x)->a+s); } +B c32slice_slice(B x, usz s) { B r = m_c32slice(inci(c(C32Slice,x)->p), c(C32Slice,x)->a+s); dec(x); return r; } + + +B c32arr_get (B x, usz n) { VT(x,t_c32arr ); return m_c32(c(C32Arr ,x)->a[n]); } +B c32slice_get(B x, usz n) { VT(x,t_c32slice); return m_c32(c(C32Slice,x)->a[n]); } +void c32arr_free(B x) { decSh(x); } + +void c32arr_init() { + ti[t_c32arr].get = c32arr_get; ti[t_c32slice].get = c32slice_get; + ti[t_c32arr].slice = c32arr_slice; ti[t_c32slice].slice = c32slice_slice; + ti[t_c32arr].free = c32arr_free; ti[t_c32slice].free = slice_free; + ti[t_c32arr].print = arr_print; ti[t_c32slice].print = arr_print; +} diff --git a/src/fillarr.c b/src/fillarr.c new file mode 100644 index 00000000..56ec527a --- /dev/null +++ b/src/fillarr.c @@ -0,0 +1,75 @@ +#include "h.h" + +typedef struct FillArr { + struct Arr; + B fill; + B a[]; +} FillArr; + +B asFill(B x) { + if (isArr(x)) { + HArr_p r = m_harrc(x); + usz ia = r.c->ia; + BS2B xget = TI(x).get; + bool noFill = false; + for (usz i = 0; i < ia; i++) if ((r.a[i]=asFill(xget(x,i))).u == bi_noFill.u) noFill = true; + dec(x); + if (noFill) { dec(r.b); return bi_noFill; } + return r.b; + } + if (isF64(x)|isI32(x)) return m_i32(0); + if (isC32(x)) return m_c32(' '); + return bi_noFill; +} +B withFill(B x, B fill) { + B r = m_arr(fsizeof(FillArr,a,B,a(x)->ia), t_fillarr); + arr_shCopy(r, x); + c(FillArr,r)->fill = fill; + B* a = c(FillArr,r)->a; + usz ia = a(x)->ia; + BS2B xget = TI(x).get; + for (usz i = 0; i < ia; i++) a[i] = xget(x,i); + dec(x); + return r; +} +B getFill(B x) { + if (isArr(x)) { + u8 t = v(x)->type; + if (t==t_fillarr ) { B r = inci(c(FillArr,x )->fill); dec(x); return r; } + if (t==t_fillslice) { B r = inci(c(FillArr,c(Slice,x)->p)->fill); dec(x); return r; } + if (t==t_c32arr || t==t_c32slice) return m_c32(' '); + } + if (isC32(x)) return m_c32(' '); + return m_f64(0); +} + +typedef struct FillSlice { + struct Slice; + B* a; +} FillSlice; +B m_fillslice(B p, B* ptr) { + FillSlice* r = mm_allocN(sizeof(FillSlice), t_fillslice); + r->p = p; + r->a = ptr; + return tag(r, ARR_TAG); +} + +B fillarr_slice (B x, usz s) {return m_fillslice(x , c(FillArr ,x)->a+s); } +B fillslice_slice(B x, usz s) { B r = m_fillslice(inci(c(FillSlice,x)->p), c(FillSlice,x)->a+s); dec(x); return r; } + + +B fillarr_get (B x, usz n) { VT(x,t_fillarr ); return inci(c(FillArr ,x)->a[n]); } +B fillslice_get(B x, usz n) { VT(x,t_fillslice); return inci(c(FillSlice,x)->a[n]); } +void fillarr_free(B x) { + decSh(x); + B* p = c(FillArr, x)->a; + usz ia = a(x)->ia; + for (usz i = 0; i < ia; i++) dec(p[i]); +} + +void fillarr_init() { + ti[t_fillarr].get = fillarr_get; ti[t_fillslice].get = fillslice_get; + ti[t_fillarr].slice = fillarr_slice; ti[t_fillslice].slice = fillslice_slice; + ti[t_fillarr].free = fillarr_free; ti[t_fillslice].free = slice_free; + ti[t_fillarr].print = arr_print; ti[t_fillslice].print = arr_print; +} diff --git a/src/h.h b/src/h.h index 4aaacc7d..8cad8f13 100644 --- a/src/h.h +++ b/src/h.h @@ -39,7 +39,7 @@ // .111111111110nnn................................................ sNaN aka tagged aka not f64, if nnnβ‰ 0 // 0111111111110................................................... direct value with no need of refcounting const u16 C32_TAG = 0b0111111111110001; // 0111111111110001................00000000000ccccccccccccccccccccc char -const u16 TAG_TAG = 0b0111111111110010; // 0111111111110010................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn special value (0=nothing, 1=undefined var, 2=bad header; 3=optimized out; 4=error?) +const u16 TAG_TAG = 0b0111111111110010; // 0111111111110010................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn special value (0=nothing, 1=undefined var, 2=bad header; 3=optimized out; 4=error?; 5=no fill) const u16 VAR_TAG = 0b0111111111110011; // 0111111111110011ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn variable reference const u16 I32_TAG = 0b0111111111110111; // 0111111111110111................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn 32-bit int; unused const u16 MD1_TAG = 0b1111111111110010; // 1111111111110010ppppppppppppppppppppppppppppppppppppppppppppp000 1-modifier @@ -60,11 +60,10 @@ enum Type { /* 8*/ t_fork, t_atop, /*10*/ t_md1D, t_md2D, t_md2H, - /*13*/ t_harr, t_i32arr, - /*15*/ t_hslice, t_i32slice, - - /*17*/ t_comp, t_block, t_body, t_scope, + /*13*/ t_harr , t_i32arr , t_fillarr , t_c32arr , + /*17*/ t_hslice, t_i32slice, t_fillslice, t_c32slice, + /*21*/ t_comp, t_block, t_body, t_scope, Type_MAX }; @@ -290,7 +289,7 @@ B def_m2_d(B m, B f, B g) { return err("cannot derive this"); } B def_slice(B x, usz s) { return err("cannot slice non-array!"); } B def_decompose(B x) { return m_v2(m_i32((isFun(x)|isMd(x))? 0 : -1),x); } -B bi_nothing, bi_noVar, bi_badHdr, bi_optOut; +B bi_nothing, bi_noVar, bi_badHdr, bi_optOut, bi_noFill; void hdr_init() { for (i32 i = 0; i < Type_MAX; ++i) { ti[i].visit = ti[i].free = do_nothing; @@ -305,6 +304,7 @@ void hdr_init() { bi_noVar = tag(1, TAG_TAG); bi_badHdr = tag(2, TAG_TAG); bi_optOut = tag(3, TAG_TAG); + bi_noFill = tag(5, TAG_TAG); assert((MD1_TAG>>1) == (MD2_TAG>>1)); // just to be sure it isn't changed incorrectly, `isMd` depends on this } diff --git a/src/harr.c b/src/harr.c index 79a78309..b1684a9d 100644 --- a/src/harr.c +++ b/src/harr.c @@ -53,18 +53,6 @@ B m_caB(usz ia, B* a) { for (usz i = 0; i < ia; i++) r.a[i] = a[i]; return r.b; } -B m_str8(u64 sz, char* s) { - HArr_p r = m_harrv(sz); - for (u64 i = 0; i < sz; i++) r.a[i] = m_c32(s[i]); - return r.b; -} -B m_str32(u32* s) { // meant to be used as m_str32(U"{𝕨‿𝕩}") - u64 sz = 0; - while(s[sz])sz++; - HArr_p r = m_harrv(sz); - for (u64 i = 0; i < sz; i++) r.a[i] = m_c32(s[i]); - return r.b; -} B m_caf64(usz sz, f64* a) { HArr_p r = m_harrv(sz); for (usz i = 0; i < sz; i++) r.a[i] = m_f64(a[i]); diff --git a/src/main.c b/src/main.c index f8d38d7c..75d6f999 100644 --- a/src/main.c +++ b/src/main.c @@ -10,7 +10,9 @@ #include "h.h" #include "mm_buddy.c" #include "harr.c" +#include "fillarr.c" #include "i32arr.c" +#include "c32arr.c" #include "utf.c" #include "arith.c" #include "sfns.c" @@ -47,7 +49,9 @@ __ssize_t getline (char **__restrict __lineptr, size_t *restrict n, FILE *restri int main() { hdr_init(); harr_init(); + fillarr_init(); i32arr_init(); + c32arr_init(); arith_init(); sfns_init(); md1_init(); @@ -56,7 +60,6 @@ int main() { derv_init(); comp_init(); - // fake runtime B bi_N = bi_nothing; B fruntime[] = { @@ -66,7 +69,7 @@ int main() { /* βŒ½β‰/β‹β’βŠβŠ‘βŠβŠ’βˆŠ */ bi_N , bi_N , bi_N , bi_N , bi_N , bi_N , bi_pick , bi_N , bi_N, bi_N, /* β·βŠ”!Λ™ΛœΛ˜Β¨βŒœβΌΒ΄ */ bi_N , bi_N , bi_asrt , bi_N , bi_N , bi_N , bi_N , bi_tbl, bi_N, bi_N, /* ˝`βˆ˜β—‹βŠΈβŸœβŒΎβŠ˜β—ΆβŽ‰ */ bi_N , bi_scan, bi_N , bi_N , bi_N , bi_N , bi_N , bi_val, bi_N, bi_N, - /* βš‡βŸ */ bi_N , bi_N + /* βš‡βŸ */ bi_N , bi_fill }; B frtObj = m_caB(62, fruntime); diff --git a/src/mm_buddy.c b/src/mm_buddy.c index d437b144..a19cd27d 100644 --- a/src/mm_buddy.c +++ b/src/mm_buddy.c @@ -15,7 +15,7 @@ EmptyValue* buckets[64]; #define BSZ(x) (1ull<<(x)) -EmptyValue* makeBucket(u8 bucket) { // next field of output is garbage +EmptyValue* makeEmpty(u8 bucket) { // result->next is garbage u8 cb = bucket; EmptyValue* c; while (true) { @@ -63,7 +63,7 @@ void* mm_allocN(usz sz, u8 type) { assert(sz>8); u8 bucket = 64-__builtin_clzl(sz-1ull); // inverse of BSZ EmptyValue* x = buckets[bucket]; - if (x==NULL) x = makeBucket(bucket); + if (x==NULL) x = makeEmpty(bucket); else buckets[bucket] = x->next; onAlloc(sz, type); x->flags = x->extra = x->type = 0; diff --git a/src/sfns.c b/src/sfns.c index d5ca8207..098d1e6a 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -31,7 +31,11 @@ B shape_c2(B t, B w, B x) { B pick_c1(B t, B x) { if (!isArr(x)) return x; - // if (a(x)->ia==0) return err("βŠ‘: called on empty array"); // no bounds check for now + if (a(x)->ia==0) { + B r = getFill(x); + if (r.u==bi_noFill.u) return err("βŠ‘: called on empty array without fill"); + return r; + } B r = TI(x).get(x, 0); dec(x); return r; diff --git a/src/sysfn.c b/src/sysfn.c index abf31700..37c146a9 100644 --- a/src/sysfn.c +++ b/src/sysfn.c @@ -31,8 +31,18 @@ B glyph_c1(B t, B x) { return x; } -B fill_c1(B t, B x) { dec(x); return m_f64(0); } -B fill_c2(B t, B w, B x) { dec(w); return x; } +B fill_c1(B t, B x) { + return getFill(x); +} +B fill_c2(B t, B w, B x) { // TODO not set fill for typed arrays + if (isArr(x)) { + B fill = asFill(w); + if (fill.u == bi_noFill.u) return x; + return withFill(x, fill); + } + dec(w); + return x; +} B grLen_c1(B t, B x) { i64 ria = -1; diff --git a/src/vm.c b/src/vm.c index 21bcf65c..5c29d19d 100644 --- a/src/vm.c +++ b/src/vm.c @@ -140,6 +140,9 @@ typedef struct Md2Block { struct Md2; Scope* sc; Block* bl; } Md2Block; Block* compile(B bcq, B objs, B blocks) { usz bam = a(blocks)->ia; + // B* objPtr = harr_ptr(objs); usz objIA = a(objs)->ia; + // for (usz i = 0; i < objIA; i++) objPtr[i] = c2(bi_fill, c1(bi_pick, inci(objPtr[i])), objPtr[i]); + I32Arr* bca = toI32Arr(bcq); i32* bc = bca->a; usz bcl = bca->ia;