scontainers
Version:
A container/collection/iterator library for JavaScript, comfortable to use, performant and versatile.
170 lines (120 loc) • 4.14 kB
JavaScript
;
function _implSymbol(target, sym, value) {
Object.defineProperty(target, sym, {
value,
configurable: true
});
return target[sym];
}
function _getSymbol(targetSymName, ...traitSets) {
let symbol;
traitSets.forEach(traitSet => {
const sym = traitSet[targetSymName];
if (typeof sym === 'symbol') {
if (!!symbol && symbol !== sym) {
throw new Error(`Symbol ${targetSymName} offered by multiple trait sets.`);
}
symbol = sym;
}
});
if (!symbol) {
throw new Error(`No trait set is providing symbol ${targetSymName}.`);
}
return symbol;
}
function _testTraitSet(traitSet) {
if (!traitSet || typeof traitSet === 'boolean' || typeof traitSet === 'number' || typeof traitSet === 'string') {
throw new Error(`${traitSet} cannot be used as a trait set.`);
}
}
const {
assert,
traits,
semantics,
toStr,
KVN
} = require('../utils.js');
_testTraitSet(traits.utils);
_testTraitSet(traits.scontainers);
_testTraitSet(traits.semantics);
const _implScontainer = _getSymbol("implScontainer", traits.utils, traits.scontainers, traits.semantics);
const _entries = _getSymbol("entries", traits.utils, traits.scontainers, traits.semantics);
const _forEach = _getSymbol("forEach", traits.utils, traits.scontainers, traits.semantics);
const _describeScontainer = _getSymbol("describeScontainer", traits.utils, traits.scontainers, traits.semantics);
const _implCoreGenerators = _getSymbol("implCoreGenerators", traits.utils, traits.scontainers, traits.semantics);
const _member = _getSymbol("member", traits.utils, traits.scontainers, traits.semantics);
const _call = _getSymbol("call", traits.utils, traits.scontainers, traits.semantics);
const _declare = _getSymbol("declare", traits.utils, traits.scontainers, traits.semantics);
const _while = _getSymbol("while", traits.utils, traits.scontainers, traits.semantics);
const _not = _getSymbol("not", traits.utils, traits.scontainers, traits.semantics);
const _implCoreTraits = _getSymbol("implCoreTraits", traits.utils, traits.scontainers, traits.semantics);
const _map = _getSymbol("map", traits.utils, traits.scontainers, traits.semantics);
const _collect = _getSymbol("collect", traits.utils, traits.scontainers, traits.semantics);
Map[_implScontainer]({
from(collection) {
if (collection[_entries]) {
return Map.from(collection[_entries]());
} else if (collection[_forEach]) {
const map = new Map();
collection[_forEach]((value, key) => void map.set(key, value));
return map;
}
assert(false);
}
});
Map[_describeScontainer]({
argKeys: []
});
Map[_implCoreGenerators]({
getUnchecked(key) {
return this.self[_member](`get`)[_call](key);
},
hasKey(key) {
return this.self[_member](`has`)[_call](key);
},
len(compiler) {
return this.self[_member](`size`);
},
loop() {
const it = this.createUniqueVariable(`it`);
const next = this.createUniqueVariable(`next`);
this.body[_declare](it, this.self[_member](semantics.id(`Symbol`)[_member](`iterator`), true)[_call](), `var`)[_declare](next, undefined, `var`) // ._Straits.declare( next, it._Straits.member(`next`).call() )
[_while](next[traits.semantics.assign](it[_member](`next`)[_call]())[_member](`done`)[_not](), this.body = semantics.block());
return new KVN(next[_member](`value`)[_member](0, true), next[_member](`value`)[_member](1, true));
}
});
Map[_implCoreTraits]({
len() {
return this.size;
},
getUnchecked(key) {
return this.get(key);
},
hasKey(key) {
return this.has(key);
},
set(key, value) {
this.set(key, value);
},
clear() {
this.clear();
},
kvIterator() {
return {
it: this[Symbol.iterator](),
next() {
const next = this.it.next();
if (!next.done) {
return new KVN(next.value[0], next.value[1]);
}
}
};
},
entries() {
return this;
},
toString() {
return `Map{${this[_map]((value, key) => `${toStr.call(key)}:${toStr.call(value)}`)[_collect](Array).join(', ')}}`;
}
});
module.exports = Map;