From a90e7de997267f0d8d9192dab048302a89934df9 Mon Sep 17 00:00:00 2001 From: dzaima Date: Tue, 6 Sep 2022 18:22:58 +0300 Subject: [PATCH] simpler atom-array arith on length 0 inputs --- src/singeli/c/arithdDispatch.c | 39 +++++++++++++++++++++++++++++- src/singeli/src/dyarith.singeli | 1 + src/singeli/src/genArithTables.bqn | 13 ++++++---- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/singeli/c/arithdDispatch.c b/src/singeli/c/arithdDispatch.c index 03beabc0..843743db 100644 --- a/src/singeli/c/arithdDispatch.c +++ b/src/singeli/c/arithdDispatch.c @@ -163,6 +163,7 @@ struct DyTableSA { EntSA ents[el_B]; BBB2B mainFn; char* repr; + u8 fill[2][2]; // 0:none 1:int 2:char DyTableSA* chrAtom; }; @@ -186,11 +187,47 @@ B dyArith_SA(DyTableSA* table, B w, B x) { usz ia = IA(x); u8 xe = TI(x,elType); - u8 width, type; // when one argument is a number, both + and - have character array result iif the other argument is a character array; therefore result type doesn't need a lookup + u8 width, type; // the currently supported character functions (+ and -) have the result type be character when left xor right is character, so it can be hard-coded u64 wa; EntSA* e; + if (ia==0) { + u8 fillVal; + bool charX; + if (xe!=el_B) { + charX = elChr(xe); + } else { + B xf = getFillQ(x); + if (isNum(xf)) charX=0; + else if (isC32(xf)) charX=1; + else if (noFill(xf)) { fillVal=0; goto fillSel; } + else { dec(xf); goto rec; } // whatever + } + bool charW; + if (isNum(w)) charW=0; + else if (isC32(w)) charW=1; + else goto rec; + + fillVal = table->fill[charW][charX]; + fillSel: + if (RNK(x)==1) { + decG(x); + if (fillVal==1) return emptyIVec(); + if (fillVal==0) return emptyHVec(); + assert(fillVal==2); + return emptyCVec(); + } else { + Arr* r; + if (fillVal==1) { u64* rp; r = m_bitarrp(&rp, 0); } + else if (fillVal==0) { r = (Arr*) m_harrUp(0).c; } + else { assert(fillVal==2); u8* rp; r = m_c8arrp (&rp, 0); } + arr_shCopy(r, x); + decG(x); + return taga(r); + } + } + if (!isF64(w)) { if (!isC32(w)) goto rec; DyTableSA* t2 = table->chrAtom; diff --git a/src/singeli/src/dyarith.singeli b/src/singeli/src/dyarith.singeli index 88af76c4..77cf3f1c 100644 --- a/src/singeli/src/dyarith.singeli +++ b/src/singeli/src/dyarith.singeli @@ -156,6 +156,7 @@ def arithAA{mode, F, W, X, R} = { # mode: 0:overflow-checked, needed; 1:overflow-erroring; 2: overflow-checked, not needed arithSAf{vw, mode, F, swap, W, X, R}(r:*u8, w:u64, x:*u8, len:u64) : u64 = { # show{fmt_op{F}, swap, mode, W, X, R} + assert{len>0} def bulk = vw / max{width{W}, width{R}} def TY = [bulk]R def overflow = tern{mode==1, {i}=>return{1}, {i}=>return{i}} diff --git a/src/singeli/src/genArithTables.bqn b/src/singeli/src/genArithTables.bqn index d28849b2..f5c020f2 100644 --- a/src/singeli/src/genArithTables.bqn +++ b/src/singeli/src/genArithTables.bqn @@ -133,17 +133,19 @@ Make ← {𝕊ns: tyi ← ⟨@, "i8","i16","i32","f64", "i8","i16","i32"⟩ tyc ← ⟨@, "c8","c16","c32",@, "c8","c16","c32"⟩ isc ← ⟨0, 0, 0, 0, 0, 1, 1, 1⟩ - { 𝕊 swap‿get: - choices ← ns.sa + { 𝕊 swap: + choices ← ⌽⍟swap⌾(2⊸↑)¨ ns.sa hadChrArr ← 0 + ResMap ← {{(2⊑¨𝕩)⌾((2↑¨𝕩)⊸⊑) 2‿2⥊@} 'c'=𝕩} { 0≡≠𝕩? @; charAtm ← 'c' ≡ ⊑⊑𝕩 hasNumArr ← ⊑'i' ∊ 1⊑¨𝕩 hasChrArr ← ⊑'c' ∊ 1⊑¨𝕩 - resChr ← {(2⊑¨𝕩)⌾((2↑¨𝕩)⊸⊑) 2‿2⥊@} 'c'=𝕩 + resChr ← ResMap 𝕩 argarr ← ⌽⍟swap "SA" canOverflow ← "f64"⊸≢¨ tyName + P ← {∾⟨"{",𝕨,",",𝕩,"}"⟩}´ cSrc∾↩ ∾⟨ "static DyTableSA ", cbqn,"DyTable", ⌽⍟swap (charAtm⊑"NC")∾"A", " = {", nl @@ -173,13 +175,14 @@ Make ← {𝕊ns: " },", nl " .chrAtom = ", hadChrArr◶"NULL"‿{𝕊: ∾⟨"&",cbqn,"DyTable", ⌽⍟swap "CA"⟩} @, ",", nl " .mainFn = ", cbqn, "_c2", swap/"R", ",", nl + " .fill = ", P P¨ <˘ '0'+@‿0‿1⊐ResMap choices, ",", nl " .repr = """, repr, """", nl "};", nl ⟩ hadChrArr∨↩ charAtm - }¨ 2↑(("ci"⊐⊑¨)⊔⊢) ⌽⍟swap⌾(2⊸↑)¨ choices - }¨ (2-commutative)↑ ⟨0‿{𝕩.sa} ⋄ 1‿{𝕩.as}⟩ + }¨ 2↑(("ci"⊐⊑¨)⊔⊢) choices + }¨ ↕2-commutative siSrc∾↩ nl }