new precompiled bytecode generator
This commit is contained in:
parent
4fb7d486e4
commit
1709fbd2f6
86
build/cc.bqn
86
build/cc.bqn
@ -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∾↩ <𝕩) ⊢ tag⋈≠values}
|
||||
Done ⇐ { 𝕊:
|
||||
unq ← ⊐values
|
||||
uncomp ⇐ {(⍋≠¨ 𝕩/values) ⊏ /𝕩} ∊unq # compressed index → canonical original index; sort by length to make length predictable
|
||||
comp ⇐ (uncomp⊏unq)⊐unq # original index → compressed index
|
||||
counts ⇐ /⁼comp # compressed index → count of such
|
||||
compvals ⇐ uncomp⊏values # 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("∾")"∾˜s∾F∘| ⋄ "m_f64("∾s∾"1.0/0.0)"⟩𝕩} # Format number
|
||||
OAny ← ≡◶⟨@⊸≤◶ONum‿OChr, 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,𝕗⊑LongList‿ConstList⟩ 𝕩}
|
||||
Li ← {"i32" 1 _makeList F¨𝕩}
|
||||
_Lo ← {"B" 0 _makeList 𝔽¨𝕩}
|
||||
OChr2C ← {"m_c32(U'"∾(Esc⥊𝕩)∾"')"} # A BQN character
|
||||
ONum2C ← {s←"-"/˜𝕩<0 ⋄ ∞⊸=∘|◶⟨"m_f64("∾")"∾˜s∾F∘| ⋄ "m_f64("∾s∾"1.0/0.0)"⟩𝕩} # Format number
|
||||
OAny2C ← ≡◶⟨@⊸≤◶ONum2C‿OChr2C, 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 {
|
||||
1‿i: n ← i⊑iarrs.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⊑𝕩? 𝕩;
|
||||
0‿n: ONum2C n;
|
||||
⟨0‿a, 0‿b, ⟨c, d⟩⟩: cs≡⌊cs←a‿b? ∧´cs≥0? ∧´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
|
||||
");"
|
||||
⟩
|
||||
}
|
||||
|
||||
31
src/load.c
31
src/load.c
@ -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());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user