feat(polynomialRoot) #57
@ -1147,7 +1147,6 @@ export default class PocomathInstance {
|
||||
behavior)
|
||||
behavior.resolved = true
|
||||
}
|
||||
this._correctPartialSelfRefs(name, tf_imps)
|
||||
// Make sure we have all of the needed (template) types; and if they
|
||||
// can't be added (because they have been instantiated too deep),
|
||||
// ditch the signature:
|
||||
@ -1306,7 +1305,6 @@ export default class PocomathInstance {
|
||||
}
|
||||
const refs = {}
|
||||
let full_self_referential = false
|
||||
let part_self_references = []
|
||||
for (const dep of uses) {
|
||||
let [func, needsig] = dep.split(/[()]/)
|
||||
/* Safety check that can perhaps be removed:
|
||||
@ -1322,18 +1320,13 @@ export default class PocomathInstance {
|
||||
}
|
||||
if (func === 'self') {
|
||||
if (needsig) {
|
||||
/* Maybe we can resolve the self reference without troubling
|
||||
* typed-function:
|
||||
/* We now resolve all specific-signature self references
|
||||
* here, without resorting to the facility in typed-function:
|
||||
*/
|
||||
if (needsig in imps && typeof imps[needsig] == 'function') {
|
||||
refs[dep] = imps[needsig]
|
||||
continue
|
||||
}
|
||||
if (full_self_referential) {
|
||||
throw new SyntaxError(
|
||||
'typed-function does not support mixed full and '
|
||||
+ 'partial self-reference')
|
||||
}
|
||||
const needTypes = typesOfSignature(needsig)
|
||||
const mergedTypes = Object.assign(
|
||||
{}, this.Types, this.Templates)
|
||||
@ -1348,11 +1341,6 @@ export default class PocomathInstance {
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
if (part_self_references.length) {
|
||||
throw new SyntaxError(
|
||||
'typed-function does not support mixed full and '
|
||||
+ 'partial self-reference')
|
||||
}
|
||||
full_self_referential = true
|
||||
continue
|
||||
}
|
||||
@ -1411,34 +1399,11 @@ export default class PocomathInstance {
|
||||
return implementation
|
||||
})
|
||||
imps[signature].uses = uses
|
||||
if (!uses) {
|
||||
throw new ReferenceError(`NANH uses for ${signature} from ${fromImp}`)
|
||||
}
|
||||
imps[signature].fromInstance = this
|
||||
imps[signature].instance = asInstance
|
||||
imps[signature].fromBehavior = fromImp
|
||||
return
|
||||
}
|
||||
if (part_self_references.length) {
|
||||
/* There is an obstruction here. The list part_self_references
|
||||
* might contain a signature that requires conversion for self to
|
||||
* handle. But I advocated this not be allowed in typed.referTo, which
|
||||
* made sense for human-written functions, but is unfortunate now.
|
||||
* So we have to defer creating these and correct them later, at
|
||||
* least until we can add an option to typed-function.
|
||||
*/
|
||||
imps[signature] = {
|
||||
deferred: true,
|
||||
builtRefs: refs,
|
||||
sigDoes: does,
|
||||
sigUses: uses,
|
||||
fromInstance: this,
|
||||
fromBehavior: fromImp,
|
||||
instance: asInstance,
|
||||
psr: part_self_references
|
||||
}
|
||||
return
|
||||
}
|
||||
const implementation = does(refs)
|
||||
implementation.fromInstance = this
|
||||
implementation.fromBehavior = fromImp
|
||||
@ -1448,96 +1413,6 @@ export default class PocomathInstance {
|
||||
imps[signature] = implementation
|
||||
}
|
||||
|
||||
_correctPartialSelfRefs(name, imps) {
|
||||
let sawDeferral = true
|
||||
while (sawDeferral) {
|
||||
// We might generate some new partial self references in resolving
|
||||
// the previously existing ones, so looping through the signatures
|
||||
// once is not enough; we have to keep looping until there are no
|
||||
// more deferrals
|
||||
sawDeferral = false
|
||||
for (const aSignature in imps) {
|
||||
if (!(imps[aSignature].deferred)) continue
|
||||
sawDeferral = true
|
||||
const deferral = imps[aSignature]
|
||||
const part_self_references = deferral.psr
|
||||
const corrected_self_references = []
|
||||
const remaining_self_references = []
|
||||
const refs = deferral.builtRefs
|
||||
for (const neededSig of part_self_references) {
|
||||
// Have to find a match for neededSig among the other signatures
|
||||
// of this function. That's a job for typed-function, but we will
|
||||
// try here:
|
||||
if (neededSig in imps) { // the easy case
|
||||
corrected_self_references.push(neededSig)
|
||||
remaining_self_references.push(neededSig)
|
||||
continue
|
||||
}
|
||||
// No exact match, try to get one that matches with
|
||||
// subtypes since the whole conversion thing in typed-function
|
||||
// is too complicated to reproduce
|
||||
let foundSig = this._findSubtypeImpl(name, imps, neededSig)
|
||||
if (foundSig) {
|
||||
corrected_self_references.push(foundSig)
|
||||
remaining_self_references.push(neededSig)
|
||||
} else {
|
||||
// Maybe it's a template instance we don't yet have
|
||||
foundSig = this._findSubtypeImpl(
|
||||
name, this._imps[name], neededSig)
|
||||
if (foundSig) {
|
||||
const match = this._pocoFindSignature(name, neededSig)
|
||||
const neededTemplate = match.fn._pocoSignature
|
||||
const neededInstance = whichSigInstance(
|
||||
neededSig, neededTemplate)
|
||||
const neededImplementation =
|
||||
this._instantiateTemplateImplementation(
|
||||
name, neededTemplate, neededInstance)
|
||||
if (!neededImplementation) {
|
||||
refs[`self(${neededSig})`] = match.implementation
|
||||
} else {
|
||||
if (typeof neededImplementation === 'function') {
|
||||
refs[`self(${neededSig})`] = neededImplementation
|
||||
} else {
|
||||
corrected_self_references.push(neededSig)
|
||||
remaining_self_references.push(neededSig)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
'Implement inexact self-reference in typed-function for '
|
||||
+ `${name}(${neededSig})`)
|
||||
}
|
||||
}
|
||||
}
|
||||
const does = deferral.sigDoes
|
||||
if (remaining_self_references.length > 0) {
|
||||
imps[aSignature] = this._typed.referTo(
|
||||
...corrected_self_references, (...impls) => {
|
||||
for (let i = 0; i < remaining_self_references.length; ++i) {
|
||||
refs[`self(${remaining_self_references[i]})`] = impls[i]
|
||||
}
|
||||
const implementation = does(refs)
|
||||
implementation.fromInstance = deferral.fromInstance
|
||||
implementation.fromBehavior = deferral.fromBehavior
|
||||
implementation.instance = deferral.instance
|
||||
implementation.uses = deferral.sigUses
|
||||
// What will we do with the return type info in here?
|
||||
return implementation
|
||||
}
|
||||
)
|
||||
} else {
|
||||
imps[aSignature] = does(refs)
|
||||
}
|
||||
imps[aSignature]._pocoSignature = deferral._pocoSignature
|
||||
imps[aSignature]._pocoInstance = deferral._pocoInstance
|
||||
imps[aSignature].fromInstance = deferral.fromInstance
|
||||
imps[aSignature].fromBehavior = deferral.fromBehavior
|
||||
imps[aSignature].instance = deferral.instance
|
||||
imps[aSignature].uses = deferral.sigUses
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function analyzes the template and makes sure the
|
||||
* instantiations of it for type and all prior types of type are present
|
||||
* in the instance.
|
||||
|
Loading…
Reference in New Issue
Block a user