@fraczak/k 6.4.0 → 6.6.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/CHANGELOG.md +17 -0
- package/Examples/arithmetics.k +86 -63
- package/Value.mjs +8 -2
- package/backends/arm64/src/runtime.c +20 -4
- package/backends/arm64/tests/integration.sh +1 -1
- package/backends/llvm/runtime/krt.c +387 -2
- package/backends/llvm/runtime/krt.h +1 -0
- package/backends/llvm/src/kvm2llvm.mjs +98 -29
- package/backends/llvm/tests/perf-support.mjs +1 -1
- package/backends/wasm/TECHNICAL-DEBT.md +11 -13
- package/backends/wasm/runtime.wat +375 -2
- package/backends/wasm/src/kvm2wasm.mjs +36 -0
- package/backends/wasm/src/wasm.mjs +48 -4
- package/backends/wasm/tests/test-wasm.mjs +8 -0
- package/browser/repl-browser.mjs +24 -7
- package/browser/tree-view.mjs +599 -0
- package/browser/vfs-data.mjs +3 -3
- package/codecs/runtime/show-value.mjs +10 -1
- package/package.json +1 -1
- package/repl.mjs +4 -0
- package/scripts/build-repl-html.mjs +301 -0
- package/scripts/perf-ieee.mjs +5 -2
- package/scripts/perf-int.mjs +331 -0
- package/scripts/run-tests.mjs +1 -0
- package/tests/test-repl-html.mjs +141 -0
- package/tests/test-tree-view.mjs +185 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [6.5.0] — 2026-09-22 — Tail-loop arena compaction & OOM diagnostics
|
|
11
|
+
|
|
12
|
+
### WebAssembly Backend
|
|
13
|
+
|
|
14
|
+
- Added threshold-based arena compaction in self-tail-recursive loops to reclaim dead scratch space, allowing deep computations (e.g. multi-thousand-bit arithmetic) without exhausting linear memory.
|
|
15
|
+
- Added explicit Out-Of-Memory error reporting (`OutOfMemoryError`), tracking allocation failure and 32-bit offset overflow via exported runtime globals.
|
|
16
|
+
|
|
17
|
+
### Runtime & REPL
|
|
18
|
+
|
|
19
|
+
- Replaced recursive traversal in `codecs/runtime/show-value.mjs` and `Value.mjs` with iterative loops, eliminating `Maximum call stack size exceeded` errors when rendering deep variant chains.
|
|
20
|
+
|
|
21
|
+
### Examples
|
|
22
|
+
|
|
23
|
+
- Converted arithmetic helper functions in `Examples/arithmetics.k` to tail-recursive relations.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
10
27
|
## [6.2.3] — 2026-06-03 — Unified k compiler output
|
|
11
28
|
|
|
12
29
|
### Toolchain
|
package/Examples/arithmetics.k
CHANGED
|
@@ -39,22 +39,33 @@ empty? = {empty /yes if, () then} .then;
|
|
|
39
39
|
concat = ${bits x, bits y} {.x inv x, .y y} concat_;
|
|
40
40
|
concat_ = ${bits x, bits y}
|
|
41
41
|
<
|
|
42
|
-
{.x
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
{.x empty? if, .y then} .then,
|
|
43
|
+
<
|
|
44
|
+
{.x /0 x, .y |0 y},
|
|
45
|
+
{.x /1 x, .y |1 y}
|
|
46
|
+
> concat_
|
|
45
47
|
>;
|
|
46
48
|
inv = {()x, 0b r} _inv;
|
|
47
|
-
_inv = ${bits x, bits r}
|
|
49
|
+
_inv = ${bits x, bits r}
|
|
50
|
+
<
|
|
51
|
+
{.x empty? if, .r then} .then,
|
|
52
|
+
<
|
|
53
|
+
{.x /0 x, .r |0 r},
|
|
54
|
+
{.x /1 x, .r |1 r}
|
|
55
|
+
> _inv
|
|
56
|
+
>;
|
|
48
57
|
|
|
49
58
|
inOrder = ${bits x, bits y} {.x inv x, .y inv y, yes inOrder} inOrder_;
|
|
50
59
|
inOrder_ = ${bits x, bits y, yes_no inOrder}
|
|
51
60
|
<
|
|
52
|
-
{.x
|
|
53
|
-
{.x /
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
61
|
+
{.x </0,/1> if1, .y /_ if2, .inOrder swap_yes_no then} .then,
|
|
62
|
+
{.x /_ if, .inOrder then} .then,
|
|
63
|
+
<
|
|
64
|
+
{.x /0 x, .y /0 y, .inOrder inOrder},
|
|
65
|
+
{.x /1 x, .y /1 y, .inOrder inOrder},
|
|
66
|
+
{.x /0 x, .y /1 y, .inOrder inOrder},
|
|
67
|
+
{.x /1 y, .y /0 x, .inOrder swap_yes_no inOrder}
|
|
68
|
+
> inOrder_
|
|
58
69
|
>;
|
|
59
70
|
|
|
60
71
|
GT = {inOrder /no if, () then} . then;
|
|
@@ -63,18 +74,21 @@ EQ = GT {.x y, .y x} GT;
|
|
|
63
74
|
|
|
64
75
|
toBitList = {inv x, nil r} _toBitList;
|
|
65
76
|
_toBitList = <
|
|
66
|
-
{.x empty? if, .r then
|
|
67
|
-
|
|
68
|
-
|
|
77
|
+
{.x empty? if, .r then}.then,
|
|
78
|
+
<
|
|
79
|
+
{.x /0 x, {0 car, .r cdr} cons r},
|
|
80
|
+
{.x /1 x, {1 car, .r cdr} cons r}
|
|
81
|
+
> _toBitList
|
|
69
82
|
>;
|
|
70
|
-
fromBitList =
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
>
|
|
83
|
+
fromBitList = {() l, 0b r} _fromBitList inv $bits;
|
|
84
|
+
_fromBitList =
|
|
85
|
+
<
|
|
86
|
+
{.l nil? if, .r then} .then,
|
|
87
|
+
<
|
|
88
|
+
{.l car /0 if, {.l cdr l, .r |0 r} then} .then,
|
|
89
|
+
{.l car /1 if, {.l cdr l, .r |1 r} then} .then
|
|
90
|
+
> _fromBitList
|
|
91
|
+
>;
|
|
78
92
|
|
|
79
93
|
--------------------------------------
|
|
80
94
|
$ int = < bits '+', bits '-' >;
|
|
@@ -99,9 +113,9 @@ inc = $int <
|
|
|
99
113
|
> $int;
|
|
100
114
|
|
|
101
115
|
_inc = ${bits x, bits y} <
|
|
116
|
+
{.x empty? if, .y |1 then} .then,
|
|
102
117
|
{.x /0 x, .y |1 y} concat_,
|
|
103
|
-
{.x /1 x, .y |0 y} _inc
|
|
104
|
-
.y |1
|
|
118
|
+
{.x /1 x, .y |0 y} _inc
|
|
105
119
|
>;
|
|
106
120
|
|
|
107
121
|
dec = $int <
|
|
@@ -149,38 +163,44 @@ _plus_ =
|
|
|
149
163
|
{.x empty? if, .y empty? and, {.r x, 1 r} _inv then} .then,
|
|
150
164
|
{.x empty? if, .c/0 and, {.r x, .y r} _inv then} .then,
|
|
151
165
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
166
|
+
<
|
|
167
|
+
{.x y, .y empty? x, .c c, .r r},
|
|
168
|
+
{<.c/0 0, 1> x, .y y, .x empty? c0 c, .r r},
|
|
155
169
|
|
|
156
|
-
|
|
157
|
-
|
|
170
|
+
{.x /0 x, .y /0 y, .c/0 c0 c, .r |0 r},
|
|
171
|
+
{.x /0 x, .y /0 y, .c/1 c0 c, .r |1 r},
|
|
158
172
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
173
|
+
{.x /0 x, .y /1 y, .c/0 c0 c, .r |1 r},
|
|
174
|
+
{.x /0 x, .y /1 y, .c/1 c1 c, .r |0 r},
|
|
175
|
+
{.x /1 x, .y /0 y, .c/0 c0 c, .r |1 r},
|
|
176
|
+
{.x /1 x, .y /0 y, .c/1 c1 c, .r |0 r},
|
|
163
177
|
|
|
164
|
-
|
|
165
|
-
|
|
178
|
+
{.x /1 x, .y /1 y, .c/0 c1 c, .r |0 r},
|
|
179
|
+
{.x /1 x, .y /1 y, .c/1 c1 c, .r |1 r}
|
|
180
|
+
> _plus_
|
|
166
181
|
>
|
|
167
182
|
;
|
|
168
183
|
|
|
169
|
-
_minus =
|
|
170
|
-
|
|
171
|
-
|
|
184
|
+
_minus = {.x x, .y y, .c c, 0b r} _minus_;
|
|
185
|
+
|
|
186
|
+
_minus_ =
|
|
187
|
+
-- least significant bit first substraction with carry
|
|
188
|
+
${bits x, bits y, carry c, bits r}
|
|
172
189
|
<
|
|
173
|
-
{.
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
190
|
+
{.y empty? if, .c/0 and, {.r x, .x r} _inv then} .then,
|
|
191
|
+
<
|
|
192
|
+
{.x/0 x, .y empty? y, .c/1 c1 c, .r |1 r},
|
|
193
|
+
{.x/1 x, .y empty? y, .c/1 c0 c, .r |0 r},
|
|
194
|
+
|
|
195
|
+
{.x/0 x, .y/0 y, .c/0 c0 c, .r |0 r},
|
|
196
|
+
{.x/0 x, .y/0 y, .c/1 c1 c, .r |1 r},
|
|
197
|
+
{.x/0 x, .y/1 y, .c/0 c1 c, .r |1 r},
|
|
198
|
+
{.x/0 x, .y/1 y, .c/1 c1 c, .r |0 r},
|
|
199
|
+
{.x/1 x, .y/0 y, .c/0 c0 c, .r |1 r},
|
|
200
|
+
{.x/1 x, .y/0 y, .c/1 c0 c, .r |0 r},
|
|
201
|
+
{.x/1 x, .y/1 y, .c/0 c0 c, .r |0 r},
|
|
202
|
+
{.x/1 x, .y/1 y, .c/1 c1 c, .r |1 r}
|
|
203
|
+
> _minus_
|
|
184
204
|
>
|
|
185
205
|
;
|
|
186
206
|
|
|
@@ -212,16 +232,18 @@ _times =
|
|
|
212
232
|
${bits result, bits _x, bits y}
|
|
213
233
|
<
|
|
214
234
|
{ .y empty? if, .result then } .then,
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
{
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
235
|
+
<
|
|
236
|
+
{
|
|
237
|
+
.result |0 result,
|
|
238
|
+
._x _x,
|
|
239
|
+
.y /0 y
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
{._x x, .result |0 y, c0 c } _plus result,
|
|
243
|
+
._x _x,
|
|
244
|
+
.y /1 y
|
|
245
|
+
}
|
|
246
|
+
> _times
|
|
225
247
|
>
|
|
226
248
|
;
|
|
227
249
|
|
|
@@ -327,17 +349,18 @@ lcm =
|
|
|
327
349
|
{{.x int x, .y int y} times x, gcd int y} div .div abs
|
|
328
350
|
;
|
|
329
351
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
352
|
+
factorial = {()n, 1 int acc} factorial_;
|
|
353
|
+
factorial_ = <
|
|
354
|
+
{.n zero_int? if, .acc then} .then,
|
|
355
|
+
{.n pos? dec n, {.n x, .acc y} times acc} factorial_
|
|
333
356
|
>;
|
|
334
357
|
|
|
335
358
|
fib_ =
|
|
336
359
|
<
|
|
360
|
+
{.n int zero_int? if, ."fib(n),fib(n.1)" then} .then,
|
|
337
361
|
{ .n int dec /"+" n,
|
|
338
362
|
."fib(n),fib(n.1)" {plus x, .x y} "fib(n),fib(n.1)"
|
|
339
|
-
} fib_
|
|
340
|
-
."fib(n),fib(n.1)"
|
|
363
|
+
} fib_
|
|
341
364
|
>
|
|
342
365
|
;
|
|
343
366
|
|
package/Value.mjs
CHANGED
|
@@ -176,8 +176,14 @@ class Value {
|
|
|
176
176
|
|
|
177
177
|
toString() {
|
|
178
178
|
if (isVariant(this)) {
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
const tags = [];
|
|
180
|
+
let curr = this;
|
|
181
|
+
while (isVariant(curr)) {
|
|
182
|
+
tags.push(pLabel(curr.tag));
|
|
183
|
+
curr = curr.value;
|
|
184
|
+
}
|
|
185
|
+
const base = curr ? curr.toString() : "";
|
|
186
|
+
return tags.length === 0 ? base : `${base}|${tags.reverse().join("|")}`;
|
|
181
187
|
}
|
|
182
188
|
if (isProduct(this)) {
|
|
183
189
|
return `{${Object.entries(this.product).map(([k, v]) => `${JSON.stringify(k)}:${v.toString()}`).join(',')}}`;
|
|
@@ -5,7 +5,21 @@
|
|
|
5
5
|
#include <string.h>
|
|
6
6
|
#include <time.h>
|
|
7
7
|
|
|
8
|
-
#define
|
|
8
|
+
#define DEFAULT_ARENA_CAPACITY (256 * 1024 * 1024)
|
|
9
|
+
|
|
10
|
+
static int parse_size_arg(const char *text, size_t *out);
|
|
11
|
+
|
|
12
|
+
static size_t get_arena_capacity(void) {
|
|
13
|
+
const char *env = getenv("K_ARENA_CAPACITY_MB");
|
|
14
|
+
if (!env || !*env) env = getenv("K_ARENA_MB");
|
|
15
|
+
if (env && *env) {
|
|
16
|
+
size_t mb = 0;
|
|
17
|
+
if (parse_size_arg(env, &mb) && mb > 0) {
|
|
18
|
+
return mb * 1024 * 1024;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return DEFAULT_ARENA_CAPACITY;
|
|
22
|
+
}
|
|
9
23
|
|
|
10
24
|
typedef enum {
|
|
11
25
|
K_VALUE_UNIT,
|
|
@@ -601,8 +615,10 @@ static int run_bench_main(void *arena_mem, const char *count_text) {
|
|
|
601
615
|
int main(int argc, char **argv) {
|
|
602
616
|
init_tag_registry();
|
|
603
617
|
|
|
618
|
+
size_t arena_capacity = get_arena_capacity();
|
|
619
|
+
|
|
604
620
|
if (argc == 2 && strcmp(argv[1], "--server") == 0) {
|
|
605
|
-
void *arena_mem = malloc(
|
|
621
|
+
void *arena_mem = malloc(arena_capacity);
|
|
606
622
|
if (!arena_mem) return 1;
|
|
607
623
|
int rc = run_server(arena_mem);
|
|
608
624
|
free(arena_mem);
|
|
@@ -610,7 +626,7 @@ int main(int argc, char **argv) {
|
|
|
610
626
|
}
|
|
611
627
|
|
|
612
628
|
if (argc == 3 && strcmp(argv[1], "--bench-main") == 0) {
|
|
613
|
-
void *arena_mem = malloc(
|
|
629
|
+
void *arena_mem = malloc(arena_capacity);
|
|
614
630
|
if (!arena_mem) return 1;
|
|
615
631
|
int rc = run_bench_main(arena_mem, argv[2]);
|
|
616
632
|
free(arena_mem);
|
|
@@ -647,7 +663,7 @@ int main(int argc, char **argv) {
|
|
|
647
663
|
}
|
|
648
664
|
}
|
|
649
665
|
|
|
650
|
-
void *arena_mem = malloc(
|
|
666
|
+
void *arena_mem = malloc(arena_capacity);
|
|
651
667
|
if (!arena_mem) {
|
|
652
668
|
if (in_fp != stdin) fclose(in_fp);
|
|
653
669
|
return 1;
|
|
@@ -105,7 +105,7 @@ node "$K_ROOT/backends/arm64/bin/k-arm64-compile.mjs" \
|
|
|
105
105
|
'{succ int x,int y}+' \
|
|
106
106
|
-o "$TMP_DIR/lib-add"
|
|
107
107
|
|
|
108
|
-
node "$K_ROOT/codecs/k-parse.mjs" <<< '{"x":{"
|
|
108
|
+
node "$K_ROOT/codecs/k-parse.mjs" <<< '{"x":{"0":"_"},"y":{"+":{"0":"_"}}}' |
|
|
109
109
|
"$TMP_DIR/lib-add" --json |
|
|
110
110
|
grep -Fxq '{"+":{"1":"_"}}'
|
|
111
111
|
|