@fraczak/k 6.10.6 → 7.0.1
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 +55 -0
- package/CLAUDE.md +1 -1
- package/DOCS/BIG_PICTURE.md +156 -172
- package/DOCS/BINARY_CODEC_STATUS_AND_TODO.md +3 -3
- package/DOCS/CODEC_ARCHITECTURE.md +2 -2
- package/DOCS/DICTIONARY.md +243 -250
- package/DOCS/DIVERGENCE_DETECTION.md +0 -1
- package/DOCS/FILE_FORMATS.md +5 -5
- package/DOCS/KIR_SPECIALIZATION_DESIGN.md +1 -1
- package/DOCS/OBJECT_FILE_AND_PATTERN.md +12 -12
- package/DOCS/PATTERNS.md +17 -17
- package/DOCS/PATTERNS_AND_TYPED_VALUES.md +1 -1
- package/DOCS/REPL.md +9 -19
- package/DOCS/TYPE_DERIVATION.md +2 -8
- package/DOCS/WEB_REPL_REQUIREMENTS.md +8 -8
- package/DOCS/book/01-introduction.md +8 -11
- package/DOCS/book/02-syntax-and-values.md +19 -20
- package/DOCS/book/03-types-as-finite-automata.md +42 -43
- package/DOCS/book/04-partial-functions-and-composition.md +2 -3
- package/DOCS/book/05-typing-filters-and-normalization.md +44 -46
- package/DOCS/book/06-values-in-memory.md +10 -10
- package/DOCS/book/08-operational-semantics-and-execution.md +21 -26
- package/DOCS/book/09-compiler-architecture.md +11 -11
- package/DOCS/book/10-from-ast-to-intermediate-representation.md +6 -7
- package/DOCS/book/14-canonical-serialization.md +2 -2
- package/DOCS/book/appendix-b-incorporating-external-predefined-types-and-functions.md +17 -17
- package/DOCS/book.md +5 -5
- package/Examples/arithmetics.k +49 -153
- package/Examples/bnat.k +13 -13
- package/Examples/byte.k +2 -50
- package/Examples/ieee.k +408 -423
- package/Examples/karatsuba-mult.k +30 -34
- package/Examples/nat.k +5 -6
- package/README.md +54 -49
- package/TODO.md +13 -18
- package/backend-api.mjs +9 -1
- package/backends/llvm/scripts/run-tests.mjs +5 -0
- package/backends/llvm/src/kvm2llvm.mjs +2 -1
- package/backends/llvm/src/llvm.mjs +18 -25
- package/backends/llvm/tests/integration.sh +2 -2
- package/backends/llvm/tests/test-llvm.mjs +3 -3
- package/backends/llvm/tests/test-open-product-misalignment.mjs +140 -0
- package/backends/wasm/demo_ieee.mjs +2 -3
- package/backends/wasm/runtime.wat +157 -5
- package/backends/wasm/src/kvm2wasm.mjs +57 -34
- package/backends/wasm/src/wasm.mjs +38 -17
- package/backends/wasm/tests/perf-support.mjs +4 -4
- package/backends/wasm/tests/test-wasm.mjs +13 -14
- package/browser/vfs-data.mjs +12 -12
- package/codecs/BINARY_FORMAT.md +4 -4
- package/codecs/POLYMORPHIC_BINARY_FORMAT.md +4 -4
- package/codecs/README.md +6 -6
- package/codecs/ieee.mjs +15 -11
- package/codecs/int.mjs +9 -5
- package/codecs/string-codec.mjs +46 -47
- package/core.k +123 -95
- package/kir.mjs +213 -17
- package/object.mjs +0 -7
- package/package.json +5 -2
- package/parser.jison +2 -41
- package/parser.mjs +55 -95
- package/pretty.mjs +11 -4
- package/repl.mjs +8 -63
- package/scripts/build-repl-html.mjs +8 -38
- package/tests/code-derivation/blowup.mjs +2 -4
- package/tests/code-derivation/bnat.mjs +2 -3
- package/tests/code-derivation/dot.mjs +5 -11
- package/tests/code-derivation/nat.mjs +2 -2
- package/tests/code-derivation/not-not.mjs +6 -6
- package/tests/code-derivation/pattern-envelope.mjs +4 -6
- package/tests/code-derivation/product.mjs +3 -6
- package/tests/code-derivation/rlz.mjs +4 -5
- package/tests/test-codecs.mjs +1 -1
- package/tests/test-fingerprint.mjs +36 -41
- package/tests/test-hash-normalization.mjs +4 -6
- package/tests/test-ieee-arithmetic.mjs +6 -7
- package/tests/test-k-object.mjs +11 -15
- package/tests/test-kir.mjs +0 -1
- package/tests/test-kvm-polymorphic.mjs +1 -2
- package/tests/test-kvm.mjs +8 -11
- package/tests/test-repl-html.mjs +20 -2
- package/tests/test-repl.mjs +48 -53
- package/tests/test.mjs +2 -3
package/kir.mjs
CHANGED
|
@@ -8,6 +8,7 @@ import { compileObject, decodeObject, hydrateObject } from "./object.mjs";
|
|
|
8
8
|
import { exportPatternGraph } from "./codecs/runtime/codec.mjs";
|
|
9
9
|
import { patternToPropertyList } from "./codecs/runtime/pattern-json.mjs";
|
|
10
10
|
import { propertyListToFilter } from "./codecs/runtime/show-value.mjs";
|
|
11
|
+
import { TypePatternGraph } from "./TypePatternGraph.mjs";
|
|
11
12
|
|
|
12
13
|
const KIR_FORMAT = "k-ir";
|
|
13
14
|
const KIR_VERSION = 1;
|
|
@@ -240,6 +241,11 @@ function resolveRelation(object, relationName = null) {
|
|
|
240
241
|
const alias = object.relAlias?.[name];
|
|
241
242
|
if (alias && object.rels?.[alias]) return { name: alias, rel: object.rels[alias] };
|
|
242
243
|
if (alias && object.rels?.[name]) return { name, rel: object.rels[name] };
|
|
244
|
+
if (alias) {
|
|
245
|
+
for (const [k, rel] of Object.entries(object.rels || {})) {
|
|
246
|
+
if (object.relAlias?.[k] === alias) return { name: k, rel };
|
|
247
|
+
}
|
|
248
|
+
}
|
|
243
249
|
|
|
244
250
|
throw new Error(`Relation '${name}' not found`);
|
|
245
251
|
}
|
|
@@ -264,7 +270,188 @@ function relationLibraryWithTarget(object, targetRel) {
|
|
|
264
270
|
};
|
|
265
271
|
}
|
|
266
272
|
|
|
267
|
-
function
|
|
273
|
+
function addPropertyListToPatternGraph(graph, propertyList) {
|
|
274
|
+
const kindToPattern = {
|
|
275
|
+
any: "(...)",
|
|
276
|
+
"open-product": "{...}",
|
|
277
|
+
"open-union": "<...>",
|
|
278
|
+
"closed-product": "{}",
|
|
279
|
+
"closed-union": "<>"
|
|
280
|
+
};
|
|
281
|
+
const nodes = propertyList.map(([kind]) =>
|
|
282
|
+
graph.addNewNode({ pattern: kindToPattern[kind] })
|
|
283
|
+
);
|
|
284
|
+
|
|
285
|
+
propertyList.forEach(([, edges], nodeIndex) => {
|
|
286
|
+
for (const [label, target] of edges) {
|
|
287
|
+
graph.edges[nodes[nodeIndex]][label] = [nodes[target]];
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
return nodes[0];
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
function cloneRelation(rel) {
|
|
295
|
+
const clonedGraph = new TypePatternGraph(
|
|
296
|
+
rel.typePatternGraph.registerCodeDef,
|
|
297
|
+
rel.typePatternGraph.findCode
|
|
298
|
+
);
|
|
299
|
+
clonedGraph.patterns.nodes = JSON.parse(JSON.stringify(rel.typePatternGraph.patterns.nodes));
|
|
300
|
+
clonedGraph.patterns.parent = [...rel.typePatternGraph.patterns.parent];
|
|
301
|
+
clonedGraph.edges = JSON.parse(JSON.stringify(rel.typePatternGraph.edges));
|
|
302
|
+
clonedGraph.codeId = { ...rel.typePatternGraph.codeId };
|
|
303
|
+
|
|
304
|
+
return {
|
|
305
|
+
...rel,
|
|
306
|
+
def: JSON.parse(JSON.stringify(rel.def)),
|
|
307
|
+
typePatternGraph: clonedGraph,
|
|
308
|
+
typeDerivation: { ...(rel.typeDerivation || {}) }
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function findCallSites(exp) {
|
|
313
|
+
const calls = [];
|
|
314
|
+
function visit(node) {
|
|
315
|
+
if (!node) return;
|
|
316
|
+
if (node.op === "ref") calls.push(node);
|
|
317
|
+
if (node.comp) node.comp.forEach(visit);
|
|
318
|
+
if (node.items) node.items.forEach(visit);
|
|
319
|
+
if (node.union) node.union.forEach(visit);
|
|
320
|
+
if (node.product) node.product.forEach((item) => visit(item.exp));
|
|
321
|
+
if (node.fields) node.fields.forEach((item) => visit(item.expr));
|
|
322
|
+
}
|
|
323
|
+
visit(exp);
|
|
324
|
+
return calls;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function findRelation(rels, relAlias, name) {
|
|
328
|
+
if (!name) return null;
|
|
329
|
+
if (rels[name]) return { name, rel: rels[name] };
|
|
330
|
+
const alias = relAlias?.[name];
|
|
331
|
+
if (alias && rels[alias]) return { name: alias, rel: rels[alias] };
|
|
332
|
+
if (alias) {
|
|
333
|
+
for (const [k, rel] of Object.entries(rels)) {
|
|
334
|
+
if (relAlias?.[k] === alias) return { name: k, rel };
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export function specializeObjectRelations(object, entryRelationName = null, inputPattern = null) {
|
|
341
|
+
if (object?.format !== "k-object") {
|
|
342
|
+
throw new Error("specializeObjectRelations requires a k object");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
const baseRels = Object.fromEntries(
|
|
346
|
+
Object.entries(object.rels || {}).map(([name, rel]) => [name, cloneRelation(rel)])
|
|
347
|
+
);
|
|
348
|
+
for (const [aliasName, hash] of Object.entries(object.relAlias || {})) {
|
|
349
|
+
if (!baseRels[aliasName]) {
|
|
350
|
+
const match = Object.entries(baseRels).find(([k]) => object.relAlias?.[k] === hash);
|
|
351
|
+
if (match) baseRels[aliasName] = match[1];
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const entry = findRelation(
|
|
356
|
+
baseRels,
|
|
357
|
+
object.relAlias,
|
|
358
|
+
entryRelationName || object.main || "__main__"
|
|
359
|
+
);
|
|
360
|
+
if (!entry) return object;
|
|
361
|
+
|
|
362
|
+
const specializedRels = new Map();
|
|
363
|
+
const specializedCounts = new Map();
|
|
364
|
+
const newRels = {};
|
|
365
|
+
|
|
366
|
+
const entryRel = cloneRelation(entry.rel);
|
|
367
|
+
newRels[entry.name] = entryRel;
|
|
368
|
+
|
|
369
|
+
if (Array.isArray(inputPattern) && inputPattern.length > 0) {
|
|
370
|
+
const inRoot = addPropertyListToPatternGraph(entryRel.typePatternGraph, inputPattern);
|
|
371
|
+
try {
|
|
372
|
+
entryRel.typePatternGraph.unify("specialize", entryRel.def.patterns[0], inRoot);
|
|
373
|
+
} catch {
|
|
374
|
+
// Best-effort entry unification
|
|
375
|
+
}
|
|
376
|
+
specializedRels.set(entry.name + "::" + JSON.stringify(inputPattern), entry.name);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const worklist = [entry.name];
|
|
380
|
+
while (worklist.length > 0) {
|
|
381
|
+
const currentName = worklist.shift();
|
|
382
|
+
const currentRel = newRels[currentName];
|
|
383
|
+
if (!currentRel) continue;
|
|
384
|
+
|
|
385
|
+
const calls = findCallSites(currentRel.def);
|
|
386
|
+
for (const call of calls) {
|
|
387
|
+
const target = findRelation(baseRels, object.relAlias, call.ref);
|
|
388
|
+
if (!target) continue;
|
|
389
|
+
|
|
390
|
+
const argPatternId = call.patterns?.[0];
|
|
391
|
+
if (argPatternId != null) {
|
|
392
|
+
const argRoot = currentRel.typePatternGraph.find(argPatternId);
|
|
393
|
+
const argPropList = patternToPropertyList(
|
|
394
|
+
exportPatternGraph(currentRel.typePatternGraph, argRoot)
|
|
395
|
+
);
|
|
396
|
+
const argSig = JSON.stringify(argPropList);
|
|
397
|
+
const specKey = target.name + "::" + argSig;
|
|
398
|
+
|
|
399
|
+
let specName = specializedRels.get(specKey);
|
|
400
|
+
if (!specName) {
|
|
401
|
+
const count = (specializedCounts.get(target.name) || 0) + 1;
|
|
402
|
+
specializedCounts.set(target.name, count);
|
|
403
|
+
specName = count === 1 ? target.name : `${target.name}$${count}`;
|
|
404
|
+
specializedRels.set(specKey, specName);
|
|
405
|
+
|
|
406
|
+
const targetRel = cloneRelation(target.rel);
|
|
407
|
+
const tInRoot = addPropertyListToPatternGraph(targetRel.typePatternGraph, argPropList);
|
|
408
|
+
try {
|
|
409
|
+
targetRel.typePatternGraph.unify("specialize", targetRel.def.patterns[0], tInRoot);
|
|
410
|
+
} catch {
|
|
411
|
+
// Unification failure: keep target unspecialized
|
|
412
|
+
}
|
|
413
|
+
newRels[specName] = targetRel;
|
|
414
|
+
worklist.push(specName);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
call.ref = specName;
|
|
418
|
+
|
|
419
|
+
const targetRel = newRels[specName];
|
|
420
|
+
const outPatternId = targetRel.def.patterns?.[1];
|
|
421
|
+
const retPatternId = call.patterns?.[1];
|
|
422
|
+
if (outPatternId != null && retPatternId != null) {
|
|
423
|
+
const outRoot = targetRel.typePatternGraph.find(outPatternId);
|
|
424
|
+
const retPropList = patternToPropertyList(
|
|
425
|
+
exportPatternGraph(targetRel.typePatternGraph, outRoot)
|
|
426
|
+
);
|
|
427
|
+
const rRetRoot = addPropertyListToPatternGraph(currentRel.typePatternGraph, retPropList);
|
|
428
|
+
try {
|
|
429
|
+
currentRel.typePatternGraph.unify("specialize", retPatternId, rRetRoot);
|
|
430
|
+
} catch {
|
|
431
|
+
// Keep existing call return pattern on unification error
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
const resultRels = {
|
|
439
|
+
...baseRels,
|
|
440
|
+
...newRels
|
|
441
|
+
};
|
|
442
|
+
const resultRelAlias = { ...(object.relAlias || {}) };
|
|
443
|
+
for (const name of Object.keys(newRels)) {
|
|
444
|
+
if (!resultRelAlias[name]) resultRelAlias[name] = name;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return {
|
|
448
|
+
...object,
|
|
449
|
+
rels: resultRels,
|
|
450
|
+
relAlias: resultRelAlias
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
export function relationPatternPropertyList(rel, index) {
|
|
268
455
|
return expPatternPropertyList(rel, rel.def, index);
|
|
269
456
|
}
|
|
270
457
|
|
|
@@ -284,28 +471,35 @@ export function retypeObjectRelationForBackend(object, relationName, inputPatter
|
|
|
284
471
|
}
|
|
285
472
|
|
|
286
473
|
const target = resolveRelation(object, relationName);
|
|
287
|
-
const
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
libraries: [relationLibraryWithTarget(object, target.rel)]
|
|
291
|
-
}));
|
|
292
|
-
const kir = objectToKIRP(retypedObject);
|
|
293
|
-
const entryName = retypedObject.main || "__main__";
|
|
294
|
-
const retypedRel = retypedObject.rels[entryName];
|
|
295
|
-
const entryInputPattern = relationPatternPropertyList(retypedRel, 0);
|
|
474
|
+
const specializedObject = specializeObjectRelations(object, target.name, inputPattern);
|
|
475
|
+
const specializedRel = resolveRelation(specializedObject, target.name);
|
|
476
|
+
const kir = objectToKIRP(specializedObject);
|
|
296
477
|
|
|
297
478
|
return {
|
|
298
|
-
relation:
|
|
299
|
-
retypedObject,
|
|
479
|
+
relation: target.name,
|
|
480
|
+
retypedObject: specializedObject,
|
|
300
481
|
kir,
|
|
301
|
-
entryName,
|
|
302
|
-
inputPattern:
|
|
303
|
-
outputPattern: relationPatternPropertyList(
|
|
482
|
+
entryName: target.name,
|
|
483
|
+
inputPattern: relationPatternPropertyList(specializedRel.rel, 0),
|
|
484
|
+
outputPattern: relationPatternPropertyList(specializedRel.rel, 1)
|
|
304
485
|
};
|
|
305
486
|
}
|
|
306
487
|
|
|
307
488
|
export function retypeObjectRelation(object, relationName, inputPattern, options = {}) {
|
|
308
|
-
|
|
489
|
+
if (object?.format !== "k-object") {
|
|
490
|
+
throw new Error("KIR retyping requires a k object");
|
|
491
|
+
}
|
|
492
|
+
if (!Array.isArray(inputPattern)) {
|
|
493
|
+
throw new Error("KIR retyping requires an input pattern property list");
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
const target = resolveRelation(object, relationName);
|
|
497
|
+
const source = `?${propertyListToFilter(inputPattern)} __kir_target__`;
|
|
498
|
+
const retypedObject = hydrateObject(compileObject(source, {
|
|
499
|
+
source: options.source || "<kir-retype>",
|
|
500
|
+
libraries: [relationLibraryWithTarget(object, target.rel)]
|
|
501
|
+
}));
|
|
502
|
+
return objectToKIRP(retypedObject);
|
|
309
503
|
}
|
|
310
504
|
|
|
311
505
|
export { KIR_FORMAT, KIR_VERSION };
|
|
@@ -314,8 +508,10 @@ export default {
|
|
|
314
508
|
KIR_FORMAT,
|
|
315
509
|
KIR_VERSION,
|
|
316
510
|
objectToKIRP,
|
|
511
|
+
relationPatternPropertyList,
|
|
317
512
|
retypeObjectRelation,
|
|
318
|
-
retypeObjectRelationForBackend
|
|
513
|
+
retypeObjectRelationForBackend,
|
|
514
|
+
specializeObjectRelations
|
|
319
515
|
};
|
|
320
516
|
|
|
321
517
|
function helpText() {
|
package/object.mjs
CHANGED
|
@@ -737,9 +737,6 @@ function decompileObject(object) {
|
|
|
737
737
|
...Object.values(relAliases)
|
|
738
738
|
]);
|
|
739
739
|
|
|
740
|
-
const codeDefs = Object.keys(hydrated.codes)
|
|
741
|
-
.sort()
|
|
742
|
-
.map((name) => `$ ${aliases[name]} = ${codeToSource(hydrated.codes[name], aliases)};`);
|
|
743
740
|
const emittedRelAliases = new Set();
|
|
744
741
|
const relDefForName = (name) => {
|
|
745
742
|
const rel = rels[name];
|
|
@@ -766,8 +763,6 @@ function decompileObject(object) {
|
|
|
766
763
|
if (hydrated.main == null) {
|
|
767
764
|
// Library: no main section
|
|
768
765
|
return [
|
|
769
|
-
"----- codes -----",
|
|
770
|
-
...codeDefs,
|
|
771
766
|
"----- rels -----",
|
|
772
767
|
...relDefs,
|
|
773
768
|
""
|
|
@@ -788,8 +783,6 @@ function decompileObject(object) {
|
|
|
788
783
|
].join(" ");
|
|
789
784
|
|
|
790
785
|
return [
|
|
791
|
-
"----- codes -----",
|
|
792
|
-
...codeDefs,
|
|
793
786
|
"----- rels -----",
|
|
794
787
|
...relDefs,
|
|
795
788
|
"----- main -----",
|
package/package.json
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fraczak/k",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "k — a language for
|
|
3
|
+
"version": "7.0.1",
|
|
4
|
+
"description": "k — a language for content-addressable schemas and data transformations over algebraic data types (products and tagged unions); includes runtime, contract derivation, REPL, and codec toolchain",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
5
8
|
"main": "index.mjs",
|
|
6
9
|
"exports": {
|
|
7
10
|
".": "./index.mjs",
|
package/parser.jison
CHANGED
|
@@ -60,7 +60,6 @@ function fromEscString(escString) {
|
|
|
60
60
|
"," return 'COMMA';
|
|
61
61
|
";" return 'SC';
|
|
62
62
|
":" return 'COL';
|
|
63
|
-
"$" return 'DOLLAR';
|
|
64
63
|
"?" return 'QMARK';
|
|
65
64
|
"@" return 'AT';
|
|
66
65
|
\"([^"\\]|\\(.|\n))*\"|\'([^'\\]|\\(.|\n))*\' return 'STRING';
|
|
@@ -72,7 +71,7 @@ function fromEscString(escString) {
|
|
|
72
71
|
/lex
|
|
73
72
|
|
|
74
73
|
%token NAME STRING
|
|
75
|
-
%token LA LC LP RA RP RC EQ DOT COMMA SC COL
|
|
74
|
+
%token LA LC LP RA RP RC EQ DOT COMMA SC COL AT QMARK DOTS DIV VID
|
|
76
75
|
%token INCREMENTAL
|
|
77
76
|
%token EOF
|
|
78
77
|
|
|
@@ -97,7 +96,6 @@ vid: VID { $$ = getToken(yytext,yy,_$); };
|
|
|
97
96
|
comma: COMMA { $$ = getToken(yytext,yy,_$); };
|
|
98
97
|
sc: SC { $$ = getToken(yytext,yy,_$); };
|
|
99
98
|
col: COL { $$ = getToken(yytext,yy,_$); };
|
|
100
|
-
dollar: DOLLAR { $$ = getToken(yytext,yy,_$); };
|
|
101
99
|
qmark: QMARK { $$ = getToken(yytext,yy,_$); };
|
|
102
100
|
incremental: INCREMENTAL { $$ = getToken(yytext,yy,_$); };
|
|
103
101
|
|
|
@@ -115,46 +113,10 @@ initialize_symbol_table
|
|
|
115
113
|
|
|
116
114
|
defs: { }
|
|
117
115
|
| defs name eq comp sc { s.add_rel($2.value,$4); }
|
|
118
|
-
| defs dollar name eq codeDef SC { s.add_code($3.value,$5); }
|
|
119
|
-
;
|
|
120
|
-
|
|
121
|
-
code
|
|
122
|
-
: name { $$ = { code: "ref", ref: $1.value, start: $1.start, end: $1.end}; }
|
|
123
|
-
| codeDef { $$ = $1; }
|
|
124
|
-
;
|
|
125
|
-
|
|
126
|
-
codeDef
|
|
127
|
-
: lc labelled_codes rc { $$ = { code: "product", product: $2, start: $1.start, end: $3.end }; }
|
|
128
|
-
| la labelled_codes ra { $$ = { code: "union", union: $2, start: $1.start, end: $3.end }; }
|
|
129
|
-
| at name { $$ = { code: "ref", ref: "@" + $2.value, start: $1.start, end: $2.end}; }
|
|
130
|
-
;
|
|
131
|
-
|
|
132
|
-
labelled_codes
|
|
133
|
-
: { $$ = {}; }
|
|
134
|
-
| non_empty_labelled_codes { $$ = $1.reduce((r, lc) => {
|
|
135
|
-
if (r[lc.label])
|
|
136
|
-
anError(@0,`Duplicate label '${lc.label}'.`);
|
|
137
|
-
r[lc.label] = s.as_ref(lc.code);
|
|
138
|
-
return r }
|
|
139
|
-
, {}); }
|
|
140
|
-
;
|
|
141
|
-
|
|
142
|
-
non_empty_labelled_codes
|
|
143
|
-
: code_label { $$ = [$1]; }
|
|
144
|
-
| non_empty_labelled_codes comma code_label
|
|
145
|
-
{ $$ = [].concat($1,$3); }
|
|
146
|
-
;
|
|
147
|
-
|
|
148
|
-
code_label
|
|
149
|
-
: code name { $$ = {label: $2.value, code: $1}; }
|
|
150
|
-
| code str { $$ = {label: $2.value, code: $1}; }
|
|
151
|
-
| name col code { $$ = {label: $1.value, code: $3}; }
|
|
152
|
-
| str col code { $$ = {label: $1.value, code: $3}; }
|
|
153
116
|
;
|
|
154
117
|
|
|
155
118
|
filter_
|
|
156
|
-
:
|
|
157
|
-
| lp dots rp { $$ = { type: null, open: true, fields: {}, start: $1.start, end: $3.end}; }
|
|
119
|
+
: lp dots rp { $$ = { type: null, open: true, fields: {}, start: $1.start, end: $3.end}; }
|
|
158
120
|
| la labelled_filters ra { $$ = { type: "union", open: $2.open, fields: $2.fields, start: $1.start, end: $3.end}; }
|
|
159
121
|
| lc labelled_filters rc { $$ = { type: "product", open: $2.open, fields: $2.fields, start: $1.start, end: $3.end}; }
|
|
160
122
|
;
|
|
@@ -210,7 +172,6 @@ exp
|
|
|
210
172
|
| div str { $$ = {op: "div", div: $2.value, start: $1.start, end: $2.end }; }
|
|
211
173
|
| vid name { $$ = {op: "vid", vid: $2.value, start: $1.start, end: $2.end }; }
|
|
212
174
|
| vid str { $$ = {op: "vid", vid: $2.value, start: $1.start, end: $2.end }; }
|
|
213
|
-
| dollar code { $$ = {op: "code", code: s.as_ref($2), start: $1.start, end: $2.end}; }
|
|
214
175
|
| qmark filter { $$ = {op: "filter", filter: $2, start: $1.start, end:$2.end}; }
|
|
215
176
|
;
|
|
216
177
|
|