Further refine schema schema
This commit is contained in:
parent
376e83acd0
commit
5f71239130
|
@ -200,12 +200,12 @@ function decoderFor(ctx: FunctionContext, p: Definition, dest: string, recordFie
|
|||
const alt = recs[i];
|
||||
if (alt.label !== M.$rec) throw new Error("Internal error"); // avoid a cast
|
||||
return [
|
||||
seq(`if (`, predicateFor(ctx, label, alt[0]), `) `, ctx.block(() => {
|
||||
seq(`if (`, predicateFor(ctx, label, unname(alt[0])), `) `, ctx.block(() => {
|
||||
const fs = ctx.gentemp();
|
||||
return [... decoderFor(ctx, alt[1], fs, true),
|
||||
return [... decoderFor(ctx, unname(alt[1]), fs, true),
|
||||
seq(`if (${fs} !== void 0) ${dest} = _.Record`,
|
||||
anglebrackets(typeFor(ctx.mod, alt[0]),
|
||||
typeFor(ctx.mod, alt[1])),
|
||||
anglebrackets(typeFor(ctx.mod, unname(alt[0])),
|
||||
typeFor(ctx.mod, unname(alt[1]))),
|
||||
parens(seq(label, ` as any`),
|
||||
seq(fs, ` as any`)))];
|
||||
})),
|
||||
|
@ -242,12 +242,13 @@ function decoderFor(ctx: FunctionContext, p: Definition, dest: string, recordFie
|
|||
case M.$and:
|
||||
switch (p[0].length) {
|
||||
case 0: return [`${dest} = d.next()`];
|
||||
case 1: return decoderFor(ctx, p[0][0], dest);
|
||||
case 1: return decoderFor(ctx, unname(p[0][0]), dest);
|
||||
default: {
|
||||
const [pp0, ... ppN] = p[0];
|
||||
return [... decoderFor(ctx, pp0, dest),
|
||||
return [... decoderFor(ctx, unname(pp0), dest),
|
||||
seq(`if (!`, opseq('true', ' && ',
|
||||
... ppN.map(pp => predicateFor(ctx, dest, pp))),
|
||||
... ppN.map(pp =>
|
||||
predicateFor(ctx, dest, unname(pp)))),
|
||||
`) ${dest} = void 0`)];
|
||||
}
|
||||
}
|
||||
|
@ -257,12 +258,13 @@ function decoderFor(ctx: FunctionContext, p: Definition, dest: string, recordFie
|
|||
// assume dest is already void 0
|
||||
return [seq(`if (d.openRecord()) `, ctx.block(() => {
|
||||
const label = ctx.gentemp();
|
||||
return [... decoderFor(ctx, p[0], label),
|
||||
return [... decoderFor(ctx, unname(p[0]), label),
|
||||
seq(`if (${label} !== void 0) `, ctx.block(() => {
|
||||
const fs = ctx.gentemp();
|
||||
return [... decoderFor(ctx, p[1], fs, true),
|
||||
return [... decoderFor(ctx, unname(p[1]), fs, true),
|
||||
seq(`if (${fs} !== void 0) ${dest} = _.Record`,
|
||||
anglebrackets(typeFor(ctx.mod, p[0]), typeFor(ctx.mod, p[1])),
|
||||
anglebrackets(typeFor(ctx.mod, unname(p[0])),
|
||||
typeFor(ctx.mod, unname(p[1]))),
|
||||
parens(seq(label, ` as any`),
|
||||
seq(fs, ` as any`)))];
|
||||
}))];
|
||||
|
@ -330,7 +332,8 @@ function typeFor(mod: ModuleContext, p: Pattern): Item {
|
|||
case M.$pointer:
|
||||
return `_ptr`;
|
||||
case M.$rec:
|
||||
return seq('_.Record', anglebrackets(typeFor(mod, p[0]), typeFor(mod, p[1]), '_ptr'));
|
||||
return seq('_.Record', anglebrackets(typeFor(mod, unname(p[0])),
|
||||
typeFor(mod, unname(p[1])), '_ptr'));
|
||||
case M.$tuple:
|
||||
return brackets(... p[0].map(pp => typeFor(mod, unname(pp))));
|
||||
case M.$tuple_STAR_:
|
||||
|
@ -371,7 +374,7 @@ function typeForDefinition(mod: ModuleContext, _name: symbol, d: Definition): It
|
|||
|
||||
function typeForAlternative(mod: ModuleContext, a: Alternative): Item {
|
||||
if (a.label === M.$and) {
|
||||
return opseq('_val', ' & ', ... a[0].map(p => typeFor(mod, p)));
|
||||
return opseq('_val', ' & ', ... a[0].map(p => typeFor(mod, unname(p))));
|
||||
} else {
|
||||
return typeFor(mod, a);
|
||||
}
|
||||
|
@ -409,22 +412,22 @@ function predicateFor(ctx: FunctionContext, v: string, p: Definition, recordOkAs
|
|||
parens(opseq('false', ' || ',
|
||||
... recs.map(r =>
|
||||
(r.label !== M.$rec) ? '' : parens(seq(
|
||||
predicateFor(ctx, `${v}.label`, r[0]),
|
||||
predicateFor(ctx, `${v}.label`, unname(r[0])),
|
||||
' && ',
|
||||
predicateFor(ctx, v, r[1], true)))))));
|
||||
predicateFor(ctx, v, unname(r[1]), true)))))));
|
||||
} else {
|
||||
return opseq('false', ' || ', ... p[0].map(pp => predicateFor(ctx, v, pp[1])));
|
||||
}
|
||||
}
|
||||
case M.$and:
|
||||
return opseq('true', ' && ', ... p[0].map(pp => predicateFor(ctx, v, pp)));
|
||||
return opseq('true', ' && ', ... p[0].map(pp => predicateFor(ctx, v, unname(pp))));
|
||||
case M.$pointer:
|
||||
return `_.isPointer(${v})`;
|
||||
case M.$rec:
|
||||
return opseq('true', ' && ',
|
||||
`_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(${v})`,
|
||||
predicateFor(ctx, `${v}.label`, p[0]),
|
||||
predicateFor(ctx, v, p[1], true));
|
||||
predicateFor(ctx, `${v}.label`, unname(p[0])),
|
||||
predicateFor(ctx, v, unname(p[1]), true));
|
||||
case M.$tuple:
|
||||
return opseq('true', ' && ',
|
||||
... (recordOkAsTuple ? []
|
||||
|
|
|
@ -35,7 +35,7 @@ export const Schema = _.Record.makeConstructor<{
|
|||
{
|
||||
get(k: typeof $version): Version;
|
||||
get(k: typeof $pointer): PointerName;
|
||||
get(k: typeof $definitions): _.KeyedDictionary<symbol, Definition, _ptr>;
|
||||
get(k: typeof $definitions): Definitions;
|
||||
has(k: typeof $version): true;
|
||||
has(k: typeof $pointer): true;
|
||||
has(k: typeof $definitions): true;
|
||||
|
@ -50,7 +50,7 @@ export type Schema = _.Record<
|
|||
{
|
||||
get(k: typeof $version): Version;
|
||||
get(k: typeof $pointer): PointerName;
|
||||
get(k: typeof $definitions): _.KeyedDictionary<symbol, Definition, _ptr>;
|
||||
get(k: typeof $definitions): Definitions;
|
||||
has(k: typeof $version): true;
|
||||
has(k: typeof $pointer): true;
|
||||
has(k: typeof $definitions): true;
|
||||
|
@ -64,6 +64,8 @@ export type Version = (typeof $1);
|
|||
|
||||
export type PointerName = (Ref | (typeof __lit5));
|
||||
|
||||
export type Definitions = _.KeyedDictionary<symbol, Definition, _ptr>;
|
||||
|
||||
export type Definition = (_.Record<(typeof $or), [Array<NamedAlternative>], _ptr> | Alternative);
|
||||
|
||||
export type NamedAlternative = [symbol, Alternative];
|
||||
|
@ -80,7 +82,7 @@ export type SimplePattern = (
|
|||
);
|
||||
|
||||
export type CompoundPattern = (
|
||||
_.Record<(typeof $rec), [Pattern, Pattern], _ptr> |
|
||||
_.Record<(typeof $rec), [NamedPattern, NamedPattern], _ptr> |
|
||||
_.Record<(typeof $tuple), [Array<NamedPattern>], _ptr> |
|
||||
_.Record<(typeof $tuple_STAR_), [Array<NamedPattern>, NamedPattern], _ptr> |
|
||||
_.Record<(typeof $setof), [SimplePattern], _ptr> |
|
||||
|
@ -88,7 +90,9 @@ export type CompoundPattern = (
|
|||
_.Record<(typeof $dict), [DictionaryEntries], _ptr>
|
||||
);
|
||||
|
||||
export type DictionaryEntries = _.KeyedDictionary<_val, NamedPattern, _ptr>;
|
||||
export type DictionaryEntries = _.KeyedDictionary<_val, DictionaryEntryPattern, _ptr>;
|
||||
|
||||
export type DictionaryEntryPattern = (NamedSimplePattern | SimplePattern);
|
||||
|
||||
export type AtomKind = (
|
||||
(typeof $Boolean) |
|
||||
|
@ -100,7 +104,11 @@ export type AtomKind = (
|
|||
(typeof $Symbol)
|
||||
);
|
||||
|
||||
export type NamedPattern = (_.Record<(typeof $named), [symbol, SimplePattern], _ptr> | Pattern);
|
||||
export type NamedPattern = (NamedSimplePattern | Pattern);
|
||||
|
||||
export const NamedSimplePattern = _.Record.makeConstructor<{"name": symbol, "pattern": SimplePattern}, _ptr>()($named, ["name","pattern"]);
|
||||
|
||||
export type NamedSimplePattern = _.Record<(typeof $named), [symbol, SimplePattern], _ptr>;
|
||||
|
||||
export const Ref = _.Record.makeConstructor<{"module": ModulePath, "name": symbol}, _ptr>()($ref, ["module","name"]);
|
||||
|
||||
|
@ -122,18 +130,7 @@ export function isSchema(v: any): v is Schema {
|
|||
_.Dictionary.isDictionary<_ptr>(v[0]) &&
|
||||
((_tmp0 = v[0].get($version)) !== void 0 && isVersion(_tmp0)) &&
|
||||
((_tmp1 = v[0].get($pointer)) !== void 0 && isPointerName(_tmp1)) &&
|
||||
(
|
||||
(_tmp2 = v[0].get($definitions)) !== void 0 && (
|
||||
_.Dictionary.isDictionary<_ptr>(_tmp2) &&
|
||||
((() => {
|
||||
for (const e of _tmp2) {
|
||||
if (!(typeof e[0] === 'symbol')) return false;
|
||||
if (!(isDefinition(e[1]))) return false;
|
||||
};
|
||||
return true;
|
||||
})())
|
||||
)
|
||||
)
|
||||
((_tmp2 = v[0].get($definitions)) !== void 0 && isDefinitions(_tmp2))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
@ -155,18 +152,7 @@ export function decodeSchema(d: _.TypedDecoder<_ptr>): Schema | undefined {
|
|||
_.Dictionary.isDictionary<_ptr>(_tmp2) &&
|
||||
((_tmp3 = _tmp2.get($version)) !== void 0 && isVersion(_tmp3)) &&
|
||||
((_tmp4 = _tmp2.get($pointer)) !== void 0 && isPointerName(_tmp4)) &&
|
||||
(
|
||||
(_tmp5 = _tmp2.get($definitions)) !== void 0 && (
|
||||
_.Dictionary.isDictionary<_ptr>(_tmp5) &&
|
||||
((() => {
|
||||
for (const e of _tmp5) {
|
||||
if (!(typeof e[0] === 'symbol')) return false;
|
||||
if (!(isDefinition(e[1]))) return false;
|
||||
};
|
||||
return true;
|
||||
})())
|
||||
)
|
||||
)
|
||||
((_tmp5 = _tmp2.get($definitions)) !== void 0 && isDefinitions(_tmp5))
|
||||
))) _tmp2 = void 0;
|
||||
if (_tmp2 !== void 0) {
|
||||
if (d.closeCompound()) _tmp1 = [_tmp2] as [
|
||||
|
@ -174,7 +160,7 @@ export function decodeSchema(d: _.TypedDecoder<_ptr>): Schema | undefined {
|
|||
{
|
||||
get(k: typeof $version): Version;
|
||||
get(k: typeof $pointer): PointerName;
|
||||
get(k: typeof $definitions): _.KeyedDictionary<symbol, Definition, _ptr>;
|
||||
get(k: typeof $definitions): Definitions;
|
||||
has(k: typeof $version): true;
|
||||
has(k: typeof $pointer): true;
|
||||
has(k: typeof $definitions): true;
|
||||
|
@ -189,7 +175,7 @@ export function decodeSchema(d: _.TypedDecoder<_ptr>): Schema | undefined {
|
|||
{
|
||||
get(k: typeof $version): Version;
|
||||
get(k: typeof $pointer): PointerName;
|
||||
get(k: typeof $definitions): _.KeyedDictionary<symbol, Definition, _ptr>;
|
||||
get(k: typeof $definitions): Definitions;
|
||||
has(k: typeof $version): true;
|
||||
has(k: typeof $pointer): true;
|
||||
has(k: typeof $definitions): true;
|
||||
|
@ -225,6 +211,41 @@ export function decodePointerName(d: _.TypedDecoder<_ptr>): PointerName | undefi
|
|||
return result;
|
||||
}
|
||||
|
||||
export function isDefinitions(v: any): v is Definitions {
|
||||
return (
|
||||
_.Dictionary.isDictionary<_ptr>(v) &&
|
||||
((() => {
|
||||
for (const e of v) {
|
||||
if (!(typeof e[0] === 'symbol')) return false;
|
||||
if (!(isDefinition(e[1]))) return false;
|
||||
};
|
||||
return true;
|
||||
})())
|
||||
);
|
||||
}
|
||||
|
||||
export function asDefinitions(v: any): Definitions {
|
||||
if (!isDefinitions(v)) {throw new TypeError(`Invalid Definitions: ${_.stringify(v)}`);} else {return v;};
|
||||
}
|
||||
|
||||
export function decodeDefinitions(d: _.TypedDecoder<_ptr>): Definitions | undefined {
|
||||
let result;
|
||||
if (d.openDictionary()) {
|
||||
let r: _.KeyedDictionary<symbol, Definition, _ptr> | undefined = new _.KeyedDictionary();
|
||||
while (!d.closeCompound()) {
|
||||
let K: undefined | symbol = void 0;
|
||||
K = d.nextSymbol();
|
||||
if (K === void 0) { r = void 0; break; };
|
||||
let V: undefined | Definition = void 0;
|
||||
V = decodeDefinition(d);
|
||||
if (V === void 0) { r = void 0; break; };
|
||||
r.set(K, V);
|
||||
};
|
||||
result = r;
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
export function isDefinition(v: any): v is Definition {
|
||||
return (
|
||||
(
|
||||
|
@ -439,7 +460,7 @@ export function isCompoundPattern(v: any): v is CompoundPattern {
|
|||
return _.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v) && (
|
||||
(
|
||||
(
|
||||
_.is(v.label, $rec) && ((v.length === 2) && isPattern(v[0]) && isPattern(v[1]))
|
||||
_.is(v.label, $rec) && ((v.length === 2) && isNamedPattern(v[0]) && isNamedPattern(v[1]))
|
||||
) ||
|
||||
(
|
||||
_.is(v.label, $tuple) && (
|
||||
|
@ -485,12 +506,12 @@ export function decodeCompoundPattern(d: _.TypedDecoder<_ptr>): CompoundPattern
|
|||
_tmp1 = d.mark();
|
||||
if (_.is(_tmp0, $rec)) {
|
||||
let _tmp2, _tmp3, _tmp4: any;
|
||||
_tmp3 = decodePattern(d);
|
||||
_tmp3 = decodeNamedPattern(d);
|
||||
if (_tmp3 !== void 0) {
|
||||
_tmp4 = decodePattern(d);
|
||||
if (_tmp4 !== void 0) {if (d.closeCompound()) _tmp2 = [_tmp3, _tmp4] as [Pattern, Pattern];};
|
||||
_tmp4 = decodeNamedPattern(d);
|
||||
if (_tmp4 !== void 0) {if (d.closeCompound()) _tmp2 = [_tmp3, _tmp4] as [NamedPattern, NamedPattern];};
|
||||
};
|
||||
if (_tmp2 !== void 0) result = _.Record<(typeof $rec), [Pattern, Pattern]>(_tmp0 as any, _tmp2 as any);
|
||||
if (_tmp2 !== void 0) result = _.Record<(typeof $rec), [NamedPattern, NamedPattern]>(_tmp0 as any, _tmp2 as any);
|
||||
};
|
||||
if (result === void 0) {
|
||||
d.restoreMark(_tmp1);
|
||||
|
@ -579,7 +600,10 @@ export function isDictionaryEntries(v: any): v is DictionaryEntries {
|
|||
return (
|
||||
_.Dictionary.isDictionary<_ptr>(v) &&
|
||||
((() => {
|
||||
for (const e of v) {if (!(true)) return false; if (!(isNamedPattern(e[1]))) return false;};
|
||||
for (const e of v) {
|
||||
if (!(true)) return false;
|
||||
if (!(isDictionaryEntryPattern(e[1]))) return false;
|
||||
};
|
||||
return true;
|
||||
})())
|
||||
);
|
||||
|
@ -592,13 +616,13 @@ export function asDictionaryEntries(v: any): DictionaryEntries {
|
|||
export function decodeDictionaryEntries(d: _.TypedDecoder<_ptr>): DictionaryEntries | undefined {
|
||||
let result;
|
||||
if (d.openDictionary()) {
|
||||
let r: _.KeyedDictionary<_val, NamedPattern, _ptr> | undefined = new _.KeyedDictionary();
|
||||
let r: _.KeyedDictionary<_val, DictionaryEntryPattern, _ptr> | undefined = new _.KeyedDictionary();
|
||||
while (!d.closeCompound()) {
|
||||
let K: undefined | _val = void 0;
|
||||
K = d.next();
|
||||
if (K === void 0) { r = void 0; break; };
|
||||
let V: undefined | NamedPattern = void 0;
|
||||
V = decodeNamedPattern(d);
|
||||
let V: undefined | DictionaryEntryPattern = void 0;
|
||||
V = decodeDictionaryEntryPattern(d);
|
||||
if (V === void 0) { r = void 0; break; };
|
||||
r.set(K, V);
|
||||
};
|
||||
|
@ -607,6 +631,21 @@ export function decodeDictionaryEntries(d: _.TypedDecoder<_ptr>): DictionaryEntr
|
|||
return result;
|
||||
}
|
||||
|
||||
export function isDictionaryEntryPattern(v: any): v is DictionaryEntryPattern {return (isNamedSimplePattern(v) || isSimplePattern(v));}
|
||||
|
||||
export function asDictionaryEntryPattern(v: any): DictionaryEntryPattern {
|
||||
if (!isDictionaryEntryPattern(v)) {throw new TypeError(`Invalid DictionaryEntryPattern: ${_.stringify(v)}`);} else {return v;};
|
||||
}
|
||||
|
||||
export function decodeDictionaryEntryPattern(d: _.TypedDecoder<_ptr>): DictionaryEntryPattern | undefined {
|
||||
let _tmp0: any;
|
||||
let result;
|
||||
_tmp0 = d.mark();
|
||||
result = decodeNamedSimplePattern(d);
|
||||
if (result === void 0) {d.restoreMark(_tmp0); result = decodeSimplePattern(d);};
|
||||
return result;
|
||||
}
|
||||
|
||||
export function isAtomKind(v: any): v is AtomKind {
|
||||
return (
|
||||
_.is(v, $Boolean) ||
|
||||
|
@ -652,16 +691,7 @@ export function decodeAtomKind(d: _.TypedDecoder<_ptr>): AtomKind | undefined {
|
|||
return result;
|
||||
}
|
||||
|
||||
export function isNamedPattern(v: any): v is NamedPattern {
|
||||
return (
|
||||
(
|
||||
_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v) &&
|
||||
_.is(v.label, $named) &&
|
||||
((v.length === 2) && typeof v[0] === 'symbol' && isSimplePattern(v[1]))
|
||||
) ||
|
||||
isPattern(v)
|
||||
);
|
||||
}
|
||||
export function isNamedPattern(v: any): v is NamedPattern {return (isNamedSimplePattern(v) || isPattern(v));}
|
||||
|
||||
export function asNamedPattern(v: any): NamedPattern {
|
||||
if (!isNamedPattern(v)) {throw new TypeError(`Invalid NamedPattern: ${_.stringify(v)}`);} else {return v;};
|
||||
|
@ -671,20 +701,38 @@ export function decodeNamedPattern(d: _.TypedDecoder<_ptr>): NamedPattern | unde
|
|||
let _tmp0: any;
|
||||
let result;
|
||||
_tmp0 = d.mark();
|
||||
result = decodeNamedSimplePattern(d);
|
||||
if (result === void 0) {d.restoreMark(_tmp0); result = decodePattern(d);};
|
||||
return result;
|
||||
}
|
||||
|
||||
export function isNamedSimplePattern(v: any): v is NamedSimplePattern {
|
||||
return (
|
||||
_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v) &&
|
||||
_.is(v.label, $named) &&
|
||||
((v.length === 2) && typeof v[0] === 'symbol' && isSimplePattern(v[1]))
|
||||
);
|
||||
}
|
||||
|
||||
export function asNamedSimplePattern(v: any): NamedSimplePattern {
|
||||
if (!isNamedSimplePattern(v)) {throw new TypeError(`Invalid NamedSimplePattern: ${_.stringify(v)}`);} else {return v;};
|
||||
}
|
||||
|
||||
export function decodeNamedSimplePattern(d: _.TypedDecoder<_ptr>): NamedSimplePattern | undefined {
|
||||
let result;
|
||||
if (d.openRecord()) {
|
||||
let _tmp1: any;
|
||||
_tmp1 = _.asLiteral(d.nextSymbol(), $named);
|
||||
if (_tmp1 !== void 0) {
|
||||
let _tmp2, _tmp3, _tmp4: any;
|
||||
_tmp3 = d.nextSymbol();
|
||||
if (_tmp3 !== void 0) {
|
||||
_tmp4 = decodeSimplePattern(d);
|
||||
if (_tmp4 !== void 0) {if (d.closeCompound()) _tmp2 = [_tmp3, _tmp4] as [symbol, SimplePattern];};
|
||||
let _tmp0: any;
|
||||
_tmp0 = _.asLiteral(d.nextSymbol(), $named);
|
||||
if (_tmp0 !== void 0) {
|
||||
let _tmp1, _tmp2, _tmp3: any;
|
||||
_tmp2 = d.nextSymbol();
|
||||
if (_tmp2 !== void 0) {
|
||||
_tmp3 = decodeSimplePattern(d);
|
||||
if (_tmp3 !== void 0) {if (d.closeCompound()) _tmp1 = [_tmp2, _tmp3] as [symbol, SimplePattern];};
|
||||
};
|
||||
if (_tmp2 !== void 0) result = _.Record<(typeof $named), [symbol, SimplePattern]>(_tmp1 as any, _tmp2 as any);
|
||||
if (_tmp1 !== void 0) result = _.Record<(typeof $named), [symbol, SimplePattern]>(_tmp0 as any, _tmp1 as any);
|
||||
};
|
||||
};
|
||||
if (result === void 0) {d.restoreMark(_tmp0); result = decodePattern(d);};
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { Reader, Annotated, Dictionary, is, peel, preserves, Record, strip, Tuple, Position, position, ReaderOptions, stringify, isCompound } from '@preserves/core';
|
||||
import { Input, NamedPattern, Pattern, Schema, Alternative, Definition } from './meta';
|
||||
import { Input, Pattern, Schema, Alternative, Definition, CompoundPattern, NamedSimplePattern, SimplePattern } from './meta';
|
||||
import * as M from './meta';
|
||||
import { SchemaSyntaxError } from './error';
|
||||
import { CompoundPattern, SimplePattern } from 'gen/schema';
|
||||
|
||||
const positionTable = new WeakMap<Input & object, Position>();
|
||||
|
||||
|
@ -193,13 +192,16 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
|
|||
});
|
||||
const walk = (b: Input): Pattern => parsePattern(name, [b]);
|
||||
|
||||
function maybeNamed(b: Input): NamedPattern {
|
||||
const name = findName(b);
|
||||
if (name === false) return walk(b);
|
||||
return Record(M.$named, [name, parseSimple(b, () => {
|
||||
throw new SchemaSyntaxError(`Named patterns must be Simple patterns`, position(b));
|
||||
})]);
|
||||
function _maybeNamed<R>(recur: (b: Input) => R): (b: Input) => NamedSimplePattern | R {
|
||||
return (b: Input) => {
|
||||
const name = findName(b);
|
||||
if (name === false) return recur(b);
|
||||
return Record(M.$named, [name, parseSimple(b, () => {
|
||||
throw new SchemaSyntaxError(`Named patterns must be Simple patterns`, position(b));
|
||||
})]);
|
||||
};
|
||||
}
|
||||
const maybeNamed = _maybeNamed(walk);
|
||||
|
||||
if (Record.isRecord<Input, Tuple<Input>, never>(item)) {
|
||||
const label = item.label;
|
||||
|
@ -232,8 +234,8 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
|
|||
const [[kp, vp]] = v.entries();
|
||||
return Record(M.$dictof, [walkSimple(kp), walkSimple(vp)]);
|
||||
} else {
|
||||
return Record(M.$dict, [item.mapEntries<Pattern, Input, never>(
|
||||
([k, vp]) => [strip(k), walk(vp)])]);
|
||||
return Record(M.$dict, [item.mapEntries<M.DictionaryEntryPattern, Input, never>(
|
||||
([k, vp]) => [strip(k), _maybeNamed(walkSimple)(vp)])]);
|
||||
}
|
||||
} else if (Set.isSet<never>(item)) {
|
||||
if (item.size !== 1) complain();
|
||||
|
|
|
@ -5,7 +5,7 @@ version 1 .
|
|||
Schema = <schema {
|
||||
version: Version
|
||||
pointer: PointerName
|
||||
definitions: { symbol: Definition ...:... }
|
||||
definitions: Definitions
|
||||
}>.
|
||||
|
||||
; version 1 .
|
||||
|
@ -13,6 +13,8 @@ Version = 1 .
|
|||
|
||||
PointerName = Ref / #f.
|
||||
|
||||
Definitions = { symbol: Definition ...:... }.
|
||||
|
||||
; Pattern / Pattern / ...
|
||||
; and the empty pattern is <or []>
|
||||
Definition = <or [@patterns NamedAlternative ...]> / Alternative .
|
||||
|
@ -43,7 +45,7 @@ CompoundPattern =
|
|||
; <label a b c> ----> <rec <lit label> <tuple [<ref a> <ref b> <ref c>]>>
|
||||
; except for record labels
|
||||
; <<rec> x y> ---> <rec <ref x> <ref y>>
|
||||
/ <rec @label Pattern @fields Pattern>
|
||||
/ <rec @label NamedPattern @fields NamedPattern>
|
||||
|
||||
; [a b c] ----> <tuple [<ref a> <ref b> <ref c>]>
|
||||
/ <tuple [@patterns NamedPattern ...]>
|
||||
|
@ -61,11 +63,13 @@ CompoundPattern =
|
|||
/ <dict @entries DictionaryEntries>
|
||||
.
|
||||
|
||||
DictionaryEntries = { any: NamedPattern ...:... }.
|
||||
DictionaryEntries = { any: DictionaryEntryPattern ...:... }.
|
||||
DictionaryEntryPattern = NamedSimplePattern / SimplePattern .
|
||||
|
||||
AtomKind = =Boolean / =Float / =Double / =SignedInteger / =String / =ByteString / =Symbol .
|
||||
|
||||
NamedPattern = <named @name symbol @pattern SimplePattern> / @anonymous Pattern .
|
||||
NamedPattern = NamedSimplePattern / Pattern .
|
||||
NamedSimplePattern = <named @name symbol @pattern SimplePattern>.
|
||||
|
||||
Ref = <ref @module ModulePath @name symbol>.
|
||||
ModulePath = [symbol ...].
|
||||
|
|
Loading…
Reference in New Issue