@fraczak/k 7.0.1 → 7.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 (89) hide show
  1. package/CHANGELOG.md +78 -0
  2. package/DOCS/BIG_PICTURE.md +5 -5
  3. package/DOCS/FILE_FORMATS.md +241 -18
  4. package/DOCS/OBJECT_FILE_AND_PATTERN.md +9 -9
  5. package/DOCS/PATTERNS.md +3 -3
  6. package/DOCS/POLYMORPHIC_IR.md +104 -0
  7. package/DOCS/PROFILING_AND_TRACING.md +60 -72
  8. package/DOCS/REPL.md +3 -3
  9. package/DOCS/book/03-types-as-finite-automata.md +4 -4
  10. package/DOCS/book/06-values-in-memory.md +9 -9
  11. package/DOCS/book/08-operational-semantics-and-execution.md +1 -1
  12. package/DOCS/book/09-compiler-architecture.md +2 -2
  13. package/DOCS/book/10-from-ast-to-intermediate-representation.md +2 -2
  14. package/DOCS/book/14-canonical-serialization.md +1 -1
  15. package/Examples/arithmetics.k +2 -2
  16. package/Examples/bnat.k +1 -1
  17. package/Examples/karatsuba-mult.k +2 -2
  18. package/JOURNAL.md +288 -0
  19. package/README.md +13 -10
  20. package/access-table.mjs +343 -0
  21. package/backend-api.mjs +18 -0
  22. package/backends/llvm/README.md +20 -21
  23. package/backends/llvm/bin/k-llvm-build.mjs +105 -32
  24. package/backends/llvm/bin/k-llvm-compile.mjs +63 -24
  25. package/backends/llvm/bin/k-llvm.mjs +292 -0
  26. package/backends/llvm/runtime/krt.c +41 -0
  27. package/backends/llvm/runtime/krt.h +2 -0
  28. package/backends/llvm/src/cli.mjs +95 -17
  29. package/backends/llvm/src/executable.mjs +132 -15
  30. package/backends/llvm/src/kvm2llvm.mjs +50 -23
  31. package/backends/llvm/src/llvm.mjs +133 -20
  32. package/backends/llvm/tests/integration.sh +11 -11
  33. package/backends/llvm/{bin → tests}/k-llvm-run.mjs +48 -22
  34. package/backends/llvm/tests/perf-support.mjs +25 -58
  35. package/backends/llvm/tests/test-llvm.mjs +25 -4
  36. package/backends/wasm/bin/k-wasm-compile.mjs +46 -20
  37. package/backends/wasm/bin/k-wasm-run.mjs +61 -20
  38. package/backends/wasm/bin/k-wasm.mjs +47 -13
  39. package/backends/wasm/src/cli.mjs +141 -19
  40. package/backends/wasm/src/wasm.mjs +132 -24
  41. package/backends/wasm/tests/test-wasm.mjs +5 -5
  42. package/browser/repl-browser.mjs +16 -5
  43. package/browser/vfs-data.mjs +5 -5
  44. package/codecs/k-parse.mjs +29 -8
  45. package/codecs/k-print.mjs +22 -6
  46. package/codecs/runtime/codec-sdk.mjs +8 -4
  47. package/codecs/show.mjs +20 -6
  48. package/core.k +8 -8
  49. package/harness/format.mjs +2 -2
  50. package/harness/registry.mjs +0 -2
  51. package/k.mjs +56 -16
  52. package/kir.mjs +200 -75
  53. package/kvm.mjs +49 -12
  54. package/objects/compile.mjs +37 -23
  55. package/objects/decompile.mjs +40 -10
  56. package/objects/extract-aliases.mjs +44 -14
  57. package/objects/inspect.mjs +19 -14
  58. package/objects/validate.mjs +18 -11
  59. package/package.json +10 -7
  60. package/pkir.mjs +772 -0
  61. package/repl.mjs +36 -18
  62. package/scripts/benchmark-idempotency.mjs +12 -8
  63. package/scripts/benchmark.mjs +5 -9
  64. package/scripts/build-repl-html.mjs +16 -4
  65. package/scripts/perf-ieee.mjs +253 -103
  66. package/scripts/perf-int.mjs +585 -297
  67. package/scripts/perf-multiplication.mjs +66 -25
  68. package/scripts/perf-poly.mjs +292 -164
  69. package/scripts/run-tests.mjs +3 -0
  70. package/tests/code-derivation/pattern-envelope.mjs +4 -4
  71. package/tests/test-access-table.mjs +213 -0
  72. package/tests/test-kvm-polymorphic.mjs +2 -2
  73. package/tests/test-pkir.mjs +530 -0
  74. package/tests/test-polymorphic-tdd.mjs +196 -0
  75. package/tests/test-repl-html.mjs +15 -2
  76. package/tests/test-repl.mjs +30 -1
  77. package/backends/arm64/README.md +0 -103
  78. package/backends/arm64/bin/k-arm64-compile.mjs +0 -93
  79. package/backends/arm64/bin/k-arm64-run.mjs +0 -58
  80. package/backends/arm64/bin/k-arm64.mjs +0 -88
  81. package/backends/arm64/scripts/run-tests.mjs +0 -57
  82. package/backends/arm64/src/arm64.mjs +0 -229
  83. package/backends/arm64/src/cli.mjs +0 -155
  84. package/backends/arm64/src/kvm2arm64.mjs +0 -906
  85. package/backends/arm64/src/runtime.c +0 -744
  86. package/backends/arm64/tests/integration.sh +0 -112
  87. package/backends/arm64/tests/test-arm64.mjs +0 -240
  88. package/backends/llvm/bin/k-llvm-jit.mjs +0 -160
  89. package/harness/adapters/arm64.mjs +0 -105
@@ -7,10 +7,32 @@ import { isMainEntrypoint } from "./runtime/cli-entry.mjs";
7
7
  import { patternFromFilter } from "./runtime/pattern-k.mjs";
8
8
  import { encodeToWire } from "./runtime/prefix-codec.mjs";
9
9
 
10
- function usage(prog) {
11
- console.error(`Usage: ${prog} [--input-type <type-script|type-file> | --input-pattern <pattern-script|pattern-file>] [value-file]`);
12
- console.error(" Parse a textual k value and emit the self-hosted binary pattern+value stream.");
13
- console.error(" If no pattern or type is provided, derive a closed pattern from the value.");
10
+ function helpText() {
11
+ const prog = argv[1] || "k-parse.mjs";
12
+ return [
13
+ "Parse a textual k value and emit a binary pattern+value stream.",
14
+ "If no pattern or type is provided, derives a closed pattern from",
15
+ "the value.",
16
+ "",
17
+ `Usage: ${prog} [options] [value-file]`,
18
+ "",
19
+ "Arguments:",
20
+ " value-file Input textual k value file.",
21
+ " Reads from stdin when omitted.",
22
+ "",
23
+ "Options:",
24
+ " --input-type type Type filter script or file for pattern.",
25
+ " --input-pattern json Pattern JSON string or file.",
26
+ " -h, --help Show this help.",
27
+ "",
28
+ "Examples:",
29
+ ` echo '{"x": 1}' | ${prog} | k-print`,
30
+ ` ${prog} --input-type '<{} a, {} b>' value.kv`
31
+ ].join("\n");
32
+ }
33
+
34
+ function usage(stream = console.error) {
35
+ stream(helpText());
14
36
  }
15
37
 
16
38
  function maybeReadFile(s) {
@@ -31,11 +53,10 @@ function readAll(stream) {
31
53
  }
32
54
 
33
55
  async function main() {
34
- const prog = argv[1];
35
56
  const args = argv.slice(2);
36
57
 
37
58
  if (args.includes("-h") || args.includes("--help")) {
38
- usage(prog);
59
+ usage(console.log);
39
60
  return exit(0);
40
61
  }
41
62
 
@@ -51,13 +72,13 @@ async function main() {
51
72
  } else if (valueFile == null) {
52
73
  valueFile = args[i];
53
74
  } else {
54
- usage(prog);
75
+ usage();
55
76
  return exit(1);
56
77
  }
57
78
  }
58
79
 
59
80
  if (inputTypeArg != null && inputPatternArg != null) {
60
- usage(prog);
81
+ usage();
61
82
  return exit(1);
62
83
  }
63
84
 
@@ -5,13 +5,29 @@ import { argv, stdin, stdout } from "node:process";
5
5
  import { isMainEntrypoint } from "./runtime/cli-entry.mjs";
6
6
  import { decodeWire } from "./runtime/prefix-codec.mjs";
7
7
 
8
+ function helpText() {
9
+ const prog = argv[1] || "k-print.mjs";
10
+ return [
11
+ "Read a binary pattern+value stream and print the decoded",
12
+ "textual value.",
13
+ "",
14
+ `Usage: ${prog} [options] [file]`,
15
+ "",
16
+ "Arguments:",
17
+ " file Input binary wire file (default: stdin).",
18
+ "",
19
+ "Options:",
20
+ " --debug Print decoded pattern and value as JSON.",
21
+ " -h, --help Show this help.",
22
+ "",
23
+ "Examples:",
24
+ ` echo '"hello"' | k-parse | ${prog}`,
25
+ ` ${prog} input.wire`
26
+ ].join("\n");
27
+ }
28
+
8
29
  function usage(stream = console.error) {
9
- stream(`Usage: ${argv[1]} [--debug] [file]`);
10
- stream(" Read a binary pattern+value stream and print the decoded textual value.");
11
- stream("");
12
- stream("Options:");
13
- stream(" --debug Print decoded pattern and value as JSON.");
14
- stream(" -h, --help Show this help.");
30
+ stream(helpText());
15
31
  }
16
32
 
17
33
  function readAll(stream) {
@@ -22,10 +22,14 @@ function printUsage(fileName, doc) {
22
22
  if (doc) {
23
23
  stdout.write(`${doc.trim()}\n\n`);
24
24
  }
25
- stdout.write("Options:\n");
26
- stdout.write(" --parse Read external text from stdin, write binary pattern+value stream to stdout.\n");
27
- stdout.write(" --print Read binary pattern+value stream from stdin, write external text to stdout.\n");
28
- stdout.write(" -h, --help Show this help.\n");
25
+ stdout.write(
26
+ "Options:\n" +
27
+ " --parse Read external text from stdin, write binary\n" +
28
+ " pattern+value stream to stdout.\n" +
29
+ " --print Read binary pattern+value stream from stdin,\n" +
30
+ " write external text to stdout.\n" +
31
+ " -h, --help Show this help.\n"
32
+ );
29
33
  }
30
34
 
31
35
  function runCodecCLI(metaUrl, codec) {
package/codecs/show.mjs CHANGED
@@ -6,13 +6,27 @@ import { isMainEntrypoint } from "./runtime/cli-entry.mjs";
6
6
  import { decodeWire } from "./runtime/prefix-codec.mjs";
7
7
  import { propertyListToFilter, valueToK } from "./runtime/show-value.mjs";
8
8
 
9
+ function helpText() {
10
+ const prog = argv[1] || "show.mjs";
11
+ return [
12
+ "Pass a binary wire stream through unchanged on stdout while",
13
+ "printing the decoded value and filter to stderr.",
14
+ "",
15
+ `Usage: ${prog} [wire-file]`,
16
+ "",
17
+ "Arguments:",
18
+ " wire-file Input binary wire file (default: stdin).",
19
+ "",
20
+ "Options:",
21
+ " -h, --help Show this help.",
22
+ "",
23
+ "Examples:",
24
+ ` echo '"hello"' | k-parse | ${prog} | k-print`
25
+ ].join("\n");
26
+ }
27
+
9
28
  function usage(stream = console.error) {
10
- stream(`Usage: ${argv[1]} [wire-file]`);
11
- stream(" Pass the wire stream through unchanged on stdout.");
12
- stream(" Print the decoded value and filter to stderr.");
13
- stream("");
14
- stream("Options:");
15
- stream(" -h, --help Show this help.");
29
+ stream(helpText());
16
30
  }
17
31
 
18
32
  function readAll(stream) {
package/core.k CHANGED
@@ -1,17 +1,17 @@
1
1
  -- core.k — the k standard core library
2
2
  --
3
3
  -- Defines:
4
- -- 1. bits — canonical binary number / bit-path relation
5
- -- 2. string — unicode strings relation (used for labels)
6
- -- 3. pattern — pattern graph relation
4
+ -- 1. bits? — canonical binary number / bit-path relation
5
+ -- 2. string? — unicode strings relation (used for labels)
6
+ -- 3. pattern? — pattern graph relation
7
7
 
8
8
  ---------------------------------------------------------------
9
9
  -- §1. Bits
10
10
  ---------------------------------------------------------------
11
11
 
12
- bit = ?< {} 0, {} 1 >;
12
+ bit? = ?< {} 0, {} 1 >;
13
13
 
14
- bits = ?< {} _, bits 0, bits 1 > = bits;
14
+ bits? = ?< {} _, bits? 0, bits? 1 > = bits?;
15
15
 
16
16
  _ = {}|_;
17
17
 
@@ -22,7 +22,7 @@ _ = {}|_;
22
22
  -- §2. Unicode and String
23
23
  ---------------------------------------------------------------
24
24
 
25
- string = ? <
25
+ string? = ? <
26
26
  {} nil,
27
27
  {
28
28
  <
@@ -82,7 +82,7 @@ string = ? <
82
82
  -- to decode any value, first decode a pattern under that constant,
83
83
  -- then decode the value under the pattern just obtained.
84
84
 
85
- pattern = ? <
85
+ pattern? = ? <
86
86
  {} nil,
87
87
  {
88
88
  <
@@ -150,4 +150,4 @@ pattern = ? <
150
150
  } cons
151
151
  > = Pattern;
152
152
 
153
- pattern
153
+ pattern?
@@ -1,6 +1,6 @@
1
1
  import { PHASES, formatUs } from "./trace.mjs";
2
2
 
3
- export function formatPhaseTable(phaseResults, backendIds = ["arm64", "llvm", "wasm", "kvm"]) {
3
+ export function formatPhaseTable(phaseResults, backendIds = ["llvm", "wasm", "kvm"]) {
4
4
  const lines = [];
5
5
 
6
6
  for (const item of phaseResults) {
@@ -25,7 +25,7 @@ export function formatPhaseTable(phaseResults, backendIds = ["arm64", "llvm", "w
25
25
  return lines.join("\n");
26
26
  }
27
27
 
28
- export function formatProfileTable(profileResults, backendIds = ["arm64", "wasm", "kvm"]) {
28
+ export function formatProfileTable(profileResults, backendIds = ["wasm", "kvm"]) {
29
29
  const lines = [];
30
30
 
31
31
  for (const item of profileResults) {
@@ -1,7 +1,6 @@
1
1
  import { NativeAdapter } from "./adapters/native.mjs";
2
2
  import { KVMAdapter } from "./adapters/kvm.mjs";
3
3
  import { WasmAdapter } from "./adapters/wasm.mjs";
4
- import { ARM64Adapter } from "./adapters/arm64.mjs";
5
4
  import { LLVMAdapter } from "./adapters/llvm.mjs";
6
5
 
7
6
  export function createRegistry(config = {}) {
@@ -16,7 +15,6 @@ export function createRegistry(config = {}) {
16
15
  register("kvm", () => new KVMAdapter(config.state));
17
16
  register("wasm", () => new WasmAdapter(config.wasm || {}));
18
17
  register("wasm-in-process", () => new WasmAdapter({ id: "wasm-in-process", mode: "in-process", ...(config.wasm || {}) }));
19
- register("arm64", () => new ARM64Adapter(config.arm64 || {}));
20
18
  register("llvm", () => new LLVMAdapter(config.llvm || {}));
21
19
 
22
20
  return {
package/k.mjs CHANGED
@@ -4,27 +4,58 @@
4
4
  import fs from "node:fs";
5
5
  import { argv, stdin, exit, stdout } from "node:process";
6
6
  import k from "./index.mjs";
7
- import { decodeWire, encodeToWire } from "./codecs/runtime/prefix-codec.mjs";
8
- import { decodeObject, objectToFunction, loadLibrary } from "./object.mjs";
9
-
10
- const prog = argv[1];
7
+ import {
8
+ decodeWire,
9
+ encodeToWire
10
+ } from "./codecs/runtime/prefix-codec.mjs";
11
+ import {
12
+ compileLibrary,
13
+ decodeObject,
14
+ objectToFunction,
15
+ loadLibrary
16
+ } from "./object.mjs";
11
17
 
12
18
  let kScript, inputStream;
13
19
 
14
- function usage() {
15
- console.error(`Usage: ${prog} [ --lib lib-file ] [ --export spec ]... ( k-expr | file ) [ input-file ]`);
16
- console.error(` E.g., echo '["zebara","ela"]' | k-parse --input-type '$x=<{} zebara, {} ela>; $v={x 0, x 1}; $v' | ${prog} '{.1 0}'`);
17
- console.error("Options:");
18
- console.error(" --lib file Load one .klib dependency before compiling.");
19
- console.error(" --export spec Export a library alias into scope. 'name' or 'libname:localname'. May be repeated.");
20
- console.error(" -h, --help Show this help.");
20
+ function helpText() {
21
+ const prog = argv[1] || "k.mjs";
22
+ return [
23
+ "Compile and execute a k expression or file over a binary",
24
+ "pattern+value wire stream using the JavaScript interpreter.",
25
+ "",
26
+ `Usage: ${prog} [options]`,
27
+ " ( source-snippet | input-file ) [ input-wire-file ]",
28
+ "",
29
+ "Arguments:",
30
+ " source-snippet Inline k source snippet.",
31
+ " input-file Source .k, .ko, or .klib file.",
32
+ " input-wire-file Optional binary wire input (default: stdin).",
33
+ "",
34
+ "Options:",
35
+ " --lib file Load one .klib or .k library before compiling.",
36
+ " --export spec Export library alias into scope. Repeatable.",
37
+ " spec is 'name' or 'libname:localname'.",
38
+ " -h, --help Show this help.",
39
+ "",
40
+ "Examples:",
41
+ ` echo '"abc"' | k-parse | ${prog} '{.1 0}' | k-print`,
42
+ ` echo '{"x":1,"y":2}' | k-json --parse | \\`,
43
+ ` ${prog} --lib Examples/poly.k --export concat \\`,
44
+ ` 's={()xs,()ys}concat; s' | k-json --print`
45
+ ].join("\n");
46
+ }
47
+
48
+ function usage(stream = console.error) {
49
+ stream(helpText());
21
50
  }
22
51
 
23
52
  function isFile(filePath) {
24
53
  try {
25
54
  return fs.statSync(filePath).isFile();
26
55
  } catch (error) {
27
- if (error?.code === "ENOENT" || error?.code === "ENOTDIR") return false;
56
+ if (error?.code === "ENOENT" || error?.code === "ENOTDIR") {
57
+ return false;
58
+ }
28
59
  throw error;
29
60
  }
30
61
  }
@@ -41,7 +72,7 @@ function compileFile(filePath, libraries, preamble) {
41
72
  ({ kScript, inputStream } = ((args) => {
42
73
  try {
43
74
  if (args.includes("-h") || args.includes("--help")) {
44
- usage();
75
+ usage(console.log);
45
76
  return exit(0);
46
77
  }
47
78
 
@@ -53,9 +84,18 @@ function compileFile(filePath, libraries, preamble) {
53
84
  args.shift();
54
85
  const libPath = args.shift();
55
86
  if (!libPath) throw new Error("--lib requires a file argument");
56
- if (libraries.length > 0) throw new Error("--lib may be specified at most once");
57
- const libBuffer = fs.readFileSync(libPath);
58
- libraries.push(loadLibrary(decodeObject(libBuffer)));
87
+ if (libraries.length > 0) {
88
+ throw new Error("--lib may be specified at most once");
89
+ }
90
+ if (libPath.endsWith(".k")) {
91
+ const raw = fs.readFileSync(libPath, "utf8");
92
+ libraries.push(
93
+ loadLibrary(compileLibrary(raw, { source: libPath }))
94
+ );
95
+ } else {
96
+ const libBuffer = fs.readFileSync(libPath);
97
+ libraries.push(loadLibrary(decodeObject(libBuffer)));
98
+ }
59
99
  } else if (args[0] === "--export") {
60
100
  args.shift();
61
101
  const spec = args.shift();