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 171b6941f4 - Show all commits

View File

@ -7,6 +7,14 @@ const anySpec = {} // fixed dummy specification of 'any' type
const theTemplateParam = 'T' // First pass: only allow this one exact parameter
/* Returns a new signature just like sig but with the parameter replaced by
* the type
*/
function substituteInSig(sig, parameter, type) {
const pattern = new RegExp("\\b" + parameter + "\\b", 'g')
return sig.replaceAll(pattern, type)
}
export default class PocomathInstance {
/* Disallowed names for ops; beware, this is slightly non-DRY
* in that if a new top-level PocomathInstance method is added, its name
@ -413,15 +421,22 @@ export default class PocomathInstance {
}
}
if (explicit) {
this._addTFimplementation(
tf_imps, rawSignature, behavior.uses, behavior.does)
this._addTFimplementation(tf_imps, rawSignature, behavior)
continue
}
/* It's a template, have to instantiate */
/* But just for initial testing, punt and use T as synonym for 'any' */
const signature = rawSignature.replaceAll(theTemplateParam, 'any')
this._addTFimplementation(
tf_imps, signature, behavior.uses, behavior.does)
/* First, add the known instantiations */
if (!('instantiations' in behavior)) {
behavior.instantiations = new Set()
}
for (const instType of behavior.instantiations) {
const signature =
substituteInSig(rawSignature, theTemplateParam, instType)
this._addTFimplementation(tf_imps, signature, behavior, instType)
}
/* Now add the catchall signature; for now, punting on the behavior */
const signature = substituteInSig(rawSignature, theTemplateParam, 'any')
this._addTFimplementation(tf_imps, signature, behavior)
}
const tf = this._typed(name, tf_imps)
Object.defineProperty(this, name, {configurable: true, value: tf})
@ -432,7 +447,8 @@ export default class PocomathInstance {
* to typed-function implementations and inserts the result into plain object
* imps
*/
_addTFimplementation(imps, signature, uses, does) {
_addTFimplementation(imps, signature, behavior, instType) {
const {uses, does} = behavior
if (uses.length === 0) {
imps[signature] = does()
return