Repair quasipattern parameter passing for union types

This commit is contained in:
Tony Garnock-Jones 2022-04-30 14:54:56 +03:00
parent 7668dbb401
commit 5b835dc13a
1 changed files with 15 additions and 6 deletions

View File

@ -101,10 +101,12 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]):
const definfo = info.schema(); const definfo = info.schema();
const schema = Meta.asSchema(definfo.schema); const schema = Meta.asSchema(definfo.schema);
const def = schema.definitions.get(definfo.definitionName)!; const def = schema.definitions.get(definfo.definitionName)!;
const defType = GenType.typeForDefinition(r => Type.Type.ref(r.name.description!, null), def);
const defNameStr = definfo.definitionName.description!; const defNameStr = definfo.definitionName.description!;
const ctorArgs = items.slice(); const ctorArgs = items.slice();
let defType = GenType.typeForDefinition(r => Type.Type.ref(r.name.description!, null), def);
// ^ defType is updated when we are facing a variant in a union
function qLiteral(p: Meta.NamedPattern): AnyValue { function qLiteral(p: Meta.NamedPattern): AnyValue {
if (p._variant === 'anonymous' && if (p._variant === 'anonymous' &&
p.value._variant === 'SimplePattern' && p.value._variant === 'SimplePattern' &&
@ -213,12 +215,15 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]):
function qTopPattern(p: Meta.Pattern): QuasiValue { function qTopPattern(p: Meta.Pattern): QuasiValue {
switch (p._variant) { switch (p._variant) {
case 'SimplePattern': { case 'SimplePattern':
if (ctorArgs.length === 0) { if (defType.kind === 'unit') {
throw new Error(`Missing argument to ${defNameStr}`); return qSimple(p.value);
} else {
if (ctorArgs.length === 0) {
throw new Error(`Missing argument to ${defNameStr}`);
}
return ctorArgs[0];
} }
return ctorArgs[0];
}
case 'CompoundPattern': case 'CompoundPattern':
return qCompound(p.value); return qCompound(p.value);
} }
@ -230,8 +235,12 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]):
if (variant === void 0) { if (variant === void 0) {
throw new Error("Cannot use union definition as pattern"); throw new Error("Cannot use union definition as pattern");
} }
if (defType.kind !== 'union') {
throw new Error(`Non-union type for union definition ${defNameStr}`);
}
for (const p of [def.pattern0, def.pattern1, ...def.patternN]) { for (const p of [def.pattern0, def.pattern1, ...def.patternN]) {
if (p.variantLabel === variant) { if (p.variantLabel === variant) {
defType = defType.variants.get(variant)!;
return qTopPattern(p.pattern); return qTopPattern(p.pattern);
} }
} }