@fraczak/k 6.10.4 → 6.10.6

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 CHANGED
@@ -5,6 +5,70 @@ All notable changes to this project will be documented here.
5
5
  The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
6
6
  This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [6.10.6] — 2026-10-08 — Minimal Core Schema and REPL VFS Uploads
9
+
10
+ ### Core Schema & Language
11
+
12
+ - **Minimal `core.k` Schema**:
13
+ - Streamlined `core.k` to focus strictly on structural type schemas
14
+ and pattern foundations.
15
+ - Removed legacy bit arithmetic (`succ`, `plus`, `times`, constants
16
+ `2`..`10`, and helpers `inv`, `concat`), achieving a 39% reduction
17
+ in file size.
18
+ - Retained `$bit`, `$bits`, `_`, `0`, `1`, `$string`, `$unicode`, and
19
+ `$pattern` definitions intact for type derivation and codecs.
20
+
21
+ ### Web REPL & VFS
22
+
23
+ - **VFS Namespace Flattening**:
24
+ - Flattened VFS back to root filenames (`int.mjs`, `json.mjs`,
25
+ `utf8.mjs`, `unit.mjs`, `ieee.mjs`), ensuring consistent resolution
26
+ across browser and CLI environments.
27
+ - **Upload File Directly to VFS**:
28
+ - Updated "Upload" action to strictly add uploaded files into the VFS
29
+ without auto-loading or evaluating them as K code.
30
+ - Enables uploading JavaScript codecs, JSON payloads, and test vectors.
31
+ - Expanded file picker `accept` filter to allow `.mjs`, `.js`, and
32
+ `.json` files.
33
+ - Supported `:codec load` for `.js` codecs in the VFS explorer modal.
34
+
35
+ ---
36
+
37
+ ## [6.10.5] — 2026-10-08 — Adaptive Division and VFS Codecs
38
+
39
+ ### Arithmetic & Algorithms
40
+
41
+ - **Adaptive Hybrid Division (`Examples/arithmetics.k`)**:
42
+ - Implemented hybrid integer division that dynamically chooses between
43
+ down-shift division ($|x| < 2|y|$) and restoring long division
44
+ ($|x| \ge 2|y|$).
45
+ - Down-shift division scales divisor $y$ up to match length of $x$,
46
+ performing trial subtraction and down-shifting in $O(1)$ per step.
47
+ - Crossover condition is evaluated structurally in $O(\min(|y|, |x|/2))$
48
+ without prior length computations.
49
+ - Added native number-theory operations: `mod`, Euclidean `gcd`, and
50
+ `lcm`.
51
+ - Refactored `arithmetics.k` to focus purely on arithmetic operations.
52
+
53
+ ### Polymorphic Lists
54
+
55
+ - **Polymorphic List Library (`Examples/poly.k`)**:
56
+ - Encapsulated list constructors and destructors (`list?`, `nil`,
57
+ `cons`, `car`, `cdr`, `singleton`, `nil?`) directly in `poly.k`.
58
+ - Updated benchmark suites (`harness/suites/poly.mjs`,
59
+ `scripts/perf-poly.mjs`) to import only arithmetic symbols from
60
+ `arithmetics.k`.
61
+
62
+ ### Web REPL & Codecs
63
+
64
+ - **VFS Codec Subfolder Organization**:
65
+ - Reorganized all codec files in the Virtual File System under the
66
+ `codecs/` subfolder (`codecs/int.mjs`, `codecs/json.mjs`, etc.).
67
+ - Added backward-compatible resolution in `repl-codecs.mjs`.
68
+ - Added `karatsuba-mult.k` to the VFS and example picker in `repl.html`.
69
+
70
+ ---
71
+
8
72
  ## [6.10.4] — 2026-10-06 — Karatsuba Multiplication, Multi-Backend Harness, and CLI Help
9
73
 
10
74
  ### Arithmetic & Algorithms
@@ -4,14 +4,6 @@ swap_yes_no = < /yes |no, /no |yes > $yes_no;
4
4
  yes = {}|yes $yes_no;
5
5
  no = yes swap_yes_no;
6
6
 
7
- list? = ?< {} nil, {X car, Y cdr} cons > = Y;
8
- nil = {}|nil list?;
9
- singleton = {() car, nil cdr} |cons list?;
10
- cons = {.car car, .cdr cdr} |cons list?;
11
- nil? = list? / nil nil;
12
- car = list? /cons .car;
13
- cdr = list? /cons .cdr;
14
-
15
7
  $ bits = < {} _, bits 0, bits 1 >;
16
8
 
17
9
  0b = {} | _;
@@ -70,29 +62,10 @@ inOrder_ = ${bits x, bits y, yes_no inOrder}
70
62
 
71
63
  GT = {inOrder /no if, () then} . then;
72
64
 
73
- EQ = GT {.x y, .y x} GT;
74
-
75
- toBitList = {inv x, nil r} _toBitList;
76
- _toBitList = <
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
82
- >;
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
- >;
65
+ EQ = {inOrder /yes if, {.x y, .y x} inOrder /yes and, () then} .then;
92
66
 
93
67
  --------------------------------------
94
68
  $ int = < bits '+', bits '-' >;
95
- $ ints = <{int car, ints cdr} cons, {} nil>;
96
69
 
97
70
  remove_leading_zeros = <
98
71
  /0 remove_leading_zeros,
@@ -102,7 +75,7 @@ nat = remove_leading_zeros <empty? 0, ()>;
102
75
  int = nat | '+' $int;
103
76
  abs = $int </'+',/'-'>;
104
77
 
105
- pos? = $int {dec /'+' if, () then} .then;
78
+ pos? = $int {/'+' remove_leading_zeros /1 if, () then} .then;
106
79
  neg? = $int {/'-' if, () then} .then;
107
80
  zero_int? = $int {/'+' /0 empty? if, () then} .then;
108
81
  minus_one? = $int {/'-' /1 empty? if, () then} .then;
@@ -125,12 +98,12 @@ dec = $int <
125
98
  /'-' {inv x, 0b y} _inc nat |'-'
126
99
  > $int;
127
100
 
128
- _dec = ?{X x, X y, ...} <
101
+ _dec = ${bits x, bits y} <
129
102
  {.x /1 x, .y |0 y} concat_,
130
103
  {.x /0 x, .y |1 y} _dec
131
- > ?X;
104
+ >;
132
105
 
133
- $carry = <{} 0, {} 1>;
106
+ $ carry = <{} 0, {} 1>;
134
107
  c0 = {}|0 $carry;
135
108
  c1 = {}|1 $carry;
136
109
 
@@ -218,7 +191,7 @@ times = ${int x, int y}
218
191
  sign_minus
219
192
  > sign,
220
193
  {
221
- 0 result,
194
+ 0b result,
222
195
  .x abs inv _x,
223
196
  .y abs y
224
197
  } _times result
@@ -249,105 +222,244 @@ _times =
249
222
  ;
250
223
 
251
224
 
252
- mod =
253
- ${bits x, bits y}
254
- -- _log!
255
- <
256
- -- if y > x then (x mod y) = x
257
- {.y x, .x y} GT .y,
258
- -- else, i.e.
259
- -- if x >= y then (x mod y) = ((x-y mod 2y) mod y)
260
- {
261
- {
262
- {.x int x, .y int y} minus /"+" x,
263
- .y inv |0 inv y
264
- } mod x,
265
- .y y
266
- } mod
267
- >
268
- ;
269
225
 
270
226
 
271
- // gratest common divisor
272
- gcd = ${bits x, bits y}
273
- <
274
- {.y x, .x y} GT,
275
- ()
276
- > _gcd
277
- ;
278
227
 
279
- _gcd = <
280
- { .y /0 if, .x then } .then,
281
- { .y x, mod y } _gcd
282
- >;
228
+ // ----------------------------------------------------------------------
229
+ // Integer Division: Adaptive Hybrid Algorithm
230
+ //
231
+ // Combines two complementary strategies based on the bit-length
232
+ // comparison between dividend x and divisor y (|x| vs |y|):
233
+ //
234
+ // 1. Down-Shift Division (|x| < 2|y|, y is large relative to x):
235
+ // - Scales y up to y_max = y * 2^k to match length(x) via 'y inv'
236
+ // and prepending k zeros (|0).
237
+ // - In each step: trial subtraction x = x - y_scaled, then down-shifts
238
+ // y_scaled by 1 bit in O(1) by popping the outer zero (/_0).
239
+ // - Runs in exactly (|x| - |y| + 1) iterations. When y ~= x, this
240
+ // terminates in 1-2 steps rather than looping through all bits of x.
241
+ //
242
+ // 2. Restoring Division (|x| >= 2|y|, y is small relative to x):
243
+ // - Consumes bits of x from MSB to LSB into remainder accumulator r.
244
+ // - Remainder r stays small (r <= 2y), so trial subtractions operate
245
+ // on tiny numbers of length |y| rather than full-length |x|.
246
+ //
247
+ // The crossover condition |x| < 2|y| is evaluated structurally in
248
+ // O(min(|y|, |x|/2)) by consuming 2 bits of x for every 1 bit of y.
249
+ // ----------------------------------------------------------------------
250
+
251
+ // Helpers for Restoring Division (shift-and-subtract)
252
+ shift_in_0 = inv |0 inv nat;
253
+ shift_in_1 = inv |1 inv nat;
254
+ sub_bits = ${bits x, bits y} {.x inv x, .y inv y, c0 c} _minus inv nat;
255
+
256
+ _div_restoring =
257
+ ${bits x, bits y, bits r, bits q}
258
+ <
259
+ {.x empty? if, {.q inv int div, .r rem} then} .then,
260
+ <
261
+ {.x /0 x, .r shift_in_0 r, .y y, .q q},
262
+ {.x /1 x, .r shift_in_1 r, .y y, .q q}
263
+ >
264
+ {
265
+ .x x,
266
+ .y y,
267
+ .q q,
268
+ .r r,
269
+ {.y x, .r y} inOrder test
270
+ }
271
+ <
272
+ {.test /yes if, {.x x, .y y, .q |1 q, {.r x, .y y} sub_bits r} then} .then,
273
+ {.test /no if, {.x x, .y y, .q |0 q, .r r} then} .then
274
+ >
275
+ _div_restoring
276
+ >;
283
277
 
278
+ // Helpers for Down-Shift Division (align and shift divisor down)
279
+ // Phase 1: pad _y with |0 to match length of x, counting shift steps
280
+ _pad_down = ${bits x, bits _y, bits steps}
281
+ <
282
+ {.x empty? if, {._y _y, .steps steps} then} .then,
283
+ {
284
+ .x </0, /1> x,
285
+ ._y |0 _y,
286
+ .steps |0 steps
287
+ } _pad_down
288
+ >;
284
289
 
290
+ _align_down = ${bits x, bits y, bits _y}
291
+ <
292
+ // Both x and y have bits remaining: advance both
293
+ {
294
+ .x </0, /1> x,
295
+ .y </0, /1> y,
296
+ ._y _y
297
+ } _align_down,
285
298
 
286
- // div
299
+ // y is empty while x remains: pad _y with shift zeros
300
+ {
301
+ .y empty? if,
302
+ {.x x, ._y _y, 0b steps} _pad_down then
303
+ } .then,
287
304
 
288
- log2_floor =
289
- ${bits x, bits step}
290
- -- finds the largest k, such that 'step * 2^k <= x',
291
- -- returns k1_, i.e., 0 if x < step, and k1_ otherwise.
292
- {.x x, .step step, 0 log} log2_floor_;
305
+ // Both x and y are empty: lengths equal (0 shift steps)
306
+ {
307
+ .x empty? if,
308
+ .y empty? and,
309
+ {._y _y, 0b steps} then
310
+ } .then
311
+ >;
293
312
 
294
- log2_floor_ = <
295
- {{.step x,.x y} GT if, .log then} .then,
296
- {.x x, {.step x,0 y} GT {.x x,2 y} {.x int x, .y int y} times abs step, .log int inc abs log} log2_floor_
297
- >;
313
+ // Phase 2: down-shift trial subtraction
314
+ _div_down = ${bits x, bits _y, bits steps, bits q}
315
+ {
316
+ .x x,
317
+ ._y _y,
318
+ .steps steps,
319
+ .q q,
320
+ ._y inv nat y_scaled
321
+ }
322
+ {
323
+ .x x,
324
+ ._y _y,
325
+ .steps steps,
326
+ .q q,
327
+ .y_scaled y_scaled,
328
+ {.y_scaled x, .x y} inOrder test
329
+ }
330
+ <
331
+ // If x >= y_scaled, subtract and emit quotient bit 1
332
+ {
333
+ .test /yes if,
334
+ {
335
+ {.x int x, .y_scaled int y} minus /+ x,
336
+ .q |1 q,
337
+ ._y _y,
338
+ .steps steps
339
+ } then
340
+ } .then,
341
+ // If x < y_scaled, keep x and emit quotient bit 0
342
+ {
343
+ .test /no if,
344
+ {.x x, .q |0 q, ._y _y, .steps steps} then
345
+ } .then
346
+ >
347
+ <
348
+ // If no more shift steps remaining, division is complete
349
+ {
350
+ .steps empty? if,
351
+ {.q inv int div, .x rem} then
352
+ } .then,
353
+ // Otherwise down-shift: remove the last 0 from _y and steps
354
+ {
355
+ .x x,
356
+ ._y /0 _y,
357
+ .steps /0 steps,
358
+ .q q
359
+ } _div_down
360
+ >;
298
361
 
362
+ $ choose_div = < {} down_shift, {} restore >;
299
363
 
300
- x_times_2_to_k =
301
- ${bits x, bits k}
302
- {.x inv _x, .k int k} _x_times_2_to_the_power_of_k inv
303
- ;
364
+ // Evaluates whether |x| < 2|y| by advancing 2 bits of x per 1 bit of y
365
+ _check_2y = ${bits x, bits y}
366
+ <
367
+ // x is empty -> |x| < 2|y| (choose down_shift)
368
+ {.x empty? if, {} | down_shift $choose_div then} .then,
369
+ // y is empty while x remains -> |x| >= 2|y| (choose restore)
370
+ {.y empty? if, {} | restore $choose_div then} .then,
371
+ // x has only 1 bit left while y remains -> |x| < 2|y|
372
+ {.x </0, /1> empty? if, {} | down_shift $choose_div then} .then,
373
+ // Advance 2 bits from x and 1 bit from y
374
+ {
375
+ .x </0, /1> </0, /1> x,
376
+ .y </0, /1> y
377
+ } _check_2y
378
+ >;
304
379
 
305
- _x_times_2_to_the_power_of_k = <
306
- {.k zero_int? if, ._x then} .then,
307
- {._x |0 _x, .k dec k} _x_times_2_to_the_power_of_k
308
- >
309
- ;
310
-
311
- div =
312
- ${int x, int y}
313
- // remember sign
380
+ // Public division interface
381
+ div = ${int x, int y}
314
382
  {
315
383
  <
316
384
  { .x/'+' if, .y get_sign then } .then,
317
- { .x/'-' if, .y swap_sign get_sign then } .then
385
+ { .x/'-' if, .y swap_sign get_sign then } .then
318
386
  > sign,
319
- {.x abs x, .y abs step, 0 int res} _div res_wo_sign
387
+ .x abs remove_leading_zeros x_norm,
388
+ .y abs remove_leading_zeros y_norm
320
389
  }
321
- <
322
- {.sign/'+' if, {.res_wo_sign.div div, .res_wo_sign.rem rem} then} .then,
323
- { .res_wo_sign.div swap_sign div, .res_wo_sign.rem rem }
324
- >
325
- ;
326
-
327
- _div =
328
- {
329
- .x x,
330
- .step step,
331
- .res res,
332
- {.x x, .step step} log2_floor log
333
- }
334
- <
335
- { .log int zero_int? if, {.res div, .x rem} then } .then,
336
- {
337
- {1 x, .log int dec abs k} x_times_2_to_k factor,
338
- () i
339
- }
390
+ <
391
+ // Case 1: x == 0 -> quotient 0, remainder 0
392
+ {
393
+ .x_norm empty? if,
394
+ { 0 int div, 0 rem } then
395
+ } .then,
396
+ // Case 2: |x| < |y| -> x < y, quotient 0, remainder x
397
+ {
398
+ {.y_norm x, .x_norm y} GT if,
399
+ { 0 int div, .x_norm rem } then
400
+ } .then,
401
+ // Case 3: general division via adaptive hybrid choice
340
402
  {
341
- {.i.x int x, {.i.step int x, .factor int y} times y} minus abs x,
342
- .i.step step,
343
- {.i.res x, .factor int y} plus res
344
- } _div
403
+ .sign sign,
404
+ {
405
+ .x_norm x,
406
+ .y_norm y,
407
+ {.x_norm x, .y_norm y} _check_2y choice
408
+ }
409
+ <
410
+ // If |x| < 2|y|, use down-shift division
411
+ {
412
+ .choice /down_shift if,
413
+ {
414
+ .x x,
415
+ {.x x, .y y, .y inv _y} _align_down aligned
416
+ }
417
+ {
418
+ .x x,
419
+ .aligned._y _y,
420
+ .aligned.steps steps,
421
+ 0b q
422
+ } _div_down then
423
+ } .then,
424
+ // If |x| >= 2|y|, use restoring long division
425
+ {
426
+ .choice /restore if,
427
+ {.x x, .y y, 0 r, 0b q} _div_restoring then
428
+ } .then
429
+ > res
430
+ }
431
+ <
432
+ {.sign/'+' if, {.res.div div, .res.rem rem} then} .then,
433
+ { .res.div swap_sign div, .res.rem rem }
434
+ >
345
435
  >;
346
436
 
347
437
 
438
+ // ----------------------------------------------------------------------
439
+ // Number Theory: Modulo, Greatest Common Divisor, Least Common Multiple
440
+ // ----------------------------------------------------------------------
441
+
442
+ // Modulo: remainder of x divided by y in $bits, delegated to div
443
+ mod = ${bits x, bits y}
444
+ {{.x int x, .y int y} div .rem rem} .rem;
445
+
446
+ // Greatest common divisor (Euclidean algorithm)
447
+ gcd = ${bits x, bits y}
448
+ <
449
+ {.y x, .x y} GT,
450
+ ()
451
+ > _gcd
452
+ ;
453
+
454
+ _gcd = <
455
+ { .y remove_leading_zeros empty? if, .x nat then } .then,
456
+ { .y x, mod y } _gcd
457
+ >;
458
+
459
+ // Least common multiple: (x / gcd(x, y)) * y
348
460
  lcm =
349
461
  ${bits x, bits y}
350
- {{.x int x, .y int y} times x, gcd int y} div .div abs
462
+ {{.x int x, gcd int y} div .div x, .y int y} times abs
351
463
  ;
352
464
 
353
465
  factorial = {()n, 1 int acc} factorial_;
package/Examples/poly.k CHANGED
@@ -1,8 +1,16 @@
1
1
  -- Examples/poly.k: Polymorphic list functions in k
2
- -- Uses list constructors/destructors from Examples/list.k
3
- -- and arbitrary-precision integer representations from Examples/arithmetics.k.
4
-
5
- -- Decrement an integer and normalize its representation (stripping leading zeros)
2
+ -- Uses arbitrary-precision integers from Examples/arithmetics.k.
3
+
4
+ -- List constructors and destructors
5
+ list? = ?< {} nil, {X car, Y cdr} cons > = Y;
6
+ nil = {} | nil list?;
7
+ singleton = {() car, nil cdr} | cons list?;
8
+ cons = {.car car, .cdr cdr} | cons list?;
9
+ nil? = list? / nil nil;
10
+ car = list? /cons .car;
11
+ cdr = list? /cons .cdr;
12
+
13
+ -- Decrement an integer and normalize (stripping leading zeros)
6
14
  pred_int = dec /'+' nat | '+';
7
15
 
8
16
  -- Concatenate two lists: {xs, ys} -> list
@@ -82,7 +90,8 @@ gt? =
82
90
  >
83
91
  ;
84
92
 
85
- -- Split list into two halves by alternating elements: xs -> {first, second}
93
+ -- Split list into two halves by alternating elements:
94
+ -- xs -> {first, second}
86
95
  split = {() xs, nil first, nil second} _split;
87
96
  _split = <
88
97
  {.xs /nil if, {.first first, .second second} then} .then,
@@ -477,7 +477,7 @@ function showVfsFilePreview(filename) {
477
477
  function loadPreviewedFile() {
478
478
  if (!currentPreviewFile) return;
479
479
  closeVfsModal();
480
- if (currentPreviewFile.endsWith(".mjs") || currentPreviewFile.startsWith("codecs/")) {
480
+ if (currentPreviewFile.endsWith(".mjs") || currentPreviewFile.endsWith(".js") || currentPreviewFile.startsWith("codecs/")) {
481
481
  executeCommand(`:codec load ${currentPreviewFile}`);
482
482
  } else {
483
483
  executeCommand(`:load ${currentPreviewFile}`);
@@ -498,32 +498,49 @@ function downloadPreviewedFile() {
498
498
  URL.revokeObjectURL(url);
499
499
  }
500
500
 
501
- // File Upload Handler
501
+ // File Upload Handler (adds file to VFS without auto-loading)
502
502
  function handleFileUpload(file) {
503
- const reader = new FileReader();
504
- const isBinary = file.name.endsWith(".klib") || file.name.endsWith(".ko") || file.name.endsWith(".wasm");
503
+ return new Promise((resolve, reject) => {
504
+ const reader = new FileReader();
505
+ const isBinary = file.name.endsWith(".klib") ||
506
+ file.name.endsWith(".ko") ||
507
+ file.name.endsWith(".wasm");
508
+
509
+ reader.onload = (e) => {
510
+ let data;
511
+ if (isBinary) {
512
+ data = new Uint8Array(e.target.result);
513
+ } else {
514
+ data = e.target.result;
515
+ }
516
+ setVfsFile(file.name, data);
517
+ appendSystemMessage(
518
+ `📁 Uploaded <b>${escapeHtml(file.name)}</b> into VFS (` +
519
+ `${(data.length / 1024).toFixed(1)} KB).`,
520
+ false,
521
+ true
522
+ );
523
+ if (vfsModal && vfsModal.classList.contains("open")) {
524
+ renderVfsFileList();
525
+ showVfsFilePreview(file.name);
526
+ }
527
+ resolve();
528
+ };
529
+
530
+ reader.onerror = () => {
531
+ appendSystemMessage(
532
+ `❌ Error reading file: ${file.name}`,
533
+ true
534
+ );
535
+ reject(reader.error || new Error("Failed to read file"));
536
+ };
505
537
 
506
- reader.onload = (e) => {
507
- let data;
508
538
  if (isBinary) {
509
- data = new Uint8Array(e.target.result);
539
+ reader.readAsArrayBuffer(file);
510
540
  } else {
511
- data = e.target.result;
541
+ reader.readAsText(file);
512
542
  }
513
- setVfsFile(file.name, data);
514
- appendSystemMessage(`📁 Uploaded <b>${escapeHtml(file.name)}</b> into VFS (${(data.length / 1024).toFixed(1)} KB).`);
515
- if (file.name.endsWith("-codec.mjs") || file.name.endsWith("-codec.js") || file.name.includes("codec")) {
516
- executeCommand(`:codec load ${file.name}`);
517
- } else {
518
- executeCommand(`:load ${file.name}`);
519
- }
520
- };
521
-
522
- if (isBinary) {
523
- reader.readAsArrayBuffer(file);
524
- } else {
525
- reader.readAsText(file);
526
- }
543
+ });
527
544
  }
528
545
 
529
546
  // Export State as .klib
@@ -993,6 +1010,7 @@ if (typeof window !== "undefined") {
993
1010
  getVfsFile,
994
1011
  setVfsFile,
995
1012
  getAllVfsFiles,
1013
+ handleFileUpload,
996
1014
  openCodecsModal,
997
1015
  registerCodec,
998
1016
  unregisterCodec
@@ -53,6 +53,8 @@ const CURATED_VFS_FILES = [
53
53
  "core.k",
54
54
  "arithmetics.k",
55
55
  "ieee.k",
56
+ "poly.k",
57
+ "karatsuba-mult.k",
56
58
  "json.mjs",
57
59
  "utf8.mjs",
58
60
  "int.mjs",