edict-lang 1.2.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ast/nodes.d.ts +3 -3
- package/dist/ast/nodes.d.ts.map +1 -1
- package/dist/ast/nodes.js +1 -0
- package/dist/ast/nodes.js.map +1 -1
- package/dist/ast/type-constants.d.ts +12 -0
- package/dist/ast/type-constants.d.ts.map +1 -0
- package/dist/ast/type-constants.js +16 -0
- package/dist/ast/type-constants.js.map +1 -0
- package/dist/ast/types.d.ts +1 -1
- package/dist/ast/types.d.ts.map +1 -1
- package/dist/builtins/builtin-enums.d.ts +12 -0
- package/dist/builtins/builtin-enums.d.ts.map +1 -0
- package/dist/builtins/builtin-enums.js +45 -0
- package/dist/builtins/builtin-enums.js.map +1 -0
- package/dist/builtins/builtins.d.ts +24 -0
- package/dist/builtins/builtins.d.ts.map +1 -0
- package/dist/builtins/builtins.js +691 -0
- package/dist/builtins/builtins.js.map +1 -0
- package/dist/checker/check.d.ts.map +1 -1
- package/dist/checker/check.js +81 -38
- package/dist/checker/check.js.map +1 -1
- package/dist/checker/type-env.d.ts +2 -0
- package/dist/checker/type-env.d.ts.map +1 -1
- package/dist/checker/type-env.js +9 -0
- package/dist/checker/type-env.js.map +1 -1
- package/dist/codegen/browser-host-adapter.d.ts +29 -0
- package/dist/codegen/browser-host-adapter.d.ts.map +1 -0
- package/dist/codegen/browser-host-adapter.js +51 -0
- package/dist/codegen/browser-host-adapter.js.map +1 -0
- package/dist/codegen/builtins.d.ts +2 -26
- package/dist/codegen/builtins.d.ts.map +1 -1
- package/dist/codegen/builtins.js +2 -341
- package/dist/codegen/builtins.js.map +1 -1
- package/dist/codegen/closures.d.ts +17 -0
- package/dist/codegen/closures.d.ts.map +1 -0
- package/dist/codegen/closures.js +140 -0
- package/dist/codegen/closures.js.map +1 -0
- package/dist/codegen/codegen.d.ts +11 -30
- package/dist/codegen/codegen.d.ts.map +1 -1
- package/dist/codegen/codegen.js +154 -982
- package/dist/codegen/codegen.js.map +1 -1
- package/dist/codegen/collect-strings.d.ts +4 -0
- package/dist/codegen/collect-strings.d.ts.map +1 -0
- package/dist/codegen/collect-strings.js +76 -0
- package/dist/codegen/collect-strings.js.map +1 -0
- package/dist/codegen/compile-calls.d.ts +10 -0
- package/dist/codegen/compile-calls.d.ts.map +1 -0
- package/dist/codegen/compile-calls.js +344 -0
- package/dist/codegen/compile-calls.js.map +1 -0
- package/dist/codegen/compile-data.d.ts +22 -0
- package/dist/codegen/compile-data.d.ts.map +1 -0
- package/dist/codegen/compile-data.js +243 -0
- package/dist/codegen/compile-data.js.map +1 -0
- package/dist/codegen/compile-match.d.ts +7 -0
- package/dist/codegen/compile-match.d.ts.map +1 -0
- package/dist/codegen/compile-match.js +195 -0
- package/dist/codegen/compile-match.js.map +1 -0
- package/dist/codegen/compile-scalars.d.ts +25 -0
- package/dist/codegen/compile-scalars.d.ts.map +1 -0
- package/dist/codegen/compile-scalars.js +210 -0
- package/dist/codegen/compile-scalars.js.map +1 -0
- package/dist/codegen/hof-generators.d.ts +39 -0
- package/dist/codegen/hof-generators.d.ts.map +1 -0
- package/dist/codegen/hof-generators.js +336 -0
- package/dist/codegen/hof-generators.js.map +1 -0
- package/dist/codegen/host-adapter.d.ts +44 -0
- package/dist/codegen/host-adapter.d.ts.map +1 -0
- package/dist/codegen/host-adapter.js +9 -0
- package/dist/codegen/host-adapter.js.map +1 -0
- package/dist/codegen/host-functions.d.ts +35 -0
- package/dist/codegen/host-functions.d.ts.map +1 -0
- package/dist/codegen/host-functions.js +680 -0
- package/dist/codegen/host-functions.js.map +1 -0
- package/dist/codegen/imports.d.ts +12 -0
- package/dist/codegen/imports.d.ts.map +1 -0
- package/dist/codegen/imports.js +162 -0
- package/dist/codegen/imports.js.map +1 -0
- package/dist/codegen/node-host-adapter.d.ts +35 -0
- package/dist/codegen/node-host-adapter.d.ts.map +1 -0
- package/dist/codegen/node-host-adapter.js +155 -0
- package/dist/codegen/node-host-adapter.js.map +1 -0
- package/dist/codegen/runner.d.ts +36 -2
- package/dist/codegen/runner.d.ts.map +1 -1
- package/dist/codegen/runner.js +146 -271
- package/dist/codegen/runner.js.map +1 -1
- package/dist/codegen/types.d.ts +91 -0
- package/dist/codegen/types.d.ts.map +1 -0
- package/dist/codegen/types.js +63 -0
- package/dist/codegen/types.js.map +1 -0
- package/dist/compact/expand.d.ts +25 -0
- package/dist/compact/expand.d.ts.map +1 -0
- package/dist/compact/expand.js +198 -0
- package/dist/compact/expand.js.map +1 -0
- package/dist/compile.d.ts +2 -1
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +1 -1
- package/dist/compile.js.map +1 -1
- package/dist/contracts/translate.js.map +1 -1
- package/dist/effects/call-graph.d.ts.map +1 -1
- package/dist/effects/call-graph.js +6 -2
- package/dist/effects/call-graph.js.map +1 -1
- package/dist/errors/error-catalog.d.ts +1 -1
- package/dist/errors/error-catalog.d.ts.map +1 -1
- package/dist/errors/error-catalog.js +119 -0
- package/dist/errors/error-catalog.js.map +1 -1
- package/dist/errors/structured-errors.d.ts +6 -1
- package/dist/errors/structured-errors.d.ts.map +1 -1
- package/dist/errors/structured-errors.js +3 -0
- package/dist/errors/structured-errors.js.map +1 -1
- package/dist/index.d.ts +17 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -10
- package/dist/index.js.map +1 -1
- package/dist/lint/lint.d.ts +9 -0
- package/dist/lint/lint.d.ts.map +1 -0
- package/dist/lint/lint.js +354 -0
- package/dist/lint/lint.js.map +1 -0
- package/dist/lint/warnings.d.ts +54 -0
- package/dist/lint/warnings.d.ts.map +1 -0
- package/dist/lint/warnings.js +39 -0
- package/dist/lint/warnings.js.map +1 -0
- package/dist/mcp/create-server.d.ts.map +1 -1
- package/dist/mcp/create-server.js +66 -5
- package/dist/mcp/create-server.js.map +1 -1
- package/dist/mcp/handlers.d.ts +18 -4
- package/dist/mcp/handlers.d.ts.map +1 -1
- package/dist/mcp/handlers.js +54 -12
- package/dist/mcp/handlers.js.map +1 -1
- package/dist/mcp/prompts.d.ts +17 -0
- package/dist/mcp/prompts.d.ts.map +1 -0
- package/dist/mcp/prompts.js +181 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/server.js +1 -4
- package/dist/mcp/server.js.map +1 -1
- package/dist/resolver/resolve.d.ts.map +1 -1
- package/dist/resolver/resolve.js +22 -8
- package/dist/resolver/resolve.js.map +1 -1
- package/dist/validator/node-validators.d.ts.map +1 -1
- package/dist/validator/node-validators.js +34 -5
- package/dist/validator/node-validators.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Scalar expression compilers — literal, ident, binop, unop, if, let, block
|
|
3
|
+
// =============================================================================
|
|
4
|
+
import binaryen from "binaryen";
|
|
5
|
+
import { wasmValidationError } from "../errors/structured-errors.js";
|
|
6
|
+
import { edictTypeToWasm, } from "./types.js";
|
|
7
|
+
import { allocClosurePair } from "./closures.js";
|
|
8
|
+
import { compileExpr, inferExprWasmType } from "./codegen.js";
|
|
9
|
+
export function compileLiteral(expr, cc) {
|
|
10
|
+
const { mod, strings } = cc;
|
|
11
|
+
const val = expr.value;
|
|
12
|
+
if (typeof val === "boolean") {
|
|
13
|
+
return mod.i32.const(val ? 1 : 0);
|
|
14
|
+
}
|
|
15
|
+
// Int64 literal — value may be string (for >2^53 precision) or number
|
|
16
|
+
if (expr.type?.kind === "basic" && expr.type.name === "Int64") {
|
|
17
|
+
try {
|
|
18
|
+
const big = BigInt(val);
|
|
19
|
+
const low = Number(big & 0xffffffffn);
|
|
20
|
+
const high = Number((big >> 32n) & 0xffffffffn);
|
|
21
|
+
return mod.i64.const(low, high);
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
cc.errors.push(wasmValidationError(`invalid Int64 literal value: ${JSON.stringify(val)}`));
|
|
25
|
+
return mod.unreachable();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (typeof val === "number") {
|
|
29
|
+
// Check type annotation first — 0.0 is integer in JS but Float in Edict
|
|
30
|
+
if (expr.type && expr.type.kind === "basic" && expr.type.name === "Float") {
|
|
31
|
+
return mod.f64.const(val);
|
|
32
|
+
}
|
|
33
|
+
if (Number.isInteger(val)) {
|
|
34
|
+
return mod.i32.const(val);
|
|
35
|
+
}
|
|
36
|
+
return mod.f64.const(val);
|
|
37
|
+
}
|
|
38
|
+
if (typeof val === "string") {
|
|
39
|
+
const interned = strings.intern(val);
|
|
40
|
+
// Return the pointer (offset). The caller/callee will also need
|
|
41
|
+
// the length — for builtin calls we handle this specially in compileCall.
|
|
42
|
+
return mod.i32.const(interned.offset);
|
|
43
|
+
}
|
|
44
|
+
return mod.unreachable();
|
|
45
|
+
}
|
|
46
|
+
export function compileIdent(expr, cc, ctx) {
|
|
47
|
+
const { mod } = cc;
|
|
48
|
+
const local = ctx.getLocal(expr.name);
|
|
49
|
+
if (local) {
|
|
50
|
+
return mod.local.get(local.index, local.type);
|
|
51
|
+
}
|
|
52
|
+
// Check module-level const globals
|
|
53
|
+
const globalType = cc.constGlobals.get(expr.name);
|
|
54
|
+
if (globalType !== undefined) {
|
|
55
|
+
return mod.global.get(expr.name, globalType);
|
|
56
|
+
}
|
|
57
|
+
// Check function table — return a closure pair (table_index, env_ptr=0)
|
|
58
|
+
// This enables `let f = myFunc` to store a function reference as a closure
|
|
59
|
+
const tableIndex = cc.fnTableIndices.get(expr.name);
|
|
60
|
+
if (tableIndex !== undefined) {
|
|
61
|
+
return allocClosurePair(mod, ctx, mod.i32.const(tableIndex), mod.i32.const(0), `ident_${expr.name}`);
|
|
62
|
+
}
|
|
63
|
+
return mod.unreachable();
|
|
64
|
+
}
|
|
65
|
+
export function compileBinop(expr, cc, ctx) {
|
|
66
|
+
const { mod, errors } = cc;
|
|
67
|
+
const left = compileExpr(expr.left, cc, ctx);
|
|
68
|
+
const right = compileExpr(expr.right, cc, ctx);
|
|
69
|
+
// Determine the WASM type from the left operand.
|
|
70
|
+
// Type checker guarantees matching types for both operands.
|
|
71
|
+
const opType = inferExprWasmType(expr.left, cc, ctx);
|
|
72
|
+
const isFloat = opType === binaryen.f64;
|
|
73
|
+
const isInt64 = opType === binaryen.i64;
|
|
74
|
+
switch (expr.op) {
|
|
75
|
+
case "+":
|
|
76
|
+
return isFloat ? mod.f64.add(left, right) : isInt64 ? mod.i64.add(left, right) : mod.i32.add(left, right);
|
|
77
|
+
case "-":
|
|
78
|
+
return isFloat ? mod.f64.sub(left, right) : isInt64 ? mod.i64.sub(left, right) : mod.i32.sub(left, right);
|
|
79
|
+
case "*":
|
|
80
|
+
return isFloat ? mod.f64.mul(left, right) : isInt64 ? mod.i64.mul(left, right) : mod.i32.mul(left, right);
|
|
81
|
+
case "/":
|
|
82
|
+
return isFloat ? mod.f64.div(left, right) : isInt64 ? mod.i64.div_s(left, right) : mod.i32.div_s(left, right);
|
|
83
|
+
case "%":
|
|
84
|
+
if (isFloat) {
|
|
85
|
+
errors.push(wasmValidationError(`modulo (%) not supported for Float`));
|
|
86
|
+
return mod.unreachable();
|
|
87
|
+
}
|
|
88
|
+
return isInt64 ? mod.i64.rem_s(left, right) : mod.i32.rem_s(left, right);
|
|
89
|
+
case "==":
|
|
90
|
+
return isFloat ? mod.f64.eq(left, right) : isInt64 ? mod.i64.eq(left, right) : mod.i32.eq(left, right);
|
|
91
|
+
case "!=":
|
|
92
|
+
return isFloat ? mod.f64.ne(left, right) : isInt64 ? mod.i64.ne(left, right) : mod.i32.ne(left, right);
|
|
93
|
+
case "<":
|
|
94
|
+
return isFloat ? mod.f64.lt(left, right) : isInt64 ? mod.i64.lt_s(left, right) : mod.i32.lt_s(left, right);
|
|
95
|
+
case ">":
|
|
96
|
+
return isFloat ? mod.f64.gt(left, right) : isInt64 ? mod.i64.gt_s(left, right) : mod.i32.gt_s(left, right);
|
|
97
|
+
case "<=":
|
|
98
|
+
return isFloat ? mod.f64.le(left, right) : isInt64 ? mod.i64.le_s(left, right) : mod.i32.le_s(left, right);
|
|
99
|
+
case ">=":
|
|
100
|
+
return isFloat ? mod.f64.ge(left, right) : isInt64 ? mod.i64.ge_s(left, right) : mod.i32.ge_s(left, right);
|
|
101
|
+
case "and":
|
|
102
|
+
return mod.i32.and(left, right);
|
|
103
|
+
case "or":
|
|
104
|
+
return mod.i32.or(left, right);
|
|
105
|
+
case "implies":
|
|
106
|
+
// A implies B ≡ (not A) or B
|
|
107
|
+
return mod.i32.or(mod.i32.eqz(left), right);
|
|
108
|
+
default:
|
|
109
|
+
errors.push(wasmValidationError(`unsupported binop: ${expr.op}`));
|
|
110
|
+
return mod.unreachable();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
export function compileUnop(expr, cc, ctx) {
|
|
114
|
+
const { mod, errors } = cc;
|
|
115
|
+
const operand = compileExpr(expr.operand, cc, ctx);
|
|
116
|
+
const opType = inferExprWasmType(expr.operand, cc, ctx);
|
|
117
|
+
const isFloat = opType === binaryen.f64;
|
|
118
|
+
const isInt64 = opType === binaryen.i64;
|
|
119
|
+
switch (expr.op) {
|
|
120
|
+
case "-":
|
|
121
|
+
return isFloat
|
|
122
|
+
? mod.f64.neg(operand)
|
|
123
|
+
: isInt64
|
|
124
|
+
? mod.i64.sub(mod.i64.const(0, 0), operand)
|
|
125
|
+
: mod.i32.sub(mod.i32.const(0), operand);
|
|
126
|
+
case "not":
|
|
127
|
+
return mod.i32.eqz(operand);
|
|
128
|
+
default:
|
|
129
|
+
errors.push(wasmValidationError(`unsupported unop: ${expr.op}`));
|
|
130
|
+
return mod.unreachable();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export function compileIf(expr, cc, ctx) {
|
|
134
|
+
const { mod } = cc;
|
|
135
|
+
const cond = compileExpr(expr.condition, cc, ctx);
|
|
136
|
+
// Infer the result type from the then-branch's last expression
|
|
137
|
+
const resultType = expr.then.length > 0
|
|
138
|
+
? inferExprWasmType(expr.then[expr.then.length - 1], cc, ctx)
|
|
139
|
+
: binaryen.i32;
|
|
140
|
+
const thenExprs = expr.then.map((e) => compileExpr(e, cc, ctx));
|
|
141
|
+
const thenBody = thenExprs.length === 1
|
|
142
|
+
? thenExprs[0]
|
|
143
|
+
: mod.block(null, thenExprs, resultType);
|
|
144
|
+
if (expr.else) {
|
|
145
|
+
const elseExprs = expr.else.map((e) => compileExpr(e, cc, ctx));
|
|
146
|
+
const elseBody = elseExprs.length === 1
|
|
147
|
+
? elseExprs[0]
|
|
148
|
+
: mod.block(null, elseExprs, resultType);
|
|
149
|
+
return mod.if(cond, thenBody, elseBody);
|
|
150
|
+
}
|
|
151
|
+
return mod.if(cond, thenBody);
|
|
152
|
+
}
|
|
153
|
+
export function compileLet(expr, cc, ctx) {
|
|
154
|
+
const { mod, strings } = cc;
|
|
155
|
+
const wasmType = expr.type
|
|
156
|
+
? edictTypeToWasm(expr.type)
|
|
157
|
+
: inferExprWasmType(expr.value, cc, ctx);
|
|
158
|
+
let edictTypeName;
|
|
159
|
+
if (expr.type && expr.type.kind === "named") {
|
|
160
|
+
edictTypeName = expr.type.name;
|
|
161
|
+
}
|
|
162
|
+
else if (expr.type && expr.type.kind === "option") {
|
|
163
|
+
edictTypeName = "Option";
|
|
164
|
+
}
|
|
165
|
+
else if (expr.type && expr.type.kind === "result") {
|
|
166
|
+
edictTypeName = "Result";
|
|
167
|
+
}
|
|
168
|
+
else if (expr.value.kind === "record_expr") {
|
|
169
|
+
edictTypeName = expr.value.name;
|
|
170
|
+
}
|
|
171
|
+
else if (expr.value.kind === "enum_constructor") {
|
|
172
|
+
edictTypeName = expr.value.enumName;
|
|
173
|
+
}
|
|
174
|
+
const index = ctx.addLocal(expr.name, wasmType, edictTypeName);
|
|
175
|
+
const value = compileExpr(expr.value, cc, ctx);
|
|
176
|
+
const localSet = mod.local.set(index, value);
|
|
177
|
+
// For String-type let bindings, save __str_ret_len into a companion local
|
|
178
|
+
// so the correct length is available when the variable is later used as an argument.
|
|
179
|
+
const isStringType = expr.type?.kind === "basic" && expr.type.name === "String";
|
|
180
|
+
if (isStringType) {
|
|
181
|
+
const lenIndex = ctx.addLocal(`__str_len_${expr.name}`, binaryen.i32);
|
|
182
|
+
if (expr.value.kind === "literal" && typeof expr.value.value === "string") {
|
|
183
|
+
// String literal — length known at compile time
|
|
184
|
+
const interned = strings.intern(expr.value.value);
|
|
185
|
+
return mod.block(null, [
|
|
186
|
+
localSet,
|
|
187
|
+
mod.local.set(lenIndex, mod.i32.const(interned.length)),
|
|
188
|
+
], binaryen.none);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
// Non-literal (host call result, etc.) — capture __str_ret_len
|
|
192
|
+
return mod.block(null, [
|
|
193
|
+
localSet,
|
|
194
|
+
mod.local.set(lenIndex, mod.global.get("__str_ret_len", binaryen.i32)),
|
|
195
|
+
], binaryen.none);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return localSet;
|
|
199
|
+
}
|
|
200
|
+
export function compileBlock(expr, cc, ctx) {
|
|
201
|
+
const { mod } = cc;
|
|
202
|
+
const bodyExprs = expr.body.map((e) => compileExpr(e, cc, ctx));
|
|
203
|
+
if (bodyExprs.length === 0)
|
|
204
|
+
return mod.nop();
|
|
205
|
+
if (bodyExprs.length === 1)
|
|
206
|
+
return bodyExprs[0];
|
|
207
|
+
const blockType = inferExprWasmType(expr.body[expr.body.length - 1], cc, ctx);
|
|
208
|
+
return mod.block(null, bodyExprs, blockType);
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=compile-scalars.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compile-scalars.js","sourceRoot":"","sources":["../../src/codegen/compile-scalars.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import binaryen from "binaryen";
|
|
2
|
+
/**
|
|
3
|
+
* Generate array_map(arrPtr: i32, closurePtr: i32) → i32
|
|
4
|
+
*
|
|
5
|
+
* Allocates a new array, maps each element through the closure, returns result ptr.
|
|
6
|
+
*/
|
|
7
|
+
export declare function generateArrayMap(mod: binaryen.Module): void;
|
|
8
|
+
/**
|
|
9
|
+
* Generate array_filter(arrPtr: i32, closurePtr: i32) → i32
|
|
10
|
+
*
|
|
11
|
+
* Single-pass overalloc: allocates max-length result, filters in one pass,
|
|
12
|
+
* then writes actual count. Tail waste is acceptable (arena allocator).
|
|
13
|
+
*/
|
|
14
|
+
export declare function generateArrayFilter(mod: binaryen.Module): void;
|
|
15
|
+
/**
|
|
16
|
+
* Generate array_reduce(arrPtr: i32, init: i32, closurePtr: i32) → i32
|
|
17
|
+
*
|
|
18
|
+
* Folds array elements into an accumulator via the closure.
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateArrayReduce(mod: binaryen.Module): void;
|
|
21
|
+
/**
|
|
22
|
+
* Generate array_find(arrPtr: i32, closurePtr: i32) → i32
|
|
23
|
+
*
|
|
24
|
+
* Scans array, calls predicate on each element. Returns Option<Int>:
|
|
25
|
+
* - Some(elem): heap-allocated [tag=1][pad(4)][value][pad(4)]
|
|
26
|
+
* - None: heap-allocated [tag=0][pad(4)]
|
|
27
|
+
*
|
|
28
|
+
* Option layout matches the built-in enum: None=tag0/8 bytes, Some=tag1/16 bytes.
|
|
29
|
+
*/
|
|
30
|
+
export declare function generateArrayFind(mod: binaryen.Module): void;
|
|
31
|
+
/**
|
|
32
|
+
* Generate array_sort(arrPtr: i32, closurePtr: i32) → i32
|
|
33
|
+
*
|
|
34
|
+
* Copies the input array to a new heap allocation, then sorts in-place
|
|
35
|
+
* using insertion sort. The comparator closure returns:
|
|
36
|
+
* negative if a < b, 0 if a == b, positive if a > b (C qsort convention).
|
|
37
|
+
*/
|
|
38
|
+
export declare function generateArraySort(mod: binaryen.Module): void;
|
|
39
|
+
//# sourceMappingURL=hof-generators.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hof-generators.d.ts","sourceRoot":"","sources":["../../src/codegen/hof-generators.ts"],"names":[],"mappings":"AAUA,OAAO,QAAQ,MAAM,UAAU,CAAC;AAEhC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAqE3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CAgF9D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CA0D9D;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CA8F5D;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,GAAG,IAAI,CA+I5D"}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// HOF Array Builtin WASM Generation
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// These builtins need call_indirect to invoke closure arguments, so they
|
|
5
|
+
// are generated as internal WASM functions rather than host imports.
|
|
6
|
+
//
|
|
7
|
+
// Array layout: [length:i32][elem0:i32][elem1:i32]...
|
|
8
|
+
// Closure pair: [table_index:i32][env_ptr:i32]
|
|
9
|
+
// Closure calling convention: call_indirect(table, idx, [env_ptr, ...args])
|
|
10
|
+
import binaryen from "binaryen";
|
|
11
|
+
/**
|
|
12
|
+
* Generate array_map(arrPtr: i32, closurePtr: i32) → i32
|
|
13
|
+
*
|
|
14
|
+
* Allocates a new array, maps each element through the closure, returns result ptr.
|
|
15
|
+
*/
|
|
16
|
+
export function generateArrayMap(mod) {
|
|
17
|
+
// Params: arrPtr=0, closurePtr=1
|
|
18
|
+
// Locals: length=2, tableIdx=3, envPtr=4, resultPtr=5, i=6
|
|
19
|
+
const paramType = binaryen.createType([binaryen.i32, binaryen.i32]);
|
|
20
|
+
const vars = [
|
|
21
|
+
binaryen.i32, // length
|
|
22
|
+
binaryen.i32, // tableIdx
|
|
23
|
+
binaryen.i32, // envPtr
|
|
24
|
+
binaryen.i32, // resultPtr
|
|
25
|
+
binaryen.i32, // i
|
|
26
|
+
];
|
|
27
|
+
const arrPtr = 0, closurePtr = 1, length = 2, tableIdx = 3, envPtr = 4, resultPtr = 5, idx = 6;
|
|
28
|
+
// callbackType: (env:i32, elem:i32) → i32
|
|
29
|
+
const callbackParamType = binaryen.createType([binaryen.i32, binaryen.i32]);
|
|
30
|
+
const body = mod.block(null, [
|
|
31
|
+
// length = i32.load(arrPtr, 0)
|
|
32
|
+
mod.local.set(length, mod.i32.load(0, 0, mod.local.get(arrPtr, binaryen.i32))),
|
|
33
|
+
// tableIdx = i32.load(closurePtr, 0)
|
|
34
|
+
mod.local.set(tableIdx, mod.i32.load(0, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
35
|
+
// envPtr = i32.load(closurePtr, 4)
|
|
36
|
+
mod.local.set(envPtr, mod.i32.load(4, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
37
|
+
// resultPtr = __heap_ptr
|
|
38
|
+
mod.local.set(resultPtr, mod.global.get("__heap_ptr", binaryen.i32)),
|
|
39
|
+
// __heap_ptr += 4 + length * 4
|
|
40
|
+
mod.global.set("__heap_ptr", mod.i32.add(mod.global.get("__heap_ptr", binaryen.i32), mod.i32.add(mod.i32.const(4), mod.i32.mul(mod.local.get(length, binaryen.i32), mod.i32.const(4))))),
|
|
41
|
+
// i32.store(resultPtr, 0, length)
|
|
42
|
+
mod.i32.store(0, 0, mod.local.get(resultPtr, binaryen.i32), mod.local.get(length, binaryen.i32)),
|
|
43
|
+
// i = 0
|
|
44
|
+
mod.local.set(idx, mod.i32.const(0)),
|
|
45
|
+
// loop
|
|
46
|
+
mod.if(mod.i32.gt_s(mod.local.get(length, binaryen.i32), mod.i32.const(0)), mod.loop("map_loop", mod.block(null, [
|
|
47
|
+
// result[i] = call_indirect(tableIdx, [envPtr, arr[i]])
|
|
48
|
+
mod.i32.store(4, 0, // offset 4 + i*4 from resultPtr
|
|
49
|
+
mod.i32.add(mod.local.get(resultPtr, binaryen.i32), mod.i32.mul(mod.local.get(idx, binaryen.i32), mod.i32.const(4))), mod.call_indirect("__fn_table", mod.local.get(tableIdx, binaryen.i32), [
|
|
50
|
+
mod.local.get(envPtr, binaryen.i32),
|
|
51
|
+
// arr[i] = i32.load(arrPtr + 4 + i*4)
|
|
52
|
+
mod.i32.load(4, 0, mod.i32.add(mod.local.get(arrPtr, binaryen.i32), mod.i32.mul(mod.local.get(idx, binaryen.i32), mod.i32.const(4)))),
|
|
53
|
+
], callbackParamType, binaryen.i32)),
|
|
54
|
+
// i++
|
|
55
|
+
mod.local.set(idx, mod.i32.add(mod.local.get(idx, binaryen.i32), mod.i32.const(1))),
|
|
56
|
+
// br_if map_loop (i < length)
|
|
57
|
+
mod.br("map_loop", mod.i32.lt_s(mod.local.get(idx, binaryen.i32), mod.local.get(length, binaryen.i32))),
|
|
58
|
+
], binaryen.none))),
|
|
59
|
+
// return resultPtr
|
|
60
|
+
mod.local.get(resultPtr, binaryen.i32),
|
|
61
|
+
], binaryen.i32);
|
|
62
|
+
mod.addFunction("array_map", paramType, binaryen.i32, vars, body);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Generate array_filter(arrPtr: i32, closurePtr: i32) → i32
|
|
66
|
+
*
|
|
67
|
+
* Single-pass overalloc: allocates max-length result, filters in one pass,
|
|
68
|
+
* then writes actual count. Tail waste is acceptable (arena allocator).
|
|
69
|
+
*/
|
|
70
|
+
export function generateArrayFilter(mod) {
|
|
71
|
+
// Params: arrPtr=0, closurePtr=1
|
|
72
|
+
// Locals: length=2, tableIdx=3, envPtr=4, resultPtr=5, i=6, count=7, elem=8
|
|
73
|
+
const paramType = binaryen.createType([binaryen.i32, binaryen.i32]);
|
|
74
|
+
const vars = [
|
|
75
|
+
binaryen.i32, // length
|
|
76
|
+
binaryen.i32, // tableIdx
|
|
77
|
+
binaryen.i32, // envPtr
|
|
78
|
+
binaryen.i32, // resultPtr
|
|
79
|
+
binaryen.i32, // i
|
|
80
|
+
binaryen.i32, // count
|
|
81
|
+
binaryen.i32, // elem
|
|
82
|
+
];
|
|
83
|
+
const arrPtr = 0, closurePtr = 1, length = 2, tableIdx = 3, envPtr = 4, resultPtr = 5, idx = 6, count = 7, elem = 8;
|
|
84
|
+
// callbackType: (env:i32, elem:i32) → i32 (bool)
|
|
85
|
+
const callbackParamType = binaryen.createType([binaryen.i32, binaryen.i32]);
|
|
86
|
+
const body = mod.block(null, [
|
|
87
|
+
// length = i32.load(arrPtr, 0)
|
|
88
|
+
mod.local.set(length, mod.i32.load(0, 0, mod.local.get(arrPtr, binaryen.i32))),
|
|
89
|
+
// tableIdx = i32.load(closurePtr, 0)
|
|
90
|
+
mod.local.set(tableIdx, mod.i32.load(0, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
91
|
+
// envPtr = i32.load(closurePtr, 4)
|
|
92
|
+
mod.local.set(envPtr, mod.i32.load(4, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
93
|
+
// resultPtr = __heap_ptr (overalloc: 4 + length*4)
|
|
94
|
+
mod.local.set(resultPtr, mod.global.get("__heap_ptr", binaryen.i32)),
|
|
95
|
+
mod.global.set("__heap_ptr", mod.i32.add(mod.global.get("__heap_ptr", binaryen.i32), mod.i32.add(mod.i32.const(4), mod.i32.mul(mod.local.get(length, binaryen.i32), mod.i32.const(4))))),
|
|
96
|
+
// count = 0, i = 0
|
|
97
|
+
mod.local.set(count, mod.i32.const(0)),
|
|
98
|
+
mod.local.set(idx, mod.i32.const(0)),
|
|
99
|
+
// loop
|
|
100
|
+
mod.if(mod.i32.gt_s(mod.local.get(length, binaryen.i32), mod.i32.const(0)), mod.loop("filter_loop", mod.block(null, [
|
|
101
|
+
// elem = arr[i]
|
|
102
|
+
mod.local.set(elem, mod.i32.load(4, 0, mod.i32.add(mod.local.get(arrPtr, binaryen.i32), mod.i32.mul(mod.local.get(idx, binaryen.i32), mod.i32.const(4))))),
|
|
103
|
+
// if call_indirect(tableIdx, [envPtr, elem]) != 0
|
|
104
|
+
mod.if(mod.call_indirect("__fn_table", mod.local.get(tableIdx, binaryen.i32), [
|
|
105
|
+
mod.local.get(envPtr, binaryen.i32),
|
|
106
|
+
mod.local.get(elem, binaryen.i32),
|
|
107
|
+
], callbackParamType, binaryen.i32), mod.block(null, [
|
|
108
|
+
// result[count] = elem
|
|
109
|
+
mod.i32.store(4, 0, mod.i32.add(mod.local.get(resultPtr, binaryen.i32), mod.i32.mul(mod.local.get(count, binaryen.i32), mod.i32.const(4))), mod.local.get(elem, binaryen.i32)),
|
|
110
|
+
// count++
|
|
111
|
+
mod.local.set(count, mod.i32.add(mod.local.get(count, binaryen.i32), mod.i32.const(1))),
|
|
112
|
+
], binaryen.none)),
|
|
113
|
+
// i++
|
|
114
|
+
mod.local.set(idx, mod.i32.add(mod.local.get(idx, binaryen.i32), mod.i32.const(1))),
|
|
115
|
+
// br_if filter_loop (i < length)
|
|
116
|
+
mod.br("filter_loop", mod.i32.lt_s(mod.local.get(idx, binaryen.i32), mod.local.get(length, binaryen.i32))),
|
|
117
|
+
], binaryen.none))),
|
|
118
|
+
// Write actual count as result length
|
|
119
|
+
mod.i32.store(0, 0, mod.local.get(resultPtr, binaryen.i32), mod.local.get(count, binaryen.i32)),
|
|
120
|
+
// return resultPtr
|
|
121
|
+
mod.local.get(resultPtr, binaryen.i32),
|
|
122
|
+
], binaryen.i32);
|
|
123
|
+
mod.addFunction("array_filter", paramType, binaryen.i32, vars, body);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Generate array_reduce(arrPtr: i32, init: i32, closurePtr: i32) → i32
|
|
127
|
+
*
|
|
128
|
+
* Folds array elements into an accumulator via the closure.
|
|
129
|
+
*/
|
|
130
|
+
export function generateArrayReduce(mod) {
|
|
131
|
+
// Params: arrPtr=0, init=1, closurePtr=2
|
|
132
|
+
// Locals: length=3, tableIdx=4, envPtr=5, acc=6, i=7
|
|
133
|
+
const paramType = binaryen.createType([binaryen.i32, binaryen.i32, binaryen.i32]);
|
|
134
|
+
const vars = [
|
|
135
|
+
binaryen.i32, // length
|
|
136
|
+
binaryen.i32, // tableIdx
|
|
137
|
+
binaryen.i32, // envPtr
|
|
138
|
+
binaryen.i32, // acc
|
|
139
|
+
binaryen.i32, // i
|
|
140
|
+
];
|
|
141
|
+
const arrPtr = 0, init = 1, closurePtr = 2, length = 3, tableIdx = 4, envPtr = 5, acc = 6, idx = 7;
|
|
142
|
+
// callbackType: (env:i32, acc:i32, elem:i32) → i32
|
|
143
|
+
const callbackParamType = binaryen.createType([binaryen.i32, binaryen.i32, binaryen.i32]);
|
|
144
|
+
const body = mod.block(null, [
|
|
145
|
+
// length = i32.load(arrPtr, 0)
|
|
146
|
+
mod.local.set(length, mod.i32.load(0, 0, mod.local.get(arrPtr, binaryen.i32))),
|
|
147
|
+
// tableIdx = i32.load(closurePtr, 0)
|
|
148
|
+
mod.local.set(tableIdx, mod.i32.load(0, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
149
|
+
// envPtr = i32.load(closurePtr, 4)
|
|
150
|
+
mod.local.set(envPtr, mod.i32.load(4, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
151
|
+
// acc = init
|
|
152
|
+
mod.local.set(acc, mod.local.get(init, binaryen.i32)),
|
|
153
|
+
// i = 0
|
|
154
|
+
mod.local.set(idx, mod.i32.const(0)),
|
|
155
|
+
// loop
|
|
156
|
+
mod.if(mod.i32.gt_s(mod.local.get(length, binaryen.i32), mod.i32.const(0)), mod.loop("reduce_loop", mod.block(null, [
|
|
157
|
+
// acc = call_indirect(tableIdx, [envPtr, acc, arr[i]])
|
|
158
|
+
mod.local.set(acc, mod.call_indirect("__fn_table", mod.local.get(tableIdx, binaryen.i32), [
|
|
159
|
+
mod.local.get(envPtr, binaryen.i32),
|
|
160
|
+
mod.local.get(acc, binaryen.i32),
|
|
161
|
+
mod.i32.load(4, 0, mod.i32.add(mod.local.get(arrPtr, binaryen.i32), mod.i32.mul(mod.local.get(idx, binaryen.i32), mod.i32.const(4)))),
|
|
162
|
+
], callbackParamType, binaryen.i32)),
|
|
163
|
+
// i++
|
|
164
|
+
mod.local.set(idx, mod.i32.add(mod.local.get(idx, binaryen.i32), mod.i32.const(1))),
|
|
165
|
+
// br_if reduce_loop (i < length)
|
|
166
|
+
mod.br("reduce_loop", mod.i32.lt_s(mod.local.get(idx, binaryen.i32), mod.local.get(length, binaryen.i32))),
|
|
167
|
+
], binaryen.none))),
|
|
168
|
+
// return acc
|
|
169
|
+
mod.local.get(acc, binaryen.i32),
|
|
170
|
+
], binaryen.i32);
|
|
171
|
+
mod.addFunction("array_reduce", paramType, binaryen.i32, vars, body);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Generate array_find(arrPtr: i32, closurePtr: i32) → i32
|
|
175
|
+
*
|
|
176
|
+
* Scans array, calls predicate on each element. Returns Option<Int>:
|
|
177
|
+
* - Some(elem): heap-allocated [tag=1][pad(4)][value][pad(4)]
|
|
178
|
+
* - None: heap-allocated [tag=0][pad(4)]
|
|
179
|
+
*
|
|
180
|
+
* Option layout matches the built-in enum: None=tag0/8 bytes, Some=tag1/16 bytes.
|
|
181
|
+
*/
|
|
182
|
+
export function generateArrayFind(mod) {
|
|
183
|
+
// Params: arrPtr=0, closurePtr=1
|
|
184
|
+
// Locals: length=2, tableIdx=3, envPtr=4, i=5, elem=6, resultPtr=7
|
|
185
|
+
const paramType = binaryen.createType([binaryen.i32, binaryen.i32]);
|
|
186
|
+
const vars = [
|
|
187
|
+
binaryen.i32, // length
|
|
188
|
+
binaryen.i32, // tableIdx
|
|
189
|
+
binaryen.i32, // envPtr
|
|
190
|
+
binaryen.i32, // i
|
|
191
|
+
binaryen.i32, // elem
|
|
192
|
+
binaryen.i32, // resultPtr
|
|
193
|
+
];
|
|
194
|
+
const arrPtr = 0, closurePtr = 1, length = 2, tableIdx = 3, envPtr = 4, idx = 5, elem = 6, resultPtr = 7;
|
|
195
|
+
// callbackType: (env:i32, elem:i32) → i32 (bool)
|
|
196
|
+
const callbackParamType = binaryen.createType([binaryen.i32, binaryen.i32]);
|
|
197
|
+
// Inner loop block label — we use "find_block" so we can br out on match
|
|
198
|
+
const body = mod.block(null, [
|
|
199
|
+
// length = i32.load(arrPtr, 0)
|
|
200
|
+
mod.local.set(length, mod.i32.load(0, 0, mod.local.get(arrPtr, binaryen.i32))),
|
|
201
|
+
// tableIdx = i32.load(closurePtr, 0)
|
|
202
|
+
mod.local.set(tableIdx, mod.i32.load(0, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
203
|
+
// envPtr = i32.load(closurePtr, 4)
|
|
204
|
+
mod.local.set(envPtr, mod.i32.load(4, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
205
|
+
// i = 0
|
|
206
|
+
mod.local.set(idx, mod.i32.const(0)),
|
|
207
|
+
// Search loop — break out when found
|
|
208
|
+
mod.if(mod.i32.gt_s(mod.local.get(length, binaryen.i32), mod.i32.const(0)), mod.block("find_block", [
|
|
209
|
+
mod.loop("find_loop", mod.block(null, [
|
|
210
|
+
// elem = arr[i]
|
|
211
|
+
mod.local.set(elem, mod.i32.load(4, 0, mod.i32.add(mod.local.get(arrPtr, binaryen.i32), mod.i32.mul(mod.local.get(idx, binaryen.i32), mod.i32.const(4))))),
|
|
212
|
+
// if predicate(elem) → return Some(elem)
|
|
213
|
+
mod.if(mod.call_indirect("__fn_table", mod.local.get(tableIdx, binaryen.i32), [
|
|
214
|
+
mod.local.get(envPtr, binaryen.i32),
|
|
215
|
+
mod.local.get(elem, binaryen.i32),
|
|
216
|
+
], callbackParamType, binaryen.i32), mod.block(null, [
|
|
217
|
+
// Allocate Some(elem): [tag=1][pad][value][pad] = 16 bytes
|
|
218
|
+
mod.local.set(resultPtr, mod.global.get("__heap_ptr", binaryen.i32)),
|
|
219
|
+
mod.global.set("__heap_ptr", mod.i32.add(mod.global.get("__heap_ptr", binaryen.i32), mod.i32.const(16))),
|
|
220
|
+
// Write tag = 1 (Some)
|
|
221
|
+
mod.i32.store(0, 0, mod.local.get(resultPtr, binaryen.i32), mod.i32.const(1)),
|
|
222
|
+
// Write value at offset 8
|
|
223
|
+
mod.i32.store(8, 0, mod.local.get(resultPtr, binaryen.i32), mod.local.get(elem, binaryen.i32)),
|
|
224
|
+
// Break out of search block
|
|
225
|
+
mod.br("find_block"),
|
|
226
|
+
], binaryen.none)),
|
|
227
|
+
// i++
|
|
228
|
+
mod.local.set(idx, mod.i32.add(mod.local.get(idx, binaryen.i32), mod.i32.const(1))),
|
|
229
|
+
// br_if find_loop (i < length)
|
|
230
|
+
mod.br("find_loop", mod.i32.lt_s(mod.local.get(idx, binaryen.i32), mod.local.get(length, binaryen.i32))),
|
|
231
|
+
], binaryen.none)),
|
|
232
|
+
// If we reach here, no match found → allocate None
|
|
233
|
+
mod.local.set(resultPtr, mod.global.get("__heap_ptr", binaryen.i32)),
|
|
234
|
+
mod.global.set("__heap_ptr", mod.i32.add(mod.global.get("__heap_ptr", binaryen.i32), mod.i32.const(8))),
|
|
235
|
+
// Write tag = 0 (None)
|
|
236
|
+
mod.i32.store(0, 0, mod.local.get(resultPtr, binaryen.i32), mod.i32.const(0)),
|
|
237
|
+
], binaryen.none),
|
|
238
|
+
// Empty array → allocate None
|
|
239
|
+
mod.block(null, [
|
|
240
|
+
mod.local.set(resultPtr, mod.global.get("__heap_ptr", binaryen.i32)),
|
|
241
|
+
mod.global.set("__heap_ptr", mod.i32.add(mod.global.get("__heap_ptr", binaryen.i32), mod.i32.const(8))),
|
|
242
|
+
mod.i32.store(0, 0, mod.local.get(resultPtr, binaryen.i32), mod.i32.const(0)),
|
|
243
|
+
], binaryen.none)),
|
|
244
|
+
// return resultPtr
|
|
245
|
+
mod.local.get(resultPtr, binaryen.i32),
|
|
246
|
+
], binaryen.i32);
|
|
247
|
+
mod.addFunction("array_find", paramType, binaryen.i32, vars, body);
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Generate array_sort(arrPtr: i32, closurePtr: i32) → i32
|
|
251
|
+
*
|
|
252
|
+
* Copies the input array to a new heap allocation, then sorts in-place
|
|
253
|
+
* using insertion sort. The comparator closure returns:
|
|
254
|
+
* negative if a < b, 0 if a == b, positive if a > b (C qsort convention).
|
|
255
|
+
*/
|
|
256
|
+
export function generateArraySort(mod) {
|
|
257
|
+
// Params: arrPtr=0, closurePtr=1
|
|
258
|
+
// Locals: length=2, tableIdx=3, envPtr=4, resultPtr=5,
|
|
259
|
+
// i=6, j=7, key=8, cmpResult=9
|
|
260
|
+
const paramType = binaryen.createType([binaryen.i32, binaryen.i32]);
|
|
261
|
+
const vars = [
|
|
262
|
+
binaryen.i32, // length
|
|
263
|
+
binaryen.i32, // tableIdx
|
|
264
|
+
binaryen.i32, // envPtr
|
|
265
|
+
binaryen.i32, // resultPtr
|
|
266
|
+
binaryen.i32, // i (outer loop)
|
|
267
|
+
binaryen.i32, // j (inner loop)
|
|
268
|
+
binaryen.i32, // key
|
|
269
|
+
binaryen.i32, // cmpResult
|
|
270
|
+
];
|
|
271
|
+
const arrPtr = 0, closurePtr = 1, length = 2, tableIdx = 3, envPtr = 4, resultPtr = 5, i = 6, j = 7, key = 8;
|
|
272
|
+
// callbackType: (env:i32, a:i32, b:i32) → i32
|
|
273
|
+
const callbackParamType = binaryen.createType([binaryen.i32, binaryen.i32, binaryen.i32]);
|
|
274
|
+
// Helper: result[idx] = i32.load(resultPtr + 4 + idx*4)
|
|
275
|
+
const loadResult = (idxLocal) => mod.i32.load(4, 0, mod.i32.add(mod.local.get(resultPtr, binaryen.i32), mod.i32.mul(mod.local.get(idxLocal, binaryen.i32), mod.i32.const(4))));
|
|
276
|
+
const storeResult = (idxLocal, value) => mod.i32.store(4, 0, mod.i32.add(mod.local.get(resultPtr, binaryen.i32), mod.i32.mul(mod.local.get(idxLocal, binaryen.i32), mod.i32.const(4))), value);
|
|
277
|
+
const body = mod.block(null, [
|
|
278
|
+
// length = i32.load(arrPtr, 0)
|
|
279
|
+
mod.local.set(length, mod.i32.load(0, 0, mod.local.get(arrPtr, binaryen.i32))),
|
|
280
|
+
// tableIdx = i32.load(closurePtr, 0)
|
|
281
|
+
mod.local.set(tableIdx, mod.i32.load(0, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
282
|
+
// envPtr = i32.load(closurePtr, 4)
|
|
283
|
+
mod.local.set(envPtr, mod.i32.load(4, 0, mod.local.get(closurePtr, binaryen.i32))),
|
|
284
|
+
// Allocate result array: [length][elem0]...[elemN-1]
|
|
285
|
+
mod.local.set(resultPtr, mod.global.get("__heap_ptr", binaryen.i32)),
|
|
286
|
+
mod.global.set("__heap_ptr", mod.i32.add(mod.global.get("__heap_ptr", binaryen.i32), mod.i32.add(mod.i32.const(4), mod.i32.mul(mod.local.get(length, binaryen.i32), mod.i32.const(4))))),
|
|
287
|
+
// Write length header
|
|
288
|
+
mod.i32.store(0, 0, mod.local.get(resultPtr, binaryen.i32), mod.local.get(length, binaryen.i32)),
|
|
289
|
+
// Copy elements from input to result
|
|
290
|
+
mod.local.set(i, mod.i32.const(0)),
|
|
291
|
+
mod.if(mod.i32.gt_s(mod.local.get(length, binaryen.i32), mod.i32.const(0)), mod.loop("copy_loop", mod.block(null, [
|
|
292
|
+
storeResult(i, mod.i32.load(4, 0, mod.i32.add(mod.local.get(arrPtr, binaryen.i32), mod.i32.mul(mod.local.get(i, binaryen.i32), mod.i32.const(4))))),
|
|
293
|
+
mod.local.set(i, mod.i32.add(mod.local.get(i, binaryen.i32), mod.i32.const(1))),
|
|
294
|
+
mod.br("copy_loop", mod.i32.lt_s(mod.local.get(i, binaryen.i32), mod.local.get(length, binaryen.i32))),
|
|
295
|
+
], binaryen.none))),
|
|
296
|
+
// Insertion sort: for i = 1 to length-1
|
|
297
|
+
mod.if(mod.i32.gt_s(mod.local.get(length, binaryen.i32), mod.i32.const(1)), mod.block(null, [
|
|
298
|
+
mod.local.set(i, mod.i32.const(1)),
|
|
299
|
+
mod.loop("sort_outer", mod.block(null, [
|
|
300
|
+
// key = result[i]
|
|
301
|
+
mod.local.set(key, loadResult(i)),
|
|
302
|
+
// j = i - 1
|
|
303
|
+
mod.local.set(j, mod.i32.sub(mod.local.get(i, binaryen.i32), mod.i32.const(1))),
|
|
304
|
+
// Inner loop: while j >= 0 && compare(result[j], key) > 0
|
|
305
|
+
mod.block("shift_break", [
|
|
306
|
+
mod.loop("shift_loop", mod.block(null, [
|
|
307
|
+
// if j < 0, break
|
|
308
|
+
mod.br("shift_break", mod.i32.lt_s(mod.local.get(j, binaryen.i32), mod.i32.const(0))),
|
|
309
|
+
// cmp = compare(result[j], key)
|
|
310
|
+
// if cmp <= 0, break
|
|
311
|
+
mod.br("shift_break", mod.i32.le_s(mod.call_indirect("__fn_table", mod.local.get(tableIdx, binaryen.i32), [
|
|
312
|
+
mod.local.get(envPtr, binaryen.i32),
|
|
313
|
+
loadResult(j),
|
|
314
|
+
mod.local.get(key, binaryen.i32),
|
|
315
|
+
], callbackParamType, binaryen.i32), mod.i32.const(0))),
|
|
316
|
+
// result[j+1] = result[j]
|
|
317
|
+
mod.i32.store(4, 0, mod.i32.add(mod.local.get(resultPtr, binaryen.i32), mod.i32.mul(mod.i32.add(mod.local.get(j, binaryen.i32), mod.i32.const(1)), mod.i32.const(4))), loadResult(j)),
|
|
318
|
+
// j--
|
|
319
|
+
mod.local.set(j, mod.i32.sub(mod.local.get(j, binaryen.i32), mod.i32.const(1))),
|
|
320
|
+
mod.br("shift_loop"),
|
|
321
|
+
], binaryen.none)),
|
|
322
|
+
], binaryen.none),
|
|
323
|
+
// result[j+1] = key
|
|
324
|
+
mod.i32.store(4, 0, mod.i32.add(mod.local.get(resultPtr, binaryen.i32), mod.i32.mul(mod.i32.add(mod.local.get(j, binaryen.i32), mod.i32.const(1)), mod.i32.const(4))), mod.local.get(key, binaryen.i32)),
|
|
325
|
+
// i++
|
|
326
|
+
mod.local.set(i, mod.i32.add(mod.local.get(i, binaryen.i32), mod.i32.const(1))),
|
|
327
|
+
// br_if sort_outer (i < length)
|
|
328
|
+
mod.br("sort_outer", mod.i32.lt_s(mod.local.get(i, binaryen.i32), mod.local.get(length, binaryen.i32))),
|
|
329
|
+
], binaryen.none)),
|
|
330
|
+
], binaryen.none)),
|
|
331
|
+
// return resultPtr
|
|
332
|
+
mod.local.get(resultPtr, binaryen.i32),
|
|
333
|
+
], binaryen.i32);
|
|
334
|
+
mod.addFunction("array_sort", paramType, binaryen.i32, vars, body);
|
|
335
|
+
}
|
|
336
|
+
//# sourceMappingURL=hof-generators.js.map
|