Allow naming of `and` branches

This commit is contained in:
Tony Garnock-Jones 2021-03-17 16:25:29 +01:00
parent 306c7c2cae
commit 376e83acd0
3 changed files with 32 additions and 28 deletions

View File

@ -474,6 +474,22 @@ function predicateFor(ctx: FunctionContext, v: string, p: Definition, recordOkAs
export function compile(env: Environment, schema: Schema, options: CompilerOptions = {}): string {
const mod = new ModuleContext(env, schema, options);
const pointerName = Schema._._field0(schema).get(M.$pointer);
mod.defineType(seq(`export type _ptr = `,
pointerName === false ? 'never' : typeFor(mod, pointerName),
`;`));
mod.defineType(`export type _val = _.Value<_ptr>;`);
mod.defineFunction(ctx =>
seq(`export const _decodePtr = `,
(pointerName === false
? '() => { throw new _.DecodeError("Pointers forbidden"); }'
: seq(`(d: _.TypedDecoder<_ptr>) => `, ctx.block(() => [
seq(`let result`),
... decoderFor(ctx, pointerName, 'result'),
seq(`return result`)]))),
`;`));
for (const [name0, def] of Schema._._field0(schema).get(M.$definitions)) {
const name = name0 as symbol;
@ -493,6 +509,10 @@ export function compile(env: Environment, schema: Schema, options: CompilerOptio
mod.defineType(
seq(`export type ${name.description!} = `, typeForDefinition(mod, name, def), `;`));
}
for (const [name0, def] of Schema._._field0(schema).get(M.$definitions)) {
const name = name0 as symbol;
mod.defineFunction(ctx =>
seq(`export function is${name.description!}`,
@ -516,22 +536,6 @@ export function compile(env: Environment, schema: Schema, options: CompilerOptio
seq(`return result`)])));
}
const pointerName = Schema._._field0(schema).get(M.$pointer);
mod.defineType(seq(`export type _ptr = `,
pointerName === false ? 'never' : typeFor(mod, pointerName),
`;`));
mod.defineType(`export type _val = _.Value<_ptr>;`);
mod.defineFunction(ctx =>
seq(`export const _decodePtr = `,
(pointerName === false
? '() => { throw new _.DecodeError("Pointers forbidden"); }'
: seq(`(d: _.TypedDecoder<_ptr>) => `, ctx.block(() => [
seq(`let result`),
... decoderFor(ctx, pointerName, 'result'),
seq(`return result`)]))),
`;`));
const f = new Formatter();
f.write(`import * as _ from ${JSON.stringify(options.preservesModule ?? '@preserves/core')};\n`);
mod.imports.forEach(([identifier, path]) => {

View File

@ -26,6 +26,10 @@ export const $tuple_STAR_ = Symbol.for("tuple*");
export const $version = Symbol.for("version");
export const __lit5 = false;
export type _ptr = never;
export type _val = _.Value<_ptr>;
export const Schema = _.Record.makeConstructor<{
"_field0": (
{
@ -64,7 +68,7 @@ export type Definition = (_.Record<(typeof $or), [Array<NamedAlternative>], _ptr
export type NamedAlternative = [symbol, Alternative];
export type Alternative = (_.Record<(typeof $and), [Array<Pattern>], _ptr> | Pattern);
export type Alternative = (_.Record<(typeof $and), [Array<NamedPattern>], _ptr> | Pattern);
export type Pattern = (SimplePattern | CompoundPattern);
@ -104,10 +108,8 @@ export type Ref = _.Record<(typeof $ref), [ModulePath, symbol], _ptr>;
export type ModulePath = Array<symbol>;
export type _ptr = never;
export type _val = _.Value<_ptr>;
export const _decodePtr = () => { throw new _.DecodeError("Pointers forbidden"); };
export function isSchema(v: any): v is Schema {
let _tmp0, _tmp1, _tmp2: any;
@ -314,7 +316,7 @@ export function isAlternative(v: any): v is Alternative {
_.Array.isArray(v[0]) &&
!_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v[0]) &&
(v[0].length >= 0) &&
v[0].every(v => (isPattern(v)))
v[0].every(v => (isNamedPattern(v)))
)
)
) ||
@ -338,18 +340,18 @@ export function decodeAlternative(d: _.TypedDecoder<_ptr>): Alternative | undefi
if (d.openSequence()) {
let _tmp4: any;
{
let vN: Array<Pattern> | undefined = [];
let vN: Array<NamedPattern> | undefined = [];
while (!d.closeCompound()) {
_tmp4 = void 0;
_tmp4 = decodePattern(d);
_tmp4 = decodeNamedPattern(d);
if (_tmp4 === void 0) {vN = void 0; break;};
vN.push(_tmp4);
};
_tmp3 = vN;
};
};
if (_tmp3 !== void 0) {if (d.closeCompound()) _tmp2 = [_tmp3] as [Array<Pattern>];};
if (_tmp2 !== void 0) result = _.Record<(typeof $and), [Array<Pattern>]>(_tmp1 as any, _tmp2 as any);
if (_tmp3 !== void 0) {if (d.closeCompound()) _tmp2 = [_tmp3] as [Array<NamedPattern>];};
if (_tmp2 !== void 0) result = _.Record<(typeof $and), [Array<NamedPattern>]>(_tmp1 as any, _tmp2 as any);
};
};
if (result === void 0) {d.restoreMark(_tmp0); result = decodePattern(d);};
@ -747,5 +749,3 @@ export function decodeModulePath(d: _.TypedDecoder<_ptr>): ModulePath | undefine
return result;
}
export const _decodePtr = () => { throw new _.DecodeError("Pointers forbidden"); };

View File

@ -21,7 +21,7 @@ NamedAlternative = [@name symbol @alternative Alternative].
; Pattern & Pattern & ...
; and the universal pattern, "any", is <and []>
Alternative = <and [@patterns Pattern ...]> / Pattern .
Alternative = <and [@patterns NamedPattern ...]> / Pattern .
Pattern = SimplePattern / CompoundPattern .