improve pure function detection

This commit is contained in:
dzaima 2025-05-30 02:08:59 +03:00
parent 5c2ac27410
commit 624c74058c
3 changed files with 49 additions and 18 deletions

View File

@ -439,22 +439,33 @@ char* eltype_repr(u8 u) {
}
}
bool isPureFn(B x) { // doesn't consume
if (isCallable(x)) {
if (isPrim(x)) return true;
B2B dcf = TI(x,decompose);
B xd = dcf(inc(x));
B* xdp = harr_ptr(xd);
i32 t = o2iG(xdp[0]);
if (t<2) { decG(xd); return t==0; }
usz xdia = IA(xd);
for (u64 i = 1; i<xdia; i++) if(!isPureFn(xdp[i])) { decG(xd); return false; }
decG(xd); return true;
} else if (isArr(x)) {
usz ia = IA(x);
SGetU(x)
for (usz i = 0; i < ia; i++) if (!isPureFn(GetU(x,i))) return false;
return true;
} else return isNum(x) || isC32(x);
NOGC_CHECK("cannot call isPureFn during noAlloc");
if (!isCallable(x)) return true;
if (isPrim(x)) return true;
B xd = TI(x,decompose)(inc(x));
B* xdp = harr_ptr(xd);
i32 t = o2iG(xdp[0]);
if (t < 2) { decG(xd); return t==0; }
if (t == 5) { // ⟨5, F, _r_, G⟩
if (isPrim(xdp[2]) && RTID(xdp[2])==n_cond) {
B sel = xdp[3];
if (isArr(sel)) {
usz ia = IA(sel);
SGetU(sel)
for (ux i = 0; i < ia; i++) if (!isPureFn(GetU(sel,i))) goto retf;
}
if (isPureFn(xdp[1])) goto rett;
else goto retf;
}
}
usz xdia = IA(xd);
for (ux i = 1; i < xdia; i++) if(!isPureFn(xdp[i])) { retf: decG(xd); return false; }
rett: decG(xd); return true;
}
B bqn_merge(B x, u32 type) {

View File

@ -55,6 +55,14 @@
•internal.HasFill "ab""cde" %% 0
a0 0{𝕊: a1}0˘ 002 a %% 0
a0 0{𝕊: a1}0˘˜002 a %% 0
a0 0{𝕊: a1}0¨ 0 a %% 0
a0 0{𝕊: a1}0¨˜ 0 a %% 0
a0 0{𝕊: a1}0 0 a %% 0
a0 0{𝕊: a1}0˜ 0 a %% 0
# TODO:
# ⟨↑‿3⥊↕10 ⋄ ↑‿3⥊<¨↕10 ⋄ ↑‿3⥊<˘↕10⟩
# 5‿¯5↑⌜⟨↕2 ⋄ "ab" ⋄ <¨↕2 ⋄ <˘↕2⟩

View File

@ -400,16 +400,28 @@ Str ← {!=𝕩 ⋄ !×≠𝕩 ⋄ ! ∧´2=•Type¨𝕩} ⋄ Str •platform.o
•internal.Refc •internal.Unshare 10 %% 1
a•internal.Unshare 10 b10<a ! 11 •internal.Refc a •internal.Keep b
# •internal.IsPure
! 1 •internal.IsPure +
•internal.IsPure¨ @,1,,¨,,{},12,{𝕩}{𝔽}{𝔽𝔾𝕩} %% 81
! 1 •internal.IsPure +¨++
! 1 •internal.IsPure 123+¨++
! 1 •internal.IsPure -
! 0 •internal.IsPure {𝕩}-
! 0 •internal.IsPure 12{𝕩}+¨++ # could be 1
! 1 •internal.IsPure 12{𝕩}+¨++
! 0 •internal.IsPure •show
! 0 •internal.IsPure •file.chars
! 0 •internal.IsPure •internal.keep
! 1 •internal.IsPure •internal.pureKeep
! 0 •internal.IsPure {𝕩}
! 0 •internal.IsPure {𝕩}
! 0 •internal.IsPure {𝕩}
! 0 •internal.IsPure {𝕩}
! 0 •internal.IsPure {𝕩}
! 0 •internal.IsPure {𝕩}¨
! 0 •internal.IsPure {𝔽𝕩}
! 0 •internal.IsPure {𝕩}
! 0 •internal.IsPure {𝔽𝔾𝕩}
! 0 •internal.IsPure {𝕩}
# •internal.Info
•internal.Info 1 %% "3ff0000000000000: not heap-allocated"
33•internal.Info •internal.Unshare 10 %% "fff7: refc:1 type:23=i8arr alloc:"