Named instead of positional ctor args

This commit is contained in:
Tony Garnock-Jones 2021-03-23 16:59:44 +01:00
parent d64bb82c22
commit 94f6959ac8
4 changed files with 72 additions and 47 deletions

View File

@ -27,10 +27,15 @@ export function genConstructor(
const initializers: Item[] = (variant !== void 0)
? [keyvalue('_variant', JSON.stringify(variant))]
: [];
formals.forEach(([n, _t]) => initializers.push(n));
formals.forEach(([n, _t]) => initializers.push(seq(JSON.stringify(n), ': ', M.jsId(n))));
const declArgs: Array<Item> = (formals.length > 1)
? [seq(braces(...formals.map(f => M.jsId(f[0]))), ': ',
braces(...formals.map(f => seq(M.jsId(f[0]), ': ', renderType(f[1])))))]
: formals.map(f => seq(M.jsId(f[0]), ': ', renderType(f[1])));
return seq(`export function ${M.jsId(name)}`,
parens(... formals.map(([n, t]) => seq(n, ': ', renderType(t)))),
parens(... declArgs),
': ', resultType, ' ', block(
seq(`return `,
((arg.kind === 'unit' && initializers.length === 0)

View File

@ -108,49 +108,51 @@ export type ModulePath = Array<symbol>;
export const _toPtr = () => { throw new _.DecodeError("Pointers forbidden"); };
export function Schema(version: Version, pointer: PointerName, definitions: Definitions): Schema {return {version, pointer, definitions};}
export function Schema(
{version, pointer, definitions}: {version: Version, pointer: PointerName, definitions: Definitions}
): Schema {return {"version": version, "pointer": pointer, "definitions": definitions};}
export function Version(): Version {return null;}
export namespace PointerName {
export function Ref(value: Ref): PointerName {return {"_variant": "Ref", value};};
export function Ref(value: Ref): PointerName {return {"_variant": "Ref", "value": value};};
export function $false(): PointerName {return {"_variant": "false"};};
}
export function Definitions(value: _.KeyedDictionary<symbol, Definition, _ptr>): Definitions {return value;}
export namespace Definition {
export function or(patterns: Array<NamedAlternative>): Definition {return {"_variant": "or", patterns};};
export function Alternative(value: Alternative): Definition {return {"_variant": "Alternative", value};};
export function or(patterns: Array<NamedAlternative>): Definition {return {"_variant": "or", "patterns": patterns};};
export function Alternative(value: Alternative): Definition {return {"_variant": "Alternative", "value": value};};
}
export function NamedAlternative(variantLabel: string, alternative: Alternative): NamedAlternative {return {variantLabel, alternative};}
export function NamedAlternative({variantLabel, alternative}: {variantLabel: string, alternative: Alternative}): NamedAlternative {return {"variantLabel": variantLabel, "alternative": alternative};}
export namespace Alternative {
export function and(patterns: Array<NamedPattern>): Alternative {return {"_variant": "and", patterns};};
export function Pattern(value: Pattern): Alternative {return {"_variant": "Pattern", value};};
export function and(patterns: Array<NamedPattern>): Alternative {return {"_variant": "and", "patterns": patterns};};
export function Pattern(value: Pattern): Alternative {return {"_variant": "Pattern", "value": value};};
}
export namespace Pattern {
export function SimplePattern(value: SimplePattern): Pattern {return {"_variant": "SimplePattern", value};};
export function CompoundPattern(value: CompoundPattern): Pattern {return {"_variant": "CompoundPattern", value};};
export function SimplePattern(value: SimplePattern): Pattern {return {"_variant": "SimplePattern", "value": value};};
export function CompoundPattern(value: CompoundPattern): Pattern {return {"_variant": "CompoundPattern", "value": value};};
}
export namespace SimplePattern {
export function any(): SimplePattern {return {"_variant": "any"};};
export function atom(atomKind: AtomKind): SimplePattern {return {"_variant": "atom", atomKind};};
export function atom(atomKind: AtomKind): SimplePattern {return {"_variant": "atom", "atomKind": atomKind};};
export function pointer(): SimplePattern {return {"_variant": "pointer"};};
export function lit(value: _val): SimplePattern {return {"_variant": "lit", value};};
export function Ref(value: Ref): SimplePattern {return {"_variant": "Ref", value};};
export function lit(value: _val): SimplePattern {return {"_variant": "lit", "value": value};};
export function Ref(value: Ref): SimplePattern {return {"_variant": "Ref", "value": value};};
}
export namespace CompoundPattern {
export function rec(label: NamedPattern, fields: NamedPattern): CompoundPattern {return {"_variant": "rec", label, fields};};
export function tuple(patterns: Array<NamedPattern>): CompoundPattern {return {"_variant": "tuple", patterns};};
export function tuple$STAR$(fixed: Array<NamedPattern>, variable: NamedSimplePattern): CompoundPattern {return {"_variant": "tuple*", fixed, variable};};
export function setof(pattern: SimplePattern): CompoundPattern {return {"_variant": "setof", pattern};};
export function dictof(key: SimplePattern, value: SimplePattern): CompoundPattern {return {"_variant": "dictof", key, value};};
export function dict(entries: DictionaryEntries): CompoundPattern {return {"_variant": "dict", entries};};
export function rec({label, fields}: {label: NamedPattern, fields: NamedPattern}): CompoundPattern {return {"_variant": "rec", "label": label, "fields": fields};};
export function tuple(patterns: Array<NamedPattern>): CompoundPattern {return {"_variant": "tuple", "patterns": patterns};};
export function tuple$STAR$({fixed, variable}: {fixed: Array<NamedPattern>, variable: NamedSimplePattern}): CompoundPattern {return {"_variant": "tuple*", "fixed": fixed, "variable": variable};};
export function setof(pattern: SimplePattern): CompoundPattern {return {"_variant": "setof", "pattern": pattern};};
export function dictof({key, value}: {key: SimplePattern, value: SimplePattern}): CompoundPattern {return {"_variant": "dictof", "key": key, "value": value};};
export function dict(entries: DictionaryEntries): CompoundPattern {return {"_variant": "dict", "entries": entries};};
}
export function DictionaryEntries(value: _.KeyedDictionary<_val, NamedSimplePattern, _ptr>): DictionaryEntries {return value;}
@ -166,18 +168,18 @@ export namespace AtomKind {
}
export namespace NamedSimplePattern {
export function named(value: NamedSimplePattern_): NamedSimplePattern {return {"_variant": "named", value};};
export function anonymous(value: SimplePattern): NamedSimplePattern {return {"_variant": "anonymous", value};};
export function named(value: NamedSimplePattern_): NamedSimplePattern {return {"_variant": "named", "value": value};};
export function anonymous(value: SimplePattern): NamedSimplePattern {return {"_variant": "anonymous", "value": value};};
}
export namespace NamedPattern {
export function named(value: NamedSimplePattern_): NamedPattern {return {"_variant": "named", value};};
export function anonymous(value: Pattern): NamedPattern {return {"_variant": "anonymous", value};};
export function named(value: NamedSimplePattern_): NamedPattern {return {"_variant": "named", "value": value};};
export function anonymous(value: Pattern): NamedPattern {return {"_variant": "anonymous", "value": value};};
}
export function NamedSimplePattern_(name: symbol, pattern: SimplePattern): NamedSimplePattern_ {return {name, pattern};}
export function NamedSimplePattern_({name, pattern}: {name: symbol, pattern: SimplePattern}): NamedSimplePattern_ {return {"name": name, "pattern": pattern};}
export function Ref(module: ModulePath, name: symbol): Ref {return {module, name};}
export function Ref({module, name}: {module: ModulePath, name: symbol}): Ref {return {"module": module, "name": name};}
export function ModulePath(value: Array<symbol>): ModulePath {return value;}

View File

@ -111,7 +111,10 @@ export function addNameIfAbsent(p: M.NamedSimplePattern, k: M._val): M.NamedSimp
} else {
const s = namelike(k);
if (s !== void 0) {
return M.NamedSimplePattern.named(M.NamedSimplePattern_(Symbol.for(s), p.value));
return M.NamedSimplePattern.named(M.NamedSimplePattern_({
name: Symbol.for(s),
pattern: p.value
}));
} else {
return p;
}

View File

@ -118,7 +118,7 @@ export function parseSchema(toplevelTokens: Array<Input>,
throw new SchemaSyntaxError("Schema: missing version declaration.", null);
}
return M.Schema(M.Version(), pointer, definitions);
return M.Schema({ version: M.Version(), pointer, definitions });
}
function namedMustBeSimple(p: Position | null): never {
@ -132,7 +132,7 @@ function parseDefinition(name: symbol, body: Array<Input>): Definition {
{
const n = findName(input) || findName(input[0]);
if (n !== false) {
return M.NamedAlternative(n.description!, p);
return M.NamedAlternative({ variantLabel: n.description!, alternative: p });
}
if (p._variant === 'Pattern' &&
p.value._variant === 'CompoundPattern' &&
@ -142,29 +142,38 @@ function parseDefinition(name: symbol, body: Array<Input>): Definition {
p.value.value.label.value.value._variant === 'lit' &&
typeof p.value.value.label.value.value.value === 'symbol')
{
return M.NamedAlternative(p.value.value.label.value.value.value.description!, p);
return M.NamedAlternative({
variantLabel: p.value.value.label.value.value.value.description!,
alternative: p
});
}
if (p._variant === 'Pattern' &&
p.value._variant === 'SimplePattern' &&
p.value.value._variant === 'Ref')
{
return M.NamedAlternative(p.value.value.value.name.description!, p);
return M.NamedAlternative({
variantLabel: p.value.value.value.name.description!,
alternative: p
});
}
if (p._variant === 'Pattern' &&
p.value._variant === 'SimplePattern' &&
p.value.value._variant === 'lit')
{
const s = M.namelike(p.value.value.value);
if (s !== void 0) return M.NamedAlternative(s, p);
if (s !== void 0) return M.NamedAlternative({ variantLabel: s, alternative: p });
}
return M.NamedAlternative('_anonymous' + nextAnonymousAlternativeNumber++, p);
return M.NamedAlternative({
variantLabel: '_anonymous' + nextAnonymousAlternativeNumber++,
alternative: p
});
}
function patternName([input, p]: readonly [Array<Input>, Pattern]) : M.NamedPattern {
const n = findName(input) || findName(input[0]);
if (n !== false) {
if (p._variant !== 'SimplePattern') namedMustBeSimple(position(input[0]));
return M.NamedPattern.named(M.NamedSimplePattern_(n, p.value));
return M.NamedPattern.named(M.NamedSimplePattern_({ name: n, pattern: p.value }));
}
return M.NamedPattern.anonymous(p);
}
@ -253,8 +262,8 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
if (name === false) {
return anonymous(recur(b));
}
return named(M.NamedSimplePattern_(name, parseSimple(b, p => p, () =>
namedMustBeSimple(position(b)))));
return named(M.NamedSimplePattern_({ name, pattern: parseSimple(b, p => p, () =>
namedMustBeSimple(position(b))) }));
};
}
const maybeNamed = _maybeNamed(M.NamedPattern.named, M.NamedPattern.anonymous, walk);
@ -264,9 +273,10 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
function parseArrayLike(item: Array<Input>): CompoundPattern {
if (is(item[item.length - 1], M.DOTDOTDOT)) {
if (item.length < 2) complain();
return M.CompoundPattern.tuple$STAR$(
item.slice(0, item.length - 2).map(maybeNamed),
maybeNamedSimple(item[item.length - 2]));
return M.CompoundPattern.tuple$STAR$({
fixed: item.slice(0, item.length - 2).map(maybeNamed),
variable: maybeNamedSimple(item[item.length - 2])
});
} else {
return M.CompoundPattern.tuple(item.map(maybeNamed));
}
@ -279,14 +289,18 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
switch (label.label) {
case M.$rec:
if (item.length !== 2) complain();
return M.CompoundPattern.rec(maybeNamed(item[0]), maybeNamed(item[1]));
return M.CompoundPattern.rec({
label: maybeNamed(item[0]),
fields: maybeNamed(item[1])
});
default:
complain();
}
} else {
return M.CompoundPattern.rec(
M.NamedPattern.anonymous(M.Pattern.SimplePattern(M.SimplePattern.lit(label))),
M.NamedPattern.anonymous(M.Pattern.CompoundPattern(parseArrayLike(item))));
return M.CompoundPattern.rec({
label: M.NamedPattern.anonymous(M.Pattern.SimplePattern(M.SimplePattern.lit(label))),
fields: M.NamedPattern.anonymous(M.Pattern.CompoundPattern(parseArrayLike(item)))
});
}
} else if (Array.isArray(item)) {
return parseArrayLike(item);
@ -295,7 +309,7 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
const v = item.clone();
v.delete(M.DOTDOTDOT);
const [[kp, vp]] = v.entries();
return M.CompoundPattern.dictof(walkSimple(kp), walkSimple(vp));
return M.CompoundPattern.dictof({ key: walkSimple(kp), value: walkSimple(vp) });
} else {
return M.CompoundPattern.dict(
M.DictionaryEntries(item.mapEntries<M.NamedSimplePattern, Input, M._ptr>(
@ -347,7 +361,8 @@ function findName(x: Input): symbol | false {
function parseRef(s: string, pos: Position | null): M.Ref {
const pieces = s.split('.');
return recordPosition(M.Ref(
M.ModulePath(pieces.slice(0, pieces.length - 1).map(Symbol.for)),
Symbol.for(pieces[pieces.length - 1])), pos);
return recordPosition(M.Ref({
module: M.ModulePath(pieces.slice(0, pieces.length - 1).map(Symbol.for)),
name: Symbol.for(pieces[pieces.length - 1])
}), pos);
}