refactor(core): Resolve partial self-references at Pocomath level
This commit is contained in:
parent
c4b1ac9045
commit
269b9f5fc6
@ -1147,7 +1147,6 @@ export default class PocomathInstance {
|
|||||||
behavior)
|
behavior)
|
||||||
behavior.resolved = true
|
behavior.resolved = true
|
||||||
}
|
}
|
||||||
this._correctPartialSelfRefs(name, tf_imps)
|
|
||||||
// Make sure we have all of the needed (template) types; and if they
|
// Make sure we have all of the needed (template) types; and if they
|
||||||
// can't be added (because they have been instantiated too deep),
|
// can't be added (because they have been instantiated too deep),
|
||||||
// ditch the signature:
|
// ditch the signature:
|
||||||
@ -1306,7 +1305,6 @@ export default class PocomathInstance {
|
|||||||
}
|
}
|
||||||
const refs = {}
|
const refs = {}
|
||||||
let full_self_referential = false
|
let full_self_referential = false
|
||||||
let part_self_references = []
|
|
||||||
for (const dep of uses) {
|
for (const dep of uses) {
|
||||||
let [func, needsig] = dep.split(/[()]/)
|
let [func, needsig] = dep.split(/[()]/)
|
||||||
/* Safety check that can perhaps be removed:
|
/* Safety check that can perhaps be removed:
|
||||||
@ -1322,18 +1320,13 @@ export default class PocomathInstance {
|
|||||||
}
|
}
|
||||||
if (func === 'self') {
|
if (func === 'self') {
|
||||||
if (needsig) {
|
if (needsig) {
|
||||||
/* Maybe we can resolve the self reference without troubling
|
/* We now resolve all specific-signature self references
|
||||||
* typed-function:
|
* here, without resorting to the facility in typed-function:
|
||||||
*/
|
*/
|
||||||
if (needsig in imps && typeof imps[needsig] == 'function') {
|
if (needsig in imps && typeof imps[needsig] == 'function') {
|
||||||
refs[dep] = imps[needsig]
|
refs[dep] = imps[needsig]
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if (full_self_referential) {
|
|
||||||
throw new SyntaxError(
|
|
||||||
'typed-function does not support mixed full and '
|
|
||||||
+ 'partial self-reference')
|
|
||||||
}
|
|
||||||
const needTypes = typesOfSignature(needsig)
|
const needTypes = typesOfSignature(needsig)
|
||||||
const mergedTypes = Object.assign(
|
const mergedTypes = Object.assign(
|
||||||
{}, this.Types, this.Templates)
|
{}, this.Types, this.Templates)
|
||||||
@ -1348,11 +1341,6 @@ export default class PocomathInstance {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (part_self_references.length) {
|
|
||||||
throw new SyntaxError(
|
|
||||||
'typed-function does not support mixed full and '
|
|
||||||
+ 'partial self-reference')
|
|
||||||
}
|
|
||||||
full_self_referential = true
|
full_self_referential = true
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -1411,34 +1399,11 @@ export default class PocomathInstance {
|
|||||||
return implementation
|
return implementation
|
||||||
})
|
})
|
||||||
imps[signature].uses = uses
|
imps[signature].uses = uses
|
||||||
if (!uses) {
|
|
||||||
throw new ReferenceError(`NANH uses for ${signature} from ${fromImp}`)
|
|
||||||
}
|
|
||||||
imps[signature].fromInstance = this
|
imps[signature].fromInstance = this
|
||||||
imps[signature].instance = asInstance
|
imps[signature].instance = asInstance
|
||||||
imps[signature].fromBehavior = fromImp
|
imps[signature].fromBehavior = fromImp
|
||||||
return
|
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)
|
const implementation = does(refs)
|
||||||
implementation.fromInstance = this
|
implementation.fromInstance = this
|
||||||
implementation.fromBehavior = fromImp
|
implementation.fromBehavior = fromImp
|
||||||
@ -1448,96 +1413,6 @@ export default class PocomathInstance {
|
|||||||
imps[signature] = implementation
|
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
|
/* This function analyzes the template and makes sure the
|
||||||
* instantiations of it for type and all prior types of type are present
|
* instantiations of it for type and all prior types of type are present
|
||||||
* in the instance.
|
* in the instance.
|
||||||
|
Loading…
Reference in New Issue
Block a user