feat(Tuple): Stub for a template type
This adds the target initial definition of a homogeneous Tuple<T> type, and just enough processing that the type can be defined and non-template methods that deal with the generic base type Tuple can be called. Still has no actual template instantiation.
This commit is contained in:
parent
21ce098f98
commit
27bf23db54
9 changed files with 176 additions and 3 deletions
|
|
@ -45,6 +45,8 @@ export default class PocomathInstance {
|
|||
*/
|
||||
this.Types = {any: anySpec}
|
||||
this.Types[theTemplateParam] = anySpec
|
||||
// All the template types that have been defined
|
||||
this._templateTypes = {}
|
||||
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.
|
||||
|
|
@ -263,10 +265,15 @@ export default class PocomathInstance {
|
|||
* the corresponding changes to the _typed object immediately
|
||||
*/
|
||||
installType(type, spec) {
|
||||
if (this._templateParam(type)) {
|
||||
const parts = type.split(/[<,>]/)
|
||||
if (this._templateParam(parts[0])) {
|
||||
throw new SyntaxError(
|
||||
`Type name '${type}' reserved for template parameter`)
|
||||
}
|
||||
if (parts.some(this._templateParam.bind(this))) {
|
||||
// It's a template, deal with it separately
|
||||
return this._installTemplateType(type, spec)
|
||||
}
|
||||
if (type in this.Types) {
|
||||
if (spec !== this.Types[type]) {
|
||||
throw new SyntaxError(`Conflicting definitions of type ${type}`)
|
||||
|
|
@ -353,7 +360,6 @@ export default class PocomathInstance {
|
|||
// update the typeOf function
|
||||
const imp = {}
|
||||
imp[type] = {uses: new Set(), does: () => () => type}
|
||||
console.log('Adding', type, 'to typeOf')
|
||||
this._installFunctions({typeOf: imp})
|
||||
}
|
||||
|
||||
|
|
@ -393,6 +399,7 @@ export default class PocomathInstance {
|
|||
}
|
||||
return 'any'
|
||||
}
|
||||
|
||||
/* Returns a list of all types that have been mentioned in the
|
||||
* signatures of operations, but which have not actually been installed:
|
||||
*/
|
||||
|
|
@ -400,6 +407,23 @@ export default class PocomathInstance {
|
|||
return Array.from(this._usedTypes).filter(t => !(t in this.Types))
|
||||
}
|
||||
|
||||
/* Used internally to install a template type */
|
||||
_installTemplateType(type, spec) {
|
||||
const base = type.split('<')[0]
|
||||
/* For now, just allow a single template per base type; that
|
||||
* might need to change later:
|
||||
*/
|
||||
if (base in this._templateTypes) {
|
||||
if (spec !== this._templateTypes[base].spec) {
|
||||
throw new SyntaxError(
|
||||
`Conflicting definitions of template type ${type}`)
|
||||
}
|
||||
return
|
||||
}
|
||||
// Nothing actually happens until we match a template parameter
|
||||
this._templateTypes[base] = {type, spec}
|
||||
}
|
||||
|
||||
/* Used internally by install, see the documentation there */
|
||||
_installFunctions(functions) {
|
||||
for (const [name, spec] of Object.entries(functions)) {
|
||||
|
|
@ -509,6 +533,7 @@ export default class PocomathInstance {
|
|||
`Every implementation for ${name} uses an undefined type;\n`
|
||||
+ ` signatures: ${Object.keys(imps)}`)
|
||||
}
|
||||
// Mark this method as being in the midst of being reassembled
|
||||
Object.defineProperty(this, name, {configurable: true, value: 'limbo'})
|
||||
const tf_imps = {}
|
||||
for (const [rawSignature, behavior] of usableEntries) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue