Repair embedded reading; and preserve annotations in generic embedded values

This commit is contained in:
Tony Garnock-Jones 2021-06-01 16:46:23 +02:00
parent 9014a0ffb8
commit 498c63ef67
6 changed files with 22 additions and 9 deletions

View File

@ -8,6 +8,7 @@ import { Bytes, BytesLike, underlying } from "./bytes";
import { Value } from "./values";
import { is } from "./is";
import { embed, GenericEmbedded, Embedded, EmbeddedTypeDecode } from "./embedded";
import { ReaderStateOptions } from "reader";
export interface DecoderOptions {
includeAnnotations?: boolean;
@ -166,7 +167,7 @@ export const neverEmbeddedTypeDecode: EmbeddedTypeDecode<never> = {
throw new Error("Embeddeds not permitted at this point in Preserves document");
},
fromValue(_v: Value<GenericEmbedded>): never {
fromValue(_v: Value<GenericEmbedded>, _options: ReaderStateOptions): never {
throw new Error("Embeddeds not permitted at this point in Preserves document");
},
};

View File

@ -1,6 +1,7 @@
import type { EncoderState } from "./encoder";
import type { DecoderState } from "./decoder";
import type { Value } from "./values";
import { ReaderStateOptions } from "./reader";
export type EmbeddedTypeEncode<T> = {
encode(s: EncoderState, v: T): void;
@ -9,7 +10,7 @@ export type EmbeddedTypeEncode<T> = {
export type EmbeddedTypeDecode<T> = {
decode(s: DecoderState): T;
fromValue(v: Value<GenericEmbedded>): T;
fromValue(v: Value<GenericEmbedded>, options: ReaderStateOptions): T;
}
export type EmbeddedType<T> = EmbeddedTypeEncode<T> & EmbeddedTypeDecode<T>;

View File

@ -1,6 +1,6 @@
import { GenericEmbedded, EmbeddedType, EmbeddedTypeDecode, EmbeddedTypeEncode } from "./embedded";
import { Encoder, EncoderState, identityEmbeddedTypeEncode } from "./encoder";
import { genericEmbeddedTypeDecode } from "./reader";
import { genericEmbeddedTypeDecode, ReaderStateOptions } from "./reader";
import { Value } from "./values";
import { DecoderState, neverEmbeddedTypeDecode } from "./decoder";
@ -39,7 +39,7 @@ export const identityEmbeddedTypeDecode: EmbeddedTypeDecode<any> = {
throw new Error("Cannot decode identityEmbeddedType");
},
fromValue(_v: Value<GenericEmbedded>): any {
fromValue(_v: Value<GenericEmbedded>, _options: ReaderStateOptions): any {
throw new Error("Cannot decode identityEmbeddedType");
},
};

View File

@ -280,8 +280,8 @@ export const genericEmbeddedTypeDecode: EmbeddedTypeDecode<GenericEmbedded> = {
return new GenericEmbedded(new Decoder(s, this).next());
},
fromValue(v: Value<GenericEmbedded>): GenericEmbedded {
return new GenericEmbedded(strip(v));
fromValue(v: Value<GenericEmbedded>, options: ReaderStateOptions): GenericEmbedded {
return new GenericEmbedded(options.includeAnnotations ? v : strip(v));
},
};
@ -393,7 +393,8 @@ export class Reader<T> {
});
}
case '!': return embed(this.embeddedType.fromValue(
new Reader<GenericEmbedded>(this.state, genericEmbeddedTypeDecode).next()));
new Reader<GenericEmbedded>(this.state, genericEmbeddedTypeDecode).next(),
this.state.options));
default:
this.state.error(`Invalid # syntax: ${c}`, startPos);
}

View File

@ -259,7 +259,7 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
} else if (isCompound(item)) {
return kf();
} else if (isEmbedded(item)) {
return ks(M.SimplePattern.embedded(walkSimple(item.embeddedValue)));
return ks(M.SimplePattern.embedded(walkSimple(item.embeddedValue.generic)));
} else {
return ks(M.SimplePattern.lit(strip(item)));
}

View File

@ -1,4 +1,4 @@
import { readSchema } from '../src/index';
import { readSchema, Meta } from '../src/index';
describe('reader schema', () => {
it('complains about bad version', () => {
@ -13,4 +13,14 @@ describe('reader schema', () => {
expect(s.definitions.size).toBe(0);
expect(s.embeddedType._variant).toBe('false');
});
it('understands patterns under embed', () => {
const s = readSchema('version 1 . X = #!0 .');
const def: Meta.Definition = s.definitions.get(Symbol.for('X'))!;
if (def._variant !== 'Pattern') fail('bad definition 1');
if (def.value._variant !== 'SimplePattern') fail ('bad definition 2');
if (def.value.value._variant !== 'embedded') fail('bad definition 3');
const i = def.value.value.interface;
if (i._variant !== 'lit') fail('Non-tuple embedded pattern');
expect(i.value).toBe(0);
});
});