preserves/implementations/javascript/src/annotations.js

55 lines
1.5 KiB
JavaScript
Raw Normal View History

2019-08-24 18:08:07 +00:00
"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);
}