Skip to content

Commit cb08f38

Browse files
committed
feat(compiler): Arbitrary-position spreads
1 parent 86b092c commit cb08f38

33 files changed

+661
-128
lines changed

compiler/src/codegen/compcore.re

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,15 @@ let equal_mod = "GRAIN$MODULE$runtime/equal";
7676
let equal_ident = Ident.create_persistent("equal");
7777
let equal_closure_ident = Ident.create_persistent("GRAIN$EXPORT$equal");
7878

79+
/* List concat */
80+
let collection_concat_mod = "GRAIN$MODULE$runtime/concat";
81+
let list_concat_ident = Ident.create_persistent("listConcat");
82+
let list_concat_closure_ident =
83+
Ident.create_persistent("GRAIN$EXPORT$listConcat");
84+
let array_concat_ident = Ident.create_persistent("arrayConcat");
85+
let array_concat_closure_ident =
86+
Ident.create_persistent("GRAIN$EXPORT$arrayConcat");
87+
7988
/* JS-runner support */
8089
let console_mod = "console";
8190
let tracepoint_ident = Ident.create_persistent("tracepoint");
@@ -147,6 +156,24 @@ let grain_runtime_imports = [
147156
mimp_setup: MSetupNone,
148157
mimp_used: false,
149158
},
159+
{
160+
mimp_id: list_concat_closure_ident,
161+
mimp_mod: collection_concat_mod,
162+
mimp_name: Ident.name(list_concat_closure_ident),
163+
mimp_type: MGlobalImport(Types.Unmanaged(WasmI32), true),
164+
mimp_kind: MImportWasm,
165+
mimp_setup: MSetupNone,
166+
mimp_used: false,
167+
},
168+
{
169+
mimp_id: array_concat_closure_ident,
170+
mimp_mod: collection_concat_mod,
171+
mimp_name: Ident.name(array_concat_closure_ident),
172+
mimp_type: MGlobalImport(Types.Unmanaged(WasmI32), true),
173+
mimp_kind: MImportWasm,
174+
mimp_setup: MSetupNone,
175+
mimp_used: false,
176+
},
150177
];
151178

152179
let runtime_global_imports =
@@ -230,6 +257,24 @@ let grain_function_imports = [
230257
mimp_setup: MSetupNone,
231258
mimp_used: false,
232259
},
260+
{
261+
mimp_id: list_concat_ident,
262+
mimp_mod: collection_concat_mod,
263+
mimp_name: Ident.name(list_concat_ident),
264+
mimp_type: MFuncImport([Types.Managed, Types.Managed], [Types.Managed]),
265+
mimp_kind: MImportWasm,
266+
mimp_setup: MSetupNone,
267+
mimp_used: false,
268+
},
269+
{
270+
mimp_id: array_concat_ident,
271+
mimp_mod: collection_concat_mod,
272+
mimp_name: Ident.name(array_concat_ident),
273+
mimp_type: MFuncImport([Types.Managed, Types.Managed], [Types.Managed]),
274+
mimp_kind: MImportWasm,
275+
mimp_setup: MSetupNone,
276+
mimp_used: false,
277+
},
233278
];
234279

235280
let runtime_function_imports =
@@ -388,6 +433,44 @@ let call_equal = (wasm_mod, env, args) =>
388433
],
389434
Type.int32,
390435
);
436+
let call_list_concat = (wasm_mod, env, args) => {
437+
let args = [
438+
Expression.Global_get.make(
439+
wasm_mod,
440+
get_wasm_imported_name(
441+
collection_concat_mod,
442+
list_concat_closure_ident,
443+
),
444+
Type.int32,
445+
),
446+
...args,
447+
];
448+
Expression.Call.make(
449+
wasm_mod,
450+
get_wasm_imported_name(collection_concat_mod, list_concat_ident),
451+
args,
452+
Type.int32,
453+
);
454+
};
455+
let call_array_concat = (wasm_mod, env, args) => {
456+
let args = [
457+
Expression.Global_get.make(
458+
wasm_mod,
459+
get_wasm_imported_name(
460+
collection_concat_mod,
461+
array_concat_closure_ident,
462+
),
463+
Type.int32,
464+
),
465+
...args,
466+
];
467+
Expression.Call.make(
468+
wasm_mod,
469+
get_wasm_imported_name(collection_concat_mod, array_concat_ident),
470+
args,
471+
Type.int32,
472+
);
473+
};
391474

392475
/** Will print "tracepoint <n> reached" to the console when executed (for debugging WASM output) */
393476

@@ -3029,6 +3112,14 @@ and compile_instr = (wasm_mod, env, instr) =>
30293112
compile_record_op(wasm_mod, env, record, record_op)
30303113
| MClosureOp(closure_op, closure) =>
30313114
compile_closure_op(wasm_mod, env, closure, closure_op)
3115+
| MCollectionConcat(t, colls) =>
3116+
let colls_arr = allocate_array(wasm_mod, env, colls);
3117+
let concat =
3118+
switch (t) {
3119+
| TExpListConcat => call_list_concat
3120+
| TExpArrayConcat => call_array_concat
3121+
};
3122+
concat(wasm_mod, env, [colls_arr]);
30323123
| MPrim0(p0) => compile_prim0(wasm_mod, env, p0)
30333124
| MPrim1(p1, arg) => compile_prim1(wasm_mod, env, p1, arg, instr.instr_loc)
30343125
| MPrim2(p2, arg1, arg2) => compile_prim2(wasm_mod, env, p2, arg1, arg2)

compiler/src/codegen/mashtree.re

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,7 @@ and instr_desc =
438438
| MAdtOp(adt_op, immediate)
439439
| MRecordOp(record_op, immediate)
440440
| MClosureOp(closure_op, immediate)
441+
| MCollectionConcat(Typedtree.collection_concat_type, list(immediate))
441442
| MStore(list((binding, instr))) /* Items in the same list have their backpatching delayed until the end of that list */
442443
| MSet(binding, instr)
443444
| MDrop(instr, Types.allocation_type) /* Ignore the result of an expression. Used for sequences. */

compiler/src/codegen/transl_anf.re

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ module RegisterAllocation = {
185185
| MArrayOp(aop, i) => MArrayOp(aop, apply_allocation_to_imm(i))
186186
| MRecordOp(rop, i) => MRecordOp(rop, apply_allocation_to_imm(i))
187187
| MAdtOp(aop, i) => MAdtOp(aop, apply_allocation_to_imm(i))
188+
| MCollectionConcat(t, colls) =>
189+
MCollectionConcat(t, List.map(apply_allocation_to_imm, colls))
188190
| MClosureOp(cop, i) => MClosureOp(cop, apply_allocation_to_imm(i))
189191
| MCallRaw({func, func_type, args}) =>
190192
MCallRaw({
@@ -308,6 +310,7 @@ let run_register_allocation = (instrs: list(Mashtree.instr)) => {
308310
| MAdtOp(_, imm)
309311
| MClosureOp(_, imm) => imm_live_local(imm)
310312
| MCallRaw({args: is})
313+
| MCollectionConcat(_, is)
311314
| MError(_, is) => List.concat(List.map(imm_live_local, is))
312315
| MCallKnown({closure: imm, args: is})
313316
| MReturnCallKnown({closure: imm, args: is})
@@ -908,6 +911,8 @@ let rec compile_comp = (~id=?, env, c) => {
908911
MRecordSet(idx, compile_imm(env, arg)),
909912
compile_imm(env, record),
910913
)
914+
| CCollectionConcat(t, lists) =>
915+
MCollectionConcat(t, List.map(compile_imm(env), lists))
911916
| CLambda(name, args, body) =>
912917
let (body, return_type) = body;
913918
let body = (body, [return_type]);

compiler/src/formatting/debug.re

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ let debug_expression = (expr: Parsetree.expression) => {
6161
print_loc("PExpRecordGet", expr.pexp_loc)
6262
| PExpRecordSet(expression, {txt, _}, expression2) =>
6363
print_loc("PExpRecordSet", expr.pexp_loc)
64+
| PExpCollectionConcat(t, colls) =>
65+
print_loc("PExpCollectionConcat", expr.pexp_loc)
6466
| PExpMatch(expression, match_branches) =>
6567
print_loc("PExpMatch", expr.pexp_loc)
6668
| PExpPrim0(prim0) => print_loc("PExpPrim0", expr.pexp_loc)

0 commit comments

Comments
 (0)