This commit is contained in:
dzaima 2021-04-04 18:18:47 +03:00
parent 9136d6000d
commit d0f835aa2e
9 changed files with 170 additions and 25 deletions

62
src/c32arr.c Normal file
View File

@ -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;
}

75
src/fillarr.c Normal file
View File

@ -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;
}

12
src/h.h
View File

@ -39,7 +39,7 @@
// .111111111110nnn................................................ sNaN aka tagged aka not f64, if nnn≠0 // .111111111110nnn................................................ sNaN aka tagged aka not f64, if nnn≠0
// 0111111111110................................................... direct value with no need of refcounting // 0111111111110................................................... direct value with no need of refcounting
const u16 C32_TAG = 0b0111111111110001; // 0111111111110001................00000000000ccccccccccccccccccccc char 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 VAR_TAG = 0b0111111111110011; // 0111111111110011ddddddddddddddddnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn variable reference
const u16 I32_TAG = 0b0111111111110111; // 0111111111110111................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn 32-bit int; unused const u16 I32_TAG = 0b0111111111110111; // 0111111111110111................nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn 32-bit int; unused
const u16 MD1_TAG = 0b1111111111110010; // 1111111111110010ppppppppppppppppppppppppppppppppppppppppppppp000 1-modifier const u16 MD1_TAG = 0b1111111111110010; // 1111111111110010ppppppppppppppppppppppppppppppppppppppppppppp000 1-modifier
@ -60,11 +60,10 @@ enum Type {
/* 8*/ t_fork, t_atop, /* 8*/ t_fork, t_atop,
/*10*/ t_md1D, t_md2D, t_md2H, /*10*/ t_md1D, t_md2D, t_md2H,
/*13*/ t_harr, t_i32arr, /*13*/ t_harr , t_i32arr , t_fillarr , t_c32arr ,
/*15*/ t_hslice, t_i32slice, /*17*/ t_hslice, t_i32slice, t_fillslice, t_c32slice,
/*17*/ t_comp, t_block, t_body, t_scope,
/*21*/ t_comp, t_block, t_body, t_scope,
Type_MAX 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_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 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() { void hdr_init() {
for (i32 i = 0; i < Type_MAX; ++i) { for (i32 i = 0; i < Type_MAX; ++i) {
ti[i].visit = ti[i].free = do_nothing; ti[i].visit = ti[i].free = do_nothing;
@ -305,6 +304,7 @@ void hdr_init() {
bi_noVar = tag(1, TAG_TAG); bi_noVar = tag(1, TAG_TAG);
bi_badHdr = tag(2, TAG_TAG); bi_badHdr = tag(2, TAG_TAG);
bi_optOut = tag(3, 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 assert((MD1_TAG>>1) == (MD2_TAG>>1)); // just to be sure it isn't changed incorrectly, `isMd` depends on this
} }

View File

@ -53,18 +53,6 @@ B m_caB(usz ia, B* a) {
for (usz i = 0; i < ia; i++) r.a[i] = a[i]; for (usz i = 0; i < ia; i++) r.a[i] = a[i];
return r.b; 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) { B m_caf64(usz sz, f64* a) {
HArr_p r = m_harrv(sz); HArr_p r = m_harrv(sz);
for (usz i = 0; i < sz; i++) r.a[i] = m_f64(a[i]); for (usz i = 0; i < sz; i++) r.a[i] = m_f64(a[i]);

View File

@ -10,7 +10,9 @@
#include "h.h" #include "h.h"
#include "mm_buddy.c" #include "mm_buddy.c"
#include "harr.c" #include "harr.c"
#include "fillarr.c"
#include "i32arr.c" #include "i32arr.c"
#include "c32arr.c"
#include "utf.c" #include "utf.c"
#include "arith.c" #include "arith.c"
#include "sfns.c" #include "sfns.c"
@ -47,7 +49,9 @@ __ssize_t getline (char **__restrict __lineptr, size_t *restrict n, FILE *restri
int main() { int main() {
hdr_init(); hdr_init();
harr_init(); harr_init();
fillarr_init();
i32arr_init(); i32arr_init();
c32arr_init();
arith_init(); arith_init();
sfns_init(); sfns_init();
md1_init(); md1_init();
@ -56,7 +60,6 @@ int main() {
derv_init(); derv_init();
comp_init(); comp_init();
// fake runtime // fake runtime
B bi_N = bi_nothing; B bi_N = bi_nothing;
B fruntime[] = { 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_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_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_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); B frtObj = m_caB(62, fruntime);

View File

@ -15,7 +15,7 @@ EmptyValue* buckets[64];
#define BSZ(x) (1ull<<(x)) #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; u8 cb = bucket;
EmptyValue* c; EmptyValue* c;
while (true) { while (true) {
@ -63,7 +63,7 @@ void* mm_allocN(usz sz, u8 type) {
assert(sz>8); assert(sz>8);
u8 bucket = 64-__builtin_clzl(sz-1ull); // inverse of BSZ u8 bucket = 64-__builtin_clzl(sz-1ull); // inverse of BSZ
EmptyValue* x = buckets[bucket]; EmptyValue* x = buckets[bucket];
if (x==NULL) x = makeBucket(bucket); if (x==NULL) x = makeEmpty(bucket);
else buckets[bucket] = x->next; else buckets[bucket] = x->next;
onAlloc(sz, type); onAlloc(sz, type);
x->flags = x->extra = x->type = 0; x->flags = x->extra = x->type = 0;

View File

@ -31,7 +31,11 @@ B shape_c2(B t, B w, B x) {
B pick_c1(B t, B x) { B pick_c1(B t, B x) {
if (!isArr(x)) return 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); B r = TI(x).get(x, 0);
dec(x); dec(x);
return r; return r;

View File

@ -31,8 +31,18 @@ B glyph_c1(B t, B x) {
return x; return x;
} }
B fill_c1(B t, B x) { dec(x); return m_f64(0); } B fill_c1(B t, B x) {
B fill_c2(B t, B w, B x) { dec(w); return 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) { B grLen_c1(B t, B x) {
i64 ria = -1; i64 ria = -1;

View File

@ -140,6 +140,9 @@ typedef struct Md2Block { struct Md2; Scope* sc; Block* bl; } Md2Block;
Block* compile(B bcq, B objs, B blocks) { Block* compile(B bcq, B objs, B blocks) {
usz bam = a(blocks)->ia; 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); I32Arr* bca = toI32Arr(bcq);
i32* bc = bca->a; i32* bc = bca->a;
usz bcl = bca->ia; usz bcl = bca->ia;