feat: Template operations #41
@ -31,6 +31,13 @@ export default class PocomathInstance {
|
||||
*/
|
||||
this.Types = {any: anySpec, T: anySpec}
|
||||
this._subtypes = {} // For each type, gives all of its (in)direct subtypes
|
||||
/* The following gives for each type, a set of all types that could
|
||||
* match in typed-function's dispatch algorithm before the given type.
|
||||
* This is important because if we instantiate a template, we must
|
||||
* instantiate it for all prior types as well, or else the wrong instance
|
||||
* might match.
|
||||
*/
|
||||
this._priorTypes = {}
|
||||
this._usedTypes = new Set() // all types that have occurred in a signature
|
||||
this._doomed = new Set() // for detecting circular reference
|
||||
this._config = {predictable: false}
|
||||
@ -170,7 +177,12 @@ export default class PocomathInstance {
|
||||
const mod = await import(modName)
|
||||
this.install(mod)
|
||||
} catch (err) {
|
||||
// No such module, but that's OK
|
||||
if (!(err.message.includes('find'))) {
|
||||
// Not just a error because module doesn't exist
|
||||
// So take it seriously
|
||||
throw err
|
||||
}
|
||||
// We don't care if a module doesn't exist, so merely proceed
|
||||
}
|
||||
}
|
||||
doneSet.add(name)
|
||||
@ -235,6 +247,7 @@ export default class PocomathInstance {
|
||||
}
|
||||
this._typed.addTypes([{name: type, test: testFn}], beforeType)
|
||||
this.Types[type] = spec
|
||||
this._priorTypes[type] = new Set()
|
||||
/* Now add conversions to this type */
|
||||
for (const from in (spec.from || {})) {
|
||||
if (from in this.Types) {
|
||||
@ -243,6 +256,7 @@ export default class PocomathInstance {
|
||||
while (nextSuper) {
|
||||
this._typed.addConversion(
|
||||
{from, to: nextSuper, convert: spec.from[from]})
|
||||
this._priorTypes[nextSuper].add(from)
|
||||
nextSuper = this.Types[nextSuper].refines
|
||||
}
|
||||
}
|
||||
@ -261,21 +275,24 @@ export default class PocomathInstance {
|
||||
to: nextSuper,
|
||||
convert: this.Types[to].from[type]
|
||||
})
|
||||
this._priorTypes[nextSuper].add(type)
|
||||
nextSuper = this.Types[nextSuper].refines
|
||||
}
|
||||
}
|
||||
}
|
||||
if (spec.refines) {
|
||||
this._typed.addConversion(
|
||||
{from: type, to: spec.refines, convert: x => x})
|
||||
}
|
||||
// Update all the subtype sets of supertypes up the chain, and
|
||||
// while we are at it add trivial conversions from subtypes to supertypes
|
||||
// to help typed-function match signatures properly:
|
||||
this._subtypes[type] = new Set()
|
||||
// Update all the subtype sets of supertypes up the chain:
|
||||
let nextSuper = spec.refines
|
||||
while (nextSuper) {
|
||||
this._typed.addConversion(
|
||||
{from: type, to: nextSuper, convert: x => x})
|
||||
this._priorTypes[nextSuper].add(type)
|
||||
this._subtypes[nextSuper].add(type)
|
||||
nextSuper = this.Types[nextSuper].refines
|
||||
}
|
||||
|
||||
// rebundle anything that uses the new type:
|
||||
this._invalidateDependents(':' + type)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user