UNPKG

scontainers

Version:

A container/collection/iterator library for JavaScript, comfortable to use, performant and versatile.

170 lines (120 loc) 4.14 kB
"use strict"; 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;