Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions bend2/comp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2712,13 +2712,36 @@ function effect_src(k: Name, tld: Bend.Def & { i: string[] }): void {
// WL_LOAD is a ladder: clang is O(n^2) on a fallthrough switch.

function c_units(): Unit[] {
const lists = tld_of("Array.to_list.go")?.b
&& new Set(FL.book.tmps["Array.to_list.go"]?.values());
for (const [k, tld] of [...done_defs().reverse(),
...done_defs(def_foreign)]) {
unit_new(k, () => {
const [dl, vals] = emit_open(k);
FL.unit!.segs.push(dl.seg);
if (def_foreign(tld)) {
emit_put(dl, null, val_new([ctr_build(dl, k, dl.seg.params)], BOX));
} else if (lists && lists.has(k)) {
const [a, acc] = vals.flatMap((v) => val_own(v));
const T = adt_of(fun_of(k).live[0][2]).x[0];
const el = lay_el(T);
const stride = 2 ** lay_arr(el).lgs;
const [loc] = emit_hold(dl, [arr_loc(dl, a)], "at");
const i = name_local(dl, "i");
const poll = name_local(dl, "poll");
file_push(dl, `u32 ${poll} = 0;`);
fact_when("ctr", "Con", () => facts_ctr(k, FL.book.ctrs.Con,
adt_of(tele_unbind(tld.T).ret).x));
block(dl, `for (u32 ${i} = 1u << blk_cls(${a}); ${i} >= ${stride}u;) {`, () => {
file_push(dl, `if (err_spun(e.mem, &${poll})) { return 0; }`,
`${i} -= ${stride}u;`);
const v = arr_cells(dl, loc, i, el,
`blk_shr(${a}) ? blk_keep(e, $) : e.mem[$]`);
const con = ctr_build(dl, "Con", [val_box(dl, v), acc]);
file_push(dl, `${acc} = ${con};`);
});
file_push(dl, `blk_free(e, ${a});`);
emit_put(dl, null, val_new([acc], BOX));
} else {
emit_body(dl, fun_of(k).h!, tld.T, vals, null);
}
Expand Down
28 changes: 28 additions & 0 deletions tests/compile/array_to_list_device.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Base

def vals(a: Array<U32>) -> U32:
List.foldl(~&1, ~U32, ~U32, ~(s => x => (s * 31 + x : U32)), Array.to_list(~U32, a), 0)

def texts(xs: List<String>) -> Nat:
match xs:
case []: 0n
case h <> t: (String.length(h) + texts(t) : Nat)

def boxed(p: Array<String> & Array<String>) -> U32:
(a, b) = p
xs = Array.to_list(~String, a)
ys = Array.to_list(~String, Array.set(String, b, 0, "changed"))
U32.from_nat((texts(xs) + texts(ys) : Nat))

def fan(+d: Nat, +x: U32) -> U32:
match d:
case 0n:
(vals(Array.set(U32, [x : U32*8n], 6, (x + 1 : U32))) + boxed(Array.fork(String, [U32.show(x) : String*4n])) : U32)
case 1n+p:
a b = fan(p, x) fan(p, (x + 1 : U32))
(a + b : U32)

def main() -> U32:
fan!(6n, 42)

#|2578033920
57 changes: 57 additions & 0 deletions tests/compile/array_to_list_flat.bend
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import Base

type Shape is Data:
Z{}
W{x: U32, y: U32}
S{text: String}

def shape(x: Shape) -> String:
match x:
case Z{}: "z"
case W{x, y}: U32.show(x) ++ ":" ++ U32.show(y)
case S{text}: text

def shapes(xs: List<Shape>) -> String:
match xs:
case []:
""
case h <> t:
shape(h) ++ "/" ++ shapes(t)

def nums(xs: List<U32>, +s: U32) -> U32:
match xs:
case []: s
case h <> t: nums(t, (s * 10 + h : U32))

def funcs(xs: List<(U32 -> U32)>, +s: U32) -> U32:
match xs:
case []: s
case h <> t: funcs(t, (s * 10 + h(3) : U32))

def box(n: U32) -> Array<(U32 -> U32)>:
ALeaf{x => (n + x : U32)}

def shared(p: Array<Shape> & Array<Shape>) -> String:
(a, b) = p
xs = Array.to_list(~Shape, a)
ys = Array.to_list(~Shape, Array.set(Shape, b, 0, S{"changed"}))
shapes(xs) ++ "|" ++ shapes(ys)

def run(+n: U32) -> IO(Unit):
a = Array.set(Shape, Array.set(Shape, [Z{} : Shape*4n], 1, W{n, 2}), 2, S{U32.show(n)})
f = Array.to_list(~(U32 -> U32))
do IO<Unit>:
Unit <- IO.print(U32.show(nums(Array.to_list(~U32, Array.set(U32, [n : U32*4n], 2, 3)), 0)))
Unit <- IO.print(U32.show(funcs(f(ANode{box(n), box(2)}), 0)))
Unit <- IO.print(shared(Array.fork(Shape, a)))
Unit <- IO.print(shapes(Array.to_list.go(~Shape, ALeaf{S{U32.show(n)}}, [S{"tail"}])))
IO.print(Nat.show(List.length(&1, Unit, Array.to_list(~Unit, [Unit{} : Unit*4n]))))

def main() -> IO(Unit):
run(4)

#|4434
#|75
#|z/4:2/4/z/|changed/4:2/4/z/
#|4/tail/
#|4
Loading