55 lines
1.5 KiB
JavaScript
55 lines
1.5 KiB
JavaScript
|
"use strict";
|
||
|
// Preserves Annotations.
|
||
|
|
||
|
if (require('./singletonmodule.js')('leastfixedpoint.com/preserves',
|
||
|
require('../package.json').version,
|
||
|
'annotations.js',
|
||
|
module)) return;
|
||
|
|
||
|
const { Record, List, Map, Set } = require('./values.js');
|
||
|
const { PreserveOn, AsPreserve } = require('./symbols.js');
|
||
|
|
||
|
function Annotated(item) {
|
||
|
this.annotations = [];
|
||
|
this.item = item;
|
||
|
}
|
||
|
|
||
|
Annotated.prototype[AsPreserve] = function () {
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
Annotated.prototype[PreserveOn] = function (encoder) {
|
||
|
for (const a of this.annotations) {
|
||
|
encoder.header(0, 0, 5);
|
||
|
encoder.push(a);
|
||
|
}
|
||
|
encoder.push(this.item);
|
||
|
};
|
||
|
|
||
|
function stripAnnotations(v, depth) {
|
||
|
function step(v, depth) {
|
||
|
if (depth === 0) return v;
|
||
|
if (!(v instanceof Annotated)) return v;
|
||
|
|
||
|
const nextDepth = depth - 1;
|
||
|
function walk(v) { return step(v, nextDepth); }
|
||
|
|
||
|
if (v.item instanceof Record) {
|
||
|
return Record(walk(v.item.label), v.item.fields.map(walk));
|
||
|
} else if (List.isList(v.item)) {
|
||
|
return v.item.map(walk);
|
||
|
} else if (Set.isSet(v.item)) {
|
||
|
return v.item.map(walk);
|
||
|
} else if (Map.isMap(v.item)) {
|
||
|
return v.item.mapEntries((e) => [walk(e[0]), walk(e[1])]);
|
||
|
} else if (v.item instanceof Annotated) {
|
||
|
const e = new Error("Improper annotation structure");
|
||
|
e.irritant = v;
|
||
|
throw e;
|
||
|
} else {
|
||
|
return v.item;
|
||
|
}
|
||
|
}
|
||
|
step(v, (depth === void 0) ? Infinity : depth);
|
||
|
}
|