From 269b9f5fc65d50ed0fa8a2f2b73384c01ea7e381 Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Wed, 30 Nov 2022 09:00:39 -0500 Subject: [PATCH] refactor(core): Resolve partial self-references at Pocomath level --- src/core/PocomathInstance.mjs | 129 +--------------------------------- 1 file changed, 2 insertions(+), 127 deletions(-) diff --git a/src/core/PocomathInstance.mjs b/src/core/PocomathInstance.mjs index f28bf91..cc1e089 100644 --- a/src/core/PocomathInstance.mjs +++ b/src/core/PocomathInstance.mjs @@ -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.