new precompiled bytecode generator

This commit is contained in:
dzaima 2024-09-15 20:07:18 +03:00
parent 4fb7d486e4
commit 1709fbd2f6
2 changed files with 90 additions and 27 deletions

View File

@ -27,33 +27,79 @@ FmtComp ← {
𝕩 i out((i<out)/) 𝕩 # Replace
(i<in) /"\"¨ 𝕩 # Insert \
}
U32Len ( - ·+´ 55296 56319)-@ # for dzaima/BQN; shouldn't break things in proper BQN impls, as surrogate values don't map to valid codepoints
CStr {"""" () Esc 𝕩}
OStr { # A BQN string
List (0<)"",1·","¨
lf @+10
Cache {
tag 𝕩
values
Add {(values <𝕩) tagvalues}
Done { 𝕊:
unq values
uncomp {(¨ 𝕩/values) /𝕩} unq # compressed index → canonical original index; sort by length to make length predictable
comp (uncompunq)unq # original index → compressed index
counts /comp # compressed index → count of such
compvals uncompvalues # compressed index → data
n uncomp
}
}
intarrCache Cache 1
Li intarrCache.Add
_Lo {{"m_lvB_", F𝕩, "(", List 𝕩, ")"} 𝔽¨𝕩}
OStr2C { # A BQN string
a´𝕩<128+@
a"m_c32vec""m_c8vec","(",a¬"U","",CStr𝕩,",",•Repr U32Len 𝕩,")"
}
OChr {"m_c32(U'"(Esc𝕩)"')"} # A BQN character
ONum {s"-"/˜𝕩<0 =|"m_f64("")"˜sF| "m_f64("s"1.0/0.0)"𝕩} # Format number
OAny @ONumOChr, OStr,
List (0<)"",1·","¨
ShortList {"m_lv"𝕨"_"(F𝕩)"("(List𝕩)")"}
LongList {"m_ca"𝕨"("(F𝕩)",("𝕨"[]){"(List𝕩)"})"}
ConstList {"m_ca"𝕨"("(F𝕩)",({static "𝕨" l_[]={"(List𝕩)"};l_;}))"}
_makeList {𝕨 (>4˙)ShortList,𝕗LongListConstList 𝕩}
Li {"i32" 1 _makeList F¨𝕩}
_Lo {"B" 0 _makeList 𝔽¨𝕩}
OChr2C {"m_c32(U'"(Esc𝕩)"')"} # A BQN character
ONum2C {s"-"/˜𝕩<0 =|"m_f64("")"˜sF| "m_f64("s"1.0/0.0)"𝕩} # Format number
OAny2C @ONum2COChr2C, OStr2C,
TmpNum 0
# 0‿123: number
# 1‿n: int arr ref
# ⟨a,b,c⟩: obj arr
# "foo": literal code
a ((𝕩)Li OAny2C¨ {0=´=¨𝕩? Li 𝕩; =TmpNum,Li¨¨ 𝕩}¨ (Li 2)¨ Li¨ OStr2C) {𝕎𝕩}¨ 𝕩
iarrs intarrCache.Done@ Li!
! iarrs.compvals
init
a {
1i: n iiarrs.comp (0=n) "iarrs[",F n,"]", "iarrs0"; # special-case first array (i.e. empty array) as there isn't enough aliasing info for the compiler to deduplicate loads
2=•Type𝕩? 𝕩;
0n: ONum2C n;
0a, 0b, c, d: cscsab? ´cs0? ´cs<4? "m_blockinfo(", F a+b×4, ", ", 𝕊 c, ", ", 𝕊 d, ")";
4𝕩? 𝕊_Lo 𝕩;
n "a" F init
np n"p"
init< lf
"B ", n, "; B* ", np, " = m_lvBn(&", n, ", ", F 𝕩, ");", lf
"assume_separate_storage(", np, ", ", "iarrs", ");", lf # allow the compiler to vectorize copying from iarrs to np if so beneficial
({'('𝕩}¨) {np,"[", F 𝕩, "] = ", 𝕨, ";", lf}¨ 𝕊¨ 𝕩
n
}¨
a ((𝕩)Li OAny¨ {0=´=¨𝕩? Li 𝕩; =ONum,Li¨¨ 𝕩}¨ (Li 2)¨ Li¨ OStr) {𝕎𝕩}¨ 𝕩
a {2=•Type𝕩? 𝕩; 𝕊_Lo 𝕩}¨
"load_importBlock", srcmap/"_src", "(", CStr name, ",", @+10,
(","@+10) Join a
@+10
"B iarrs[", F iarrs.n, "];", lf
"static const i32 iarrs_data[] = {", lf
lf¨ {','¨ F¨ 𝕨, " // ", F 𝕩}¨ iarrs.compvals
"};", lf
"static const u32 iarrs_lens[] = {", ','Join F¨ iarrs.compvals, "};", lf
"init_intarrs(iarrs, iarrs_data, iarrs_lens, ", F iarrs.n, ");", lf
"B iarrs0 = iarrs[0];", lf
{0𝕊𝕩: ""; "incByG(iarrs[", F 𝕩, "], ", F 𝕨, ");", lf}¨ iarrs.counts-1
init
"load_importBlock", srcmap/"_src", "(", CStr name, ",", lf
(','lf) Join " "¨ a
lf
");"
}

View File

@ -23,8 +23,6 @@ FOR_INIT(F)
GLOBAL u64 mm_heapMax = HEAP_MAX;
GLOBAL u64 mm_heapAlloc;
extern Arr* staticSliceRoot;
// compiler result:
// [
// [...bytecode],
@ -104,16 +102,35 @@ GLOBAL B r1Objs[RT_LEN];
B rtWrap_wrap(B x, bool nnbi); // consumes
void rtWrap_print(void);
static NOINLINE B* m_lvBn(B* dst, ux n) { HArr_p p = m_harr0v(n); *dst = p.b; return p.a; } // m_harrUv might be fine for initial init as it doesn't run with GC, but explain is loaded later
static NOINLINE B m_lvB_0( ) { return emptyHVec(); }
static NOINLINE B m_lvB_1(B a ) { return m_hvec1(a); }
static NOINLINE B m_lvB_2(B a, B b ) { return m_hvec2(a,b); }
static NOINLINE B m_lvB_3(B a, B b, B c ) { return m_hvec3(a,b,c); }
static NOINLINE B m_lvB_4(B a, B b, B c, B d) { return m_hvec4(a,b,c,d); }
static NOINLINE B m_lvi32_0( ) { return emptyIVec(); }
static NOINLINE B m_lvi32_1(i32 a ) { i32* rp; B r = m_i32arrv(&rp,1); rp[0]=a; return r; }
static NOINLINE B m_lvi32_2(i32 a, i32 b ) { i32* rp; B r = m_i32arrv(&rp,2); rp[0]=a; rp[1]=b; return r; }
static NOINLINE B m_lvi32_3(i32 a, i32 b, i32 c ) { i32* rp; B r = m_i32arrv(&rp,3); rp[0]=a; rp[1]=b; rp[2]=c; return r; }
static NOINLINE B m_lvi32_4(i32 a, i32 b, i32 c, i32 d) { i32* rp; B r = m_i32arrv(&rp,4); rp[0]=a; rp[1]=b; rp[2]=c; rp[3]=d; return r; }
static NOINLINE B m_blockinfo(ux info, B c, B d) {
return m_lvB_3(m_f64(info&3), m_f64(info>>2), m_lvB_2(c, d));
}
#ifndef __has_builtin
#define __has_builtin(x) 0
#endif
#if __has_builtin(__builtin_assume_separate_storage)
#define assume_separate_storage(A, B) __builtin_assume_separate_storage(A, B)
#else
#define assume_separate_storage(A, B)
#endif
extern Arr* staticSliceRoot;
static NOINLINE void init_intarrs(B* dst, const i32* all_data, const u32* lengths, ux n) {
ptr_incBy(staticSliceRoot, n);
for (ux i = 0; i < n; i++) {
ux len = lengths[i];
dst[i] = taga(arr_shVec(m_tyslice((i32*) all_data, staticSliceRoot, t_i32slice, len)));
all_data+= len;
}
}
static NOINLINE B m_importMap(void) {
return c2(bi_hashMap, emptyHVec(), emptyHVec());