diff --git a/src/c32arr.c b/src/c32arr.c index eeaec18f..1938708a 100644 --- a/src/c32arr.c +++ b/src/c32arr.c @@ -55,6 +55,20 @@ 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); } bool c32arr_canStore(B x) { return isC32(x); } + +bool eqStr(B w, u32* x) { + if (!isArr(w) || rnk(w)!=1) return false; + BS2B wget = TI(w).get; + u64 i = 0; + while (x[i]) { + B c = wget(w, i); + if (!isC32(c) || x[i]!=(u32)c.u) return false; + i++; + } + return i==a(w)->ia; +} + + 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; diff --git a/src/fillarr.c b/src/fillarr.c index aeeba4d6..497fca30 100644 --- a/src/fillarr.c +++ b/src/fillarr.c @@ -22,6 +22,17 @@ B asFill(B x) { return bi_noFill; } B withFill(B x, B fill) { + assert(isArr(x)); + switch(v(x)->type) { + case t_i32arr : case t_i32slice : if(fill.u == m_i32(0 ).u) return x; break; + case t_c32arr : case t_c32slice : if(fill.u == m_c32(' ').u) return x; break; + case t_fillarr: case t_fillslice: if (equal(c(FillArr,x)->fill, fill)) return x; + if (reusable(x)) { + c(FillArr, x)->fill = fill; + return x; + } + break; + } B r = m_arr(fsizeof(FillArr,a,B,a(x)->ia), t_fillarr); arr_shCopy(r, x); c(FillArr,r)->fill = fill; diff --git a/src/h.h b/src/h.h index 72703aee..3f998c77 100644 --- a/src/h.h +++ b/src/h.h @@ -73,21 +73,36 @@ enum Type { Type_MAX }; +char* format_type(u8 u) { + switch(u) { default: return"(unknown type)"; + case t_empty:return"empty"; case t_noGC:return"noGC"; + case t_fun_def:return"fun_def"; case t_fun_block:return"fun_block"; + case t_md1_def:return"md1_def"; case t_md1_block:return"md1_block"; + case t_md2_def:return"md2_def"; case t_md2_block:return"md2_block"; + case t_fork:return"fork"; case t_atop:return"atop"; + case t_md1D:return"md1D"; case t_md2D:return"md2D"; case t_md2H:return"md2H"; + case t_harr :return"harr" ; case t_i32arr :return"i32arr" ; case t_fillarr :return"fillarr" ; case t_c32arr :return"c32arr" ; + case t_hslice:return"hslice"; case t_i32slice:return"i32slice"; case t_fillslice:return"fillslice"; case t_c32slice:return"c32slice"; + case t_comp:return"comp"; case t_block:return"block"; case t_body:return"body"; case t_scope:return"scope"; + } +} enum PrimFns { pf_none, pf_add, pf_sub, pf_mul, pf_div, pf_pow, pf_floor, pf_eq, pf_le, pf_log, // arith.c - pf_shape, pf_pick, pf_ud, pf_pair, pf_fne, pf_lt, pf_rt, pf_fmtF, pf_fmtN, // sfns.c + pf_shape, pf_pick, pf_ud, pf_pair, pf_fne, pf_feq, pf_lt, pf_rt, pf_fmtF, pf_fmtN, // sfns.c pf_fork, pf_atop, pf_md1d, pf_md2d, // derv.c - pf_type, pf_decp, pf_primInd, pf_glyph, pf_fill, pf_grLen, pf_grOrd, pf_asrt, // sysfn.c + pf_type, pf_decp, pf_primInd, pf_glyph, pf_fill, // sysfn.c + pf_grLen, pf_grOrd, pf_asrt, pf_sys, pf_internal, // sysfn.c }; char* format_pf(u8 u) { - switch(u) { - default: case pf_none: return"(unknown fn)"; + switch(u) { default: case pf_none: return"(unknown fn)"; case pf_add:return"+"; case pf_sub:return"-"; case pf_mul:return"×"; case pf_div:return"÷"; case pf_pow:return"⋆"; case pf_floor:return"⌊"; case pf_eq:return"="; case pf_le:return"≤"; case pf_log:return"⋆⁼"; - case pf_shape:return"⥊"; case pf_pick:return"⊑"; case pf_ud:return"↕"; case pf_pair:return"{𝕨‿𝕩}"; case pf_fne:return"≢"; case pf_lt:return"⊣"; case pf_rt:return"⊢"; case pf_fmtF:case pf_fmtN:return"⍕"; + case pf_shape:return"⥊"; case pf_pick:return"⊑"; case pf_ud:return"↕"; case pf_pair:return"{𝕨‿𝕩}"; case pf_fne:return"≢"; case pf_feq:return"≡"; case pf_lt:return"⊣"; case pf_rt:return"⊢"; case pf_fmtF:case pf_fmtN:return"⍕"; case pf_fork:return"(fork)"; case pf_atop:return"(atop)"; case pf_md1d:return"(derived 1-modifier)"; case pf_md2d:return"(derived 2-modifier)"; - case pf_type:return"•Type"; case pf_decp:return"•Decompose"; case pf_primInd:return"•PrimInd"; case pf_glyph:return"•Glyph"; case pf_fill:return"•FillFn"; case pf_grLen:return"•GroupLen"; case pf_grOrd:return"•GroupOrd"; case pf_asrt:return"!"; } + case pf_type:return"•Type"; case pf_decp:return"Decompose"; case pf_primInd:return"•PrimInd"; case pf_glyph:return"•Glyph"; case pf_fill:return"•FillFn"; + case pf_grLen:return"•GroupLen"; case pf_grOrd:return"•groupOrd"; case pf_asrt:return"!"; case pf_sys:return"•getsys"; case pf_internal:return"•Internal"; + } } enum PrimMd1 { pm1_none, @@ -283,7 +298,7 @@ typedef bool (*B2b)(B); typedef struct TypeInfo { B2v free; // expects refc==0 - BS2B get; // increments result, doesn't consume arg + BS2B get; // increments result, doesn't consume arg; TODO figure out if this should never allocate, so GC wouldn't happen BB2B m1_d; // consume all args; (m, f) BBB2B m2_d; // consume all args; (m, f, g) BS2B slice; // consumes; create slice from given starting position; add ia, rank, shape yourself @@ -395,6 +410,25 @@ void printRaw(B x) { } } +B eq_c2(B t, B w, B x); +bool equal(B w, B x) { // doesn't consume + bool wa = isArr(w); + bool xa = isArr(x); + if (wa!=xa) return false; + if (!wa) return o2iu(eq_c2(bi_nothing, inc(w), inc(x)))?1:0; + if (!shEq(w,x)) return false; + usz ia = a(x)->ia; + BS2B xget = TI(x).get; + BS2B wget = TI(w).get; + for (usz i = 0; i < ia; i++) { + B wc=wget(w,i); B xc=xget(x,i); // getdec + bool eq=equal(wc,xc); + decR(wc); decR(xc); + if(!eq) return false; + } + return true; +} + typedef struct Fun { diff --git a/src/main.c b/src/main.c index 9ee080d2..e75d097e 100644 --- a/src/main.c +++ b/src/main.c @@ -138,7 +138,7 @@ int main() { // free(c_src); // } - B currentRuntime = FAKE_RUNTIME? frtObj : rtObj; + B compArg = m_v2(FAKE_RUNTIME? frtObj : rtObj, bi_sys); while (true) { // exit by evaluating an empty expression char* ln = NULL; @@ -146,7 +146,7 @@ int main() { getline(&ln, &gl, stdin); if (ln[0]==10) break; B obj = fromUTF8(ln, strlen(ln)); - B cbc = c2(comp, inc(currentRuntime), obj); + B cbc = c2(comp, inc(compArg), obj); free(ln); Block* cbc_b = ca3(cbc); diff --git a/src/sfns.c b/src/sfns.c index 098d1e6a..f787c350 100644 --- a/src/sfns.c +++ b/src/sfns.c @@ -107,14 +107,20 @@ B fmtF_c1(B t, B x) { return m_c32(U"+-×÷⋆√⌊⌈|¬∧∨<>≠=≤≥≡≢⊣⊢⥊∾≍↑↓↕«»⌽⍉/⍋⍒⊏⊑⊐⊒∊⍷⊔!˙˜˘¨⌜⁼´˝`∘○⊸⟜⌾⊘◶⎉⚇⍟"[fl-1]); } +B feq_c2(B t, B w, B x) { + bool r = equal(w, x); + dec(w); dec(x); + return m_i32(r); +} + #define ba(NAME) bi_##NAME = mm_alloc(sizeof(Fun), t_fun_def, ftag(FUN_TAG)); c(Fun,bi_##NAME)->c2 = NAME##_c2; c(Fun,bi_##NAME)->c1 = NAME##_c1 ; c(Fun,bi_##NAME)->extra=pf_##NAME; #define bd(NAME) bi_##NAME = mm_alloc(sizeof(Fun), t_fun_def, ftag(FUN_TAG)); c(Fun,bi_##NAME)->c2 = NAME##_c2; c(Fun,bi_##NAME)->c1 = c1_invalid; c(Fun,bi_##NAME)->extra=pf_##NAME; #define bm(NAME) bi_##NAME = mm_alloc(sizeof(Fun), t_fun_def, ftag(FUN_TAG)); c(Fun,bi_##NAME)->c2 = c2_invalid;c(Fun,bi_##NAME)->c1 = NAME##_c1 ; c(Fun,bi_##NAME)->extra=pf_##NAME; void print_fun_def(B x) { printf("%s", format_pf(c(Fun,x)->extra)); } -B bi_shape, bi_pick, bi_ud, bi_pair, bi_fne, bi_lt, bi_rt, bi_fmtF, bi_fmtN; -void sfns_init() { ba(shape) ba(pick) bm(ud) ba(pair) bm(fne) ba(lt) ba(rt) bm(fmtF) bm(fmtN) +B bi_shape, bi_pick, bi_ud, bi_pair, bi_fne, bi_feq, bi_lt, bi_rt, bi_fmtF, bi_fmtN; +void sfns_init() { ba(shape) ba(pick) bm(ud) ba(pair) bm(fne) bd(feq) ba(lt) ba(rt) bm(fmtF) bm(fmtN) ti[t_fun_def].print = print_fun_def; } diff --git a/src/sysfn.c b/src/sysfn.c index d7ceaf97..f0e47cd1 100644 --- a/src/sysfn.c +++ b/src/sysfn.c @@ -117,14 +117,40 @@ B asrt_c2(B t, B w, B x) { return err("assertion error with message"); } +B internal_c2(B t, B w, B x) { + B r; + u64 id = o2s(w); + if(id==0) { char* c = format_type(v(x)->type); r = m_str8(strlen(c), c); } + else if(id==1) { r = m_i32(v(x)->mmInfo); } + else if(id==2) { r = m_i32(v(x)->refc); } + else return err("Unknown •Internal 𝕨"); + dec(x); + return r; +} +B sys_c1(B t, B x); + #define ba(NAME) bi_##NAME = mm_alloc(sizeof(Fun), t_fun_def, ftag(FUN_TAG)); c(Fun,bi_##NAME)->c2 = NAME##_c2; c(Fun,bi_##NAME)->c1 = NAME##_c1 ; c(Fun,bi_##NAME)->extra=pf_##NAME; #define bd(NAME) bi_##NAME = mm_alloc(sizeof(Fun), t_fun_def, ftag(FUN_TAG)); c(Fun,bi_##NAME)->c2 = NAME##_c2; c(Fun,bi_##NAME)->c1 = c1_invalid; c(Fun,bi_##NAME)->extra=pf_##NAME; #define bm(NAME) bi_##NAME = mm_alloc(sizeof(Fun), t_fun_def, ftag(FUN_TAG)); c(Fun,bi_##NAME)->c2 = c2_invalid;c(Fun,bi_##NAME)->c1 = NAME##_c1 ; c(Fun,bi_##NAME)->extra=pf_##NAME; -B bi_type, bi_decp, bi_primInd, bi_glyph, bi_fill, bi_grLen, bi_grOrd, bi_asrt; -void sysfn_init() { bm(type) bm(decp) bm(primInd) bm(glyph) ba(fill) ba(grLen) bd(grOrd) ba(asrt) } +B bi_type, bi_decp, bi_primInd, bi_glyph, bi_fill, bi_grLen, bi_grOrd, bi_asrt, bi_sys, bi_internal; +void sysfn_init() { bm(type) bm(decp) bm(primInd) bm(glyph) ba(fill) ba(grLen) bd(grOrd) ba(asrt) bm(sys) bd(internal) } #undef ba #undef bd #undef bm + +B sys_c1(B t, B x) { + assert(isArr(x)); + HArr_p r = m_harrc(x); + BS2B xget = TI(x).get; + for (usz i = 0; i < a(x)->ia; i++) { + B c = xget(x,i); + if (eqStr(c, U"internal")) r.a[i] = inc(bi_internal); + else if (eqStr(c, U"eq")) r.a[i] = inc(bi_feq); + else err("Unknown system function"); + } + dec(x); + return r.b; +} \ No newline at end of file