diff --git a/packages/core/src/runtime/quasivalue.ts b/packages/core/src/runtime/quasivalue.ts index 93842ee..ab5ceaf 100644 --- a/packages/core/src/runtime/quasivalue.ts +++ b/packages/core/src/runtime/quasivalue.ts @@ -211,23 +211,37 @@ export function ctor(info: QuasiValueConstructorInfo, ... items: QuasiValue[]): } } - switch (def._variant) { - case 'or': throw new Error("Cannot use union definition as pattern"); - case 'and': throw new Error("Cannot use intersection definition as pattern"); - case 'Pattern': { - const p = def.value; - switch (p._variant) { - case 'SimplePattern': { - if (ctorArgs.length === 0) { - throw new Error(`Missing argument to ${defNameStr}`); - } - return ctorArgs[0]; + function qTopPattern(p: Meta.Pattern): QuasiValue { + switch (p._variant) { + case 'SimplePattern': { + if (ctorArgs.length === 0) { + throw new Error(`Missing argument to ${defNameStr}`); } - case 'CompoundPattern': - return qCompound(p.value); + return ctorArgs[0]; } + case 'CompoundPattern': + return qCompound(p.value); } } + + switch (def._variant) { + case 'or': { + const variant = definfo.variant?.description; + if (variant === void 0) { + throw new Error("Cannot use union definition as pattern"); + } + for (const p of [def.pattern0, def.pattern1, ...def.patternN]) { + if (p.variantLabel === variant) { + return qTopPattern(p.pattern); + } + } + throw new Error(`Unknown variant ${variant} in definition ${defNameStr}`); + } + case 'and': + throw new Error("Cannot use intersection definition as pattern"); + case 'Pattern': + return qTopPattern(def.value); + } } else if ('quasiValue' in info) { return info.quasiValue(... items); } else {