diff --git a/canonical-binary.md b/canonical-binary.md index 097ace1..7048292 100644 --- a/canonical-binary.md +++ b/canonical-binary.md @@ -38,7 +38,7 @@ representations of their keys.[^no-need-for-by-value] **Other kinds of `Value`.** There are no special canonicalization restrictions on `SignedInteger`s, `String`s, `ByteString`s, `Symbol`s, `Boolean`s, -`Float`s, `Double`s, `Record`s, `Sequence`s, or `Pointer`s. The +`Float`s, `Double`s, `Record`s, `Sequence`s, or `Embedded`s. The constraints given for these `Value`s in the [specification][spec] suffice to ensure canonicity. diff --git a/implementations/javascript/packages/core/package.json b/implementations/javascript/packages/core/package.json index a44adf9..5ed5d67 100644 --- a/implementations/javascript/packages/core/package.json +++ b/implementations/javascript/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@preserves/core", - "version": "0.14.0", + "version": "0.15.0", "description": "Preserves data serialization format", "homepage": "https://gitlab.com/preserves/preserves", "license": "Apache-2.0", diff --git a/implementations/javascript/packages/core/src/annotated.ts b/implementations/javascript/packages/core/src/annotated.ts index 964b466..cbdb2c4 100644 --- a/implementations/javascript/packages/core/src/annotated.ts +++ b/implementations/javascript/packages/core/src/annotated.ts @@ -4,7 +4,7 @@ import { AsPreserve, PreserveOn } from "./symbols"; import { Value } from "./values"; import { is, isAnnotated, IsPreservesAnnotated } from "./is"; import { stringify } from "./text"; -import { GenericPointer } from "./pointer"; +import { GenericEmbedded } from "./embedded"; export interface Position { line?: number; @@ -53,7 +53,7 @@ export function formatPosition(p: Position | null | string): string { } } -export class Annotated { +export class Annotated { readonly annotations: Array>; readonly pos: Position | null; readonly item: Value; @@ -99,17 +99,17 @@ export class Annotated { return true; } - static isAnnotated(x: any): x is Annotated { + static isAnnotated(x: any): x is Annotated { return isAnnotated(x); } } -export function annotate(v0: Value, ...anns: Value[]): Annotated { +export function annotate(v0: Value, ...anns: Value[]): Annotated { const v = Annotated.isAnnotated(v0) ? v0 : new Annotated(v0); anns.forEach((a) => v.annotations.push(a)); return v; } -export function position(v: Value): Position | null { +export function position(v: Value): Position | null { return Annotated.isAnnotated(v) ? v.pos : null; } diff --git a/implementations/javascript/packages/core/src/bytes.ts b/implementations/javascript/packages/core/src/bytes.ts index fa4831e..daa3a08 100644 --- a/implementations/javascript/packages/core/src/bytes.ts +++ b/implementations/javascript/packages/core/src/bytes.ts @@ -2,7 +2,7 @@ import { Tag } from './constants'; import { AsPreserve, PreserveOn } from './symbols'; import { Encoder, Preservable } from './encoder'; import { Value } from './values'; -import { GenericPointer } from './pointer'; +import { GenericEmbedded } from './embedded'; const textEncoder = new TextEncoder(); const textDecoder = new TextDecoder(); @@ -127,7 +127,7 @@ export class Bytes implements Preservable { return this.asPreservesText(); } - [AsPreserve](): Value { + [AsPreserve](): Value { return this; } diff --git a/implementations/javascript/packages/core/src/compound.ts b/implementations/javascript/packages/core/src/compound.ts index 10fc11b..198eebe 100644 --- a/implementations/javascript/packages/core/src/compound.ts +++ b/implementations/javascript/packages/core/src/compound.ts @@ -1,8 +1,8 @@ import type { Compound, Value } from "./values"; -import type { GenericPointer } from "./pointer"; +import type { GenericEmbedded } from "./embedded"; import { Dictionary, Set } from "./dictionary"; -export function isCompound(x: Value): x is Compound +export function isCompound(x: Value): x is Compound { return (Array.isArray(x) || Set.isSet(x) || Dictionary.isDictionary(x)); } diff --git a/implementations/javascript/packages/core/src/constants.ts b/implementations/javascript/packages/core/src/constants.ts index 461a417..d583885 100644 --- a/implementations/javascript/packages/core/src/constants.ts +++ b/implementations/javascript/packages/core/src/constants.ts @@ -5,7 +5,7 @@ export enum Tag { Double, End, Annotation, - Pointer, + Embedded, SmallInteger_lo = 0x90, MediumInteger_lo = 0xa0, diff --git a/implementations/javascript/packages/core/src/decoder.ts b/implementations/javascript/packages/core/src/decoder.ts index 59db2cc..cf0058c 100644 --- a/implementations/javascript/packages/core/src/decoder.ts +++ b/implementations/javascript/packages/core/src/decoder.ts @@ -7,14 +7,14 @@ import { Record } from "./record"; import { Bytes, BytesLike, underlying } from "./bytes"; import { Value } from "./values"; import { is } from "./is"; -import { embed, GenericPointer, Pointer, PointerTypeDecode } from "./pointer"; +import { embed, GenericEmbedded, Embedded, EmbeddedTypeDecode } from "./embedded"; export interface DecoderOptions { includeAnnotations?: boolean; } -export interface DecoderPointerOptions extends DecoderOptions { - pointerDecode?: PointerTypeDecode; +export interface DecoderEmbeddedOptions extends DecoderOptions { + embeddedDecode?: EmbeddedTypeDecode; } export interface TypedDecoder { @@ -25,14 +25,14 @@ export interface TypedDecoder { skip(): void; next(): Value; - withPointerDecode( - pointerDecode: PointerTypeDecode, + withEmbeddedDecode( + embeddedDecode: EmbeddedTypeDecode, body: (d: TypedDecoder) => R): R; nextBoolean(): boolean | undefined; nextFloat(): SingleFloat | undefined; nextDouble(): DoubleFloat | undefined; - nextPointer(): Pointer | undefined; + nextEmbedded(): Embedded | undefined; nextSignedInteger(): number | undefined; nextString(): string | undefined; nextByteString(): Bytes | undefined; @@ -161,33 +161,33 @@ export class DecoderState { } } -export const neverPointerTypeDecode: PointerTypeDecode = { +export const neverEmbeddedTypeDecode: EmbeddedTypeDecode = { decode(_s: DecoderState): never { - throw new Error("Pointers not permitted at this point in Preserves document"); + throw new Error("Embeddeds not permitted at this point in Preserves document"); }, - fromValue(_v: Value): never { - throw new Error("Pointers not permitted at this point in Preserves document"); + fromValue(_v: Value): never { + throw new Error("Embeddeds not permitted at this point in Preserves document"); }, }; export class Decoder implements TypedDecoder { state: DecoderState; - pointerDecode: PointerTypeDecode; + embeddedDecode: EmbeddedTypeDecode; - constructor(state: DecoderState, pointerDecode?: PointerTypeDecode); - constructor(packet?: BytesLike, options?: DecoderPointerOptions); + constructor(state: DecoderState, embeddedDecode?: EmbeddedTypeDecode); + constructor(packet?: BytesLike, options?: DecoderEmbeddedOptions); constructor( packet_or_state: (DecoderState | BytesLike) = new Uint8Array(0), - options_or_pointerDecode?: (DecoderPointerOptions | PointerTypeDecode)) + options_or_embeddedDecode?: (DecoderEmbeddedOptions | EmbeddedTypeDecode)) { if (packet_or_state instanceof DecoderState) { this.state = packet_or_state; - this.pointerDecode = (options_or_pointerDecode as PointerTypeDecode) ?? neverPointerTypeDecode; + this.embeddedDecode = (options_or_embeddedDecode as EmbeddedTypeDecode) ?? neverEmbeddedTypeDecode; } else { - const options = (options_or_pointerDecode as DecoderPointerOptions) ?? {}; + const options = (options_or_embeddedDecode as DecoderEmbeddedOptions) ?? {}; this.state = new DecoderState(packet_or_state, options); - this.pointerDecode = options.pointerDecode ?? neverPointerTypeDecode; + this.embeddedDecode = options.embeddedDecode ?? neverEmbeddedTypeDecode; } } @@ -223,7 +223,7 @@ export class Decoder implements TypedDecoder { const v = this.next() as Annotated; return this.state.unshiftAnnotation(a, v); } - case Tag.Pointer: return this.state.wrap(embed(this.pointerDecode.decode(this.state))); + case Tag.Embedded: return this.state.wrap(embed(this.embeddedDecode.decode(this.state))); case Tag.SignedInteger: return this.state.wrap(this.state.nextint(this.state.varint())); case Tag.String: return this.state.wrap(Bytes.from(this.state.nextbytes(this.state.varint())).fromUtf8()); case Tag.ByteString: return this.state.wrap(Bytes.from(this.state.nextbytes(this.state.varint()))); @@ -267,11 +267,11 @@ export class Decoder implements TypedDecoder { this.next(); } - withPointerDecode( - pointerDecode: PointerTypeDecode, + withEmbeddedDecode( + embeddedDecode: EmbeddedTypeDecode, body: (d: TypedDecoder) => R): R { - return body(new Decoder(this.state, pointerDecode)); + return body(new Decoder(this.state, embeddedDecode)); } skipAnnotations(): void { @@ -306,10 +306,10 @@ export class Decoder implements TypedDecoder { } } - nextPointer(): Pointer | undefined { + nextEmbedded(): Embedded | undefined { this.skipAnnotations(); switch (this.state.nextbyte()) { - case Tag.Pointer: return embed(this.pointerDecode.decode(this.state)); + case Tag.Embedded: return embed(this.embeddedDecode.decode(this.state)); default: return void 0; } } @@ -374,11 +374,11 @@ export class Decoder implements TypedDecoder { } } -export function decode(bs: BytesLike, options: DecoderPointerOptions = {}): Value { +export function decode(bs: BytesLike, options: DecoderEmbeddedOptions = {}): Value { return new Decoder(bs, options).next(); } export function decodeWithAnnotations(bs: BytesLike, - options: DecoderPointerOptions = {}): Annotated { + options: DecoderEmbeddedOptions = {}): Annotated { return decode(bs, { ... options, includeAnnotations: true }) as Annotated; } diff --git a/implementations/javascript/packages/core/src/dictionary.ts b/implementations/javascript/packages/core/src/dictionary.ts index e53cd0c..de89d46 100644 --- a/implementations/javascript/packages/core/src/dictionary.ts +++ b/implementations/javascript/packages/core/src/dictionary.ts @@ -5,17 +5,17 @@ import { PreserveOn } from "./symbols"; import { stringify } from "./text"; import { Value } from "./values"; import { Bytes } from './bytes'; -import { GenericPointer } from "./pointer"; +import { GenericEmbedded } from "./embedded"; export type DictionaryType = 'Dictionary' | 'Set'; export const DictionaryType = Symbol.for('DictionaryType'); -export class KeyedDictionary, V, T = GenericPointer> extends FlexMap { +export class KeyedDictionary, V, T = GenericEmbedded> extends FlexMap { get [DictionaryType](): DictionaryType { return 'Dictionary'; } - static isKeyedDictionary, V, T = GenericPointer>(x: any): x is KeyedDictionary { + static isKeyedDictionary, V, T = GenericEmbedded>(x: any): x is KeyedDictionary { return x?.[DictionaryType] === 'Dictionary'; } @@ -25,7 +25,7 @@ export class KeyedDictionary, V, T = GenericPointer> extends super(canonicalString, items); } - mapEntries, R = GenericPointer>(f: (entry: [K, V]) => [S, W]): KeyedDictionary { + mapEntries, R = GenericEmbedded>(f: (entry: [K, V]) => [S, W]): KeyedDictionary { const result = new KeyedDictionary(); for (let oldEntry of this.entries()) { const newEntry = f(oldEntry); @@ -74,18 +74,18 @@ export class KeyedDictionary, V, T = GenericPointer> extends } } -export class Dictionary> extends KeyedDictionary, V, T> { - static isDictionary>(x: any): x is Dictionary { +export class Dictionary> extends KeyedDictionary, V, T> { + static isDictionary>(x: any): x is Dictionary { return x?.[DictionaryType] === 'Dictionary'; } } -export class KeyedSet, T = GenericPointer> extends FlexSet { +export class KeyedSet, T = GenericEmbedded> extends FlexSet { get [DictionaryType](): DictionaryType { return 'Set'; } - static isKeyedSet, T = GenericPointer>(x: any): x is KeyedSet { + static isKeyedSet, T = GenericEmbedded>(x: any): x is KeyedSet { return x?.[DictionaryType] === 'Set'; } @@ -93,7 +93,7 @@ export class KeyedSet, T = GenericPointer> extends FlexSet super(canonicalString, items); } - map, R = GenericPointer>(f: (value: K) => S): KeyedSet { + map, R = GenericEmbedded>(f: (value: K) => S): KeyedSet { return new KeyedSet(_iterMap(this[Symbol.iterator](), f)); } @@ -130,8 +130,8 @@ export class KeyedSet, T = GenericPointer> extends FlexSet } } -export class Set extends KeyedSet, T> { - static isSet(x: any): x is Set { +export class Set extends KeyedSet, T> { + static isSet(x: any): x is Set { return x?.[DictionaryType] === 'Set'; } } diff --git a/implementations/javascript/packages/core/src/pointer.ts b/implementations/javascript/packages/core/src/embedded.ts similarity index 62% rename from implementations/javascript/packages/core/src/pointer.ts rename to implementations/javascript/packages/core/src/embedded.ts index 40653a7..f5ee18c 100644 --- a/implementations/javascript/packages/core/src/pointer.ts +++ b/implementations/javascript/packages/core/src/embedded.ts @@ -2,19 +2,19 @@ import type { EncoderState } from "./encoder"; import type { DecoderState } from "./decoder"; import type { Value } from "./values"; -export type PointerTypeEncode = { +export type EmbeddedTypeEncode = { encode(s: EncoderState, v: T): void; - toValue(v: T): Value; + toValue(v: T): Value; } -export type PointerTypeDecode = { +export type EmbeddedTypeDecode = { decode(s: DecoderState): T; - fromValue(v: Value): T; + fromValue(v: Value): T; } -export type PointerType = PointerTypeEncode & PointerTypeDecode; +export type EmbeddedType = EmbeddedTypeEncode & EmbeddedTypeDecode; -export class Pointer { +export class Embedded { embeddedValue: T; constructor(embeddedValue: T) { @@ -22,7 +22,7 @@ export class Pointer { } equals(other: any, is: (a: any, b: any) => boolean) { - return isPointer(other) && is(this.embeddedValue, other.embeddedValue); + return isEmbedded(other) && is(this.embeddedValue, other.embeddedValue); } asPreservesText(): string { @@ -30,15 +30,15 @@ export class Pointer { } } -export function embed(embeddedValue: T): Pointer { - return new Pointer(embeddedValue); +export function embed(embeddedValue: T): Embedded { + return new Embedded(embeddedValue); } -export function isPointer(v: Value): v is Pointer { +export function isEmbedded(v: Value): v is Embedded { return typeof v === 'object' && 'embeddedValue' in v; } -export class GenericPointer { +export class GenericEmbedded { generic: Value; constructor(generic: Value) { diff --git a/implementations/javascript/packages/core/src/embeddedTypes.ts b/implementations/javascript/packages/core/src/embeddedTypes.ts new file mode 100644 index 0000000..fc93a55 --- /dev/null +++ b/implementations/javascript/packages/core/src/embeddedTypes.ts @@ -0,0 +1,50 @@ +import { GenericEmbedded, EmbeddedType, EmbeddedTypeDecode, EmbeddedTypeEncode } from "./embedded"; +import { Encoder, EncoderState, identityEmbeddedTypeEncode } from "./encoder"; +import { genericEmbeddedTypeDecode } from "./reader"; +import { Value } from "./values"; +import { DecoderState, neverEmbeddedTypeDecode } from "./decoder"; + +export const genericEmbeddedTypeEncode: EmbeddedTypeEncode = { + encode(s: EncoderState, v: GenericEmbedded): void { + new Encoder(s, this).push(v.generic); + }, + + toValue(v: GenericEmbedded): Value { + return v.generic; + } +}; + +export const genericEmbeddedType: EmbeddedType = + Object.assign({}, + genericEmbeddedTypeDecode, + genericEmbeddedTypeEncode); + +export const neverEmbeddedTypeEncode: EmbeddedTypeEncode = { + encode(_s: EncoderState, _v: never): void { + throw new Error("Embeddeds not permitted encoding Preserves document"); + }, + + toValue(_v: never): Value { + throw new Error("Embeddeds not permitted encoding Preserves document"); + } +}; + +export const neverEmbeddedType: EmbeddedType = + Object.assign({}, + neverEmbeddedTypeDecode, + neverEmbeddedTypeEncode); + +export const identityEmbeddedTypeDecode: EmbeddedTypeDecode = { + decode(_s: DecoderState): any { + throw new Error("Cannot decode identityEmbeddedType"); + }, + + fromValue(_v: Value): any { + throw new Error("Cannot decode identityEmbeddedType"); + }, +}; + +export const identityEmbeddedType: EmbeddedType = + Object.assign({}, + identityEmbeddedTypeDecode, + identityEmbeddedTypeEncode); diff --git a/implementations/javascript/packages/core/src/encoder.ts b/implementations/javascript/packages/core/src/encoder.ts index d00f9c5..a24ed5f 100644 --- a/implementations/javascript/packages/core/src/encoder.ts +++ b/implementations/javascript/packages/core/src/encoder.ts @@ -4,7 +4,7 @@ import { Value } from "./values"; import { PreserveOn } from "./symbols"; import { EncodeError } from "./codec"; import { Record, Tuple } from "./record"; -import { GenericPointer, PointerTypeEncode } from "./pointer"; +import { GenericEmbedded, EmbeddedTypeEncode } from "./embedded"; export type Encodable = Value | Preservable | Iterable> | ArrayBufferView; @@ -22,8 +22,8 @@ export interface EncoderOptions { includeAnnotations?: boolean; } -export interface EncoderPointerOptions extends EncoderOptions { - pointerEncode?: PointerTypeEncode; +export interface EncoderEmbeddedOptions extends EncoderOptions { + embeddedEncode?: EmbeddedTypeEncode; } export function asLatin1(bs: Uint8Array): string { @@ -36,7 +36,7 @@ function isIterable(v: any): v is Iterable { let _nextId = 0; const _registry = new WeakMap(); -export function pointerId(v: any): number { +export function embeddedId(v: any): number { let id = _registry.get(v); if (id === void 0) { id = _nextId++; @@ -45,13 +45,13 @@ export function pointerId(v: any): number { return id; } -export const identityPointerTypeEncode: PointerTypeEncode = { +export const identityEmbeddedTypeEncode: EmbeddedTypeEncode = { encode(s: EncoderState, v: any): void { - new Encoder(s, this).push(pointerId(v)); + new Encoder(s, this).push(embeddedId(v)); }, - toValue(v: any): Value { - return pointerId(v); + toValue(v: any): Value { + return embeddedId(v); } }; @@ -159,28 +159,28 @@ export class EncoderState { export class Encoder { state: EncoderState; - pointerEncode: PointerTypeEncode; + embeddedEncode: EmbeddedTypeEncode; - constructor(options: EncoderPointerOptions); - constructor(state: EncoderState, pointerEncode?: PointerTypeEncode); + constructor(options: EncoderEmbeddedOptions); + constructor(state: EncoderState, embeddedEncode?: EmbeddedTypeEncode); constructor( - state_or_options: (EncoderState | EncoderPointerOptions) = {}, - pointerEncode?: PointerTypeEncode) + state_or_options: (EncoderState | EncoderEmbeddedOptions) = {}, + embeddedEncode?: EmbeddedTypeEncode) { if (state_or_options instanceof EncoderState) { this.state = state_or_options; - this.pointerEncode = pointerEncode ?? identityPointerTypeEncode; + this.embeddedEncode = embeddedEncode ?? identityEmbeddedTypeEncode; } else { this.state = new EncoderState(state_or_options); - this.pointerEncode = state_or_options.pointerEncode ?? identityPointerTypeEncode; + this.embeddedEncode = state_or_options.embeddedEncode ?? identityEmbeddedTypeEncode; } } - withPointerEncode( - pointerEncode: PointerTypeEncode, + withEmbeddedEncode( + embeddedEncode: EmbeddedTypeEncode, body: (e: Encoder) => void): this { - body(new Encoder(this.state, pointerEncode)); + body(new Encoder(this.state, embeddedEncode)); return this; } @@ -252,8 +252,8 @@ export class Encoder { this.encodevalues(Tag.Sequence, v as Iterable>); } else { - this.state.emitbyte(Tag.Pointer); - this.pointerEncode.encode(this.state, v.embeddedValue); + this.state.emitbyte(Tag.Embedded); + this.embeddedEncode.encode(this.state, v.embeddedValue); } return this; // for chaining } @@ -261,7 +261,7 @@ export class Encoder { export function encode( v: Encodable, - options: EncoderPointerOptions = {}): Bytes + options: EncoderEmbeddedOptions = {}): Bytes { return new Encoder(options).push(v).contents(); } @@ -269,9 +269,9 @@ export function encode( const _canonicalEncoder = new Encoder({ canonical: true }); let _usingCanonicalEncoder = false; -export function canonicalEncode(v: Encodable, options?: EncoderPointerOptions): Bytes; -export function canonicalEncode(v: Encodable, options?: EncoderPointerOptions): Bytes; -export function canonicalEncode(v: any, options?: EncoderPointerOptions): Bytes { +export function canonicalEncode(v: Encodable, options?: EncoderEmbeddedOptions): Bytes; +export function canonicalEncode(v: Encodable, options?: EncoderEmbeddedOptions): Bytes; +export function canonicalEncode(v: any, options?: EncoderEmbeddedOptions): Bytes { if (options === void 0 && !_usingCanonicalEncoder) { _usingCanonicalEncoder = true; const bs = _canonicalEncoder.push(v).contents(); @@ -294,6 +294,6 @@ export function canonicalString(v: Encodable): string { } export function encodeWithAnnotations(v: Encodable, - options: EncoderPointerOptions = {}): Bytes { + options: EncoderEmbeddedOptions = {}): Bytes { return encode(v, { ... options, includeAnnotations: true }); } diff --git a/implementations/javascript/packages/core/src/float.ts b/implementations/javascript/packages/core/src/float.ts index b1baedd..a2f0980 100644 --- a/implementations/javascript/packages/core/src/float.ts +++ b/implementations/javascript/packages/core/src/float.ts @@ -2,7 +2,7 @@ import { Encoder, Preservable } from "./encoder"; import { Tag } from "./constants"; import { AsPreserve, PreserveOn } from "./symbols"; import { Value } from "./values"; -import { GenericPointer } from "./pointer"; +import { GenericEmbedded } from "./embedded"; export type FloatType = 'Single' | 'Double'; export const FloatType = Symbol.for('FloatType'); @@ -45,7 +45,7 @@ export function floatValue(f: any): number { } export class SingleFloat extends Float implements Preservable { - [AsPreserve](): Value { + [AsPreserve](): Value { return this; } @@ -70,7 +70,7 @@ export function Single(value: number | Float): SingleFloat { } export class DoubleFloat extends Float implements Preservable { - [AsPreserve](): Value { + [AsPreserve](): Value { return this; } diff --git a/implementations/javascript/packages/core/src/fold.ts b/implementations/javascript/packages/core/src/fold.ts index ba40d50..87b002c 100644 --- a/implementations/javascript/packages/core/src/fold.ts +++ b/implementations/javascript/packages/core/src/fold.ts @@ -4,7 +4,7 @@ import { Value } from "./values"; import { Set, Dictionary } from "./dictionary"; import { annotate, Annotated } from "./annotated"; import { Double, Float, Single } from "./float"; -import { Pointer } from "./pointer"; +import { Embedded } from "./embedded"; export type Fold> = (v: Value) => R; @@ -24,7 +24,7 @@ export interface FoldMethods { annotated(a: Annotated, k: Fold): R; - pointer(t: Pointer, k: Fold): R; + embedded(t: Embedded, k: Fold): R; } export abstract class ValueFold implements FoldMethods> { @@ -64,11 +64,11 @@ export abstract class ValueFold implements FoldMethods> { annotated(a: Annotated, k: Fold>): Value { return annotate(k(a.item), ...a.annotations.map(k)); } - abstract pointer(t: Pointer, k: Fold>): Value; + abstract embedded(t: Embedded, k: Fold>): Value; } export class IdentityFold extends ValueFold { - pointer(t: Pointer, _k: Fold>): Value { + embedded(t: Embedded, _k: Fold>): Value { return t; } } @@ -81,7 +81,7 @@ export class MapFold extends ValueFold { this.f = f; } - pointer(t: Pointer, _k: Fold>): Value { + embedded(t: Embedded, _k: Fold>): Value { return this.f(t.embeddedValue); } } @@ -122,7 +122,7 @@ export function fold(v: Value, o: FoldMethods): R { } else if (Float.isDouble(v)) { return o.double(v.value); } else { - return o.pointer(v, walk); + return o.embedded(v, walk); } default: ((_v: never): never => { throw new Error("Internal error"); })(v); @@ -131,7 +131,7 @@ export function fold(v: Value, o: FoldMethods): R { return walk(v); } -export function mapPointers( +export function mapEmbeddeds( v: Value, f: (t: T) => Value, ): Value diff --git a/implementations/javascript/packages/core/src/fromjs.ts b/implementations/javascript/packages/core/src/fromjs.ts index d22ca4a..587d846 100644 --- a/implementations/javascript/packages/core/src/fromjs.ts +++ b/implementations/javascript/packages/core/src/fromjs.ts @@ -1,11 +1,11 @@ -import { embed, GenericPointer } from "./pointer"; +import { embed, GenericEmbedded } from "./embedded"; import { Bytes } from "./bytes"; import { Record, Tuple } from "./record"; import { AsPreserve } from "./symbols"; import { Value } from "./values"; import { Dictionary, Set } from "./dictionary"; -export function fromJS(x: any): Value { +export function fromJS(x: any): Value { switch (typeof x) { case 'number': if (!Number.isInteger(x)) { @@ -61,11 +61,11 @@ export function fromJS(x: any): Value { declare module "./dictionary" { namespace Dictionary { - export function fromJS(x: object): Dictionary>; + export function fromJS(x: object): Dictionary>; } } -Dictionary.fromJS = function (x: object): Dictionary> { +Dictionary.fromJS = function (x: object): Dictionary> { if (Dictionary.isDictionary>(x)) return x; const d = new Dictionary>(); Object.entries(x).forEach(([key, value]) => d.set(key, fromJS(value))); diff --git a/implementations/javascript/packages/core/src/is.ts b/implementations/javascript/packages/core/src/is.ts index 61ed216..03551da 100644 --- a/implementations/javascript/packages/core/src/is.ts +++ b/implementations/javascript/packages/core/src/is.ts @@ -1,9 +1,9 @@ -import type { GenericPointer } from "./pointer"; +import type { GenericEmbedded } from "./embedded"; import type { Annotated } from "./annotated"; export const IsPreservesAnnotated = Symbol.for('IsPreservesAnnotated'); -export function isAnnotated(x: any): x is Annotated +export function isAnnotated(x: any): x is Annotated { return !!x?.[IsPreservesAnnotated]; } diff --git a/implementations/javascript/packages/core/src/merge.ts b/implementations/javascript/packages/core/src/merge.ts index aa858f7..fb8c2a8 100644 --- a/implementations/javascript/packages/core/src/merge.ts +++ b/implementations/javascript/packages/core/src/merge.ts @@ -6,10 +6,10 @@ import { Value } from "./values"; import { Set, Dictionary } from "./dictionary"; import { Annotated } from "./annotated"; import { unannotate } from "./strip"; -import { embed, isPointer, Pointer } from "./pointer"; +import { embed, isEmbedded, Embedded } from "./embedded"; export function merge( - mergePointers: (a: T, b: T) => T | undefined, + mergeEmbeddeds: (a: T, b: T) => T | undefined, item0: Value, ... items: Array>): Value { @@ -54,9 +54,9 @@ export function merge( return walk(a, unannotate(b)); }, - pointer(t: Pointer) { - if (!isPointer(b)) die(); - const r = mergePointers(t.embeddedValue, b.embeddedValue); + embedded(t: Embedded) { + if (!isEmbedded(b)) die(); + const r = mergeEmbeddeds(t.embeddedValue, b.embeddedValue); if (r === void 0) die(); return embed(r); }, diff --git a/implementations/javascript/packages/core/src/pointerTypes.ts b/implementations/javascript/packages/core/src/pointerTypes.ts deleted file mode 100644 index 2ccf4f9..0000000 --- a/implementations/javascript/packages/core/src/pointerTypes.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { GenericPointer, PointerType, PointerTypeDecode, PointerTypeEncode } from "./pointer"; -import { Encoder, EncoderState, identityPointerTypeEncode } from "./encoder"; -import { genericPointerTypeDecode } from "./reader"; -import { Value } from "./values"; -import { DecoderState, neverPointerTypeDecode } from "./decoder"; - -export const genericPointerTypeEncode: PointerTypeEncode = { - encode(s: EncoderState, v: GenericPointer): void { - new Encoder(s, this).push(v.generic); - }, - - toValue(v: GenericPointer): Value { - return v.generic; - } -}; - -export const genericPointerType: PointerType = - Object.assign({}, - genericPointerTypeDecode, - genericPointerTypeEncode); - -export const neverPointerTypeEncode: PointerTypeEncode = { - encode(_s: EncoderState, _v: never): void { - throw new Error("Pointers not permitted encoding Preserves document"); - }, - - toValue(_v: never): Value { - throw new Error("Pointers not permitted encoding Preserves document"); - } -}; - -export const neverPointerType: PointerType = - Object.assign({}, - neverPointerTypeDecode, - neverPointerTypeEncode); - -export const identityPointerTypeDecode: PointerTypeDecode = { - decode(_s: DecoderState): any { - throw new Error("Cannot decode identityPointerType"); - }, - - fromValue(_v: Value): any { - throw new Error("Cannot decode identityPointerType"); - }, -}; - -export const identityPointerType: PointerType = - Object.assign({}, - identityPointerTypeDecode, - identityPointerTypeEncode); diff --git a/implementations/javascript/packages/core/src/reader.ts b/implementations/javascript/packages/core/src/reader.ts index a5983dc..8032792 100644 --- a/implementations/javascript/packages/core/src/reader.ts +++ b/implementations/javascript/packages/core/src/reader.ts @@ -5,12 +5,12 @@ import { DecodeError, ShortPacket } from './codec'; import { Dictionary, Set } from './dictionary'; import { strip, unannotate } from './strip'; import { Bytes, unhexDigit } from './bytes'; -import { decode, Decoder, DecoderState, neverPointerTypeDecode } from './decoder'; +import { decode, Decoder, DecoderState, neverEmbeddedTypeDecode } from './decoder'; import { Record } from './record'; import { Annotated, newPosition, Position, updatePosition } from './annotated'; import { Double, DoubleFloat, Single, SingleFloat } from './float'; import { stringify } from './text'; -import { embed, GenericPointer, PointerTypeDecode } from './pointer'; +import { embed, GenericEmbedded, EmbeddedTypeDecode } from './embedded'; export interface ReaderStateOptions { includeAnnotations?: boolean; @@ -18,7 +18,7 @@ export interface ReaderStateOptions { } export interface ReaderOptions extends ReaderStateOptions { - pointerDecode?: PointerTypeDecode; + embeddedDecode?: EmbeddedTypeDecode; } type IntOrFloat = 'int' | 'float'; @@ -275,33 +275,33 @@ export class ReaderState { } } -export const genericPointerTypeDecode: PointerTypeDecode = { - decode(s: DecoderState): GenericPointer { - return new GenericPointer(new Decoder(s, this).next()); +export const genericEmbeddedTypeDecode: EmbeddedTypeDecode = { + decode(s: DecoderState): GenericEmbedded { + return new GenericEmbedded(new Decoder(s, this).next()); }, - fromValue(v: Value): GenericPointer { - return new GenericPointer(strip(v)); + fromValue(v: Value): GenericEmbedded { + return new GenericEmbedded(strip(v)); }, }; export class Reader { state: ReaderState; - pointerType: PointerTypeDecode; + embeddedType: EmbeddedTypeDecode; - constructor(state: ReaderState, pointerType: PointerTypeDecode); + constructor(state: ReaderState, embeddedType: EmbeddedTypeDecode); constructor(buffer: string, options?: ReaderOptions); constructor( state_or_buffer: (ReaderState | string) = '', - pointerType_or_options?: (PointerTypeDecode | ReaderOptions)) + embeddedType_or_options?: (EmbeddedTypeDecode | ReaderOptions)) { if (state_or_buffer instanceof ReaderState) { this.state = state_or_buffer; - this.pointerType = pointerType_or_options as PointerTypeDecode; + this.embeddedType = embeddedType_or_options as EmbeddedTypeDecode; } else { - const options = (pointerType_or_options as ReaderOptions) ?? {}; + const options = (embeddedType_or_options as ReaderOptions) ?? {}; this.state = new ReaderState(state_or_buffer, options); - this.pointerType = options.pointerDecode ?? neverPointerTypeDecode; + this.embeddedType = options.embeddedDecode ?? neverEmbeddedTypeDecode; } } @@ -388,12 +388,12 @@ export class Reader { if (!Bytes.isBytes(bs)) this.state.error('ByteString must follow #=', startPos); return decode(bs, { - pointerDecode: this.pointerType, + embeddedDecode: this.embeddedType, includeAnnotations: this.state.options.includeAnnotations, }); } - case '!': return embed(this.pointerType.fromValue( - new Reader(this.state, genericPointerTypeDecode).next())); + case '!': return embed(this.embeddedType.fromValue( + new Reader(this.state, genericEmbeddedTypeDecode).next())); default: this.state.error(`Invalid # syntax: ${c}`, startPos); } diff --git a/implementations/javascript/packages/core/src/record.ts b/implementations/javascript/packages/core/src/record.ts index 51df0b9..83fb64d 100644 --- a/implementations/javascript/packages/core/src/record.ts +++ b/implementations/javascript/packages/core/src/record.ts @@ -1,10 +1,10 @@ -import { GenericPointer } from "./pointer"; +import { GenericEmbedded } from "./embedded"; import { is } from "./is"; import { Value } from "./values"; export type Tuple = Array | [T]; -export type Record, FieldsType extends Tuple>, T = GenericPointer> +export type Record, FieldsType extends Tuple>, T = GenericEmbedded> = FieldsType & { label: LabelType }; export type RecordGetters = { @@ -14,14 +14,14 @@ export type RecordGetters = { export type CtorTypes> = { [K in keyof Names]: Fs[keyof Fs & Names[K]] } & any[]; -export interface RecordConstructor, Fs, Names extends Tuple, T = GenericPointer> { +export interface RecordConstructor, Fs, Names extends Tuple, T = GenericEmbedded> { (...fields: CtorTypes): Record, T>; constructorInfo: RecordConstructorInfo; isClassOf(v: any): v is Record, T>; _: RecordGetters, T>>; }; -export interface RecordConstructorInfo, T = GenericPointer> { +export interface RecordConstructorInfo, T = GenericEmbedded> { label: L; arity: number; } @@ -35,7 +35,7 @@ export type InferredRecordType> = L extends Value ? (FieldsType extends Tuple> ? Record : "TYPE_ERROR_cannotMatchFieldsTypeToLabelType" & [never]) : - "TYPE_ERROR_cannotInferPointerType" & [never]; + "TYPE_ERROR_cannotInferEmbeddedType" & [never]; export function Record>( label: L, @@ -46,7 +46,7 @@ export function Record>( } export namespace Record { - export function isRecord, FieldsType extends Tuple>, T = GenericPointer>(x: any): x is Record { + export function isRecord, FieldsType extends Tuple>, T = GenericEmbedded>(x: any): x is Record { return Array.isArray(x) && 'label' in x; } @@ -54,19 +54,19 @@ export namespace Record { return ''; } - export function constructorInfo, FieldsType extends Tuple>, T = GenericPointer>( + export function constructorInfo, FieldsType extends Tuple>, T = GenericEmbedded>( r: Record): RecordConstructorInfo { return { label: r.label, arity: r.length }; } - export function isClassOf, FieldsType extends Tuple>, T = GenericPointer>( + export function isClassOf, FieldsType extends Tuple>, T = GenericEmbedded>( ci: RecordConstructorInfo, v: any): v is Record { return (Record.isRecord(v)) && is(ci.label, v.label) && (ci.arity === v.length); } - export function makeConstructor() + export function makeConstructor() : (, Names extends Tuple>(label: L, fieldNames: Names) => RecordConstructor) { @@ -86,7 +86,7 @@ export namespace Record { Array.prototype.asPreservesText = function (): string { if ('label' in (this as any)) { - const r = this as Record, GenericPointer>; + const r = this as Record, GenericEmbedded>; return '<' + r.label.asPreservesText() + (r.length > 0 ? ' ': '') + r.map(f => { try { diff --git a/implementations/javascript/packages/core/src/runtime.ts b/implementations/javascript/packages/core/src/runtime.ts index 2a16ca8..eaab6cc 100644 --- a/implementations/javascript/packages/core/src/runtime.ts +++ b/implementations/javascript/packages/core/src/runtime.ts @@ -4,6 +4,8 @@ export * from './codec'; export * from './compound'; export * from './decoder'; export * from './dictionary'; +export * from './embedded'; +export * from './embeddedTypes'; export * from './encoder'; export * from './flex'; export * from './float'; @@ -11,8 +13,6 @@ export * from './fold'; export * from './fromjs'; export * from './is'; export * from './merge'; -export * from './pointer'; -export * from './pointerTypes'; export * from './reader'; export * from './record'; export * from './strip'; diff --git a/implementations/javascript/packages/core/src/strip.ts b/implementations/javascript/packages/core/src/strip.ts index dce1baa..f3b01d3 100644 --- a/implementations/javascript/packages/core/src/strip.ts +++ b/implementations/javascript/packages/core/src/strip.ts @@ -2,17 +2,17 @@ import { Value } from "./values"; import { Annotated } from "./annotated"; import { Record, Tuple } from "./record"; import { Set, Dictionary } from "./dictionary"; -import type { GenericPointer } from "./pointer"; +import type { GenericEmbedded } from "./embedded"; -export function unannotate(v: Value): Value { +export function unannotate(v: Value): Value { return Annotated.isAnnotated(v) ? v.item : v; } -export function peel(v: Value): Value { +export function peel(v: Value): Value { return strip(v, 1); } -export function strip( +export function strip( v: Value, depth: number = Infinity): Value { diff --git a/implementations/javascript/packages/core/src/values.ts b/implementations/javascript/packages/core/src/values.ts index e4729af..1746bcb 100644 --- a/implementations/javascript/packages/core/src/values.ts +++ b/implementations/javascript/packages/core/src/values.ts @@ -4,12 +4,12 @@ import type { Bytes } from './bytes'; import type { DoubleFloat, SingleFloat } from './float'; import type { Annotated } from './annotated'; import type { Set, Dictionary } from './dictionary'; -import type { Pointer, GenericPointer } from './pointer'; +import type { Embedded, GenericEmbedded } from './embedded'; -export type Value = +export type Value = | Atom | Compound - | Pointer + | Embedded | Annotated; export type Atom = | boolean @@ -19,7 +19,7 @@ export type Atom = | string | Bytes | symbol; -export type Compound = +export type Compound = | (Array> | [Value]) & { label: Value } // ^ expanded from definition of Record<> in record.ts, // because if we use Record, Tuple>, T>, diff --git a/implementations/javascript/packages/core/test/codec.test.ts b/implementations/javascript/packages/core/test/codec.test.ts index ab4c5a6..fe99f9c 100644 --- a/implementations/javascript/packages/core/test/codec.test.ts +++ b/implementations/javascript/packages/core/test/codec.test.ts @@ -10,15 +10,15 @@ import { fromJS, Constants, Encoder, - GenericPointer, + GenericEmbedded, EncoderState, - PointerType, + EmbeddedType, DecoderState, Decoder, - Pointer, + Embedded, embed, - genericPointerTypeDecode, - genericPointerTypeEncode, + genericEmbeddedTypeDecode, + genericEmbeddedTypeEncode, } from '../src/index'; const { Tag } = Constants; import './test-utils'; @@ -28,9 +28,9 @@ import * as fs from 'fs'; const _discard = Symbol.for('discard'); const _capture = Symbol.for('capture'); const _observe = Symbol.for('observe'); -const Discard = Record.makeConstructor<{}, GenericPointer>()(_discard, []); -const Capture = Record.makeConstructor<{pattern: Value}, GenericPointer>()(_capture, ['pattern']); -const Observe = Record.makeConstructor<{pattern: Value}, GenericPointer>()(_observe, ['pattern']); +const Discard = Record.makeConstructor<{}, GenericEmbedded>()(_discard, []); +const Capture = Record.makeConstructor<{pattern: Value}, GenericEmbedded>()(_capture, ['pattern']); +const Observe = Record.makeConstructor<{pattern: Value}, GenericEmbedded>()(_observe, ['pattern']); describe('record constructors', () => { it('should have constructorInfo', () => { @@ -46,11 +46,11 @@ describe('record constructors', () => { describe('RecordConstructorInfo', () => { const C1 = Record.makeConstructor<{x: number, y: number}>()([1], ['x', 'y']); const C2 = Record.makeConstructor<{z: number, w: number}>()([1], ['z', 'w']); - it('instance comparison should ignore pointer and fieldname differences', () => { + it('instance comparison should ignore embedded and fieldname differences', () => { expect(C1(9,9)).is(C2(9,9)); expect(C1(9,9)).not.is(C2(9,8)); }); - it('comparison based on pointer equality should not work', () => { + it('comparison based on embedded equality should not work', () => { expect(C1.constructorInfo).not.toBe(C2.constructorInfo); }); it('comparison based on .equals should work', () => { @@ -87,8 +87,8 @@ describe('reusing buffer space', () => { }); }); -describe('encoding and decoding pointers', () => { - class LookasidePointerType implements PointerType { +describe('encoding and decoding embeddeds', () => { + class LookasideEmbeddedType implements EmbeddedType { readonly objects: object[]; constructor(objects: object[]) { @@ -96,7 +96,7 @@ describe('encoding and decoding pointers', () => { } decode(d: DecoderState): object { - return this.fromValue(new Decoder(d).next()); + return this.fromValue(new Decoder(d).next()); } encode(e: EncoderState, v: object): void { @@ -107,9 +107,9 @@ describe('encoding and decoding pointers', () => { return Object.is(a, b); } - fromValue(v: Value): object { + fromValue(v: Value): object { if (typeof v !== 'number' || v < 0 || v >= this.objects.length) { - throw new Error("Unknown pointer target"); + throw new Error("Unknown embedded target"); } return this.objects[v]; } @@ -122,54 +122,54 @@ describe('encoding and decoding pointers', () => { } } - it('should encode using pointerId when no function has been supplied', () => { + it('should encode using embeddedId when no function has been supplied', () => { const A1 = embed({a: 1}); const A2 = embed({a: 1}); const bs1 = canonicalEncode(A1); const bs2 = canonicalEncode(A2); const bs3 = canonicalEncode(A1); - expect(bs1.get(0)).toBe(Tag.Pointer); - expect(bs2.get(0)).toBe(Tag.Pointer); - expect(bs3.get(0)).toBe(Tag.Pointer); + expect(bs1.get(0)).toBe(Tag.Embedded); + expect(bs2.get(0)).toBe(Tag.Embedded); + expect(bs3.get(0)).toBe(Tag.Embedded); // Can't really check the value assigned to the object. But we // can check that it's different to a similar object! expect(bs1).not.is(bs2); expect(bs1).is(bs3); }); - it('should refuse to decode pointers when no function has been supplied', () => { - expect(() => decode(Bytes.from([Tag.Pointer, Tag.SmallInteger_lo]))) - .toThrow("Pointers not permitted at this point in Preserves document"); + it('should refuse to decode embeddeds when no function has been supplied', () => { + expect(() => decode(Bytes.from([Tag.Embedded, Tag.SmallInteger_lo]))) + .toThrow("Embeddeds not permitted at this point in Preserves document"); }); it('should encode properly', () => { const objects: object[] = []; - const pt = new LookasidePointerType(objects); + const pt = new LookasideEmbeddedType(objects); const A = embed({a: 1}); const B = embed({b: 2}); - expect(encode([A, B], { pointerEncode: pt })).is( + expect(encode([A, B], { embeddedEncode: pt })).is( Bytes.from([Tag.Sequence, - Tag.Pointer, Tag.SmallInteger_lo, - Tag.Pointer, Tag.SmallInteger_lo + 1, + Tag.Embedded, Tag.SmallInteger_lo, + Tag.Embedded, Tag.SmallInteger_lo + 1, Tag.End])); expect(objects).toEqual([A.embeddedValue, B.embeddedValue]); }); it('should decode properly', () => { const objects: object[] = []; - const pt = new LookasidePointerType(objects); - const X: Pointer = embed({x: 123}); - const Y: Pointer = embed({y: 456}); + const pt = new LookasideEmbeddedType(objects); + const X: Embedded = embed({x: 123}); + const Y: Embedded = embed({y: 456}); objects.push(X.embeddedValue); objects.push(Y.embeddedValue); expect(decode(Bytes.from([ Tag.Sequence, - Tag.Pointer, Tag.SmallInteger_lo, - Tag.Pointer, Tag.SmallInteger_lo + 1, + Tag.Embedded, Tag.SmallInteger_lo, + Tag.Embedded, Tag.SmallInteger_lo + 1, Tag.End - ]), { pointerDecode: pt })).is([X, Y]); + ]), { embeddedDecode: pt })).is([X, Y]); }); - it('should store pointers embedded in map keys correctly', () => { + it('should store embeddeds embedded in map keys correctly', () => { const A1a = {a: 1}; - const A1: Pointer = embed(A1a); - const A2: Pointer = embed({a: 1}); + const A1: Embedded = embed(A1a); + const A2: Embedded = embed({a: 1}); const m = new Dictionary(); m.set([A1], 1); m.set([A2], 2); @@ -184,61 +184,61 @@ describe('encoding and decoding pointers', () => { describe('common test suite', () => { const samples_bin = fs.readFileSync(__dirname + '/../../../../../tests/samples.bin'); - const samples = decodeWithAnnotations(samples_bin, { pointerDecode: genericPointerTypeDecode }); + const samples = decodeWithAnnotations(samples_bin, { embeddedDecode: genericEmbeddedTypeDecode }); const TestCases = Record.makeConstructor<{ - cases: Dictionary + cases: Dictionary }>()(Symbol.for('TestCases'), ['cases']); type TestCases = ReturnType; function DS(bs: Bytes) { - return decode(bs, { pointerDecode: genericPointerTypeDecode }); + return decode(bs, { embeddedDecode: genericEmbeddedTypeDecode }); } function D(bs: Bytes) { - return decodeWithAnnotations(bs, { pointerDecode: genericPointerTypeDecode }); + return decodeWithAnnotations(bs, { embeddedDecode: genericEmbeddedTypeDecode }); } - function E(v: Value) { - return encodeWithAnnotations(v, { pointerEncode: genericPointerTypeEncode }); + function E(v: Value) { + return encodeWithAnnotations(v, { embeddedEncode: genericEmbeddedTypeEncode }); } interface ExpectedValues { [testName: string]: ({ - value: Value; + value: Value; } | { - forward: Value; - back: Value; + forward: Value; + back: Value; }); } const expectedValues: ExpectedValues = { - annotation1: { forward: annotate(9, "abc"), + annotation1: { forward: annotate(9, "abc"), back: 9 }, - annotation2: { forward: annotate([[], annotate([], "x")], + annotation2: { forward: annotate([[], annotate([], "x")], "abc", "def"), back: [[], []] }, - annotation3: { forward: annotate(5, - annotate(2, 1), - annotate(4, 3)), + annotation3: { forward: annotate(5, + annotate(2, 1), + annotate(4, 3)), back: 5 }, annotation5: { - forward: annotate( + forward: annotate( Record(Symbol.for('R'), - [annotate(Symbol.for('f'), + [annotate(Symbol.for('f'), Symbol.for('af'))]), Symbol.for('ar')), - back: Record, any>(Symbol.for('R'), [Symbol.for('f')]) + back: Record, any>(Symbol.for('R'), [Symbol.for('f')]) }, annotation6: { - forward: Record, any>( - annotate(Symbol.for('R'), + forward: Record, any>( + annotate(Symbol.for('R'), Symbol.for('ar')), - [annotate(Symbol.for('f'), + [annotate(Symbol.for('f'), Symbol.for('af'))]), back: Record(Symbol.for('R'), [Symbol.for('f')]) }, annotation7: { - forward: annotate([], Symbol.for('a'), Symbol.for('b'), Symbol.for('c')), + forward: annotate([], Symbol.for('a'), Symbol.for('b'), Symbol.for('c')), back: [] }, list1: { @@ -258,7 +258,7 @@ describe('common test suite', () => { function runTestCase(variety: Variety, tName: string, binaryForm: Bytes, - annotatedTextForm: Value) + annotatedTextForm: Value) { describe(tName, () => { const textForm = strip(annotatedTextForm); @@ -287,10 +287,10 @@ describe('common test suite', () => { } const tests = (peel(TestCases._.cases(peel(samples) as TestCases)) as - Dictionary); - tests.forEach((t0: Value, tName0: Value) => { + Dictionary); + tests.forEach((t0: Value, tName0: Value) => { const tName = Symbol.keyFor(strip(tName0) as symbol)!; - const t = peel(t0) as Record; + const t = peel(t0) as Record; switch (t.label) { case Symbol.for('Test'): runTestCase('normal', tName, strip(t[0]) as Bytes, t[1]); diff --git a/implementations/javascript/packages/core/test/reader.test.ts b/implementations/javascript/packages/core/test/reader.test.ts index c6b4380..3484196 100644 --- a/implementations/javascript/packages/core/test/reader.test.ts +++ b/implementations/javascript/packages/core/test/reader.test.ts @@ -1,4 +1,4 @@ -import { Bytes, Decoder, genericPointerType, encode, Reader } from '../src/index'; +import { Bytes, Decoder, genericEmbeddedType, encode, Reader } from '../src/index'; import './test-utils'; import * as fs from 'fs'; @@ -8,21 +8,21 @@ describe('reading common test suite', () => { const samples_pr = fs.readFileSync(__dirname + '/../../../../../tests/samples.pr', 'utf-8'); it('should read equal to decoded binary without annotations', () => { - const s1 = new Reader(samples_pr, { pointerDecode: genericPointerType, includeAnnotations: false }).next(); - const s2 = new Decoder(samples_bin, { pointerDecode: genericPointerType, includeAnnotations: false }).next(); + const s1 = new Reader(samples_pr, { embeddedDecode: genericEmbeddedType, includeAnnotations: false }).next(); + const s2 = new Decoder(samples_bin, { embeddedDecode: genericEmbeddedType, includeAnnotations: false }).next(); expect(s1).is(s2); }); it('should read equal to decoded binary with annotations', () => { - const s1 = new Reader(samples_pr, { pointerDecode: genericPointerType, includeAnnotations: true }).next(); - const s2 = new Decoder(samples_bin, { pointerDecode: genericPointerType, includeAnnotations: true }).next(); + const s1 = new Reader(samples_pr, { embeddedDecode: genericEmbeddedType, includeAnnotations: true }).next(); + const s2 = new Decoder(samples_bin, { embeddedDecode: genericEmbeddedType, includeAnnotations: true }).next(); expect(s1).is(s2); }); it('should read and encode back to binary with annotations', () => { - const s = new Reader(samples_pr, { pointerDecode: genericPointerType, includeAnnotations: true }).next(); + const s = new Reader(samples_pr, { embeddedDecode: genericEmbeddedType, includeAnnotations: true }).next(); const bs = Bytes.toIO(encode(s, { - pointerEncode: genericPointerType, + embeddedEncode: genericEmbeddedType, includeAnnotations: true, canonical: true, })); diff --git a/implementations/javascript/packages/core/test/values.test.ts b/implementations/javascript/packages/core/test/values.test.ts index 5b41ee7..11ad12d 100644 --- a/implementations/javascript/packages/core/test/values.test.ts +++ b/implementations/javascript/packages/core/test/values.test.ts @@ -1,4 +1,4 @@ -import { Single, Double, fromJS, Dictionary, IDENTITY_FOLD, fold, mapPointers, Value, embed } from '../src/index'; +import { Single, Double, fromJS, Dictionary, IDENTITY_FOLD, fold, mapEmbeddeds, Value, embed } from '../src/index'; import './test-utils'; describe('Single', () => { @@ -33,7 +33,7 @@ describe('fold', () => { const w1 = new Date(); const v1 = mkv(w1); expect(fold(v, IDENTITY_FOLD)).not.is(v1); - expect(mapPointers(v, _t => embed(w1))).is(v1); + expect(mapEmbeddeds(v, _t => embed(w1))).is(v1); }); }); diff --git a/implementations/javascript/packages/schema/package.json b/implementations/javascript/packages/schema/package.json index 624b04d..0fc39a5 100644 --- a/implementations/javascript/packages/schema/package.json +++ b/implementations/javascript/packages/schema/package.json @@ -1,6 +1,6 @@ { "name": "@preserves/schema", - "version": "0.7.0", + "version": "0.8.0", "description": "Schema support for Preserves data serialization format", "homepage": "https://gitlab.com/preserves/preserves", "license": "Apache-2.0", @@ -27,7 +27,7 @@ "preserves-schemac": "./bin/preserves-schemac.js" }, "dependencies": { - "@preserves/core": "^0.14.0", + "@preserves/core": "^0.15.0", "@types/glob": "^7.1.3", "@types/minimatch": "^3.0.3", "chalk": "^4.1.0", diff --git a/implementations/javascript/packages/schema/src/compiler.ts b/implementations/javascript/packages/schema/src/compiler.ts index e6fa802..4c63e25 100644 --- a/implementations/javascript/packages/schema/src/compiler.ts +++ b/implementations/javascript/packages/schema/src/compiler.ts @@ -12,13 +12,13 @@ import { sourceCodeFor } from "./compiler/value"; export function compile(env: M.Environment, schema: M.Schema, options: CompilerOptions = {}): string { const mod = new ModuleContext(env, schema, options); - const pointerName = schema.pointer; - mod.defineType(seq(`export type _ptr = `, - renderType(pointerName._variant === 'false' + const embeddedName = schema.embeddedType; + mod.defineType(seq(`export type _embedded = `, + renderType(embeddedName._variant === 'false' ? Type.ref('any') - : typeForDefinition(mod, M.Definition.Alternative(M.Alternative.Pattern(M.Pattern.SimplePattern(M.SimplePattern.Ref(pointerName.value)))))), + : typeForDefinition(mod, M.Definition.Alternative(M.Alternative.Pattern(M.Pattern.SimplePattern(M.SimplePattern.Ref(embeddedName.value)))))), `;`)); - mod.defineType(`export type _val = _.Value<_ptr>;`); + mod.defineType(`export type _val = _.Value<_embedded>;`); for (const [name, def] of schema.definitions) { const t = typeForDefinition(mod, def); diff --git a/implementations/javascript/packages/schema/src/compiler/context.ts b/implementations/javascript/packages/schema/src/compiler/context.ts index 5450758..e10b306 100644 --- a/implementations/javascript/packages/schema/src/compiler/context.ts +++ b/implementations/javascript/packages/schema/src/compiler/context.ts @@ -6,7 +6,7 @@ import { ANY_TYPE, renderType, Type, variantInitFor } from "./type"; export interface CompilerOptions { preservesModule?: string; - defaultPointer?: M.Ref; + defaultEmbeddedType?: M.Ref; warn?(message: string, pos: Position | null): void; } @@ -22,7 +22,7 @@ export class ModuleContext { readonly schema: M.Schema; readonly options: CompilerOptions; - readonly literals = new Dictionary(); + readonly literals = new Dictionary(); readonly typedefs: Item[] = []; readonly functiondefs: Item[] = []; readonly imports = new KeyedSet<[string, string]>(); diff --git a/implementations/javascript/packages/schema/src/compiler/genconverter.ts b/implementations/javascript/packages/schema/src/compiler/genconverter.ts index 7adf578..4f5ad0c 100644 --- a/implementations/javascript/packages/schema/src/compiler/genconverter.ts +++ b/implementations/javascript/packages/schema/src/compiler/genconverter.ts @@ -134,7 +134,7 @@ function converterFor( const r = ctx.gentemp(setType(ctx.mod, setPattern)); const v = ctx.gentempname(); return [ - seq(`if (_.Set.isSet<_ptr>(${src})) `, ctx.block(() => [ + seq(`if (_.Set.isSet<_embedded>(${src})) `, ctx.block(() => [ seq(`${r} = new _.KeyedSet()`), seq(`for (const ${v} of ${src}) `, ctx.block(() => [ ... converterFor(ctx, M.anonymousSimplePattern(setPattern), v, vv => @@ -150,7 +150,7 @@ function converterFor( const v = ctx.gentempname(); const k = ctx.gentempname(); return [ - seq(`if (_.Dictionary.isDictionary<_ptr>(${src})) `, ctx.block(() => [ + seq(`if (_.Dictionary.isDictionary<_embedded>(${src})) `, ctx.block(() => [ seq(`${r} = new _.KeyedDictionary()`), seq(`for (const [${k}, ${v}] of ${src}) `, ctx.block(() => [ ... converterFor(ctx, M.anonymousSimplePattern(keyPattern), k, kk => @@ -205,8 +205,8 @@ export function converterForSimple( ctx.mod.imports.add([modId, modPath]); return [`${dest} = ${modId}.to${p.value.name.description!}(${src})`]; }); - case 'pointer': - return [`${dest} = _.isPointer<_ptr>(${src}) ? ${src}.embeddedValue : void 0`]; + case 'embedded': + return [`${dest} = _.isEmbedded<_embedded>(${src}) ? ${src}.embeddedValue : void 0`]; default: ((_p: never) => {})(p); throw new Error("Unreachable"); @@ -222,7 +222,7 @@ function converterForCompound( { switch (p._variant) { case 'rec': - return [seq(`if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(${src})) `, ctx.block(() => + return [seq(`if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(${src})) `, ctx.block(() => converterFor(ctx, p.label, `${src}.label`, () => converterFor(ctx, p.fields, src, ks, true))))]; case 'tuple': @@ -249,7 +249,7 @@ function converterForCompound( return ks(); } } - return [seq(`if (_.Dictionary.isDictionary<_ptr>(${src})) `, ctx.block(() => loop(0)))]; + return [seq(`if (_.Dictionary.isDictionary<_embedded>(${src})) `, ctx.block(() => loop(0)))]; } default: ((_p: never) => {})(p); diff --git a/implementations/javascript/packages/schema/src/compiler/gentype.ts b/implementations/javascript/packages/schema/src/compiler/gentype.ts index e32b262..a9abe6c 100644 --- a/implementations/javascript/packages/schema/src/compiler/gentype.ts +++ b/implementations/javascript/packages/schema/src/compiler/gentype.ts @@ -72,8 +72,8 @@ export function simpleType(mod: ModuleContext, p: M.SimplePattern): AtomicType { case 'ByteString': return Type.ref(`_.Bytes`); case 'Symbol': return Type.ref(`symbol`); } - case 'pointer': - return Type.ref(`_ptr`); + case 'embedded': + return Type.ref(`_embedded`); case 'lit': return Type.unit(); case 'Ref': diff --git a/implementations/javascript/packages/schema/src/compiler/genunconverter.ts b/implementations/javascript/packages/schema/src/compiler/genunconverter.ts index 7585a83..ca39e14 100644 --- a/implementations/javascript/packages/schema/src/compiler/genunconverter.ts +++ b/implementations/javascript/packages/schema/src/compiler/genunconverter.ts @@ -103,8 +103,8 @@ function unconverterFor(ctx: FunctionContext, p: M.Pattern, src: string, t: Simp } case 'lit': return ctx.mod.literal(p.value); - case 'pointer': - return `_.embed(${src})`; + case 'embedded': + return `_.embedded(${src})`; case 'Ref': return M.lookup( refPosition(p.value), p.value, ctx.mod.env, @@ -167,7 +167,7 @@ function unconverterFor(ctx: FunctionContext, p: M.Pattern, src: string, t: Simp throw new InsufficientInformationError( `C Cannot produce unconverter TODO ${src} ${formatItems([renderType(t)])}`); } - return seq(`new _.Set<_ptr>`, parens( + return seq(`new _.Set<_embedded>`, parens( `_.Array.from(${src}.values()).map(v => `, unconverterFor(ctx, M.Pattern.SimplePattern(p.pattern), 'v', t), `)`)); @@ -176,14 +176,14 @@ function unconverterFor(ctx: FunctionContext, p: M.Pattern, src: string, t: Simp throw new InsufficientInformationError( `D Cannot produce unconverter TODO ${src} ${formatItems([renderType(t)])}`); } - return seq(`new _.Dictionary<_ptr>`, parens(seq( + return seq(`new _.Dictionary<_embedded>`, parens(seq( `_.Array.from(${src}.entries()).map(([k, v]) => `, brackets( unconverterFor(ctx, M.Pattern.SimplePattern(p.key), 'k', t), unconverterFor(ctx, M.Pattern.SimplePattern(p.value), 'v', t)), `)`))); case 'dict': - return seq(`new _.Dictionary<_ptr>`, parens( + return seq(`new _.Dictionary<_embedded>`, parens( brackets(... Array.from(p.entries.entries()).map(([k, n]) => brackets( ctx.mod.literal(k), diff --git a/implementations/javascript/packages/schema/src/compiler/type.ts b/implementations/javascript/packages/schema/src/compiler/type.ts index 286c5c8..1a38ef8 100644 --- a/implementations/javascript/packages/schema/src/compiler/type.ts +++ b/implementations/javascript/packages/schema/src/compiler/type.ts @@ -74,11 +74,11 @@ export function renderType(t: Type): Item { case 'ref': return t.typeName; case 'set': return seq('_.KeyedSet', anglebrackets( renderType(t.type), - '_ptr')); + '_embedded')); case 'dictionary': return seq('_.KeyedDictionary', anglebrackets( renderType(t.key), renderType(t.value), - '_ptr')); + '_embedded')); case 'array': return seq('Array', anglebrackets(renderType(t.type))); case 'record': return braces(... Array.from(t.fields).map(([nn, tt]) => keyvalue(nn, renderType(tt)))); diff --git a/implementations/javascript/packages/schema/src/compiler/value.ts b/implementations/javascript/packages/schema/src/compiler/value.ts index c12e280..df28684 100644 --- a/implementations/javascript/packages/schema/src/compiler/value.ts +++ b/implementations/javascript/packages/schema/src/compiler/value.ts @@ -2,7 +2,7 @@ import { Annotated, Bytes, Set, Dictionary, Fold, fold, Record, Tuple, Value, st import { brackets, Item, parens, seq } from "./block"; import * as M from '../meta'; -export function sourceCodeFor(v: Value): Item { +export function sourceCodeFor(v: Value): Item { return fold(v, { boolean(b: boolean): Item { return b.toString(); }, single(f: number): Item { return f.toString(); }, @@ -14,26 +14,26 @@ export function sourceCodeFor(v: Value): Item { }, symbol(s: symbol): Item { return `Symbol.for(${JSON.stringify(s.description!)})`; }, - record(r: Record, Tuple>, M._ptr>, k: Fold): Item { - return seq(`_.Record<_val, _.Tuple<_val>, _ptr>`, parens(k(r.label), brackets(... r.map(k)))); + record(r: Record, Tuple>, M._embedded>, k: Fold): Item { + return seq(`_.Record<_val, _.Tuple<_val>, _embedded>`, parens(k(r.label), brackets(... r.map(k)))); }, - array(a: Array>, k: Fold): Item { + array(a: Array>, k: Fold): Item { return brackets(... a.map(k)); }, - set(s: Set, k: Fold): Item { + set(s: Set, k: Fold): Item { return seq('new _.Set<_val>', parens(brackets(... Array.from(s).map(k)))); }, - dictionary(d: Dictionary, k: Fold): Item { - return seq('new _.Dictionary<_ptr>', parens(brackets(... Array.from(d).map(([kk,vv]) => + dictionary(d: Dictionary, k: Fold): Item { + return seq('new _.Dictionary<_embedded>', parens(brackets(... Array.from(d).map(([kk,vv]) => brackets(k(kk), k(vv)))))); }, - annotated(a: Annotated, k: Fold): Item { - return seq('_.annotate<_ptr>', parens(k(a.item), ... a.annotations.map(k))); + annotated(a: Annotated, k: Fold): Item { + return seq('_.annotate<_embedded>', parens(k(a.item), ... a.annotations.map(k))); }, - pointer(t: M._ptr, _k: Fold): Item { - throw new Error(`Cannot emit source code for construction of pointer ${stringify(t)}`); + embedded(t: M._embedded, _k: Fold): Item { + throw new Error(`Cannot emit source code for construction of embedded ${stringify(t)}`); }, }); } diff --git a/implementations/javascript/packages/schema/src/gen/schema.ts b/implementations/javascript/packages/schema/src/gen/schema.ts index d0caa59..bd9b96e 100644 --- a/implementations/javascript/packages/schema/src/gen/schema.ts +++ b/implementations/javascript/packages/schema/src/gen/schema.ts @@ -15,10 +15,11 @@ export const $bundle = Symbol.for("bundle"); export const $definitions = Symbol.for("definitions"); export const $dict = Symbol.for("dict"); export const $dictof = Symbol.for("dictof"); +export const $embedded = Symbol.for("embedded"); +export const $embeddedType = Symbol.for("embeddedType"); export const $lit = Symbol.for("lit"); export const $named = Symbol.for("named"); export const $or = Symbol.for("or"); -export const $pointer = Symbol.for("pointer"); export const $rec = Symbol.for("rec"); export const $ref = Symbol.for("ref"); export const $schema = Symbol.for("schema"); @@ -28,21 +29,25 @@ export const $tuple$STAR$ = Symbol.for("tuple*"); export const $version = Symbol.for("version"); export const __lit6 = false; -export type _ptr = any; +export type _embedded = any; -export type _val = _.Value<_ptr>; +export type _val = _.Value<_embedded>; export type Bundle = {"modules": Modules}; -export type Modules = _.KeyedDictionary; +export type Modules = _.KeyedDictionary; -export type Schema = {"version": Version, "pointer": PointerName, "definitions": Definitions}; +export type Schema = { + "version": Version, + "embeddedType": EmbeddedTypeName, + "definitions": Definitions +}; export type Version = null; -export type PointerName = ({"_variant": "Ref", "value": Ref} | {"_variant": "false"}); +export type EmbeddedTypeName = ({"_variant": "Ref", "value": Ref} | {"_variant": "false"}); -export type Definitions = _.KeyedDictionary; +export type Definitions = _.KeyedDictionary; export type Definition = ( { @@ -68,7 +73,7 @@ export type Pattern = ( export type SimplePattern = ( {"_variant": "any"} | {"_variant": "atom", "atomKind": AtomKind} | - {"_variant": "pointer"} | + {"_variant": "embedded"} | {"_variant": "lit", "value": _val} | {"_variant": "Ref", "value": Ref} ); @@ -86,7 +91,7 @@ export type CompoundPattern = ( {"_variant": "dict", "entries": DictionaryEntries} ); -export type DictionaryEntries = _.KeyedDictionary<_val, NamedSimplePattern, _ptr>; +export type DictionaryEntries = _.KeyedDictionary<_val, NamedSimplePattern, _embedded>; export type AtomKind = ( {"_variant": "Boolean"} | @@ -117,20 +122,22 @@ export type ModulePath = Array; export function Bundle(modules: Modules): Bundle {return {"modules": modules};} -export function Modules(value: _.KeyedDictionary): Modules {return value;} +export function Modules(value: _.KeyedDictionary): Modules {return value;} export function Schema( - {version, pointer, definitions}: {version: Version, pointer: PointerName, definitions: Definitions} -): Schema {return {"version": version, "pointer": pointer, "definitions": definitions};} + {version, embeddedType, definitions}: {version: Version, embeddedType: EmbeddedTypeName, definitions: Definitions} +): Schema { + return {"version": version, "embeddedType": embeddedType, "definitions": definitions}; +} export function Version(): Version {return null;} -export namespace PointerName { - export function Ref(value: Ref): PointerName {return {"_variant": "Ref", "value": value};}; - export function $false(): PointerName {return {"_variant": "false"};}; +export namespace EmbeddedTypeName { + export function Ref(value: Ref): EmbeddedTypeName {return {"_variant": "Ref", "value": value};}; + export function $false(): EmbeddedTypeName {return {"_variant": "false"};}; } -export function Definitions(value: _.KeyedDictionary): Definitions {return value;} +export function Definitions(value: _.KeyedDictionary): Definitions {return value;} export namespace Definition { export function or( @@ -154,7 +161,7 @@ export namespace Pattern { export namespace SimplePattern { export function any(): SimplePattern {return {"_variant": "any"};}; export function atom(atomKind: AtomKind): SimplePattern {return {"_variant": "atom", "atomKind": atomKind};}; - export function pointer(): SimplePattern {return {"_variant": "pointer"};}; + export function embedded(): SimplePattern {return {"_variant": "embedded"};}; export function lit(value: _val): SimplePattern {return {"_variant": "lit", "value": value};}; export function Ref(value: Ref): SimplePattern {return {"_variant": "Ref", "value": value};}; } @@ -168,7 +175,7 @@ export namespace CompoundPattern { 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, _embedded>): DictionaryEntries {return value;} export namespace AtomKind { export function Boolean(): AtomKind {return {"_variant": "Boolean"};}; @@ -204,7 +211,7 @@ export function asBundle(v: _val): Bundle { export function toBundle(v: _val): undefined | Bundle { let result: undefined | Bundle; - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp0: (null) | undefined; _tmp0 = _.is(v.label, $bundle) ? null : void 0; if (_tmp0 !== void 0) { @@ -225,9 +232,9 @@ export function asModules(v: _val): Modules { } export function toModules(v: _val): undefined | Modules { - let _tmp0: (_.KeyedDictionary) | undefined; + let _tmp0: (_.KeyedDictionary) | undefined; let result: undefined | Modules; - if (_.Dictionary.isDictionary<_ptr>(v)) { + if (_.Dictionary.isDictionary<_embedded>(v)) { _tmp0 = new _.KeyedDictionary(); for (const [_tmp2, _tmp1] of v) { let _tmp3: (ModulePath) | undefined; @@ -246,7 +253,7 @@ export function toModules(v: _val): undefined | Modules { } export function fromModules(_v: Modules): _val { - return new _.Dictionary<_ptr>(_.Array.from(_v.entries()).map(([k, v]) => [fromModulePath(k), fromSchema(v)])); + return new _.Dictionary<_embedded>(_.Array.from(_v.entries()).map(([k, v]) => [fromModulePath(k), fromSchema(v)])); } export function asSchema(v: _val): Schema { @@ -257,26 +264,26 @@ export function asSchema(v: _val): Schema { export function toSchema(v: _val): undefined | Schema { let result: undefined | Schema; - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp0: (null) | undefined; _tmp0 = _.is(v.label, $schema) ? null : void 0; if (_tmp0 !== void 0) { - if (_.Dictionary.isDictionary<_ptr>(v[0])) { + if (_.Dictionary.isDictionary<_embedded>(v[0])) { let _tmp1: (_val) | undefined; if ((_tmp1 = v[0].get($version)) !== void 0) { let _tmp2: (Version) | undefined; _tmp2 = toVersion(_tmp1); if (_tmp2 !== void 0) { let _tmp3: (_val) | undefined; - if ((_tmp3 = v[0].get($pointer)) !== void 0) { - let _tmp4: (PointerName) | undefined; - _tmp4 = toPointerName(_tmp3); + if ((_tmp3 = v[0].get($embeddedType)) !== void 0) { + let _tmp4: (EmbeddedTypeName) | undefined; + _tmp4 = toEmbeddedTypeName(_tmp3); if (_tmp4 !== void 0) { let _tmp5: (_val) | undefined; if ((_tmp5 = v[0].get($definitions)) !== void 0) { let _tmp6: (Definitions) | undefined; _tmp6 = toDefinitions(_tmp5); - if (_tmp6 !== void 0) {result = {"version": _tmp2, "pointer": _tmp4, "definitions": _tmp6};}; + if (_tmp6 !== void 0) {result = {"version": _tmp2, "embeddedType": _tmp4, "definitions": _tmp6};}; }; }; }; @@ -292,10 +299,10 @@ export function fromSchema(_v: Schema): _val { return _.Record( $schema, [ - new _.Dictionary<_ptr>( + new _.Dictionary<_embedded>( [ [$version, fromVersion(_v["version"])], - [$pointer, fromPointerName(_v["pointer"])], + [$embeddedType, fromEmbeddedTypeName(_v["embeddedType"])], [$definitions, fromDefinitions(_v["definitions"])] ] ) @@ -319,15 +326,15 @@ export function toVersion(v: _val): undefined | Version { export function fromVersion(_v: Version): _val {return $1;} -export function asPointerName(v: _val): PointerName { - let result = toPointerName(v); - if (result === void 0) throw new TypeError(`Invalid PointerName: ${_.stringify(v)}`); +export function asEmbeddedTypeName(v: _val): EmbeddedTypeName { + let result = toEmbeddedTypeName(v); + if (result === void 0) throw new TypeError(`Invalid EmbeddedTypeName: ${_.stringify(v)}`); return result; } -export function toPointerName(v: _val): undefined | PointerName { +export function toEmbeddedTypeName(v: _val): undefined | EmbeddedTypeName { let _tmp0: (Ref) | undefined; - let result: undefined | PointerName; + let result: undefined | EmbeddedTypeName; _tmp0 = toRef(v); if (_tmp0 !== void 0) {result = {"_variant": "Ref", "value": _tmp0};}; if (result === void 0) { @@ -338,7 +345,7 @@ export function toPointerName(v: _val): undefined | PointerName { return result; } -export function fromPointerName(_v: PointerName): _val { +export function fromEmbeddedTypeName(_v: EmbeddedTypeName): _val { switch (_v._variant) {case "Ref": {return fromRef(_v.value);}; case "false": {return __lit6;};}; } @@ -349,9 +356,9 @@ export function asDefinitions(v: _val): Definitions { } export function toDefinitions(v: _val): undefined | Definitions { - let _tmp0: (_.KeyedDictionary) | undefined; + let _tmp0: (_.KeyedDictionary) | undefined; let result: undefined | Definitions; - if (_.Dictionary.isDictionary<_ptr>(v)) { + if (_.Dictionary.isDictionary<_embedded>(v)) { _tmp0 = new _.KeyedDictionary(); for (const [_tmp2, _tmp1] of v) { let _tmp3: (symbol) | undefined; @@ -370,7 +377,7 @@ export function toDefinitions(v: _val): undefined | Definitions { } export function fromDefinitions(_v: Definitions): _val { - return new _.Dictionary<_ptr>(_.Array.from(_v.entries()).map(([k, v]) => [k, fromDefinition(v)])); + return new _.Dictionary<_embedded>(_.Array.from(_v.entries()).map(([k, v]) => [k, fromDefinition(v)])); } export function asDefinition(v: _val): Definition { @@ -381,7 +388,7 @@ export function asDefinition(v: _val): Definition { export function toDefinition(v: _val): undefined | Definition { let result: undefined | Definition; - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp0: (null) | undefined; _tmp0 = _.is(v.label, $or) ? null : void 0; if (_tmp0 !== void 0) { @@ -462,7 +469,7 @@ export function asAlternative(v: _val): Alternative { export function toAlternative(v: _val): undefined | Alternative { let result: undefined | Alternative; - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp0: (null) | undefined; _tmp0 = _.is(v.label, $and) ? null : void 0; if (_tmp0 !== void 0) { @@ -551,7 +558,7 @@ export function toSimplePattern(v: _val): undefined | SimplePattern { _tmp0 = _.is(v, $any) ? null : void 0; if (_tmp0 !== void 0) {result = {"_variant": "any"};}; if (result === void 0) { - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp1: (null) | undefined; _tmp1 = _.is(v.label, $atom) ? null : void 0; if (_tmp1 !== void 0) { @@ -561,13 +568,13 @@ export function toSimplePattern(v: _val): undefined | SimplePattern { }; }; if (result === void 0) { - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp3: (null) | undefined; - _tmp3 = _.is(v.label, $pointer) ? null : void 0; - if (_tmp3 !== void 0) {result = {"_variant": "pointer"};}; + _tmp3 = _.is(v.label, $embedded) ? null : void 0; + if (_tmp3 !== void 0) {result = {"_variant": "embedded"};}; }; if (result === void 0) { - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp4: (null) | undefined; _tmp4 = _.is(v.label, $lit) ? null : void 0; if (_tmp4 !== void 0) { @@ -591,7 +598,7 @@ export function fromSimplePattern(_v: SimplePattern): _val { switch (_v._variant) { case "any": {return $any;}; case "atom": {return _.Record($atom, [fromAtomKind(_v["atomKind"])]);}; - case "pointer": {return _.Record($pointer, []);}; + case "embedded": {return _.Record($embedded, []);}; case "lit": {return _.Record($lit, [_v["value"]]);}; case "Ref": {return fromRef(_v.value);}; }; @@ -605,7 +612,7 @@ export function asCompoundPattern(v: _val): CompoundPattern { export function toCompoundPattern(v: _val): undefined | CompoundPattern { let result: undefined | CompoundPattern; - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp0: (null) | undefined; _tmp0 = _.is(v.label, $rec) ? null : void 0; if (_tmp0 !== void 0) { @@ -619,7 +626,7 @@ export function toCompoundPattern(v: _val): undefined | CompoundPattern { }; }; if (result === void 0) { - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp3: (null) | undefined; _tmp3 = _.is(v.label, $tuple) ? null : void 0; if (_tmp3 !== void 0) { @@ -642,7 +649,7 @@ export function toCompoundPattern(v: _val): undefined | CompoundPattern { }; }; if (result === void 0) { - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp8: (null) | undefined; _tmp8 = _.is(v.label, $tuple$STAR$) ? null : void 0; if (_tmp8 !== void 0) { @@ -669,7 +676,7 @@ export function toCompoundPattern(v: _val): undefined | CompoundPattern { }; }; if (result === void 0) { - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp14: (null) | undefined; _tmp14 = _.is(v.label, $setof) ? null : void 0; if (_tmp14 !== void 0) { @@ -679,7 +686,7 @@ export function toCompoundPattern(v: _val): undefined | CompoundPattern { }; }; if (result === void 0) { - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp16: (null) | undefined; _tmp16 = _.is(v.label, $dictof) ? null : void 0; if (_tmp16 !== void 0) { @@ -693,7 +700,7 @@ export function toCompoundPattern(v: _val): undefined | CompoundPattern { }; }; if (result === void 0) { - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp19: (null) | undefined; _tmp19 = _.is(v.label, $dict) ? null : void 0; if (_tmp19 !== void 0) { @@ -740,9 +747,9 @@ export function asDictionaryEntries(v: _val): DictionaryEntries { } export function toDictionaryEntries(v: _val): undefined | DictionaryEntries { - let _tmp0: (_.KeyedDictionary<_val, NamedSimplePattern, _ptr>) | undefined; + let _tmp0: (_.KeyedDictionary<_val, NamedSimplePattern, _embedded>) | undefined; let result: undefined | DictionaryEntries; - if (_.Dictionary.isDictionary<_ptr>(v)) { + if (_.Dictionary.isDictionary<_embedded>(v)) { _tmp0 = new _.KeyedDictionary(); for (const [_tmp2, _tmp1] of v) { let _tmp3: (_val) | undefined; @@ -761,7 +768,7 @@ export function toDictionaryEntries(v: _val): undefined | DictionaryEntries { } export function fromDictionaryEntries(_v: DictionaryEntries): _val { - return new _.Dictionary<_ptr>(_.Array.from(_v.entries()).map(([k, v]) => [k, fromNamedSimplePattern(v)])); + return new _.Dictionary<_embedded>(_.Array.from(_v.entries()).map(([k, v]) => [k, fromNamedSimplePattern(v)])); } export function asAtomKind(v: _val): AtomKind { @@ -880,7 +887,7 @@ export function asNamedSimplePattern_(v: _val): NamedSimplePattern_ { export function toNamedSimplePattern_(v: _val): undefined | NamedSimplePattern_ { let result: undefined | NamedSimplePattern_; - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp0: (null) | undefined; _tmp0 = _.is(v.label, $named) ? null : void 0; if (_tmp0 !== void 0) { @@ -906,7 +913,7 @@ export function asRef(v: _val): Ref { export function toRef(v: _val): undefined | Ref { let result: undefined | Ref; - if (_.Record.isRecord<_val, _.Tuple<_val>, _ptr>(v)) { + if (_.Record.isRecord<_val, _.Tuple<_val>, _embedded>(v)) { let _tmp0: (null) | undefined; _tmp0 = _.is(v.label, $ref) ? null : void 0; if (_tmp0 !== void 0) { diff --git a/implementations/javascript/packages/schema/src/reader.ts b/implementations/javascript/packages/schema/src/reader.ts index e1d8be6..b35fb68 100644 --- a/implementations/javascript/packages/schema/src/reader.ts +++ b/implementations/javascript/packages/schema/src/reader.ts @@ -65,8 +65,8 @@ export function parseSchema(toplevelTokens: Array, options: ReaderOptions & SchemaReaderOptions): Schema { let version: M.Version | undefined = void 0; - let pointer: M.PointerName = M.PointerName.$false(); - let definitions = new KeyedDictionary(); + let embeddedType: M.EmbeddedTypeName = M.EmbeddedTypeName.$false(); + let definitions = new KeyedDictionary(); function process(toplevelTokens: Array): void { const toplevelClauses = splitBy(peel(toplevelTokens) as Array, M.DOT); @@ -86,15 +86,15 @@ export function parseSchema(toplevelTokens: Array, definitions.set(name, parseDefinition(name, pos, clause.slice(2))); } else if (clause.length === 2 && is(clause[0], M.$version)) { version = M.asVersion(peel(clause[1])); - } else if (clause.length === 2 && is(clause[0], M.$pointer)) { + } else if (clause.length === 2 && is(clause[0], M.$embeddedType)) { const pos = position(clause[1]); const stx = peel(clause[1]); if (stx === false) { - pointer = M.PointerName.$false(); + embeddedType = M.EmbeddedTypeName.$false(); } else if (typeof stx === 'symbol') { - pointer = M.PointerName.Ref(parseRef(stx.description!, pos)); + embeddedType = M.EmbeddedTypeName.Ref(parseRef(stx.description!, pos)); } else { - invalidPattern('pointer name specification', stx, pos); + invalidPattern('embedded type name specification', stx, pos); } } else if (clause.length === 2 && is(clause[0], M.INCLUDE)) { const pos = position(clause[1]); @@ -118,7 +118,7 @@ export function parseSchema(toplevelTokens: Array, throw new SchemaSyntaxError("Schema: missing version declaration.", null); } - return M.Schema({ version: M.Version(), pointer, definitions }); + return M.Schema({ version: M.Version(), embeddedType, definitions }); } function namedMustBeSimple(p: Position | null): never { @@ -218,14 +218,14 @@ function parsePattern(name: symbol, body0: Array): Pattern { case 'string': return ks(M.SimplePattern.atom(M.AtomKind.String())); case 'bytes': return ks(M.SimplePattern.atom(M.AtomKind.ByteString())); case 'symbol': return ks(M.SimplePattern.atom(M.AtomKind.Symbol())); - case 'ref': return ks(M.SimplePattern.pointer()); + case 'embedded': return ks(M.SimplePattern.embedded()); default: return ks((str[0] === '=') ? M.SimplePattern.lit(Symbol.for(str.slice(1))) : M.SimplePattern.Ref(parseRef(str, pos))); } - } else if (Record.isRecord, M._ptr>(item)) { + } else if (Record.isRecord, M._embedded>(item)) { const label = item.label; - if (Record.isRecord(label)) { + if (Record.isRecord(label)) { if (label.length !== 0) complain(); switch (label.label) { case M.$lit: @@ -290,9 +290,9 @@ function parsePattern(name: symbol, body0: Array): Pattern { } } - if (Record.isRecord, M._ptr>(item)) { + if (Record.isRecord, M._embedded>(item)) { const label = item.label; - if (Record.isRecord(label)) { + if (Record.isRecord(label)) { if (label.length !== 0) complain(); switch (label.label) { case M.$rec: @@ -312,7 +312,7 @@ function parsePattern(name: symbol, body0: Array): Pattern { } } else if (Array.isArray(item)) { return parseArrayLike(item); - } else if (Dictionary.isDictionary(item)) { + } else if (Dictionary.isDictionary(item)) { if (item.size === 2 && item.has(M.DOTDOTDOT)) { const v = item.clone(); v.delete(M.DOTDOTDOT); @@ -320,7 +320,7 @@ function parsePattern(name: symbol, body0: Array): Pattern { return M.CompoundPattern.dictof({ key: walkSimple(kp), value: walkSimple(vp) }); } else { return M.CompoundPattern.dict( - M.DictionaryEntries(item.mapEntries( + M.DictionaryEntries(item.mapEntries( ([k, vp]) => [ strip(k), _maybeNamed( diff --git a/implementations/python/preserves/preserves.py b/implementations/python/preserves/preserves.py index 7eaf2ba..65fa825 100644 --- a/implementations/python/preserves/preserves.py +++ b/implementations/python/preserves/preserves.py @@ -257,12 +257,12 @@ def annotate(v, *anns): return v class Decoder(Codec): - def __init__(self, packet=b'', include_annotations=False, decode_pointer=None): + def __init__(self, packet=b'', include_annotations=False, decode_embedded=None): super(Decoder, self).__init__() self.packet = packet self.index = 0 self.include_annotations = include_annotations - self.decode_pointer = decode_pointer + self.decode_embedded = decode_embedded def extend(self, data): self.packet = self.packet[self.index:] + data @@ -329,9 +329,9 @@ class Decoder(Codec): v = self.next() return self.unshift_annotation(a, v) if tag == 0x86: - if self.decode_pointer is None: - raise DecodeError('No decode_pointer function supplied') - return self.wrap(self.decode_pointer(self.next())) + if self.decode_embedded is None: + raise DecodeError('No decode_embedded function supplied') + return self.wrap(self.decode_embedded(self.next())) if tag >= 0x90 and tag <= 0x9f: return self.wrap(tag - (0xa0 if tag > 0x9c else 0x90)) if tag >= 0xa0 and tag <= 0xaf: return self.wrap(self.nextint(tag - 0xa0 + 1)) if tag == 0xb0: return self.wrap(self.nextint(self.varint())) @@ -362,10 +362,10 @@ def decode_with_annotations(bs, **kwargs): return Decoder(packet=bs, include_annotations=True, **kwargs).next() class Encoder(Codec): - def __init__(self, encode_pointer=id): + def __init__(self, encode_embedded=id): super(Encoder, self).__init__() self.buffer = bytearray() - self.encode_pointer = encode_pointer + self.encode_embedded = encode_embedded def contents(self): return bytes(self.buffer) @@ -435,7 +435,7 @@ class Encoder(Codec): i = iter(v) except TypeError: self.buffer.append(0x86) - self.append(self.encode_pointer(v)) + self.append(self.encode_embedded(v)) return self.encodevalues(5, i) diff --git a/implementations/python/preserves/test_preserves.py b/implementations/python/preserves/test_preserves.py index ec55392..593a543 100644 --- a/implementations/python/preserves/test_preserves.py +++ b/implementations/python/preserves/test_preserves.py @@ -157,7 +157,7 @@ class CodecTests(unittest.TestCase): self._roundtrip((False,) * 100, _buf(0xb5, b'\x80' * 100, 0x84)) self._roundtrip((False,) * 200, _buf(0xb5, b'\x80' * 200, 0x84)) - def test_pointer_id(self): + def test_embedded_id(self): class A: def __init__(self, a): self.a = a @@ -169,23 +169,23 @@ class CodecTests(unittest.TestCase): self.assertEqual(_ord(_e(a1)[0]), 0x86) self.assertEqual(_ord(_e(a2)[0]), 0x86) - def test_decode_pointer_absent(self): + def test_decode_embedded_absent(self): with self.assertRaises(DecodeError): decode(b'\x86\xa0\xff') - def test_encode_pointer(self): + def test_encode_embedded(self): objects = [] def enc(p): objects.append(p) return len(objects) - 1 - self.assertEqual(encode([object(), object()], encode_pointer = enc), + self.assertEqual(encode([object(), object()], encode_embedded = enc), b'\xb5\x86\x90\x86\x91\x84') - def test_decode_pointer(self): + def test_decode_embedded(self): objects = [123, 234] def dec(v): return objects[v] - self.assertEqual(decode(b'\xb5\x86\x90\x86\x91\x84', decode_pointer = dec), + self.assertEqual(decode(b'\xb5\x86\x90\x86\x91\x84', decode_embedded = dec), (123, 234)) def add_method(d, tName, fn): @@ -254,7 +254,7 @@ def install_exn_test(d, tName, bs, check_proc): self.fail('did not fail as expected') add_method(d, tName, test_exn) -class Pointer: +class Embedded: def __init__(self, v): self.v = strip_annotations(v) @@ -273,7 +273,7 @@ class CommonTestSuite(unittest.TestCase): import os with open(os.path.join(os.path.dirname(__file__), '../../../tests/samples.bin'), 'rb') as f: - samples = Decoder(f.read(), include_annotations=True, decode_pointer=Pointer).next() + samples = Decoder(f.read(), include_annotations=True, decode_embedded=Embedded).next() TestCases = Record.makeConstructor('TestCases', 'cases') @@ -303,13 +303,13 @@ class CommonTestSuite(unittest.TestCase): raise Exception('Unsupported test kind', t.key) def DS(self, bs): - return decode(bs, decode_pointer=Pointer) + return decode(bs, decode_embedded=Embedded) def D(self, bs): - return decode_with_annotations(bs, decode_pointer=Pointer) + return decode_with_annotations(bs, decode_embedded=Embedded) def E(self, v): - return encode(v, encode_pointer=Pointer.value) + return encode(v, encode_embedded=Embedded.value) class RecordTests(unittest.TestCase): def test_getters(self): diff --git a/implementations/python/setup.py b/implementations/python/setup.py index 10c5fa5..d8b4fe2 100644 --- a/implementations/python/setup.py +++ b/implementations/python/setup.py @@ -5,7 +5,7 @@ except ImportError: setup( name="preserves", - version="0.5.0", + version="0.6.0", author="Tony Garnock-Jones", author_email="tonyg@leastfixedpoint.com", license="Apache Software License", diff --git a/implementations/racket/preserves/Makefile b/implementations/racket/preserves/Makefile index 06a47a0..ced62d4 100644 --- a/implementations/racket/preserves/Makefile +++ b/implementations/racket/preserves/Makefile @@ -1,5 +1,5 @@ PACKAGENAME=preserves -COLLECTS=preserves +COLLECTS=preserves preserves-schema all: setup diff --git a/implementations/racket/preserves/preserves/jelly.rkt b/implementations/racket/preserves/preserves/jelly.rkt index 45d13b3..0895429 100644 --- a/implementations/racket/preserves/preserves/jelly.rkt +++ b/implementations/racket/preserves/preserves/jelly.rkt @@ -11,7 +11,7 @@ (struct record (label fields) #:transparent) (struct float (value) #:transparent) ;; a marker for single-precision I/O (struct annotated (annotations item) #:transparent) -(struct pointer (value) #:transparent) +(struct embedded (value) #:transparent) ;;--------------------------------------------------------------------------- ;; Reader @@ -30,7 +30,7 @@ (match (next) [(annotated as i) (annotated (cons a as) i)] [i (annotated (list a) i)]))] - [#x86 (pointer (next))] + [#x86 (embedded (next))] [(? (between #x90 #x9C) v) (- v #x90)] [(? (between #x9D #x9F) v) (- v #xA0)] [(? (between #xA0 #xAF) v) (next-integer (- v #xA0 -1))] @@ -87,7 +87,7 @@ (for [(a (in-list as))] (write-byte #x85 out-port) (output a)) (output v)] - [(pointer v) (write-byte #x86 out-port) (output v)] + [(embedded v) (write-byte #x86 out-port) (output v)] [(? integer?) (cond [(<= -3 v -1) (write-byte (+ v #xA0) out-port)] diff --git a/implementations/racket/preserves/preserves/main.rkt b/implementations/racket/preserves/preserves/main.rkt index ef03b91..ae92210 100644 --- a/implementations/racket/preserves/preserves/main.rkt +++ b/implementations/racket/preserves/preserves/main.rkt @@ -25,14 +25,14 @@ (define (read-preserve [in-port (current-input-port)] #:read-syntax? [read-syntax? #f] - #:decode-pointer [decode-pointer #f] + #:decode-embedded [decode-embedded #f] #:source [source (object-name in-port)]) (define b (peek-byte in-port)) (cond [(eof-object? b) b] [(<= #x80 b #xBF) (read-preserve/binary in-port #:read-syntax? read-syntax? - #:decode-pointer decode-pointer)] + #:decode-embedded decode-embedded)] [else (read-preserve/text in-port #:read-syntax? read-syntax? - #:decode-pointer decode-pointer + #:decode-embedded decode-embedded #:source source)])) diff --git a/implementations/racket/preserves/preserves/read-binary.rkt b/implementations/racket/preserves/preserves/read-binary.rkt index 47334a0..d2fc3ee 100644 --- a/implementations/racket/preserves/preserves/read-binary.rkt +++ b/implementations/racket/preserves/preserves/read-binary.rkt @@ -13,12 +13,12 @@ (define (default-on-short) (error 'read-preserve/binary "Short Preserves binary")) (define (default-on-fail message . args) (error 'read-preserve/binary (apply format message args))) -(define (default-decode-pointer v) - (error 'read-preserve/binary "No decode-pointer function supplied")) +(define (default-decode-embedded v) + (error 'read-preserve/binary "No decode-embedded function supplied")) (define (bytes->preserve bs #:read-syntax? [read-syntax? #f] - #:decode-pointer [decode-pointer #f] + #:decode-embedded [decode-embedded #f] #:on-short [on-short default-on-short] [on-fail default-on-fail]) (call-with-input-bytes @@ -26,7 +26,7 @@ (lambda (p) (match (read-preserve/binary p #:read-syntax? read-syntax? - #:decode-pointer decode-pointer + #:decode-embedded decode-embedded #:on-short on-short on-fail) [(? eof-object?) (on-short)] @@ -36,11 +36,11 @@ (define (read-preserve/binary [in-port (current-input-port)] #:read-syntax? [read-syntax? #f] - #:decode-pointer [decode-pointer0 #f] + #:decode-embedded [decode-embedded0 #f] #:on-short [on-short default-on-short] [on-fail default-on-fail]) (define read-annotations? read-syntax?) - (define decode-pointer (or decode-pointer0 default-decode-pointer)) + (define decode-embedded (or decode-embedded0 default-decode-embedded)) (let/ec return (define (next) (wrap (pos) (next* (next-byte)))) @@ -76,7 +76,7 @@ (if read-annotations? (annotate (next) a) (next)))] - [#x86 (decode-pointer (next))] + [#x86 (decode-embedded (next))] [(? (between #x90 #x9C) v) (- v #x90)] [(? (between #x9D #x9F) v) (- v #xA0)] [(? (between #xA0 #xAF) v) (next-integer (- v #xA0 -1))] diff --git a/implementations/racket/preserves/preserves/read-text.rkt b/implementations/racket/preserves/preserves/read-text.rkt index 2f59682..c272210 100644 --- a/implementations/racket/preserves/preserves/read-text.rkt +++ b/implementations/racket/preserves/preserves/read-text.rkt @@ -24,18 +24,18 @@ pos #f)) -(define (default-decode-pointer v) - (error 'read-preserve/text "No decode-pointer function supplied")) +(define (default-decode-embedded v) + (error 'read-preserve/text "No decode-embedded function supplied")) (define (string->preserve s #:read-syntax? [read-syntax? #f] - #:decode-pointer [decode-pointer #f] + #:decode-embedded [decode-embedded #f] #:source [source ""]) (define p (open-input-string s)) (when read-syntax? (port-count-lines! p)) (define v (read-preserve/text p #:read-syntax? read-syntax? - #:decode-pointer decode-pointer + #:decode-embedded decode-embedded #:source source)) (when (eof-object? v) (parse-error* #:raise-proc raise-read-eof-error p source "Unexpected end of input")) @@ -53,10 +53,10 @@ (define (read-preserve/text [in-port (current-input-port)] #:read-syntax? [read-syntax? #f] - #:decode-pointer [decode-pointer0 #f] + #:decode-embedded [decode-embedded0 #f] #:source [source (object-name in-port)]) (define read-annotations? read-syntax?) - (define decode-pointer (or decode-pointer0 default-decode-pointer)) + (define decode-embedded (or decode-embedded0 default-decode-embedded)) ;;--------------------------------------------------------------------------- ;; Core of parser @@ -96,7 +96,7 @@ (apply parse-error (string-append "Embedded binary value: " message) args)) #:read-syntax? read-syntax? #:on-short (lambda () (parse-error "Incomplete embedded binary value")))] - [#\! (decode-pointer (next))] + [#\! (decode-embedded (next))] [c (parse-error "Invalid # syntax: ~v" c)])] [#\< (match (read-sequence #\>) diff --git a/implementations/racket/preserves/preserves/tests/test-main.rkt b/implementations/racket/preserves/preserves/tests/test-main.rkt index 2117208..d696c9f 100644 --- a/implementations/racket/preserves/preserves/tests/test-main.rkt +++ b/implementations/racket/preserves/preserves/tests/test-main.rkt @@ -9,22 +9,22 @@ (require racket/runtime-path) (require syntax/srcloc) -(struct pointer (value) #:transparent) +(struct embedded (value) #:transparent) -(define (pointer/no-annotations v) - (pointer (strip-annotations v))) +(define (embedded/no-annotations v) + (embedded (strip-annotations v))) (define (d bs #:allow-invalid-prefix? [allow-invalid-prefix? #f]) (for [(i (in-range 1 (- (bytes-length bs) 1)))] (define result (bytes->preserve (subbytes bs 0 i) - #:decode-pointer pointer/no-annotations + #:decode-embedded embedded/no-annotations #:on-short (lambda () 'short) void)) (when (and (not (eq? result 'short)) (not (and allow-invalid-prefix? (void? result)))) (error 'd "~a-byte prefix of ~v does not read as short; result: ~v" i bs result))) (bytes->preserve bs #:read-syntax? #t - #:decode-pointer pointer/no-annotations + #:decode-embedded embedded/no-annotations #:on-short (lambda () 'short) void)) @@ -134,28 +134,28 @@ [(asymmetric f b) (values f b #f)] ;; #f because e.g. annotation4 includes annotations [v (values v v #t)])) (check-equal? text-form back loc) ;; expectation 1 - (check-equal? (d-strip (preserve->bytes #:encode-pointer pointer-value text-form)) + (check-equal? (d-strip (preserve->bytes #:encode-embedded embedded-value text-form)) back loc) ;; expectation 2 - (check-equal? (d-strip (preserve->bytes #:encode-pointer pointer-value forward)) + (check-equal? (d-strip (preserve->bytes #:encode-embedded embedded-value forward)) back loc) ;; expectation 3 (check-equal? (d-strip binary-form) back loc) ;; expectation 4 (check-equal? (d binary-form) annotated-text-form loc) ;; expectation 5 - (check-equal? (d (preserve->bytes #:encode-pointer pointer-value annotated-text-form)) + (check-equal? (d (preserve->bytes #:encode-embedded embedded-value annotated-text-form)) annotated-text-form loc) ;; expectation 6 - (check-equal? (string->preserve #:decode-pointer pointer/no-annotations - (preserve->string #:encode-pointer pointer-value text-form)) + (check-equal? (string->preserve #:decode-embedded embedded/no-annotations + (preserve->string #:encode-embedded embedded-value text-form)) back loc) ;; expectation 7 - (check-equal? (string->preserve #:decode-pointer pointer/no-annotations - (preserve->string #:encode-pointer pointer-value forward)) + (check-equal? (string->preserve #:decode-embedded embedded/no-annotations + (preserve->string #:encode-embedded embedded-value forward)) back loc) ;; expectation 8 ;; similar to 8: - (check-equal? (string->preserve #:decode-pointer pointer/no-annotations - (preserve->string #:encode-pointer pointer-value + (check-equal? (string->preserve #:decode-embedded embedded/no-annotations + (preserve->string #:encode-embedded embedded-value annotated-text-form) #:read-syntax? #t) annotated-text-form @@ -165,7 +165,7 @@ (and can-execute-nondet-with-canonicalization?))) ;; expectations 9 and 10 (check-equal? (preserve->bytes forward - #:encode-pointer pointer-value + #:encode-embedded embedded-value #:canonicalizing? #t #:write-annotations? #t) binary-form @@ -173,19 +173,19 @@ (unless (memq variety '(decode nondeterministic)) ;; expectation 11 (check-equal? (preserve->bytes annotated-text-form - #:encode-pointer pointer-value + #:encode-embedded embedded-value #:write-annotations? #t) binary-form loc))) (define-runtime-path tests-path "../../../../../tests") -(let* ((path (build-path tests-path "samples.txt")) +(let* ((path (build-path tests-path "samples.pr")) (testfile (call-with-input-file path (lambda (p) (port-count-lines! p) (read-preserve p #:read-syntax? #t - #:decode-pointer pointer/no-annotations + #:decode-embedded embedded/no-annotations #:source path))))) (match-define (peel-annotations `#s(TestCases ,tests)) testfile) (for [((t-name* t*) (in-hash (annotated-item tests)))] diff --git a/implementations/racket/preserves/preserves/tool.rkt b/implementations/racket/preserves/preserves/tool.rkt index 0701b47..3f751d4 100644 --- a/implementations/racket/preserves/preserves/tool.rkt +++ b/implementations/racket/preserves/preserves/tool.rkt @@ -43,21 +43,21 @@ ["--no-annotations" "Strip annotations" (set! annotations? #f)]) - (struct pointer (value) #:transparent) + (struct embedded (value) #:transparent) (let loop ((count count)) (when (positive? count) (define v ((if annotations? values strip-annotations) (match input-format - ['any (read-preserve #:read-syntax? #t #:decode-pointer pointer #:source "")] - ['text (read-preserve/text #:read-syntax? #t #:decode-pointer pointer #:source "")] - ['binary (read-preserve/binary #:decode-pointer pointer #:read-syntax? #t)]))) + ['any (read-preserve #:read-syntax? #t #:decode-embedded embedded #:source "")] + ['text (read-preserve/text #:read-syntax? #t #:decode-embedded embedded #:source "")] + ['binary (read-preserve/binary #:decode-embedded embedded #:read-syntax? #t)]))) (when (not (eof-object? v)) (void (match output-format ['text - (write-preserve/text v #:indent indent? #:encode-pointer pointer-value) + (write-preserve/text v #:indent indent? #:encode-embedded embedded-value) (newline)] ['binary - (write-preserve/binary v #:encode-pointer pointer-value #:write-annotations? #t)])) + (write-preserve/binary v #:encode-embedded embedded-value #:write-annotations? #t)])) (flush-output) (loop (- count 1)))))) diff --git a/implementations/racket/preserves/preserves/write-binary.rkt b/implementations/racket/preserves/preserves/write-binary.rkt index cf128c0..0351cb8 100644 --- a/implementations/racket/preserves/preserves/write-binary.rkt +++ b/implementations/racket/preserves/preserves/write-binary.rkt @@ -16,19 +16,19 @@ (define (preserve->bytes v #:canonicalizing? [canonicalizing? #t] - #:encode-pointer [encode-pointer #f] + #:encode-embedded [encode-embedded #f] #:write-annotations? [write-annotations? (not canonicalizing?)]) (call-with-output-bytes (lambda (p) (write-preserve/binary v p #:canonicalizing? canonicalizing? - #:encode-pointer encode-pointer + #:encode-embedded encode-embedded #:write-annotations? write-annotations?)))) (define (write-preserve/binary v [out-port (current-output-port)] #:canonicalizing? [canonicalizing? #t] - #:encode-pointer [encode-pointer0 #f] + #:encode-embedded [encode-embedded0 #f] #:write-annotations? [write-annotations? (not canonicalizing?)]) - (define encode-pointer (or encode-pointer0 object-id)) + (define encode-embedded (or encode-embedded0 object-id)) (define (output-byte b) (write-byte b out-port)) @@ -122,6 +122,6 @@ [other (output-byte #x86) - (output (encode-pointer other))])) + (output (encode-embedded other))])) (output v)) diff --git a/implementations/racket/preserves/preserves/write-text.rkt b/implementations/racket/preserves/preserves/write-text.rkt index d7f94f3..cbafc10 100644 --- a/implementations/racket/preserves/preserves/write-text.rkt +++ b/implementations/racket/preserves/preserves/write-text.rkt @@ -25,9 +25,9 @@ (define (write-preserve/text v0 [o (current-output-port)] #:indent [indent-amount0 #f] - #:encode-pointer [encode-pointer0 #f] + #:encode-embedded [encode-embedded0 #f] #:write-annotations? [write-annotations? #t]) - (define encode-pointer (or encode-pointer0 object-id)) + (define encode-embedded (or encode-embedded0 object-id)) (define indent-amount (match indent-amount0 [#f 0] [#t 2] ;; a default @@ -169,16 +169,16 @@ [(? dict?) (write-sequence distance "{" "," "}" write-key-value (dict->list v))] [other (! "#!") - (write-value distance (encode-pointer other))])) + (write-value distance (encode-embedded other))])) (write-value 0 v0)) (define (preserve->string v0 #:indent [indent-amount #f] - #:encode-pointer [encode-pointer #f] + #:encode-embedded [encode-embedded #f] #:write-annotations? [write-annotations? #t]) (with-output-to-string (lambda () (write-preserve/text v0 #:indent indent-amount - #:encode-pointer encode-pointer + #:encode-embedded encode-embedded #:write-annotations? write-annotations?)))) diff --git a/implementations/rust/preserves/Cargo.toml b/implementations/rust/preserves/Cargo.toml index 53053fa..5e0ccd9 100644 --- a/implementations/rust/preserves/Cargo.toml +++ b/implementations/rust/preserves/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "preserves" -version = "0.12.0" +version = "0.13.0" authors = ["Tony Garnock-Jones "] edition = "2018" description = "Implementation of the Preserves serialization format via serde." diff --git a/implementations/rust/preserves/src/error.rs b/implementations/rust/preserves/src/error.rs index 2648f92..0a1a3dc 100644 --- a/implementations/rust/preserves/src/error.rs +++ b/implementations/rust/preserves/src/error.rs @@ -41,7 +41,7 @@ pub enum ExpectedKind { Set, Dictionary, - Pointer, + Embedded, SequenceOrSet, // Because of hacking up serde's data model: see open_sequence_or_set etc. diff --git a/implementations/rust/preserves/src/value/packed/constants.rs b/implementations/rust/preserves/src/value/packed/constants.rs index 716cb8f..22c9313 100644 --- a/implementations/rust/preserves/src/value/packed/constants.rs +++ b/implementations/rust/preserves/src/value/packed/constants.rs @@ -8,7 +8,7 @@ pub enum Tag { Double, End, Annotation, - Pointer, + Embedded, SmallInteger(i8), MediumInteger(u8), SignedInteger, @@ -47,7 +47,7 @@ impl TryFrom for Tag { 0x83 => Ok(Self::Double), 0x84 => Ok(Self::End), 0x85 => Ok(Self::Annotation), - 0x86 => Ok(Self::Pointer), + 0x86 => Ok(Self::Embedded), 0x90..=0x9c => Ok(Self::SmallInteger((v - 0x90) as i8)), 0x9d..=0x9f => Ok(Self::SmallInteger((v - 0x90) as i8 - 16)), 0xa0..=0xaf => Ok(Self::MediumInteger(v - 0xa0 + 1)), @@ -73,7 +73,7 @@ impl From for u8 { Tag::Double => 0x83, Tag::End => 0x84, Tag::Annotation => 0x85, - Tag::Pointer => 0x86, + Tag::Embedded => 0x86, Tag::SmallInteger(v) => if v < 0 { (v + 16) as u8 + 0x90 } else { v as u8 + 0x90 }, Tag::MediumInteger(count) => count - 1 + 0xa0, Tag::SignedInteger => 0xb0, diff --git a/implementations/rust/preserves/src/value/packed/reader.rs b/implementations/rust/preserves/src/value/packed/reader.rs index ac4b774..3c811df 100644 --- a/implementations/rust/preserves/src/value/packed/reader.rs +++ b/implementations/rust/preserves/src/value/packed/reader.rs @@ -262,7 +262,7 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { self.demand_next(read_annotations)? } } - Tag::Pointer => { + Tag::Embedded => { let v = self.demand_next(read_annotations)?; Value::Domain(IOValue::from_preserves(v)).wrap() } @@ -362,11 +362,11 @@ impl<'de, S: BinarySource<'de>> Reader<'de> for PackedReader<'de, S> { Ok(self.peekend()?) } - fn open_pointer(&mut self) -> ReaderResult<()> { - self.next_compound(Tag::Pointer, ExpectedKind::Pointer) + fn open_embedded(&mut self) -> ReaderResult<()> { + self.next_compound(Tag::Embedded, ExpectedKind::Embedded) } - fn close_pointer(&mut self) -> ReaderResult<()> { + fn close_embedded(&mut self) -> ReaderResult<()> { Ok(()) } diff --git a/implementations/rust/preserves/src/value/packed/writer.rs b/implementations/rust/preserves/src/value/packed/writer.rs index 0296dac..efe168b 100644 --- a/implementations/rust/preserves/src/value/packed/writer.rs +++ b/implementations/rust/preserves/src/value/packed/writer.rs @@ -214,7 +214,7 @@ impl Writer for BinaryOrderWriter { type AnnWriter = PackedWriter>; type SeqWriter = PackedWriter>; type SetWriter = BinaryOrderWriter; - type PointerWriter = PackedWriter>; + type EmbeddedWriter = PackedWriter>; binary_order_writer_method!(mut align(natural_chunksize: u64) -> Result<()>); @@ -272,11 +272,11 @@ impl Writer for BinaryOrderWriter { set.finish(self) } - fn start_pointer(&mut self) -> Result { - self.write_tag(Tag::Pointer)?; + fn start_embedded(&mut self) -> Result { + self.write_tag(Tag::Embedded)?; Ok(self.pop()) } - fn end_pointer(&mut self, ptr: Self::PointerWriter) -> Result<()> { + fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> Result<()> { self.push(ptr); Ok(()) } @@ -294,7 +294,7 @@ impl Writer for PackedWriter type AnnWriter = Self; type SeqWriter = Self; type SetWriter = BinaryOrderWriter; - type PointerWriter = Self; + type EmbeddedWriter = Self; fn start_annotations(&mut self) -> Result { Ok(self.suspend()) @@ -489,12 +489,12 @@ impl Writer for PackedWriter set.finish(self) } - fn start_pointer(&mut self) -> Result { - self.write_tag(Tag::Pointer)?; + fn start_embedded(&mut self) -> Result { + self.write_tag(Tag::Embedded)?; Ok(self.suspend()) } - fn end_pointer(&mut self, ann: Self::PointerWriter) -> Result<()> { + fn end_embedded(&mut self, ann: Self::EmbeddedWriter) -> Result<()> { self.resume(ann); Ok(()) } diff --git a/implementations/rust/preserves/src/value/reader.rs b/implementations/rust/preserves/src/value/reader.rs index 4c2c4d3..decff35 100644 --- a/implementations/rust/preserves/src/value/reader.rs +++ b/implementations/rust/preserves/src/value/reader.rs @@ -15,8 +15,8 @@ pub trait Reader<'de> { fn open_set(&mut self) -> ReaderResult<()>; fn open_dictionary(&mut self) -> ReaderResult<()>; fn close_compound(&mut self) -> ReaderResult; - fn open_pointer(&mut self) -> ReaderResult<()>; - fn close_pointer(&mut self) -> ReaderResult<()>; + fn open_embedded(&mut self) -> ReaderResult<()>; + fn close_embedded(&mut self) -> ReaderResult<()>; //--------------------------------------------------------------------------- @@ -145,12 +145,12 @@ impl<'r, 'de, R: Reader<'de>> Reader<'de> for &'r mut R { (*self).close_compound() } - fn open_pointer(&mut self) -> ReaderResult<()> { - (*self).open_pointer() + fn open_embedded(&mut self) -> ReaderResult<()> { + (*self).open_embedded() } - fn close_pointer(&mut self) -> ReaderResult<()> { - (*self).close_pointer() + fn close_embedded(&mut self) -> ReaderResult<()> { + (*self).close_embedded() } } diff --git a/implementations/rust/preserves/src/value/writer.rs b/implementations/rust/preserves/src/value/writer.rs index 528cb62..fdce3dc 100644 --- a/implementations/rust/preserves/src/value/writer.rs +++ b/implementations/rust/preserves/src/value/writer.rs @@ -19,7 +19,7 @@ pub trait Writer: Sized { type AnnWriter: AnnotationWriter; type SeqWriter: CompoundWriter; type SetWriter: CompoundWriter; - type PointerWriter: Writer; + type EmbeddedWriter: Writer; fn align(&mut self, natural_chunksize: u64) -> Result<()>; @@ -55,8 +55,8 @@ pub trait Writer: Sized { fn start_dictionary(&mut self, entry_count: Option) -> Result; fn end_set(&mut self, set: Self::SetWriter) -> Result<()>; - fn start_pointer(&mut self) -> Result; - fn end_pointer(&mut self, ptr: Self::PointerWriter) -> Result<()>; + fn start_embedded(&mut self) -> Result; + fn end_embedded(&mut self, ptr: Self::EmbeddedWriter) -> Result<()>; //--------------------------------------------------------------------------- @@ -133,9 +133,9 @@ pub trait Writer: Sized { self.end_set(c) } Value::Domain(ref d) => { - let mut c = self.start_pointer()?; + let mut c = self.start_embedded()?; c.write(&d.as_preserves())?; - self.end_pointer(c) + self.end_embedded(c) } } } diff --git a/implementations/rust/preserves/tests/samples_tests.rs b/implementations/rust/preserves/tests/samples_tests.rs index 5d64399..06b77ee 100644 --- a/implementations/rust/preserves/tests/samples_tests.rs +++ b/implementations/rust/preserves/tests/samples_tests.rs @@ -29,7 +29,7 @@ fn decode_all(bytes: &'_ [u8]) -> Result, std::io::Error> { assert_eq!(&PackedWriter::encode(val)?, bin); } TestCase::NondeterministicTest(ref bin, ref val) => { - // The test cases in samples.txt are carefully written + // The test cases in samples.pr are carefully written // so that while strictly "nondeterministic", the // order of keys in encoded dictionaries follows // Preserves canonical order. diff --git a/preserves.md b/preserves.md index dca86c6..30ebf7a 100644 --- a/preserves.md +++ b/preserves.md @@ -4,7 +4,7 @@ title: "Preserves: an Expressive Data Language" --- Tony Garnock-Jones -Jan 2021. Version 0.5.0. +May 2021. Version 0.6.0. [sexp.txt]: http://people.csail.mit.edu/rivest/Sexp.txt [spki]: http://world.std.com/~cme/html/spki.html @@ -36,12 +36,12 @@ definition of the *values* that we want to work with and give them meaning independent of their syntax. Our `Value`s fall into two broad categories: *atomic* and *compound* -data. Every `Value` is finite and non-cyclic. References, called -`Pointer`s, are a third, special-case category. +data. Every `Value` is finite and non-cyclic. Embedded values, called +`Embedded`s, are a third, special-case category. Value = Atom | Compound - | Pointer + | Embedded Atom = Boolean | Float @@ -63,7 +63,7 @@ values of different kinds is essentially arbitrary, but having a total order is convenient for many tasks, so we define it as follows: - (Values) Atom < Compound < Pointer + (Values) Atom < Compound < Embedded (Compounds) Record < Sequence < Set < Dictionary @@ -160,43 +160,43 @@ pairwise distinct. Instances of `Dictionary` are compared by lexicographic comparison of the sequences resulting from ordering each `Dictionary`'s pairs in ascending order by key. -### Pointers. +### Embeddeds. -A `Pointer` embeds *domain-specific*, potentially *stateful* or -*located* data into a `Value`.[^pointer-rationale] `Pointer`s may be -used to denote stateful objects, network services, object -capabilities, file descriptors, Unix processes, or other -possibly-stateful things. Because each `Pointer` is a domain-specific -datum, comparison of two `Pointer`s is done according to +An `Embedded` allows inclusion of *domain-specific*, potentially +*stateful* or *located* data into a `Value`.[^embedded-rationale] +`Embedded`s may be used to denote stateful objects, network services, +object capabilities, file descriptors, Unix processes, or other +possibly-stateful things. Because each `Embedded` is a domain-specific +datum, comparison of two `Embedded`s is done according to domain-specific rules. - [^pointer-rationale]: **Rationale.** Why include `Pointer`s as a + [^embedded-rationale]: **Rationale.** Why include `Embedded`s as a special class, distinct from, say, a specially-labeled `Record`? First, a `Record` can only hold other `Value`s: in order to embed values such as live pointers to Java objects, some means of "escaping" from the `Value` data type must be provided. Second, - `Pointer`s are meant to be able to denote stateful entities, for + `Embedded`s are meant to be able to denote stateful entities, for which comparison by address is appropriate; however, we do not wish to place restrictions on the *nature* of these entities: if - we had used `Record`s instead of distinct `Pointer`s, users would + we had used `Record`s instead of distinct `Embedded`s, users would have to invent an encoding of domain data into `Record`s that reflected domain ordering into `Value` ordering. This is often difficult and may not always be possible. Finally, because - `Pointer`s are intended to be able to represent network and memory - *locations*, they must be able to be rewritten at network and - process boundaries. Having a distinct class allows generic - `Pointer` rewriting without the quotation-related complications of - encoding references as, say, `Record`s. + `Embedded`s are intended to be able to represent network and + memory *locations*, they must be able to be rewritten at network + and process boundaries. Having a distinct class allows generic + `Embedded` rewriting without the quotation-related complications + of encoding references as, say, `Record`s. -*Examples.* In a Java or Python implementation, a `Pointer` may denote -a reference to a Java or Python object; comparison would be done via -the language's own rules for equivalence and ordering. In a Unix -application, a `Pointer` may denote an open file descriptor or a -process ID. In an HTTP-based application, each `Pointer` might be a +*Examples.* In a Java or Python implementation, an `Embedded` may +denote a reference to a Java or Python object; comparison would be +done via the language's own rules for equivalence and ordering. In a +Unix application, an `Embedded` may denote an open file descriptor or +a process ID. In an HTTP-based application, each `Embedded` might be a URL, compared according to [RFC 6943](https://tools.ietf.org/html/rfc6943#section-3.3). When a -`Value` is serialized for storage or transfer, embedded `Pointer`s -will usually be represented as ordinary `Value`s, in which case the +`Value` is serialized for storage or transfer, `Embedded`s will +usually be represented as ordinary `Value`s, in which case the ordinary rules for comparing `Value`s will apply. ## Textual Syntax @@ -241,7 +241,7 @@ Standalone documents may have trailing whitespace. Any `Value` may be preceded by whitespace. - Value = ws (Record / Collection / Atom / Pointer / Compact) + Value = ws (Record / Collection / Atom / Embedded / Compact) Collection = Sequence / Dictionary / Set Atom = Boolean / Float / Double / SignedInteger / String / ByteString / Symbol @@ -401,10 +401,10 @@ double quote mark. definition of “token representation”, and with the [R6RS definition of identifiers](http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-7.html#node_sec_4.2.4). -A `Pointer` is written as a `Value` chosen to represent the denoted +An `Embedded` is written as a `Value` chosen to represent the denoted object, prefixed with `#!`. - Pointer = "#!" Value + Embedded = "#!" Value Finally, any `Value` may be represented by escaping from the textual syntax to the [compact binary syntax](#compact-binary-syntax) by @@ -621,9 +621,9 @@ contained within the `Value` unmodified. The functions `binary32(F)` and `binary64(D)` yield big-endian 4- and 8-byte IEEE 754 binary representations of `F` and `D`, respectively. -### Pointers. +### Embeddeds. -The `Repr` of a `Pointer` is the `Repr` of a `Value` chosen to +The `Repr` of an `Embedded` is the `Repr` of a `Value` chosen to represent the denoted object, prefixed with `[0x86]`. «#!V» = [0x86] ++ «V» @@ -855,7 +855,7 @@ a binary-syntax document; otherwise, it should be interpreted as text. 83 - Double 84 - End marker 85 - Annotation - 86 - Pointer + 86 - Embedded (8x) RESERVED 87-8F 9x - Small integers 0..12,-3..-1 diff --git a/schema/schema.bin b/schema/schema.bin index 7642b06..5f613fb 100644 --- a/schema/schema.bin +++ b/schema/schema.bin @@ -1,8 +1,8 @@ -schemapointerversion definitionsRefreclitreftuplenamedmoduleref -ModulePathnamednameatomSymbolBundlereclitbundletuplenamedmodulesrefModulesSchemareclitschematupledictpointerref PointerNameversionrefVersion definitionsref DefinitionsModulesdictofref +schemaversion definitionsRefreclitreftuplenamedmoduleref +ModulePathnamednameatomSymbolBundlereclitbundletuplenamedmodulesrefModulesSchemareclitschematupledictversionrefVersion definitionsref Definitions embeddedTyperefEmbeddedTypeNameModulesdictofref ModulePathrefSchemaPatternor SimplePatternref SimplePatternCompoundPatternrefCompoundPatternVersionlitAtomKindorBooleanlitBooleanFloatlitFloatDoublelitDouble SignedIntegerlit SignedIntegerStringlitString ByteStringlit ByteStringSymbollitSymbol Definitionororreclitortupletuple*namedpatternrefNamedAlternativenamedpatternsrefNamedAlternative Alternativeref Alternative ModulePathtuple*atomSymbol Alternativeorandreclitandtupletuple*namedpatternref NamedPatternnamedpatternsref NamedPatternPatternrefPattern DefinitionsdictofatomSymbolref -Definition PointerNameorRefrefReffalselit NamedPatternornamedrefNamedSimplePattern_ anonymousrefPattern SimplePatternoranylitanyatomreclitatomtuplenamedatomKindrefAtomKindpointerreclitpointertuplelitreclitlittuplenamedvalueanyRefrefRefCompoundPatternorrecreclitrectuplenamedlabelref NamedPatternnamedfieldsref NamedPatterntuplereclittupletupletuple*namedpatternsref NamedPatterntuple*reclittuple*tupletuple*namedfixedref NamedPatternnamedvariablerefNamedSimplePatternsetofreclitsetoftuplenamedpatternref SimplePatterndictofreclitdictoftuplenamedkeyref SimplePatternnamedvalueref SimplePatterndictreclitdicttuplenamedentriesrefDictionaryEntriesNamedAlternativetuplenamed variantLabelatomStringnamed alternativeref AlternativeDictionaryEntriesdictofanyrefNamedSimplePatternNamedSimplePatternornamedrefNamedSimplePattern_ anonymousref SimplePatternNamedSimplePattern_reclitnamedtuplenamednameatomSymbolnamedpatternref SimplePattern \ No newline at end of file +Definition NamedPatternornamedrefNamedSimplePattern_ anonymousrefPattern SimplePatternoranylitanyatomreclitatomtuplenamedatomKindrefAtomKindembeddedreclitembeddedtuplelitreclitlittuplenamedvalueanyRefrefRefCompoundPatternorrecreclitrectuplenamedlabelref NamedPatternnamedfieldsref NamedPatterntuplereclittupletupletuple*namedpatternsref NamedPatterntuple*reclittuple*tupletuple*namedfixedref NamedPatternnamedvariablerefNamedSimplePatternsetofreclitsetoftuplenamedpatternref SimplePatterndictofreclitdictoftuplenamedkeyref SimplePatternnamedvalueref SimplePatterndictreclitdicttuplenamedentriesrefDictionaryEntriesEmbeddedTypeNameorRefrefReffalselitNamedAlternativetuplenamed variantLabelatomStringnamed alternativeref AlternativeDictionaryEntriesdictofanyrefNamedSimplePatternNamedSimplePatternornamedrefNamedSimplePattern_ anonymousref SimplePatternNamedSimplePattern_reclitnamedtuplenamednameatomSymbolnamedpatternref SimplePattern embeddedType \ No newline at end of file diff --git a/schema/schema.prs b/schema/schema.prs index 2ee45dd..8e7a685 100644 --- a/schema/schema.prs +++ b/schema/schema.prs @@ -1,5 +1,8 @@ @ +; TODO: some kind of constants +; TODO: rename "version" to "schema-version" ? + version 1 . Bundle = . @@ -7,14 +10,14 @@ Modules = { ModulePath: Schema ...:... }. Schema = . ; version 1 . Version = 1 . -PointerName = Ref / #f. +EmbeddedTypeName = Ref / #f. Definitions = { symbol: Definition ...:... }. @@ -37,8 +40,8 @@ SimplePattern = ; special builtins: bool, float, double, int, string, bytes, symbol / - ; matches a pointer in the input: ref - / + ; matches an embedded value in the input: embedded + / ; =symbol, < any>, or plain non-symbol atom / diff --git a/tests/samples.bin b/tests/samples.bin index 13077ad..0aa76bb 100644 Binary files a/tests/samples.bin and b/tests/samples.bin differ diff --git a/tests/samples.pr b/tests/samples.pr index 05c6eda..c12396c 100644 --- a/tests/samples.pr +++ b/tests/samples.pr @@ -112,9 +112,9 @@ list9: @"Unexpected close bracket" list10: @"Missing end byte" noinput0: @"No input at all" - pointer0: - pointer1: - pointer2: + embed0: + embed1: + embed2: record1: >> record2: , >>>> record3: "Dr">>