feat: Template operations #41
@ -31,6 +31,13 @@ export default class PocomathInstance {
|
|||||||
*/
|
*/
|
||||||
this.Types = {any: anySpec, T: anySpec}
|
this.Types = {any: anySpec, T: anySpec}
|
||||||
this._subtypes = {} // For each type, gives all of its (in)direct subtypes
|
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._usedTypes = new Set() // all types that have occurred in a signature
|
||||||
this._doomed = new Set() // for detecting circular reference
|
this._doomed = new Set() // for detecting circular reference
|
||||||
this._config = {predictable: false}
|
this._config = {predictable: false}
|
||||||
@ -170,7 +177,12 @@ export default class PocomathInstance {
|
|||||||
const mod = await import(modName)
|
const mod = await import(modName)
|
||||||
this.install(mod)
|
this.install(mod)
|
||||||
} catch (err) {
|
} 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)
|
doneSet.add(name)
|
||||||
@ -235,6 +247,7 @@ export default class PocomathInstance {
|
|||||||
}
|
}
|
||||||
this._typed.addTypes([{name: type, test: testFn}], beforeType)
|
this._typed.addTypes([{name: type, test: testFn}], beforeType)
|
||||||
this.Types[type] = spec
|
this.Types[type] = spec
|
||||||
|
this._priorTypes[type] = new Set()
|
||||||
/* Now add conversions to this type */
|
/* Now add conversions to this type */
|
||||||
for (const from in (spec.from || {})) {
|
for (const from in (spec.from || {})) {
|
||||||
if (from in this.Types) {
|
if (from in this.Types) {
|
||||||
@ -243,6 +256,7 @@ export default class PocomathInstance {
|
|||||||
while (nextSuper) {
|
while (nextSuper) {
|
||||||
this._typed.addConversion(
|
this._typed.addConversion(
|
||||||
{from, to: nextSuper, convert: spec.from[from]})
|
{from, to: nextSuper, convert: spec.from[from]})
|
||||||
|
this._priorTypes[nextSuper].add(from)
|
||||||
nextSuper = this.Types[nextSuper].refines
|
nextSuper = this.Types[nextSuper].refines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,21 +275,24 @@ export default class PocomathInstance {
|
|||||||
to: nextSuper,
|
to: nextSuper,
|
||||||
convert: this.Types[to].from[type]
|
convert: this.Types[to].from[type]
|
||||||
})
|
})
|
||||||
|
this._priorTypes[nextSuper].add(type)
|
||||||
nextSuper = this.Types[nextSuper].refines
|
nextSuper = this.Types[nextSuper].refines
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (spec.refines) {
|
// Update all the subtype sets of supertypes up the chain, and
|
||||||
this._typed.addConversion(
|
// while we are at it add trivial conversions from subtypes to supertypes
|
||||||
{from: type, to: spec.refines, convert: x => x})
|
// to help typed-function match signatures properly:
|
||||||
}
|
|
||||||
this._subtypes[type] = new Set()
|
this._subtypes[type] = new Set()
|
||||||
// Update all the subtype sets of supertypes up the chain:
|
|
||||||
let nextSuper = spec.refines
|
let nextSuper = spec.refines
|
||||||
while (nextSuper) {
|
while (nextSuper) {
|
||||||
|
this._typed.addConversion(
|
||||||
|
{from: type, to: nextSuper, convert: x => x})
|
||||||
|
this._priorTypes[nextSuper].add(type)
|
||||||
this._subtypes[nextSuper].add(type)
|
this._subtypes[nextSuper].add(type)
|
||||||
nextSuper = this.Types[nextSuper].refines
|
nextSuper = this.Types[nextSuper].refines
|
||||||
}
|
}
|
||||||
|
|
||||||
// rebundle anything that uses the new type:
|
// rebundle anything that uses the new type:
|
||||||
this._invalidateDependents(':' + type)
|
this._invalidateDependents(':' + type)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user