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) const initializers: Item[] = (variant !== void 0)
? [keyvalue('_variant', JSON.stringify(variant))] ? [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)}`, return seq(`export function ${M.jsId(name)}`,
parens(... formals.map(([n, t]) => seq(n, ': ', renderType(t)))), parens(... declArgs),
': ', resultType, ' ', block( ': ', resultType, ' ', block(
seq(`return `, seq(`return `,
((arg.kind === 'unit' && initializers.length === 0) ((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 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 function Version(): Version {return null;}
export namespace PointerName { 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 $false(): PointerName {return {"_variant": "false"};};
} }
export function Definitions(value: _.KeyedDictionary<symbol, Definition, _ptr>): Definitions {return value;} export function Definitions(value: _.KeyedDictionary<symbol, Definition, _ptr>): Definitions {return value;}
export namespace Definition { export namespace Definition {
export function or(patterns: Array<NamedAlternative>): Definition {return {"_variant": "or", patterns};}; export function or(patterns: Array<NamedAlternative>): Definition {return {"_variant": "or", "patterns": patterns};};
export function Alternative(value: Alternative): Definition {return {"_variant": "Alternative", value};}; 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 namespace Alternative {
export function and(patterns: Array<NamedPattern>): Alternative {return {"_variant": "and", patterns};}; export function and(patterns: Array<NamedPattern>): Alternative {return {"_variant": "and", "patterns": patterns};};
export function Pattern(value: Pattern): Alternative {return {"_variant": "Pattern", value};}; export function Pattern(value: Pattern): Alternative {return {"_variant": "Pattern", "value": value};};
} }
export namespace Pattern { export namespace Pattern {
export function SimplePattern(value: SimplePattern): Pattern {return {"_variant": "SimplePattern", value};}; export function SimplePattern(value: SimplePattern): Pattern {return {"_variant": "SimplePattern", "value": value};};
export function CompoundPattern(value: CompoundPattern): Pattern {return {"_variant": "CompoundPattern", value};}; export function CompoundPattern(value: CompoundPattern): Pattern {return {"_variant": "CompoundPattern", "value": value};};
} }
export namespace SimplePattern { export namespace SimplePattern {
export function any(): SimplePattern {return {"_variant": "any"};}; 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 pointer(): SimplePattern {return {"_variant": "pointer"};};
export function lit(value: _val): SimplePattern {return {"_variant": "lit", value};}; export function lit(value: _val): SimplePattern {return {"_variant": "lit", "value": value};};
export function Ref(value: Ref): SimplePattern {return {"_variant": "Ref", value};}; export function Ref(value: Ref): SimplePattern {return {"_variant": "Ref", "value": value};};
} }
export namespace CompoundPattern { export namespace CompoundPattern {
export function rec(label: NamedPattern, fields: NamedPattern): CompoundPattern {return {"_variant": "rec", label, fields};}; 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};}; export function tuple(patterns: Array<NamedPattern>): CompoundPattern {return {"_variant": "tuple", "patterns": patterns};};
export function tuple$STAR$(fixed: Array<NamedPattern>, variable: NamedSimplePattern): CompoundPattern {return {"_variant": "tuple*", fixed, variable};}; 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};}; export function setof(pattern: SimplePattern): CompoundPattern {return {"_variant": "setof", "pattern": pattern};};
export function dictof(key: SimplePattern, value: SimplePattern): CompoundPattern {return {"_variant": "dictof", key, value};}; 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};}; export function dict(entries: DictionaryEntries): CompoundPattern {return {"_variant": "dict", "entries": entries};};
} }
export function DictionaryEntries(value: _.KeyedDictionary<_val, NamedSimplePattern, _ptr>): DictionaryEntries {return value;} export function DictionaryEntries(value: _.KeyedDictionary<_val, NamedSimplePattern, _ptr>): DictionaryEntries {return value;}
@ -166,18 +168,18 @@ export namespace AtomKind {
} }
export namespace NamedSimplePattern { export namespace NamedSimplePattern {
export function named(value: NamedSimplePattern_): NamedSimplePattern {return {"_variant": "named", value};}; export function named(value: NamedSimplePattern_): NamedSimplePattern {return {"_variant": "named", "value": value};};
export function anonymous(value: SimplePattern): NamedSimplePattern {return {"_variant": "anonymous", value};}; export function anonymous(value: SimplePattern): NamedSimplePattern {return {"_variant": "anonymous", "value": value};};
} }
export namespace NamedPattern { export namespace NamedPattern {
export function named(value: NamedSimplePattern_): NamedPattern {return {"_variant": "named", value};}; export function named(value: NamedSimplePattern_): NamedPattern {return {"_variant": "named", "value": value};};
export function anonymous(value: Pattern): NamedPattern {return {"_variant": "anonymous", 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;} 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 { } else {
const s = namelike(k); const s = namelike(k);
if (s !== void 0) { 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 { } else {
return p; return p;
} }

View File

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