Require at least two branches in "&" and "/"

This commit is contained in:
Tony Garnock-Jones 2021-05-21 11:20:25 +02:00
parent 7253d1507e
commit ecdb314366
7 changed files with 100 additions and 58 deletions

View File

@ -13,7 +13,7 @@ export function converterForDefinition(
{
switch (p._variant) {
case 'or': {
const alts = [p.pattern, ... p.patterns];
const alts = [p.pattern0, p.pattern1, ... p.patternN];
function loop(i: number): Item[] {
ctx.variantName = alts[i].variantLabel;
return [... converterForPattern(ctx, alts[i].pattern, src, dest),
@ -24,7 +24,7 @@ export function converterForDefinition(
return loop(0);
}
case 'and': {
const pcs = [p.pattern, ... p.patterns];
const pcs = [p.pattern0, p.pattern1, ... p.patternN];
function loop(i: number): Item[] {
return (i < pcs.length)
? converterFor(ctx, pcs[i], src, () => loop(i + 1))

View File

@ -7,10 +7,10 @@ export function typeForDefinition(mod: ModuleContext, d: M.Definition): Type {
switch (d._variant) {
case 'or':
return Type.union(
new Map([d.pattern, ... d.patterns].map(a =>
new Map([d.pattern0, d.pattern1, ... d.patternN].map(a =>
[a.variantLabel, typeFor(mod, a.pattern)])));
case 'and':
return typeForIntersection(mod, [d.pattern, ... d.patterns]);
return typeForIntersection(mod, [d.pattern0, d.pattern1, ... d.patternN]);
case 'Pattern':
return typeFor(mod, d.value);
}

View File

@ -14,14 +14,14 @@ export function unconverterForDefinition(
switch (def._variant) {
case 'or':
return [seq(`switch (${src}._variant) `, block(
... [def.pattern, ... def.patterns].map(p =>
... [def.pattern0, def.pattern1, ... def.patternN].map(p =>
seq(`case `, JSON.stringify(p.variantLabel), `: `, ctx.block(() => {
const hasValueField = p.pattern._variant === 'SimplePattern';
return [seq(`return `, unconverterForPattern(
ctx, name, p.pattern, hasValueField ? `${src}.value` : src))];
})))))];
case 'and': {
const ps = [def.pattern , ... def.patterns];
const ps = [def.pattern0, def.pattern1, ... def.patternN];
const t = typeForIntersection(ctx.mod, ps);
const errs: [string, InsufficientInformationError][] = [];
const cs = ps.flatMap(p => {

View File

@ -52,10 +52,16 @@ export type Definitions = _.KeyedDictionary<symbol, Definition, _embedded>;
export type Definition = (
{
"_variant": "or",
"pattern": NamedAlternative,
"patterns": Array<NamedAlternative>
"pattern0": NamedAlternative,
"pattern1": NamedAlternative,
"patternN": Array<NamedAlternative>
} |
{
"_variant": "and",
"pattern0": NamedPattern,
"pattern1": NamedPattern,
"patternN": Array<NamedPattern>
} |
{"_variant": "and", "pattern": NamedPattern, "patterns": Array<NamedPattern>} |
{"_variant": "Pattern", "value": Pattern}
);
@ -137,9 +143,29 @@ export function Definitions(value: _.KeyedDictionary<symbol, Definition, _embedd
export namespace Definition {
export function or(
{pattern, patterns}: {pattern: NamedAlternative, patterns: Array<NamedAlternative>}
): Definition {return {"_variant": "or", "pattern": pattern, "patterns": patterns};};
export function and({pattern, patterns}: {pattern: NamedPattern, patterns: Array<NamedPattern>}): Definition {return {"_variant": "and", "pattern": pattern, "patterns": patterns};};
{pattern0, pattern1, patternN}: {
pattern0: NamedAlternative,
pattern1: NamedAlternative,
patternN: Array<NamedAlternative>
}
): Definition {
return {
"_variant": "or",
"pattern0": pattern0,
"pattern1": pattern1,
"patternN": patternN
};
};
export function and(
{pattern0, pattern1, patternN}: {pattern0: NamedPattern, pattern1: NamedPattern, patternN: Array<NamedPattern>}
): Definition {
return {
"_variant": "and",
"pattern0": pattern0,
"pattern1": pattern1,
"patternN": patternN
};
};
export function Pattern(value: Pattern): Definition {return {"_variant": "Pattern", "value": value};};
}
@ -384,23 +410,29 @@ export function toDefinition(v: _val): undefined | Definition {
let _tmp0: (null) | undefined;
_tmp0 = _.is(v.label, $or) ? null : void 0;
if (_tmp0 !== void 0) {
if (_.Array.isArray(v[0]) && v[0].length >= 1) {
if (_.Array.isArray(v[0]) && v[0].length >= 2) {
let _tmp1: (NamedAlternative) | undefined;
_tmp1 = toNamedAlternative(v[0][0]);
if (_tmp1 !== void 0) {
let _tmp2: (Array<_val>) | undefined;
let _tmp3: (Array<NamedAlternative>) | undefined;
_tmp2 = v[0].slice(1);
{
_tmp3 = [];
for (const _tmp4 of _tmp2) {
let _tmp5: (NamedAlternative) | undefined;
_tmp5 = toNamedAlternative(_tmp4);
if (_tmp5 !== void 0) {_tmp3.push(_tmp5); continue;};
_tmp3 = void 0;
break;
let _tmp2: (NamedAlternative) | undefined;
_tmp2 = toNamedAlternative(v[0][1]);
if (_tmp2 !== void 0) {
let _tmp3: (Array<_val>) | undefined;
let _tmp4: (Array<NamedAlternative>) | undefined;
_tmp3 = v[0].slice(2);
{
_tmp4 = [];
for (const _tmp5 of _tmp3) {
let _tmp6: (NamedAlternative) | undefined;
_tmp6 = toNamedAlternative(_tmp5);
if (_tmp6 !== void 0) {_tmp4.push(_tmp6); continue;};
_tmp4 = void 0;
break;
};
if (_tmp4 !== void 0) {
result = {"_variant": "or", "pattern0": _tmp1, "pattern1": _tmp2, "patternN": _tmp4};
};
};
if (_tmp3 !== void 0) {result = {"_variant": "or", "pattern": _tmp1, "patterns": _tmp3};};
};
};
};
@ -408,35 +440,41 @@ export function toDefinition(v: _val): undefined | Definition {
};
if (result === void 0) {
if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) {
let _tmp6: (null) | undefined;
_tmp6 = _.is(v.label, $and) ? null : void 0;
if (_tmp6 !== void 0) {
if (_.Array.isArray(v[0]) && v[0].length >= 1) {
let _tmp7: (NamedPattern) | undefined;
_tmp7 = toNamedPattern(v[0][0]);
if (_tmp7 !== void 0) {
let _tmp8: (Array<_val>) | undefined;
let _tmp9: (Array<NamedPattern>) | undefined;
_tmp8 = v[0].slice(1);
{
_tmp9 = [];
for (const _tmp10 of _tmp8) {
let _tmp11: (NamedPattern) | undefined;
_tmp11 = toNamedPattern(_tmp10);
if (_tmp11 !== void 0) {_tmp9.push(_tmp11); continue;};
_tmp9 = void 0;
break;
let _tmp7: (null) | undefined;
_tmp7 = _.is(v.label, $and) ? null : void 0;
if (_tmp7 !== void 0) {
if (_.Array.isArray(v[0]) && v[0].length >= 2) {
let _tmp8: (NamedPattern) | undefined;
_tmp8 = toNamedPattern(v[0][0]);
if (_tmp8 !== void 0) {
let _tmp9: (NamedPattern) | undefined;
_tmp9 = toNamedPattern(v[0][1]);
if (_tmp9 !== void 0) {
let _tmp10: (Array<_val>) | undefined;
let _tmp11: (Array<NamedPattern>) | undefined;
_tmp10 = v[0].slice(2);
{
_tmp11 = [];
for (const _tmp12 of _tmp10) {
let _tmp13: (NamedPattern) | undefined;
_tmp13 = toNamedPattern(_tmp12);
if (_tmp13 !== void 0) {_tmp11.push(_tmp13); continue;};
_tmp11 = void 0;
break;
};
if (_tmp11 !== void 0) {
result = {"_variant": "and", "pattern0": _tmp8, "pattern1": _tmp9, "patternN": _tmp11};
};
};
if (_tmp9 !== void 0) {result = {"_variant": "and", "pattern": _tmp7, "patterns": _tmp9};};
};
};
};
};
};
if (result === void 0) {
let _tmp12: (Pattern) | undefined;
_tmp12 = toPattern(v);
if (_tmp12 !== void 0) {result = {"_variant": "Pattern", "value": _tmp12};};
let _tmp14: (Pattern) | undefined;
_tmp14 = toPattern(v);
if (_tmp14 !== void 0) {result = {"_variant": "Pattern", "value": _tmp14};};
};
};
return result;
@ -449,8 +487,9 @@ export function fromDefinition(_v: Definition): _val {
$or,
[
[
fromNamedAlternative(_v["pattern"]),
... _v["patterns"].map(v => fromNamedAlternative(v))
fromNamedAlternative(_v["pattern0"]),
fromNamedAlternative(_v["pattern1"]),
... _v["patternN"].map(v => fromNamedAlternative(v))
]
]
);
@ -460,8 +499,9 @@ export function fromDefinition(_v: Definition): _val {
$and,
[
[
fromNamedPattern(_v["pattern"]),
... _v["patterns"].map(v => fromNamedPattern(v))
fromNamedPattern(_v["pattern0"]),
fromNamedPattern(_v["pattern1"]),
... _v["patternN"].map(v => fromNamedPattern(v))
]
]
);

View File

@ -183,15 +183,17 @@ function parseDefinition(name: symbol, pos: Position | null, body: Array<Input>)
if (andPieces.length > 1) {
return M.Definition.and({
pattern: patternName(andPieces[0]),
patterns: andPieces.slice(1).map(patternName),
pattern0: patternName(andPieces[0]),
pattern1: patternName(andPieces[1]),
patternN: andPieces.slice(2).map(patternName),
});
}
if (orPieces.length > 1) {
return M.Definition.or({
pattern: alternativeName(orPieces[0]),
patterns: orPieces.slice(1).map(alternativeName),
pattern0: alternativeName(orPieces[0]),
pattern1: alternativeName(orPieces[1]),
patternN: orPieces.slice(2).map(alternativeName),
});
}

View File

@ -3,6 +3,6 @@ ModulePath
ModulePath„´³refµ„³Schema„„³Pattern´³orµµ± SimplePattern´³refµ„³ SimplePattern„„µ±CompoundPattern´³refµ„³CompoundPattern„„„„³Version´³lit„³AtomKind´³orµµ±Boolean´³lit³Boolean„„µ±Float´³lit³Float„„µ±Double´³lit³Double„„µ± SignedInteger´³lit³ SignedInteger„„µ±String´³lit³String„„µ±
ByteString´³lit³
ByteString„„µ±Symbol´³lit³Symbol„„„„³
Definition´³orµµ±or´³rec´³lit³or„´³tupleµ´³tuple*µ´³named³pattern´³refµ„³NamedAlternative„„„´³named³patterns´³refµ„³NamedAlternative„„„„„„„µ±and´³rec´³lit³and„´³tupleµ´³tuple*µ´³named³pattern´³refµ„³ NamedPattern„„„´³named³patterns´³refµ„³ NamedPattern„„„„„„„µ±Pattern´³refµ„³Pattern„„„„³
Definition´³orµµ±or´³rec´³lit³or„´³tupleµ´³tuple*µ´³named³pattern0´³refµ„³NamedAlternative„„´³named³pattern1´³refµ„³NamedAlternative„„„´³named³patternN´³refµ„³NamedAlternative„„„„„„„µ±and´³rec´³lit³and„´³tupleµ´³tuple*µ´³named³pattern0´³refµ„³ NamedPattern„„´³named³pattern1´³refµ„³ NamedPattern„„„´³named³patternN´³refµ„³ NamedPattern„„„„„„„µ±Pattern´³refµ„³Pattern„„„„³
ModulePath´³tuple*µ„´³atom³Symbol„„³ Definitions´³dictof´³atom³Symbol„´³refµ„³
Definition„„³ NamedPattern´³orµµ±named´³refµ„³NamedSimplePattern_„„µ± anonymous´³refµ„³Pattern„„„„³ SimplePattern´³orµµ±any´³lit³any„„µ±atom´³rec´³lit³atom„´³tupleµ´³named³atomKind´³refµ„³AtomKind„„„„„„µ±embedded´³rec´³lit³embedded„´³tupleµ„„„„µ±lit´³rec´³lit³lit„´³tupleµ´³named³value³any„„„„„µ±Ref´³refµ„³Ref„„„„³CompoundPattern´³orµµ±rec´³rec´³lit³rec„´³tupleµ´³named³label´³refµ„³ NamedPattern„„´³named³fields´³refµ„³ NamedPattern„„„„„„µ±tuple´³rec´³lit³tuple„´³tupleµ´³tuple*µ„´³named³patterns´³refµ„³ NamedPattern„„„„„„„µ±tuple*´³rec´³lit³tuple*„´³tupleµ´³tuple*µ„´³named³fixed´³refµ„³ NamedPattern„„„´³named³variable´³refµ„³NamedSimplePattern„„„„„„µ±setof´³rec´³lit³setof„´³tupleµ´³named³pattern´³refµ„³ SimplePattern„„„„„„µ±dictof´³rec´³lit³dictof„´³tupleµ´³named³key´³refµ„³ SimplePattern„„´³named³value´³refµ„³ SimplePattern„„„„„„µ±dict´³rec´³lit³dict„´³tupleµ´³named³entries´³refµ„³DictionaryEntries„„„„„„„„³EmbeddedTypeName´³orµµ±Ref´³refµ„³Ref„„µ±false´³lit€„„„„³NamedAlternative´³tupleµ´³named³ variantLabel´³atom³String„„´³named³pattern´³refµ„³Pattern„„„„³DictionaryEntries´³dictof³any´³refµ„³NamedSimplePattern„„³NamedSimplePattern´³orµµ±named´³refµ„³NamedSimplePattern_„„µ± anonymous´³refµ„³ SimplePattern„„„„³NamedSimplePattern_´³rec´³lit³named„´³tupleµ´³named³name´³atom³Symbol„„´³named³pattern´³refµ„³ SimplePattern„„„„„„³ embeddedType€„„

View File

@ -23,10 +23,10 @@ Definitions = { symbol: Definition ...:... }.
Definition =
; Pattern / Pattern / ...
/ <or [@pattern NamedAlternative @patterns NamedAlternative ...]>
/ <or [@pattern0 NamedAlternative @pattern1 NamedAlternative @patternN NamedAlternative ...]>
; Pattern & Pattern & ...
/ <and [@pattern NamedPattern @patterns NamedPattern ...]>
/ <and [@pattern0 NamedPattern @pattern1 NamedPattern @patternN NamedPattern ...]>
; Pattern
/ Pattern