@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
|
@@ -50,7 +50,16 @@ function propertyListToFilter(propertyList, varPrefix = "X") {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
function valueToK(v) {
|
|
53
|
-
if (isVariant(v))
|
|
53
|
+
if (isVariant(v)) {
|
|
54
|
+
const tags = [];
|
|
55
|
+
let curr = v;
|
|
56
|
+
while (isVariant(curr)) {
|
|
57
|
+
tags.push(pLabel(curr.tag).trimStart());
|
|
58
|
+
curr = curr.value;
|
|
59
|
+
}
|
|
60
|
+
const base = valueToK(curr);
|
|
61
|
+
return tags.length === 0 ? base : `${base}|${tags.reverse().join("|")}`;
|
|
62
|
+
}
|
|
54
63
|
if (isProduct(v)) {
|
|
55
64
|
const keys = Object.keys(v.product);
|
|
56
65
|
if (keys.length === 0) return "{}";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fraczak/k",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.6.0",
|
|
4
4
|
"description": "k — a language for composing first-order partial functions over algebraic data types (products and tagged unions); includes runtime, type derivation, REPL, and codec toolchain",
|
|
5
5
|
"main": "index.mjs",
|
|
6
6
|
"exports": {
|
package/repl.mjs
CHANGED
|
@@ -87,6 +87,7 @@ function createState() {
|
|
|
87
87
|
pendingInput: null,
|
|
88
88
|
meta: {},
|
|
89
89
|
value: emptyValue(),
|
|
90
|
+
lastResult: null,
|
|
90
91
|
lastMain: null,
|
|
91
92
|
lastTiming: null,
|
|
92
93
|
showTiming: false
|
|
@@ -381,6 +382,7 @@ function commitResult(state, result, lastMain) {
|
|
|
381
382
|
if (result !== undefined) {
|
|
382
383
|
state.value = result;
|
|
383
384
|
state.lastMain = lastMain;
|
|
385
|
+
state.lastResult = result;
|
|
384
386
|
}
|
|
385
387
|
return [printValue(result, state)];
|
|
386
388
|
}
|
|
@@ -1259,11 +1261,13 @@ async function consumeCodecInput(input, state) {
|
|
|
1259
1261
|
});
|
|
1260
1262
|
const value = valueForCode(parsed, pending.codeHash, codes.find);
|
|
1261
1263
|
state.value = value;
|
|
1264
|
+
state.lastResult = value;
|
|
1262
1265
|
return [printValue(value, state)];
|
|
1263
1266
|
}
|
|
1264
1267
|
|
|
1265
1268
|
async function evaluateInput(input, state) {
|
|
1266
1269
|
state.lastTiming = null;
|
|
1270
|
+
state.lastResult = null;
|
|
1267
1271
|
if (state.pendingInput) {
|
|
1268
1272
|
return consumeCodecInput(input, state);
|
|
1269
1273
|
}
|
|
@@ -455,6 +455,307 @@ const htmlContent = `<!DOCTYPE html>
|
|
|
455
455
|
margin: 4px 0 4px 16px;
|
|
456
456
|
}
|
|
457
457
|
|
|
458
|
+
/* Tree View & Toolbar */
|
|
459
|
+
.k-entry-container {
|
|
460
|
+
display: flex;
|
|
461
|
+
flex-direction: column;
|
|
462
|
+
gap: 6px;
|
|
463
|
+
margin-top: 4px;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.k-output-toolbar {
|
|
467
|
+
display: flex;
|
|
468
|
+
align-items: center;
|
|
469
|
+
justify-content: space-between;
|
|
470
|
+
gap: 8px;
|
|
471
|
+
margin-bottom: 2px;
|
|
472
|
+
flex-wrap: wrap;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
.k-mode-group, .k-action-group {
|
|
476
|
+
display: flex;
|
|
477
|
+
align-items: center;
|
|
478
|
+
gap: 4px;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.k-btn-mode, .k-btn-action {
|
|
482
|
+
background: var(--bg-surface);
|
|
483
|
+
border: 1px solid var(--border-color);
|
|
484
|
+
color: var(--text-muted);
|
|
485
|
+
border-radius: 4px;
|
|
486
|
+
padding: 2px 8px;
|
|
487
|
+
font-size: 11px;
|
|
488
|
+
font-family: inherit;
|
|
489
|
+
cursor: pointer;
|
|
490
|
+
display: inline-flex;
|
|
491
|
+
align-items: center;
|
|
492
|
+
gap: 4px;
|
|
493
|
+
transition: all 0.15s ease;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.k-btn-mode:hover, .k-btn-action:hover {
|
|
497
|
+
background: var(--bg-subtle);
|
|
498
|
+
color: var(--text-main);
|
|
499
|
+
border-color: #8b949e;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
.k-btn-mode.active {
|
|
503
|
+
background: rgba(88, 166, 255, 0.2);
|
|
504
|
+
border-color: var(--color-prompt);
|
|
505
|
+
color: var(--color-prompt);
|
|
506
|
+
font-weight: 600;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.k-tree-view {
|
|
510
|
+
display: flex;
|
|
511
|
+
flex-direction: column;
|
|
512
|
+
gap: 6px;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.k-tree-section {
|
|
516
|
+
background: rgba(22, 27, 34, 0.6);
|
|
517
|
+
border: 1px solid var(--border-color);
|
|
518
|
+
border-radius: 6px;
|
|
519
|
+
overflow: hidden;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.k-tree-section-summary {
|
|
523
|
+
background: rgba(33, 38, 45, 0.5);
|
|
524
|
+
padding: 6px 10px;
|
|
525
|
+
cursor: pointer;
|
|
526
|
+
list-style: none;
|
|
527
|
+
display: flex;
|
|
528
|
+
align-items: center;
|
|
529
|
+
gap: 8px;
|
|
530
|
+
font-size: 12px;
|
|
531
|
+
user-select: none;
|
|
532
|
+
border-bottom: 1px solid transparent;
|
|
533
|
+
transition: background 0.15s;
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
.k-tree-section[open] > .k-tree-section-summary {
|
|
537
|
+
border-bottom-color: rgba(48, 54, 61, 0.5);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
.k-tree-section-summary::-webkit-details-marker {
|
|
541
|
+
display: none;
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
.k-tree-section-summary:hover {
|
|
545
|
+
background: rgba(33, 38, 45, 0.8);
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
.k-section-title {
|
|
549
|
+
font-weight: 700;
|
|
550
|
+
color: var(--color-prompt);
|
|
551
|
+
white-space: nowrap;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.k-section-preview {
|
|
555
|
+
color: var(--text-muted);
|
|
556
|
+
font-size: 11px;
|
|
557
|
+
overflow: hidden;
|
|
558
|
+
text-overflow: ellipsis;
|
|
559
|
+
white-space: nowrap;
|
|
560
|
+
flex: 1;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
.k-tree-section-body {
|
|
564
|
+
padding: 8px 10px;
|
|
565
|
+
font-size: 13px;
|
|
566
|
+
line-height: 1.6;
|
|
567
|
+
overflow-x: auto;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/* Tree Node & Summary */
|
|
571
|
+
.k-tree-node {
|
|
572
|
+
margin-left: 12px;
|
|
573
|
+
border-left: 1px dashed rgba(48, 54, 61, 0.6);
|
|
574
|
+
padding-left: 8px;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
.k-tree-summary {
|
|
578
|
+
cursor: pointer;
|
|
579
|
+
list-style: none;
|
|
580
|
+
display: inline-flex;
|
|
581
|
+
align-items: baseline;
|
|
582
|
+
gap: 6px;
|
|
583
|
+
outline: none;
|
|
584
|
+
user-select: none;
|
|
585
|
+
padding: 1px 4px;
|
|
586
|
+
border-radius: 4px;
|
|
587
|
+
transition: background 0.15s;
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
.k-tree-summary::-webkit-details-marker {
|
|
591
|
+
display: none;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.k-tree-summary:hover {
|
|
595
|
+
background: rgba(88, 166, 255, 0.1);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
.k-tree-arrow {
|
|
599
|
+
display: inline-block;
|
|
600
|
+
font-size: 8px;
|
|
601
|
+
width: 10px;
|
|
602
|
+
height: 10px;
|
|
603
|
+
line-height: 10px;
|
|
604
|
+
text-align: center;
|
|
605
|
+
transition: transform 0.15s ease;
|
|
606
|
+
color: var(--text-muted);
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
details[open] > summary > .k-tree-arrow {
|
|
610
|
+
transform: rotate(90deg);
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
.k-tree-children {
|
|
614
|
+
display: flex;
|
|
615
|
+
flex-direction: column;
|
|
616
|
+
gap: 2px;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
.k-tree-row {
|
|
620
|
+
display: flex;
|
|
621
|
+
align-items: baseline;
|
|
622
|
+
gap: 6px;
|
|
623
|
+
padding-left: 8px;
|
|
624
|
+
margin: 1px 0;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
.k-tree-child-val, .k-tree-child-pat {
|
|
628
|
+
flex: 1;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
.k-tree-leaf {
|
|
632
|
+
display: inline-flex;
|
|
633
|
+
align-items: baseline;
|
|
634
|
+
gap: 4px;
|
|
635
|
+
padding: 1px 4px;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
/* Syntax Highlighting */
|
|
639
|
+
.k-val-brace, .k-pat-brace {
|
|
640
|
+
color: var(--color-yellow);
|
|
641
|
+
font-weight: 600;
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
.k-pat-union {
|
|
645
|
+
color: var(--color-cyan);
|
|
646
|
+
font-weight: 600;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
.k-val-pipe {
|
|
650
|
+
color: var(--text-muted);
|
|
651
|
+
font-weight: 700;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
.k-val-tag {
|
|
655
|
+
color: var(--color-purple);
|
|
656
|
+
font-weight: 600;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
.k-pat-tag {
|
|
660
|
+
color: var(--color-cyan);
|
|
661
|
+
font-weight: 600;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
.k-tree-field-key, .k-pat-field-key {
|
|
665
|
+
color: var(--color-blue);
|
|
666
|
+
font-weight: 600;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
.k-val-empty, .k-pat-empty {
|
|
670
|
+
color: var(--text-muted);
|
|
671
|
+
font-style: italic;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.k-pat-var {
|
|
675
|
+
color: var(--color-green);
|
|
676
|
+
font-weight: 700;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
.k-pat-vardef {
|
|
680
|
+
color: var(--color-green);
|
|
681
|
+
font-size: 11px;
|
|
682
|
+
font-weight: 600;
|
|
683
|
+
background: rgba(63, 185, 80, 0.15);
|
|
684
|
+
border-radius: 3px;
|
|
685
|
+
padding: 0 4px;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
.k-pat-any {
|
|
689
|
+
color: var(--color-yellow);
|
|
690
|
+
font-style: italic;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.k-pat-ellipsis {
|
|
694
|
+
color: var(--text-muted);
|
|
695
|
+
letter-spacing: 2px;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
.k-val-preview {
|
|
699
|
+
color: var(--text-muted);
|
|
700
|
+
font-size: 11px;
|
|
701
|
+
max-width: 320px;
|
|
702
|
+
overflow: hidden;
|
|
703
|
+
text-overflow: ellipsis;
|
|
704
|
+
white-space: nowrap;
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
.k-tree-badge {
|
|
708
|
+
font-size: 10px;
|
|
709
|
+
background: rgba(139, 148, 158, 0.15);
|
|
710
|
+
color: var(--text-muted);
|
|
711
|
+
padding: 1px 5px;
|
|
712
|
+
border-radius: 10px;
|
|
713
|
+
font-weight: 500;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
.k-badge-cycle {
|
|
717
|
+
background: rgba(248, 81, 73, 0.2);
|
|
718
|
+
color: var(--color-red);
|
|
719
|
+
font-weight: 600;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
.k-codecs-box {
|
|
723
|
+
background: rgba(22, 27, 34, 0.8);
|
|
724
|
+
border: 1px solid var(--border-color);
|
|
725
|
+
border-left: 3px solid var(--color-green);
|
|
726
|
+
border-radius: 0 6px 6px 0;
|
|
727
|
+
padding: 6px 12px;
|
|
728
|
+
display: flex;
|
|
729
|
+
flex-direction: column;
|
|
730
|
+
gap: 3px;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
.k-codec-row {
|
|
734
|
+
color: var(--color-green);
|
|
735
|
+
font-weight: 500;
|
|
736
|
+
font-size: 13px;
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
.k-timing-row {
|
|
740
|
+
color: var(--text-muted);
|
|
741
|
+
font-size: 11px;
|
|
742
|
+
font-style: italic;
|
|
743
|
+
padding: 2px 4px;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.k-raw-pre {
|
|
747
|
+
background: rgba(13, 17, 23, 0.8);
|
|
748
|
+
border: 1px solid var(--border-color);
|
|
749
|
+
border-radius: 6px;
|
|
750
|
+
padding: 8px 12px;
|
|
751
|
+
font-family: inherit;
|
|
752
|
+
font-size: 13px;
|
|
753
|
+
color: var(--color-green);
|
|
754
|
+
white-space: pre-wrap;
|
|
755
|
+
word-break: break-word;
|
|
756
|
+
user-select: text;
|
|
757
|
+
}
|
|
758
|
+
|
|
458
759
|
/* Welcome banner */
|
|
459
760
|
.welcome-banner {
|
|
460
761
|
padding: 16px;
|
package/scripts/perf-ieee.mjs
CHANGED
|
@@ -74,7 +74,7 @@ const arm64OptLevel = process.env.ARM64_OPT || "-O2";
|
|
|
74
74
|
|
|
75
75
|
// LLVM options
|
|
76
76
|
const llvmWarmupIterations = parseNonNegativeIntEnv("LLVM_WARMUP_ITERATIONS", 1);
|
|
77
|
-
const llvmRuntimeMode = process.env.K_LLVM_IEEE_RUNTIME_MODE || "
|
|
77
|
+
const llvmRuntimeMode = process.env.K_LLVM_IEEE_RUNTIME_MODE || "fast";
|
|
78
78
|
|
|
79
79
|
function getClangOptLevels() {
|
|
80
80
|
for (const arg of process.argv.slice(2)) {
|
|
@@ -156,7 +156,8 @@ await evaluateInput(perfKSource, state);
|
|
|
156
156
|
|
|
157
157
|
const ieeeRaw = fs.readFileSync(ieeePath, "utf8");
|
|
158
158
|
// Exclude trailing unassigned expression and comment block to ensure clean parse
|
|
159
|
-
const
|
|
159
|
+
const endIdx = ieeeRaw.indexOf("\n()\n");
|
|
160
|
+
const ieeeBase = endIdx !== -1 ? ieeeRaw.slice(0, endIdx) : ieeeRaw;
|
|
160
161
|
const fullSource = `${ieeeBase}\n${perfKSource}\nperf_ieee`;
|
|
161
162
|
|
|
162
163
|
console.log("==> Preparing relation perf_ieee");
|
|
@@ -375,6 +376,8 @@ if (runLLVM) {
|
|
|
375
376
|
console.log(`==> Running LLVM (${opt}) (${iterations} iterations)...`);
|
|
376
377
|
const result = await llvmRunner.run(iterations);
|
|
377
378
|
llvmResults.set(opt, result);
|
|
379
|
+
} catch (err) {
|
|
380
|
+
console.log(`==> LLVM (${opt}) execution failed: ${err.message?.split("\n")[0]}`);
|
|
378
381
|
} finally {
|
|
379
382
|
llvmRunner.close();
|
|
380
383
|
}
|