diff --git a/src/fns.c b/src/fns.c index abdd2793..67dcae65 100644 --- a/src/fns.c +++ b/src/fns.c @@ -239,6 +239,26 @@ B indexOf_c2(B t, B w, B x) { return c2(rt_indexOf, w, x); } +B rt_memberOf; +B memberOf_c1(B t, B x) { + return c1(rt_memberOf, x); +} +B memberOf_c2(B t, B w, B x) { + if (!isArr(w) || rnk(w)!=1 || !isArr(x) || rnk(x)!=1) return c2(rt_memberOf, w, x); + usz wia = a(w)->ia; + usz xia = a(x)->ia; + // TODO O(wia×xia) for small wia + H_Sb* set = m_Sb(64); + bool had; + BS2B xgetU = TI(x).getU; + BS2B wgetU = TI(w).getU; + for (usz i = 0; i < xia; i++) mk_Sb(&set, xgetU(x,i), &had); + i32* rp; B r = m_i32arrv(&rp, wia); + for (usz i = 0; i < wia; i++) rp[i] = has_Sb(set, wgetU(w,i)); + dec(w);dec(x); + return r; +} + #define BI_A(N) { B t=bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); BFn*f=c(BFn,t); f->c2=N##_c2 ; f->c1=N##_c1 ; f->extra=pf_##N; f->ident=bi_N; f->uc1=def_fn_uc1; f->ucw=def_fn_ucw; gc_add(t); } #define BI_D(N) { B t=bi_##N = mm_alloc(sizeof(BFn), t_funBI, ftag(FUN_TAG)); BFn*f=c(BFn,t); f->c2=N##_c2 ; f->c1=c1_invalid; f->extra=pf_##N; f->ident=bi_N; f->uc1=def_fn_uc1; f->ucw=def_fn_ucw; gc_add(t); } @@ -248,7 +268,7 @@ B indexOf_c2(B t, B w, B x) { #define BI_FNS1(F) F(BI_A,BI_M,BI_D) -#define F(A,M,D) A(ud) A(fne) A(feq) A(ltack) A(rtack) M(fmtF) A(indexOf) +#define F(A,M,D) A(ud) A(fne) A(feq) A(ltack) A(rtack) M(fmtF) A(indexOf) A(memberOf) BI_FNS0(F); static inline void fns_init() { BI_FNS1(F) ti[t_funBI].print = print_funBI; diff --git a/src/h.h b/src/h.h index d7bed8ba..5e2b49d3 100644 --- a/src/h.h +++ b/src/h.h @@ -125,7 +125,7 @@ char* format_type(u8 u) { #define FOR_PF(F) F(none, "(unknown fn)") \ /*arith.c*/ F(add,"+") F(sub,"-") F(mul,"×") F(div,"÷") F(pow,"⋆") F(floor,"⌊") F(ceil,"⌈") F(stile,"|") F(eq,"=") \ /*arith.c*/ F(ne,"≠") F(le,"≤") F(ge,"≥") F(lt,"<") F(gt,">") F(and,"∧") F(or,"∨") F(not,"¬") F(log,"⋆⁼") \ - /*fns.c*/ F(ud,"↕") F(fne,"≢") F(feq,"≡") F(ltack,"⊣") F(rtack,"⊢") F(fmtF,"•FmtF") F(indexOf,"⊐") \ + /*fns.c*/ F(ud,"↕") F(fne,"≢") F(feq,"≡") F(ltack,"⊣") F(rtack,"⊢") F(fmtF,"•FmtF") F(indexOf,"⊐") F(memberOf,"∊") \ /*sfns.c*/ F(shape,"⥊") F(pick,"⊑") F(pair,"{𝕨‿𝕩}") F(select,"⊏") F(slash,"/") F(join,"∾") F(couple,"≍") F(shiftb,"»") F(shifta,"«") F(take,"↑") F(drop,"↓") F(group,"⊔") F(reverse,"⌽") \ /*derv.c*/ F(fork,"(fork)") F(atop,"(atop)") F(md1d,"(derived 1-modifier)") F(md2d,"(derived 2-modifier)") \ /*sort.c*/ F(gradeUp,"⍋") \ diff --git a/src/hash.c b/src/hash.c index b211d2b3..ed4458c5 100644 --- a/src/hash.c +++ b/src/hash.c @@ -86,6 +86,18 @@ u64 bqn_hashP(B x, const u64 secret[4]) { // bqn_hash but never zero #define VT i32 #include "hashmap.c" +#define N(X) X##_Sb +#define HT u64 +#define KT B +#define H1(K) bqn_hashP(K, wy_secret) +#define H2(K,h1) h1 +#define H1R(K,h2) h2 +#define EMPTY(S,K) ((S)==0) +#define HDEF 0 +#define KEYS +#define EQUAL(A,B) equal(A,B) +#include "hashmap.c" + void hash_init() { diff --git a/src/hashmap.c b/src/hashmap.c index ed554bdf..17ec4cd3 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -75,6 +75,12 @@ static inline u64 N(find) (Map* m, KT k, u64 h1, u64 h2, bool* had) { if (RARE(p++==mask)) p = 0; } } +static inline bool N(has) (Map* m, KT k) { + bool has; + u64 h1 = H1(k); u64 h2 = H2(k, h1); + N(find)(m, k, h1, h2, &has); + return has; +} static inline void N(qins) (Map* m, u64 h1, HT h2, KT k IFVAL(, VT v)) { // if guaranteed that k doesn't exist in the map yet and there's space for this diff --git a/src/load.c b/src/load.c index babf4546..11ce182b 100644 --- a/src/load.c +++ b/src/load.c @@ -65,7 +65,7 @@ static inline void load_init() { /* +-×÷⋆√⌊⌈|¬ */ bi_add , bi_sub , bi_mul , bi_div , bi_pow , bi_N , bi_floor, bi_ceil , bi_stile , bi_not, /* ∧∨<>≠=≤≥≡≢ */ bi_and , bi_or , bi_lt , bi_gt , bi_ne , bi_eq , bi_le , bi_ge , bi_feq , bi_fne, /* ⊣⊢⥊∾≍↑↓↕«» */ bi_ltack , bi_rtack , bi_shape, bi_join , bi_couple, bi_take , bi_drop , bi_ud , bi_shifta, bi_shiftb, - /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ bi_reverse, bi_N , bi_slash, bi_gradeUp, bi_N , bi_select, bi_pick , bi_indexOf, bi_N , bi_N, + /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ bi_reverse, bi_N , bi_slash, bi_gradeUp, bi_N , bi_select, bi_pick , bi_indexOf, bi_N , bi_memberOf, /* ⍷⊔!˙˜˘¨⌜⁼´ */ bi_N , bi_group , bi_asrt , bi_const , bi_swap , bi_cell , bi_each , bi_tbl , bi_N , bi_fold, /* ˝`∘○⊸⟜⌾⊘◶⎉ */ bi_N , bi_scan , bi_atop , bi_over , bi_before, bi_after , bi_under, bi_val , bi_cond , bi_N, /* ⚇⍟⎊ */ bi_N , bi_repeat, bi_catch @@ -74,7 +74,7 @@ static inline void load_init() { /* +-×÷⋆√⌊⌈|¬ */ 1,1,1,1,1,0,1,1,1,1, /* ∧∨<>≠=≤≥≡≢ */ 1,1,1,1,1,1,1,1,1,1, /* ⊣⊢⥊∾≍↑↓↕«» */ 1,1,0,1,1,1,1,1,1,1, - /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 1,0,1,1,0,1,1,1,0,0, + /* ⌽⍉/⍋⍒⊏⊑⊐⊒∊ */ 1,0,1,1,0,1,1,1,0,1, /* ⍷⊔!˙˜˘¨⌜⁼´ */ 0,1,1,1,1,1,1,1,0,1, /* ˝`∘○⊸⟜⌾⊘◶⎉ */ 0,1,1,1,1,1,1,1,0,0, /* ⚇⍟⎊ */ 0,1,1 @@ -128,6 +128,7 @@ static inline void load_init() { rt_under = rtObjGet(rtObjRaw, 56); gc_add(rt_under); rt_reverse = rtObjGet(rtObjRaw, 30); gc_add(rt_reverse); rt_indexOf = rtObjGet(rtObjRaw, 37); gc_add(rt_indexOf); + rt_memberOf= rtObjGet(rtObjRaw, 39); gc_add(rt_memberOf); rt_cell = rtObjGet(rtObjRaw, 45); gc_add(rt_cell); for (usz i = 0; i < runtimeLen; i++) { diff --git a/src/main.c b/src/main.c index 59dbe455..6a37ffa6 100644 --- a/src/main.c +++ b/src/main.c @@ -56,6 +56,19 @@ int main(int argc, char* argv[]) { cbqn_init(); + // M_b2i* map = m_b2i(16); + // i32 data[] = {5,7,1,5,9,5,3,1,7,9,4,2,6,8,43,3,234,123,5435,435,6745,23,2332,2,3,5,63,3,87}; + // for (i32 i = 0; i < 29; i++) { + // printf("upd %d→%d: %d\n", data[i], i, upd_b2i(&map, m_i32(data[i]), i, false)); + // } + // printf("sz=%ld pop=%ld\n", map->sz, map->pop); + // u64 sz = map->sz; + // for (u64 i = 0; i < sz; i++) { + // Ent_b2i e = map->ent[i]; + // if (e.hash) { print(e.key); printf(": %d\n", e.val); } + // } + // free_b2i(map); + // exit(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) #if defined(COMP_COMP) || defined(COMP_COMP_TIME)