@fraczak/k 6.1.1 → 6.1.3

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 (79) hide show
  1. package/.codex +0 -0
  2. package/Code-derivation-tests/pattern-envelope.mjs +26 -0
  3. package/DOCS/BIG_PICTURE.md +10 -10
  4. package/DOCS/DIVERGENCE_DETECTION.md +1 -1
  5. package/DOCS/REPL.md +33 -0
  6. package/DOCS/TYPE_DERIVATION.md +12 -12
  7. package/DOCS/a.html +398 -0
  8. package/DOCS/book/01-introduction.md +2 -2
  9. package/DOCS/book/02-syntax-and-values.md +8 -8
  10. package/DOCS/book/03-types-as-finite-automata.md +2 -2
  11. package/DOCS/book/04-partial-functions-and-composition.md +2 -2
  12. package/DOCS/book/05-typing-filters-and-normalization.md +3 -3
  13. package/DOCS/book/06-values-in-memory.md +3 -3
  14. package/DOCS/book/07-the-partial-function-abi.md +1 -1
  15. package/DOCS/book/08-operational-semantics-and-execution.md +1 -1
  16. package/DOCS/book/09-compiler-architecture.md +2 -2
  17. package/DOCS/book/appendix-b-incorporating-external-predefined-types-and-functions.md +1 -0
  18. package/DOCS/dependency-graph.html +140 -0
  19. package/DOCS/dependency-graph.md +144 -0
  20. package/NAT.k~ +452 -0
  21. package/README.md +7 -8
  22. package/UU/ta.k +1 -0
  23. package/UU/ta.k~ +0 -0
  24. package/UU/tb.k +0 -0
  25. package/UU/tc.k +0 -0
  26. package/a.k +138 -0
  27. package/a.klib +1 -0
  28. package/codecs/BINARY_FORMAT.html +471 -0
  29. package/codecs/BINARY_FORMAT.md +1 -1
  30. package/codecs/POLYMORPHIC_BINARY_FORMAT.html +355 -0
  31. package/codecs/POLYMORPHIC_BINARY_FORMAT.md +1 -1
  32. package/codecs/ieee.mjs +19 -4
  33. package/codecs/int.mjs +11 -4
  34. package/codecs/json.mjs +7 -4
  35. package/codecs/k-parse.mjs +7 -4
  36. package/codecs/k-print.mjs +7 -4
  37. package/codecs/runtime/cli-entry.mjs +13 -0
  38. package/codecs/show.mjs +7 -4
  39. package/codecs/unit.mjs +23 -8
  40. package/codecs/utf16.mjs +27 -5
  41. package/codecs/utf8.mjs +27 -5
  42. package/codes.mjs +14 -33
  43. package/core.json +1 -0
  44. package/core.klib +1 -0
  45. package/core.klib~ +0 -0
  46. package/export.mjs +3 -3
  47. package/ieee.klib +1 -0
  48. package/k-vscode/package-lock.json +4176 -0
  49. package/kkk.k +197 -0
  50. package/kkk.klib +0 -0
  51. package/kkk.klib~ +0 -0
  52. package/nak.klib +1 -0
  53. package/nak2.klib +1 -0
  54. package/nat.k +10 -0
  55. package/nat2.k +9 -0
  56. package/object.mjs +20 -7
  57. package/p.json +5475 -0
  58. package/package.json +3 -2
  59. package/repl-codecs.mjs +173 -0
  60. package/repl.mjs +215 -5
  61. package/run.mjs +16 -2
  62. package/scripts/benchmark-idempotency.mjs +72 -0
  63. package/test-ieee-arithmetic.mjs +93 -0
  64. package/test-k-object.mjs +19 -0
  65. package/test-repl.mjs +60 -1
  66. package/tests.sh +10 -1
  67. package/type_registry/registry.mjs~ +105 -0
  68. package/type_registry/typeParser.jison~ +132 -0
  69. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  70. package/.idea/copilot.data.migration.agent.xml +0 -6
  71. package/.idea/copilot.data.migration.ask.xml +0 -6
  72. package/.idea/copilot.data.migration.ask2agent.xml +0 -6
  73. package/.idea/copilot.data.migration.edit.xml +0 -6
  74. package/.idea/k.iml +0 -9
  75. package/.idea/misc.xml +0 -6
  76. package/.idea/modules.xml +0 -8
  77. package/.idea/vcs.xml +0 -6
  78. package/k_compiler/runtime.c +0 -205
  79. package/k_compiler/runtime.h +0 -34
@@ -0,0 +1,93 @@
1
+ import assert from "node:assert/strict";
2
+
3
+ import { createState, evaluateInput } from "./repl.mjs";
4
+ import { Product } from "./Value.mjs";
5
+ import codes from "./codes.mjs";
6
+ import { parse as parseFloat64, print as printFloat64 } from "./codecs/ieee.mjs";
7
+ import { singletonPatternToCodeHash, valueForCode } from "./repl-codecs.mjs";
8
+
9
+ const state = createState();
10
+ await evaluateInput(":load Examples/ieee.k", state);
11
+
12
+ for (const name of ["add", "sub", "mul", "div"]) {
13
+ assert.ok(state.relAliases[name], `Expected public IEEE relation '${name}'`);
14
+ }
15
+
16
+ const float64Hash = state.typeAliases.float64;
17
+ const floatPairHash = state.typeAliases.float_pair;
18
+
19
+ function float64(text) {
20
+ return valueForCode(parseFloat64(text), float64Hash, codes.find);
21
+ }
22
+
23
+ function floatPair(x, y) {
24
+ return valueForCode(new Product({
25
+ x: float64(x),
26
+ y: float64(y)
27
+ }), floatPairHash, codes.find);
28
+ }
29
+
30
+ async function runOperation(op, x, y) {
31
+ state.value = floatPair(x, y);
32
+ await evaluateInput(op, state);
33
+ return state.value;
34
+ }
35
+
36
+ async function runProjectedResult(op, x, y) {
37
+ state.value = floatPair(x, y);
38
+ await evaluateInput(`${op}.result`, state);
39
+ return state.value;
40
+ }
41
+
42
+ function assertFloatResult(value, expected, label) {
43
+ assert.equal(singletonPatternToCodeHash(value.pattern), float64Hash, `${label}: result should keep float64 envelope`);
44
+ assert.equal(printFloat64(value), expected, label);
45
+ }
46
+
47
+ async function assertOperation({ op, x, y, result, flags = null }) {
48
+ const bundle = await runOperation(op, x, y);
49
+ assert.ok(bundle instanceof Product, `${op} should return a result bundle`);
50
+ assert.deepEqual(Object.keys(bundle.product).sort(), ["flags", "result"]);
51
+ assertFloatResult(bundle.product.result, result, `${op}(${x}, ${y}).result`);
52
+ if (flags != null) {
53
+ assert.equal(bundle.product.flags.tag, flags, `${op}(${x}, ${y}).flags`);
54
+ }
55
+
56
+ const projected = await runProjectedResult(op, x, y);
57
+ assertFloatResult(projected, result, `${op}(${x}, ${y}).result projection`);
58
+ }
59
+
60
+ const cases = [
61
+ // Addition: same sign, cancellation, exact fractional add, and specials.
62
+ { op: "add", x: "1", y: "1", result: "2", flags: "none" },
63
+ { op: "add", x: "-1", y: "1", result: "0", flags: "none" },
64
+ { op: "add", x: "0.5", y: "0.25", result: "0.75", flags: "none" },
65
+ { op: "add", x: "Infinity", y: "-Infinity", result: "NaN", flags: "invalid" },
66
+ { op: "add", x: "NaN", y: "1", result: "NaN", flags: "none" },
67
+
68
+ // Subtraction: positive result, negative result, signed-zero-equivalent, and invalid infinity subtraction.
69
+ { op: "sub", x: "4", y: "2", result: "2", flags: "none" },
70
+ { op: "sub", x: "2", y: "4", result: "-2", flags: "none" },
71
+ { op: "sub", x: "0", y: "0", result: "0", flags: "none" },
72
+ { op: "sub", x: "Infinity", y: "Infinity", result: "NaN", flags: "invalid" },
73
+
74
+ // Multiplication: positive, signed, zero, and invalid infinity-by-zero.
75
+ { op: "mul", x: "4", y: "2", result: "8", flags: "none" },
76
+ { op: "mul", x: "-2", y: "4", result: "-8", flags: "none" },
77
+ { op: "mul", x: "0", y: "5", result: "0", flags: "none" },
78
+ { op: "mul", x: "Infinity", y: "0", result: "NaN", flags: "invalid" },
79
+
80
+ // Division: normalized exact cases, fractional quotient, divide-by-zero, invalid zero-over-zero, and infinity quotient.
81
+ { op: "div", x: "4", y: "2", result: "2" },
82
+ { op: "div", x: "1", y: "1", result: "1" },
83
+ { op: "div", x: "1", y: "2", result: "0.5" },
84
+ { op: "div", x: "1", y: "0", result: "Infinity", flags: "div_by_zero" },
85
+ { op: "div", x: "0", y: "0", result: "NaN", flags: "invalid" },
86
+ { op: "div", x: "Infinity", y: "2", result: "Infinity", flags: "none" }
87
+ ];
88
+
89
+ for (const testCase of cases) {
90
+ await assertOperation(testCase);
91
+ }
92
+
93
+ console.log("OK");
package/test-k-object.mjs CHANGED
@@ -91,6 +91,25 @@ assert.match(decompiledSource, /\$ Nws3 =/);
91
91
  assert.match(decompiledSource, /^7jfi = /m);
92
92
  assert.match(decompiledSource, /^----- main -----\n\?\(\.\.\.\) 7jfi \$Nws3$/m);
93
93
 
94
+ const natLibraryBuffer = compileLibraryBuffer(fs.readFileSync("Examples/nat.k", "utf8"), { source: "Examples/nat.k" });
95
+ const natDecompiledSource = decompileObjectBuffer(natLibraryBuffer);
96
+ const natRoundTripSource = decompileObjectBuffer(
97
+ compileLibraryBuffer(natDecompiledSource, { source: "Examples/nat.decompiled.k" })
98
+ );
99
+ const recursiveNatPattern = /\?\{<X0 succ, \.\.\.>=X0 x, <X1 succ, \.\.\.>=X1 y\} .* \?X1;/;
100
+ assert.equal(natRoundTripSource, natDecompiledSource);
101
+ assert.match(natDecompiledSource, recursiveNatPattern);
102
+
103
+ const arithmeticsLibraryBuffer = compileLibraryBuffer(
104
+ fs.readFileSync("Examples/arithmetics.k", "utf8"),
105
+ { source: "Examples/arithmetics.k" }
106
+ );
107
+ const arithmeticsDecompiledSource = decompileObjectBuffer(arithmeticsLibraryBuffer);
108
+ const arithmeticsRoundTripSource = decompileObjectBuffer(
109
+ compileLibraryBuffer(arithmeticsDecompiledSource, { source: "Examples/arithmetics.decompiled.k" })
110
+ );
111
+ assert.equal(arithmeticsRoundTripSource, arithmeticsDecompiledSource);
112
+
94
113
  assert.throws(() => k.compile("@A = (); @A"), /Parse error/);
95
114
  assert.throws(() => k.compile("$ @A = {}; $@A"), /Parse error/);
96
115
  assert.deepEqual(k.compile("7jfi = ?X0; 7jfi")(new Product({})).toJSON(), {});
package/test-repl.mjs CHANGED
@@ -2,7 +2,7 @@ import assert from "node:assert";
2
2
  import fs from "node:fs";
3
3
  import os from "node:os";
4
4
  import path from "node:path";
5
- import { fileURLToPath } from "node:url";
5
+ import { fileURLToPath, pathToFileURL } from "node:url";
6
6
 
7
7
  import {
8
8
  aliasNames,
@@ -12,6 +12,7 @@ import {
12
12
  createState,
13
13
  evaluateInput,
14
14
  explicitSnippetTerminated,
15
+ helpText,
15
16
  isMainEntrypoint,
16
17
  lineHasExplicitContinuation,
17
18
  lineTerminatesSnippet
@@ -61,6 +62,8 @@ assert(completions.includes(`(${state.typeAliases.nat}`));
61
62
 
62
63
  completions = completeInput(":run su", state)[0];
63
64
  assert(completions.includes(":run succ"));
65
+ completions = completeInput(":co", state)[0];
66
+ assert(completions.includes(":codec"));
64
67
 
65
68
  completions = completeInput("$na", state)[0];
66
69
  assert(completions.includes("$nat"));
@@ -89,6 +92,7 @@ const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "k-repl-"));
89
92
  const libPath = path.join(tmpDir, "session.klib");
90
93
  const koPath = path.join(tmpDir, "succ.ko");
91
94
  const sourcePath = path.join(tmpDir, "session.k");
95
+ const codecPath = path.join(tmpDir, "bool-codec.mjs");
92
96
  const symlinkPath = path.resolve(".test-k-repl-link");
93
97
  output = await evaluateInput(`:klib ${libPath}`, state);
94
98
  assert.equal(output[0], `saved ${libPath}`);
@@ -117,6 +121,61 @@ assert.match(output[0], /^twice = \$nat succ succ \$nat; -- @/);
117
121
  output = await evaluateInput(":C nat", loadedSource);
118
122
  assert.match(output[0], /^\$ nat = < nat succ, @[^ ]+ zero >; -- @/);
119
123
 
124
+ const codecState = createState();
125
+ output = await evaluateInput(":type bool = <{} true, {} false>", codecState);
126
+ assert.match(output[0], /^\$ bool = @/);
127
+ const boolHash = codecState.typeAliases.bool;
128
+ const valueModuleUrl = pathToFileURL(path.resolve("Value.mjs")).href;
129
+ fs.writeFileSync(codecPath, `
130
+ import { Product, Variant } from ${JSON.stringify(valueModuleUrl)};
131
+
132
+ export const name = "yn";
133
+ export const codes = [${JSON.stringify(boolHash)}];
134
+
135
+ export function parse(text) {
136
+ const tag = text.trim();
137
+ if (tag !== "true" && tag !== "false") throw new Error("expected true or false");
138
+ return new Variant(tag, new Product({}));
139
+ }
140
+
141
+ export function print(value) {
142
+ return value.tag;
143
+ }
144
+ `);
145
+ assert.match(helpText(), /:codec load file/);
146
+ output = await evaluateInput(":codec list", codecState);
147
+ assert.equal(output[0], "(none)");
148
+ completions = completeInput(":codec l", codecState)[0];
149
+ assert(completions.includes(":codec load"));
150
+ assert(completions.includes(":codec list"));
151
+ completions = completeInput(`:codec load ${tmpDir}/bool`, codecState)[0];
152
+ assert(completions.includes(`:codec load ${codecPath}`));
153
+ output = await evaluateInput(`:codec load ${codecPath}`, codecState);
154
+ assert.equal(output[0], `loaded codec yn for ${boolHash}`);
155
+ output = await evaluateInput(":codec list", codecState);
156
+ assert.match(output[0], new RegExp(`^yn ${boolHash.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`));
157
+ completions = completeInput(":input bo", codecState)[0];
158
+ assert(completions.includes(":input bool"));
159
+ completions = completeInput(":input bool y", codecState)[0];
160
+ assert(completions.includes(":input bool yn"));
161
+ output = await evaluateInput(":input bool yn", codecState);
162
+ assert.equal(output[0], `input ${boolHash} using yn: enter value text`);
163
+ output = await evaluateInput("true", codecState);
164
+ assert.match(output[0], /\{\}\|true \?</);
165
+ assert.match(output[0], /yn: true/);
166
+ output = await evaluateInput("{} | false", codecState);
167
+ assert.doesNotMatch(output[0], /yn: false/);
168
+
169
+ const utf8State = createState();
170
+ output = await evaluateInput(":load core.k", utf8State);
171
+ assert.equal(output[0], "loaded core.k");
172
+ output = await evaluateInput(":codec load ./codecs/utf8.mjs", utf8State);
173
+ assert.equal(output[0], `loaded codec utf8 for ${utf8State.typeAliases.string}`);
174
+ output = await evaluateInput(":input string utf8", utf8State);
175
+ assert.equal(output[0], `input ${utf8State.typeAliases.string} using utf8: enter value text`);
176
+ output = await evaluateInput("hello", utf8State);
177
+ assert.match(output[0], /utf8: hello/);
178
+
120
179
  const replPath = fileURLToPath(new URL("./repl.mjs", import.meta.url));
121
180
  try {
122
181
  fs.rmSync(symlinkPath, { force: true });
package/tests.sh CHANGED
@@ -11,5 +11,14 @@ node ./codecs/unit.mjs --parse | node ./codecs/unit.mjs --print | grep -qx '{}'
11
11
  echo
12
12
  printf 'A🙂\nBé~\t' | ./codecs/utf8.mjs --parse | ./k.mjs -k Examples/byte.k |./codecs/utf8.mjs --print
13
13
  echo
14
- echo "1031" | ./codecs/ieee.mjs --parse | ./k.mjs -k Examples/ieee.k | ./codecs/ieee.mjs --print
14
+ ./objects/compile-lib.mjs Examples/ieee.k ieee.klib
15
+ MUL=`./objects/extract-aliases.mjs ieee.klib | grep '^mul = @' | sed 's/^mul = \(@[^;]*\);.*$/\1/'`
16
+ DIV=`./objects/extract-aliases.mjs ieee.klib | grep '^div = @' | sed 's/^div = \(@[^;]*\);.*$/\1/'`
17
+ ARG=0.12
18
+ printf "$ARG * $ARG = "
19
+ echo $ARG | ./codecs/ieee.mjs --parse | ./k.mjs --lib ieee.klib "{()x,()y} $MUL .result" | ./codecs/ieee.mjs --print
20
+ printf "$ARG / $ARG = "
21
+ DIV_RESULT=`echo $ARG | ./codecs/ieee.mjs --parse | ./k.mjs --lib ieee.klib "{()x,()y} $DIV .result" | ./codecs/ieee.mjs --print`
22
+ echo "$DIV_RESULT"
23
+ test "$DIV_RESULT" = "1"
15
24
  echo
@@ -0,0 +1,105 @@
1
+ import http from 'http';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import codes from '../codes.mjs';
6
+ import { parse } from './typeParser.mjs';
7
+
8
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
+ const REGISTRY_FILE = path.join(__dirname, 'registry.json');
10
+ const PORT = 3001;
11
+
12
+ // Load existing registry if it exists
13
+ if (fs.existsSync(REGISTRY_FILE)) {
14
+ console.log('Loading existing registry...');
15
+ try {
16
+ const data = fs.readFileSync(REGISTRY_FILE, 'utf8');
17
+ const json = JSON.parse(data);
18
+ codes.load(json);
19
+ console.log(`Loaded ${Object.keys(json).length} types.`);
20
+ } catch (err) {
21
+ console.error('Error loading registry:', err);
22
+ }
23
+ } else {
24
+ console.log('No existing registry found. Starting fresh.');
25
+ }
26
+
27
+ const server = http.createServer((req, res) => {
28
+ // Helper to send JSON response
29
+ const sendJSON = (data, status = 200) => {
30
+ res.writeHead(status, { 'Content-Type': 'application/json' });
31
+ res.end(JSON.stringify(data));
32
+ };
33
+
34
+ // Helper to send Error
35
+ const sendError = (message, status = 400) => {
36
+ res.writeHead(status, { 'Content-Type': 'application/json' });
37
+ res.end(JSON.stringify({ error: message }));
38
+ };
39
+
40
+ // Route: POST
41
+ if (req.method === 'POST') {
42
+ let body = '';
43
+ req.on('data', chunk => {
44
+ body += chunk.toString();
45
+ });
46
+ req.on('end', () => {
47
+ try {
48
+ // 1. Parse the input string using the Jison parser
49
+ // The parser expects a string of type definitions
50
+ console.log("Received body:", body);
51
+ const definitions = parse(body);
52
+ console.log("Parsed definitions:", JSON.stringify(definitions, null, 2));
53
+
54
+ // 2. Register the parsed codes
55
+ // codes.register returns the representatives map { temp_name: canonical_hash }
56
+ const representatives = codes.register(definitions);
57
+
58
+ // Filter out generated names (_gen_...) and canonical names (@...)
59
+ const filteredRepresentatives = Object.fromEntries(
60
+ Object.entries(representatives).filter(([key, value]) =>
61
+ !key.startsWith('_gen_') && !key.startsWith('@')
62
+ )
63
+ );
64
+
65
+ // 3. Save to disk
66
+ const dump = codes.dump();
67
+ fs.writeFileSync(REGISTRY_FILE, JSON.stringify(dump, null, 2));
68
+
69
+ // 4. Return the mapping
70
+ sendJSON(filteredRepresentatives);
71
+
72
+ } catch (err) {
73
+ console.error(err);
74
+ sendError(`Registration failed: ${err.message}`);
75
+ }
76
+ });
77
+ }
78
+ // Route: GET
79
+ else if (req.method === 'GET') {
80
+ const typeId = req.url.split('/').pop();
81
+ console.log("Requested type ID:", typeId);
82
+ if (!typeId) {
83
+ sendError('Missing type ID');
84
+ return;
85
+ }
86
+ // Decode URI component in case @ is encoded
87
+ const decodedId = decodeURIComponent(typeId);
88
+ console.log("Decoded type ID:", decodedId);
89
+
90
+ const typeDef = codes.find(decodedId);
91
+ if (typeDef.code === 'undefined') {
92
+ sendError('Type not found', 404);
93
+ } else {
94
+ sendJSON(typeDef);
95
+ }
96
+ }
97
+ // 404 Not Found
98
+ else {
99
+ sendError('Not Found', 404);
100
+ }
101
+ });
102
+
103
+ server.listen(PORT, () => {
104
+ console.log(`Type Registry running at http://localhost:${PORT}/`);
105
+ });
@@ -0,0 +1,132 @@
1
+ %{
2
+
3
+ let defs = {};
4
+ let genCount = 0;
5
+ let genNameId;
6
+
7
+ function genName() {
8
+ return `_gen_${genCount++}`;
9
+ }
10
+
11
+ function fromEscString(escString) {
12
+ const isSingleQuoted = escString.startsWith("'");
13
+ let str = escString.substring(1, escString.length - 1);
14
+ if (isSingleQuoted) {
15
+ str = str.replace(/\\'/g, "'");
16
+ } else {
17
+ str = str.replace(/\\"/g, '"');
18
+ }
19
+ str = str.replace(/\\\\/g, '\\');
20
+ str = str.replace(/\\\//g, '/');
21
+ str = str.replace(/\\b/g, '\b');
22
+ str = str.replace(/\\f/g, '\f');
23
+ str = str.replace(/\\n/g, '\n');
24
+ str = str.replace(/\\r/g, '\r');
25
+ str = str.replace(/\\t/g, '\t');
26
+ str = str.replace(/\\u([\dA-F]{4})/gi, (match, p1) => String.fromCharCode(parseInt(p1, 16)));
27
+
28
+ return str;
29
+ }
30
+
31
+ %}
32
+
33
+ %lex
34
+
35
+ %%
36
+ \s+ /* blanks */
37
+ "<" return 'LA';
38
+ ">" return 'RA';
39
+ "{" return 'LC';
40
+ "}" return 'RC';
41
+ "=" return 'EQ';
42
+ "," return 'COMMA';
43
+ ";" return 'SC';
44
+ "@" return 'AT';
45
+ "$" return 'DOLLAR';
46
+ \"([^"\\]|\\(.|\n))*\"|\'([^'\\]|\\(.|\n))*\' return 'STRING';
47
+ [a-zA-Z0-9_+-][a-zA-Z0-9_?!+-]* return 'NAME';
48
+ <<EOF>> return 'EOF';
49
+ . return 'INVALID';
50
+
51
+ /lex
52
+
53
+ %token NAME STRING
54
+ %token LA RA LC RC EQ COMMA SC AT DOLLAR
55
+ %token EOF
56
+
57
+ %start expressions
58
+
59
+ %%
60
+
61
+ expressions
62
+ : initialize_defs definitions EOF
63
+ { return defs; }
64
+ ;
65
+
66
+ initialize_defs
67
+ : /* empty */
68
+ { defs = {}; genCount = 0; }
69
+ ;
70
+
71
+ definitions
72
+ : definition
73
+ | definitions definition
74
+ ;
75
+
76
+ definition
77
+ : DOLLAR name EQ LA field_list RA SC
78
+ { defs[$2] = { code: 'union', union: $5 }; }
79
+ | DOLLAR name EQ LC field_list RC SC
80
+ { defs[$2] = { code: 'product', product: $5 }; }
81
+ ;
82
+
83
+ type_expr
84
+ : LA field_list RA
85
+ {
86
+ genNameId = genName();
87
+ defs[genNameId] = { code: 'union', union: $2 };
88
+ $$ = genNameId;
89
+ }
90
+ | LC field_list RC
91
+ {
92
+ genNameId = genName();
93
+ defs[genNameId] = { code: 'product', product: $2 };
94
+ $$ = genNameId;
95
+ }
96
+ | ref
97
+ { $$ = $1; }
98
+ ;
99
+
100
+ ref
101
+ : name
102
+ { $$ = $1; }
103
+ | AT name
104
+ { $$ = '@' + $2; }
105
+ ;
106
+
107
+ field_list
108
+ : /* empty */
109
+ { $$ = {}; }
110
+ | field
111
+ { $$ = {}; $$[$1.label] = $1.type; }
112
+ | field_list COMMA field
113
+ { $$ = $1; $$[$3.label] = $3.type; }
114
+ ;
115
+
116
+ field
117
+ : type_expr label
118
+ { $$ = { type: $1, label: $2 }; }
119
+ ;
120
+
121
+ label
122
+ : name
123
+ { $$ = $1; }
124
+ | str
125
+ { $$ = $1; }
126
+ ;
127
+
128
+ name: NAME { $$ = yytext; };
129
+ str: STRING { $$ = fromEscString(yytext); };
130
+
131
+ %%
132
+
@@ -1,5 +0,0 @@
1
- <component name="ProjectCodeStyleConfiguration">
2
- <state>
3
- <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
4
- </state>
5
- </component>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="AgentMigrationStateService">
4
- <option name="migrationStatus" value="COMPLETED" />
5
- </component>
6
- </project>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="AskMigrationStateService">
4
- <option name="migrationStatus" value="COMPLETED" />
5
- </component>
6
- </project>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="Ask2AgentMigrationStateService">
4
- <option name="migrationStatus" value="COMPLETED" />
5
- </component>
6
- </project>
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="EditMigrationStateService">
4
- <option name="migrationStatus" value="COMPLETED" />
5
- </component>
6
- </project>
package/.idea/k.iml DELETED
@@ -1,9 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="JAVA_MODULE" version="4">
3
- <component name="NewModuleRootManager" inherit-compiler-output="true">
4
- <exclude-output />
5
- <content url="file://$MODULE_DIR$" />
6
- <orderEntry type="inheritedJdk" />
7
- <orderEntry type="sourceFolder" forTests="false" />
8
- </component>
9
- </module>
package/.idea/misc.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectRootManager">
4
- <output url="file://$PROJECT_DIR$/out" />
5
- </component>
6
- </project>
package/.idea/modules.xml DELETED
@@ -1,8 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/k.iml" filepath="$PROJECT_DIR$/.idea/k.iml" />
6
- </modules>
7
- </component>
8
- </project>
package/.idea/vcs.xml DELETED
@@ -1,6 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="" vcs="Git" />
5
- </component>
6
- </project>