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.
Files changed (141) hide show
  1. package/dist/ast/nodes.d.ts +3 -3
  2. package/dist/ast/nodes.d.ts.map +1 -1
  3. package/dist/ast/nodes.js +1 -0
  4. package/dist/ast/nodes.js.map +1 -1
  5. package/dist/ast/type-constants.d.ts +12 -0
  6. package/dist/ast/type-constants.d.ts.map +1 -0
  7. package/dist/ast/type-constants.js +16 -0
  8. package/dist/ast/type-constants.js.map +1 -0
  9. package/dist/ast/types.d.ts +1 -1
  10. package/dist/ast/types.d.ts.map +1 -1
  11. package/dist/builtins/builtin-enums.d.ts +12 -0
  12. package/dist/builtins/builtin-enums.d.ts.map +1 -0
  13. package/dist/builtins/builtin-enums.js +45 -0
  14. package/dist/builtins/builtin-enums.js.map +1 -0
  15. package/dist/builtins/builtins.d.ts +24 -0
  16. package/dist/builtins/builtins.d.ts.map +1 -0
  17. package/dist/builtins/builtins.js +691 -0
  18. package/dist/builtins/builtins.js.map +1 -0
  19. package/dist/checker/check.d.ts.map +1 -1
  20. package/dist/checker/check.js +81 -38
  21. package/dist/checker/check.js.map +1 -1
  22. package/dist/checker/type-env.d.ts +2 -0
  23. package/dist/checker/type-env.d.ts.map +1 -1
  24. package/dist/checker/type-env.js +9 -0
  25. package/dist/checker/type-env.js.map +1 -1
  26. package/dist/codegen/browser-host-adapter.d.ts +29 -0
  27. package/dist/codegen/browser-host-adapter.d.ts.map +1 -0
  28. package/dist/codegen/browser-host-adapter.js +51 -0
  29. package/dist/codegen/browser-host-adapter.js.map +1 -0
  30. package/dist/codegen/builtins.d.ts +2 -26
  31. package/dist/codegen/builtins.d.ts.map +1 -1
  32. package/dist/codegen/builtins.js +2 -341
  33. package/dist/codegen/builtins.js.map +1 -1
  34. package/dist/codegen/closures.d.ts +17 -0
  35. package/dist/codegen/closures.d.ts.map +1 -0
  36. package/dist/codegen/closures.js +140 -0
  37. package/dist/codegen/closures.js.map +1 -0
  38. package/dist/codegen/codegen.d.ts +11 -30
  39. package/dist/codegen/codegen.d.ts.map +1 -1
  40. package/dist/codegen/codegen.js +154 -982
  41. package/dist/codegen/codegen.js.map +1 -1
  42. package/dist/codegen/collect-strings.d.ts +4 -0
  43. package/dist/codegen/collect-strings.d.ts.map +1 -0
  44. package/dist/codegen/collect-strings.js +76 -0
  45. package/dist/codegen/collect-strings.js.map +1 -0
  46. package/dist/codegen/compile-calls.d.ts +10 -0
  47. package/dist/codegen/compile-calls.d.ts.map +1 -0
  48. package/dist/codegen/compile-calls.js +344 -0
  49. package/dist/codegen/compile-calls.js.map +1 -0
  50. package/dist/codegen/compile-data.d.ts +22 -0
  51. package/dist/codegen/compile-data.d.ts.map +1 -0
  52. package/dist/codegen/compile-data.js +243 -0
  53. package/dist/codegen/compile-data.js.map +1 -0
  54. package/dist/codegen/compile-match.d.ts +7 -0
  55. package/dist/codegen/compile-match.d.ts.map +1 -0
  56. package/dist/codegen/compile-match.js +195 -0
  57. package/dist/codegen/compile-match.js.map +1 -0
  58. package/dist/codegen/compile-scalars.d.ts +25 -0
  59. package/dist/codegen/compile-scalars.d.ts.map +1 -0
  60. package/dist/codegen/compile-scalars.js +210 -0
  61. package/dist/codegen/compile-scalars.js.map +1 -0
  62. package/dist/codegen/hof-generators.d.ts +39 -0
  63. package/dist/codegen/hof-generators.d.ts.map +1 -0
  64. package/dist/codegen/hof-generators.js +336 -0
  65. package/dist/codegen/hof-generators.js.map +1 -0
  66. package/dist/codegen/host-adapter.d.ts +44 -0
  67. package/dist/codegen/host-adapter.d.ts.map +1 -0
  68. package/dist/codegen/host-adapter.js +9 -0
  69. package/dist/codegen/host-adapter.js.map +1 -0
  70. package/dist/codegen/host-functions.d.ts +35 -0
  71. package/dist/codegen/host-functions.d.ts.map +1 -0
  72. package/dist/codegen/host-functions.js +680 -0
  73. package/dist/codegen/host-functions.js.map +1 -0
  74. package/dist/codegen/imports.d.ts +12 -0
  75. package/dist/codegen/imports.d.ts.map +1 -0
  76. package/dist/codegen/imports.js +162 -0
  77. package/dist/codegen/imports.js.map +1 -0
  78. package/dist/codegen/node-host-adapter.d.ts +35 -0
  79. package/dist/codegen/node-host-adapter.d.ts.map +1 -0
  80. package/dist/codegen/node-host-adapter.js +155 -0
  81. package/dist/codegen/node-host-adapter.js.map +1 -0
  82. package/dist/codegen/runner.d.ts +36 -2
  83. package/dist/codegen/runner.d.ts.map +1 -1
  84. package/dist/codegen/runner.js +146 -271
  85. package/dist/codegen/runner.js.map +1 -1
  86. package/dist/codegen/types.d.ts +91 -0
  87. package/dist/codegen/types.d.ts.map +1 -0
  88. package/dist/codegen/types.js +63 -0
  89. package/dist/codegen/types.js.map +1 -0
  90. package/dist/compact/expand.d.ts +25 -0
  91. package/dist/compact/expand.d.ts.map +1 -0
  92. package/dist/compact/expand.js +198 -0
  93. package/dist/compact/expand.js.map +1 -0
  94. package/dist/compile.d.ts +2 -1
  95. package/dist/compile.d.ts.map +1 -1
  96. package/dist/compile.js +1 -1
  97. package/dist/compile.js.map +1 -1
  98. package/dist/contracts/translate.js.map +1 -1
  99. package/dist/effects/call-graph.d.ts.map +1 -1
  100. package/dist/effects/call-graph.js +6 -2
  101. package/dist/effects/call-graph.js.map +1 -1
  102. package/dist/errors/error-catalog.d.ts +1 -1
  103. package/dist/errors/error-catalog.d.ts.map +1 -1
  104. package/dist/errors/error-catalog.js +119 -0
  105. package/dist/errors/error-catalog.js.map +1 -1
  106. package/dist/errors/structured-errors.d.ts +6 -1
  107. package/dist/errors/structured-errors.d.ts.map +1 -1
  108. package/dist/errors/structured-errors.js +3 -0
  109. package/dist/errors/structured-errors.js.map +1 -1
  110. package/dist/index.d.ts +17 -9
  111. package/dist/index.d.ts.map +1 -1
  112. package/dist/index.js +24 -10
  113. package/dist/index.js.map +1 -1
  114. package/dist/lint/lint.d.ts +9 -0
  115. package/dist/lint/lint.d.ts.map +1 -0
  116. package/dist/lint/lint.js +354 -0
  117. package/dist/lint/lint.js.map +1 -0
  118. package/dist/lint/warnings.d.ts +54 -0
  119. package/dist/lint/warnings.d.ts.map +1 -0
  120. package/dist/lint/warnings.js +39 -0
  121. package/dist/lint/warnings.js.map +1 -0
  122. package/dist/mcp/create-server.d.ts.map +1 -1
  123. package/dist/mcp/create-server.js +66 -5
  124. package/dist/mcp/create-server.js.map +1 -1
  125. package/dist/mcp/handlers.d.ts +18 -4
  126. package/dist/mcp/handlers.d.ts.map +1 -1
  127. package/dist/mcp/handlers.js +54 -12
  128. package/dist/mcp/handlers.js.map +1 -1
  129. package/dist/mcp/prompts.d.ts +17 -0
  130. package/dist/mcp/prompts.d.ts.map +1 -0
  131. package/dist/mcp/prompts.js +181 -0
  132. package/dist/mcp/prompts.js.map +1 -0
  133. package/dist/mcp/server.js +1 -4
  134. package/dist/mcp/server.js.map +1 -1
  135. package/dist/resolver/resolve.d.ts.map +1 -1
  136. package/dist/resolver/resolve.js +22 -8
  137. package/dist/resolver/resolve.js.map +1 -1
  138. package/dist/validator/node-validators.d.ts.map +1 -1
  139. package/dist/validator/node-validators.js +34 -5
  140. package/dist/validator/node-validators.js.map +1 -1
  141. 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