@fraczak/k 7.2.0 → 8.1.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 (46) hide show
  1. package/CHANGELOG.md +90 -0
  2. package/DOCS/BIG_PICTURE.md +54 -7
  3. package/DOCS/CODECS.md +21 -13
  4. package/DOCS/CODEC_ARCHITECTURE.md +1 -1
  5. package/DOCS/DICTIONARY.md +13 -4
  6. package/DOCS/FILE_FORMATS.md +3 -2
  7. package/DOCS/JSON_APPROACHES_COMPARISON.md +302 -0
  8. package/DOCS/NAMED_PATTERNS.md +317 -0
  9. package/DOCS/PATTERNS.md +59 -11
  10. package/DOCS/REPL.md +13 -2
  11. package/DOCS/WEB_REPL_REQUIREMENTS.md +3 -2
  12. package/Examples/arithmetics.k +22 -17
  13. package/Examples/bnat.k +21 -11
  14. package/Examples/buda.k +37 -20
  15. package/Examples/byte.k +3 -1
  16. package/Examples/code.k +38 -39
  17. package/Examples/djson.k +789 -0
  18. package/Examples/esc.k +1 -1
  19. package/Examples/karatsuba-mult.k +16 -13
  20. package/Examples/list.k +8 -4
  21. package/Examples/nat.k +17 -11
  22. package/Examples/poly.k +11 -3
  23. package/Examples/vhdl_to_k.k +43 -31
  24. package/README.md +40 -16
  25. package/browser/repl-browser.mjs +2 -0
  26. package/browser/tree-view.mjs +35 -16
  27. package/browser/vfs-data.mjs +10 -8
  28. package/codecs/README.md +1 -1
  29. package/codecs/djson.mjs +375 -84
  30. package/core.k +79 -115
  31. package/index.mjs +3 -0
  32. package/named-patterns.mjs +267 -0
  33. package/object.mjs +31 -3
  34. package/package.json +1 -1
  35. package/parser.jison +68 -5
  36. package/parser.mjs +111 -60
  37. package/pretty.mjs +5 -0
  38. package/repl.mjs +188 -22
  39. package/scripts/build-repl-html.mjs +58 -4
  40. package/scripts/run-tests.mjs +10 -0
  41. package/symbol-table.mjs +20 -2
  42. package/tests/test-codecs.mjs +30 -17
  43. package/tests/test-djson-methods.mjs +285 -0
  44. package/tests/test-named-patterns.mjs +189 -0
  45. package/tests/test-repl-html.mjs +47 -4
  46. package/tests/test-repl.mjs +149 -0
@@ -581,6 +581,155 @@ assert.equal(output[0], "output limit disabled");
581
581
  output = await evaluateInput(":limit", limitState);
582
582
  assert.equal(output[0], "Current output limit: none");
583
583
 
584
+ // Verify Examples/djson.k (json?, get, nth, set, del)
585
+ const djsonKState = createState({ engine: "wasm" });
586
+ output = await evaluateInput(":load Examples/djson.k", djsonKState);
587
+ assert.equal(output[0], "loaded Examples/djson.k");
588
+ await evaluateInput(":codec load codecs/djson.mjs", djsonKState);
589
+ await evaluateInput(
590
+ ':input djson.mjs ["age", {"name":"Alice","age":30}]',
591
+ djsonKState
592
+ );
593
+ output = await evaluateInput(
594
+ "{{0 index, () json} nth /string key, " +
595
+ "{1 index, () json} nth json} get",
596
+ djsonKState
597
+ );
598
+ assert.match(output[0], /djson\.mjs: 30/);
599
+
600
+ await evaluateInput(
601
+ ':input djson.mjs ["age", {"name":"Alice","age":30}]',
602
+ djsonKState
603
+ );
604
+ output = await evaluateInput(
605
+ "{{0 index, () json} nth /string key, " +
606
+ "{1 index, () json} nth json} del",
607
+ djsonKState
608
+ );
609
+ assert.match(output[0], /djson\.mjs: \{"name":"Alice"\}/);
610
+
611
+ // Verify named pattern persistence, listing, display, and tab completion
612
+ const patState = createState({ engine: "wasm" });
613
+
614
+ output = await evaluateInput(":patterns", patState);
615
+ assert.equal(output[0], "(none)");
616
+ output = await evaluateInput(":pats", patState);
617
+ assert.equal(output[0], "(none)");
618
+
619
+ output = await evaluateInput("bit[] = < {} 0, {} 1 >;", patState);
620
+ assert.match(output[0], /\/\* comp:/);
621
+
622
+ output = await evaluateInput(":patterns", patState);
623
+ assert.equal(output[0], "bit[]");
624
+ output = await evaluateInput(":pats", patState);
625
+ assert.equal(output[0], "bit[]");
626
+
627
+ output = await evaluateInput(":pattern bit", patState);
628
+ assert.equal(
629
+ output[0],
630
+ "bit[] = <{} 0, {} 1>; -- " +
631
+ "@MjusyRWZnVj8TR4BhFCCcMRrQbdKp9gPtC29LT9nZvjg"
632
+ );
633
+ output = await evaluateInput(":pattern bit[]", patState);
634
+ assert.equal(
635
+ output[0],
636
+ "bit[] = <{} 0, {} 1>; -- " +
637
+ "@MjusyRWZnVj8TR4BhFCCcMRrQbdKp9gPtC29LT9nZvjg"
638
+ );
639
+ output = await evaluateInput(":pat bit", patState);
640
+ assert.equal(
641
+ output[0],
642
+ "bit[] = <{} 0, {} 1>; -- " +
643
+ "@MjusyRWZnVj8TR4BhFCCcMRrQbdKp9gPtC29LT9nZvjg"
644
+ );
645
+ output = await evaluateInput(
646
+ ":pattern @MjusyRWZnVj8TR4BhFCCcMRrQbdKp9gPtC29LT9nZvjg",
647
+ patState
648
+ );
649
+ assert.equal(
650
+ output[0],
651
+ "bit[] = <{} 0, {} 1>; -- " +
652
+ "@MjusyRWZnVj8TR4BhFCCcMRrQbdKp9gPtC29LT9nZvjg"
653
+ );
654
+
655
+ await assert.rejects(
656
+ () => evaluateInput(":pattern unknown", patState),
657
+ /Unknown pattern 'unknown'/
658
+ );
659
+ await assert.rejects(
660
+ () => evaluateInput(":pattern", patState),
661
+ /:pattern requires a pattern name/
662
+ );
663
+
664
+ completions = completeInput(":pat", patState)[0];
665
+ assert(completions.includes(":pattern"));
666
+ assert(completions.includes(":patterns"));
667
+ assert(completions.includes(":pat"));
668
+ assert(completions.includes(":pats"));
669
+
670
+ completions = completeInput(":pattern b", patState)[0];
671
+ assert(completions.includes(":pattern bit"));
672
+ completions = completeInput(":pat b", patState)[0];
673
+ assert(completions.includes(":pat bit"));
674
+ completions = completeInput(":pattern @Mjusy", patState)[0];
675
+ assert(
676
+ completions.includes(
677
+ ":pattern @MjusyRWZnVj8TR4BhFCCcMRrQbdKp9gPtC29LT9nZvjg"
678
+ )
679
+ );
680
+
681
+ output = await evaluateInput("{} | 0 ? bit[]", patState);
682
+ assert.match(output[0], /\{\}\|0/);
683
+
684
+ output = await evaluateInput(
685
+ "pair[A, B] = { A first, B second };",
686
+ patState
687
+ );
688
+ output = await evaluateInput(":pattern pair", patState);
689
+ assert.equal(
690
+ output[0],
691
+ "pair[A, B] = {A first, B second}; -- " +
692
+ "@KqTBNkznjWWwync2Mm94XjCez63neJBJtgYcJJEE5kEm"
693
+ );
694
+
695
+ output = await evaluateInput(":load Examples/list.k", patState);
696
+ assert.equal(output[0], "loaded Examples/list.k");
697
+ output = await evaluateInput(":patterns", patState);
698
+ assert(output[0].includes("bit[]"));
699
+ assert(output[0].includes("list[X]"));
700
+ assert(output[0].includes("pair[A, B]"));
701
+
702
+ output = await evaluateInput(":pattern list", patState);
703
+ assert.equal(
704
+ output[0],
705
+ "list[X] = <{} nil, {X car, Y cdr} cons>=Y; -- " +
706
+ "@JagVexzgseRr4rVZRmVpsMbr2AKXDjzZnz6Qnf8a9SNe"
707
+ );
708
+
709
+ output = await evaluateInput("{} | nil ? list[bit[]]", patState);
710
+ assert.match(output[0], /\{\}\|nil/);
711
+
712
+ const testKlibPath = path.join(tmpDir, "patterns-test.klib");
713
+ output = await evaluateInput(`:klib ${testKlibPath}`, patState);
714
+ assert.equal(output[0], `saved ${testKlibPath}`);
715
+
716
+ const freshState = createState({ engine: "wasm" });
717
+ output = await evaluateInput(`:load ${testKlibPath}`, freshState);
718
+ assert.equal(output[0], `loaded ${testKlibPath}`);
719
+ output = await evaluateInput(":patterns", freshState);
720
+ assert(output[0].includes("bit[]"));
721
+ assert(output[0].includes("pair[A, B]"));
722
+ assert(output[0].includes("list[X]"));
723
+
724
+ output = await evaluateInput(":pattern bit", freshState);
725
+ assert.equal(
726
+ output[0],
727
+ "bit[] = <{} 0, {} 1>; -- " +
728
+ "@MjusyRWZnVj8TR4BhFCCcMRrQbdKp9gPtC29LT9nZvjg"
729
+ );
730
+ output = await evaluateInput("{} | nil ? list[bit[]]", freshState);
731
+ assert.match(output[0], /\{\}\|nil/);
732
+
584
733
  fs.rmSync(tmpDir, { recursive: true, force: true });
585
734
  fs.rmSync(symlinkPath, { force: true });
586
735
  console.log("OK");