feat: Template operations #41

Merged
glen merged 10 commits from template_operations into main 2022-08-01 10:09:32 +00:00
Showing only changes of commit d4a4d8f331 - Show all commits

View File

@ -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)
}