A more... pragmatic DefaultPointer
This commit is contained in:
parent
12121128a6
commit
8f2da8f8db
|
@ -1,9 +1,10 @@
|
|||
import { Encoder } from "./encoder";
|
||||
import { Tag } from "./constants";
|
||||
import { AsPreserve, PreserveOn } from "./symbols";
|
||||
import { DefaultPointer, Value } from "./values";
|
||||
import { Value } from "./values";
|
||||
import { is, isAnnotated, IsPreservesAnnotated } from "./is";
|
||||
import { stringify } from "./text";
|
||||
import { DefaultPointer } from "./pointer";
|
||||
|
||||
export interface Position {
|
||||
line?: number;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { Tag } from './constants';
|
||||
import { AsPreserve, PreserveOn } from './symbols';
|
||||
import { Encoder, Preservable } from './encoder';
|
||||
import { DefaultPointer, Value } from './values';
|
||||
import { Value } from './values';
|
||||
import { DefaultPointer } from './pointer';
|
||||
|
||||
const textEncoder = new TextEncoder();
|
||||
const textDecoder = new TextDecoder();
|
||||
|
|
|
@ -3,9 +3,10 @@ import { Tag } from "./constants";
|
|||
import { FlexMap, FlexSet, _iterMap } from "./flex";
|
||||
import { PreserveOn } from "./symbols";
|
||||
import { stringify } from "./text";
|
||||
import { DefaultPointer, Value } from "./values";
|
||||
import { Value } from "./values";
|
||||
import { Bytes } from './bytes';
|
||||
import { fromJS } from "./fromjs";
|
||||
import { DefaultPointer } from "./pointer";
|
||||
|
||||
export type DictionaryType = 'Dictionary' | 'Set';
|
||||
export const DictionaryType = Symbol.for('DictionaryType');
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { Encoder, Preservable } from "./encoder";
|
||||
import { Tag } from "./constants";
|
||||
import { AsPreserve, PreserveOn } from "./symbols";
|
||||
import { DefaultPointer, Value } from "./values";
|
||||
import { Value } from "./values";
|
||||
import { DefaultPointer } from "./pointer";
|
||||
|
||||
export type FloatType = 'Single' | 'Double';
|
||||
export const FloatType = Symbol.for('FloatType');
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { DefaultPointer } from "./pointer";
|
||||
import { Bytes } from "./bytes";
|
||||
import { Record, Tuple } from "./record";
|
||||
import { AsPreserve } from "./symbols";
|
||||
import { DefaultPointer, Value } from "./values";
|
||||
import { Value } from "./values";
|
||||
|
||||
export function fromJS<T = DefaultPointer>(x: any): Value<T> {
|
||||
switch (typeof x) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import type { DefaultPointer } from "./values.js";
|
||||
import type { DefaultPointer } from "./pointer.js";
|
||||
import type { Annotated } from "./annotated.js";
|
||||
|
||||
export const IsPreservesAnnotated = Symbol.for('IsPreservesAnnotated');
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
import type { Encoder } from "./encoder";
|
||||
import type { TypedDecoder } from "./decoder";
|
||||
import type { Value } from "./values";
|
||||
|
||||
import { strip } from "./strip";
|
||||
|
||||
export class DefaultPointer {
|
||||
v: Value<DefaultPointer>;
|
||||
|
||||
constructor(v: Value<DefaultPointer>) {
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
equals(other: any, is: (a: any, b: any) => boolean) {
|
||||
return Object.is(other.constructor, this.constructor) && is(this.v, other.v);
|
||||
}
|
||||
|
||||
asPreservesText(): string {
|
||||
return '#!' + this.v.asPreservesText();
|
||||
}
|
||||
}
|
||||
|
||||
export function readDefaultPointer(v: Value<DefaultPointer>): DefaultPointer {
|
||||
return new DefaultPointer(strip(v));
|
||||
}
|
||||
|
||||
export function decodeDefaultPointer(d: TypedDecoder<DefaultPointer>): DefaultPointer {
|
||||
return readDefaultPointer(d.next());
|
||||
}
|
||||
|
||||
export function encodeDefaultPointer(e: Encoder<DefaultPointer>, w: DefaultPointer): void {
|
||||
e.push(w.v);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import { DefaultPointer } from "./pointer";
|
||||
import { is } from "./is";
|
||||
import { DefaultPointer, Value } from "./values";
|
||||
import { Value } from "./values";
|
||||
|
||||
export type Tuple<T> = Array<T> | [T];
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ export * from './float';
|
|||
export * from './fold';
|
||||
export * from './fromjs';
|
||||
export * from './is';
|
||||
export * from './pointer';
|
||||
export * from './reader';
|
||||
export * from './record';
|
||||
export * from './strip';
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { DefaultPointer, Value } from "./values";
|
||||
import { Value } from "./values";
|
||||
import { Annotated } from "./annotated";
|
||||
import { Record, Tuple } from "./record";
|
||||
import { Set, Dictionary } from "./dictionary";
|
||||
import type { DefaultPointer } from "./pointer";
|
||||
|
||||
export function unannotate<T = DefaultPointer>(v: Value<T>): Value<T> {
|
||||
return Annotated.isAnnotated<T>(v) ? v.item : v;
|
||||
|
|
|
@ -4,8 +4,7 @@ import type { Bytes } from './bytes';
|
|||
import type { DoubleFloat, SingleFloat } from './float';
|
||||
import type { Annotated } from './annotated';
|
||||
import type { Set, Dictionary } from './dictionary';
|
||||
|
||||
export type DefaultPointer = never;
|
||||
import type { DefaultPointer } from './pointer';
|
||||
|
||||
export type Value<T = DefaultPointer> =
|
||||
| Atom
|
||||
|
|
|
@ -11,19 +11,21 @@ import {
|
|||
Constants,
|
||||
TypedDecoder,
|
||||
Encoder,
|
||||
DefaultPointer,
|
||||
decodeDefaultPointer,
|
||||
encodeDefaultPointer,
|
||||
} from '../src/index';
|
||||
const { Tag } = Constants;
|
||||
import './test-utils';
|
||||
import { decodePointer, encodePointer, Pointer } from './test-utils';
|
||||
|
||||
import * as fs from 'fs';
|
||||
|
||||
const _discard = Symbol.for('discard');
|
||||
const _capture = Symbol.for('capture');
|
||||
const _observe = Symbol.for('observe');
|
||||
const Discard = Record.makeConstructor<{}, Pointer>()(_discard, []);
|
||||
const Capture = Record.makeConstructor<{pattern: Value<Pointer>}, Pointer>()(_capture, ['pattern']);
|
||||
const Observe = Record.makeConstructor<{pattern: Value<Pointer>}, Pointer>()(_observe, ['pattern']);
|
||||
const Discard = Record.makeConstructor<{}, DefaultPointer>()(_discard, []);
|
||||
const Capture = Record.makeConstructor<{pattern: Value<DefaultPointer>}, DefaultPointer>()(_capture, ['pattern']);
|
||||
const Observe = Record.makeConstructor<{pattern: Value<DefaultPointer>}, DefaultPointer>()(_observe, ['pattern']);
|
||||
|
||||
describe('record constructors', () => {
|
||||
it('should have constructorInfo', () => {
|
||||
|
@ -152,52 +154,61 @@ describe('encoding and decoding pointers', () => {
|
|||
|
||||
describe('common test suite', () => {
|
||||
const samples_bin = fs.readFileSync(__dirname + '/../../../../../tests/samples.bin');
|
||||
const samples = decodeWithAnnotations(samples_bin, { decodePointer });
|
||||
const samples = decodeWithAnnotations(samples_bin, { decodePointer: decodeDefaultPointer });
|
||||
|
||||
const TestCases = Record.makeConstructor<{cases: Dictionary<Value<Pointer>, Pointer>}>()(Symbol.for('TestCases'), ['cases']);
|
||||
const TestCases = Record.makeConstructor<{
|
||||
cases: Dictionary<Value<DefaultPointer>, DefaultPointer>
|
||||
}>()(Symbol.for('TestCases'), ['cases']);
|
||||
type TestCases = ReturnType<typeof TestCases>;
|
||||
|
||||
function DS(bs: Bytes) {
|
||||
return decode(bs, { decodePointer });
|
||||
return decode(bs, { decodePointer: decodeDefaultPointer });
|
||||
}
|
||||
function D(bs: Bytes) {
|
||||
return decodeWithAnnotations(bs, { decodePointer });
|
||||
return decodeWithAnnotations(bs, { decodePointer: decodeDefaultPointer });
|
||||
}
|
||||
function E(v: Value<Pointer>) {
|
||||
return encodeWithAnnotations(v, { encodePointer });
|
||||
function E(v: Value<DefaultPointer>) {
|
||||
return encodeWithAnnotations(v, { encodePointer: encodeDefaultPointer });
|
||||
}
|
||||
|
||||
interface ExpectedValues {
|
||||
[testName: string]: { value: Value<Pointer> } | { forward: Value<Pointer>, back: Value<Pointer> };
|
||||
[testName: string]: ({
|
||||
value: Value<DefaultPointer>;
|
||||
} | {
|
||||
forward: Value<DefaultPointer>;
|
||||
back: Value<DefaultPointer>;
|
||||
});
|
||||
}
|
||||
|
||||
const expectedValues: ExpectedValues = {
|
||||
annotation1: { forward: annotate<Pointer>(9, "abc"),
|
||||
annotation1: { forward: annotate<DefaultPointer>(9, "abc"),
|
||||
back: 9 },
|
||||
annotation2: { forward: annotate<Pointer>([[], annotate<Pointer>([], "x")], "abc", "def"),
|
||||
annotation2: { forward: annotate<DefaultPointer>([[], annotate<DefaultPointer>([], "x")],
|
||||
"abc",
|
||||
"def"),
|
||||
back: [[], []] },
|
||||
annotation3: { forward: annotate<Pointer>(5,
|
||||
annotate<Pointer>(2, 1),
|
||||
annotate<Pointer>(4, 3)),
|
||||
annotation3: { forward: annotate<DefaultPointer>(5,
|
||||
annotate<DefaultPointer>(2, 1),
|
||||
annotate<DefaultPointer>(4, 3)),
|
||||
back: 5 },
|
||||
annotation5: {
|
||||
forward: annotate<Pointer>(
|
||||
forward: annotate<DefaultPointer>(
|
||||
Record<symbol, any>(Symbol.for('R'),
|
||||
[annotate<Pointer>(Symbol.for('f'),
|
||||
Symbol.for('af'))]),
|
||||
[annotate<DefaultPointer>(Symbol.for('f'),
|
||||
Symbol.for('af'))]),
|
||||
Symbol.for('ar')),
|
||||
back: Record<Value<Pointer>, any>(Symbol.for('R'), [Symbol.for('f')])
|
||||
back: Record<Value<DefaultPointer>, any>(Symbol.for('R'), [Symbol.for('f')])
|
||||
},
|
||||
annotation6: {
|
||||
forward: Record<Value<Pointer>, any>(
|
||||
annotate<Pointer>(Symbol.for('R'),
|
||||
Symbol.for('ar')),
|
||||
[annotate<Pointer>(Symbol.for('f'),
|
||||
Symbol.for('af'))]),
|
||||
forward: Record<Value<DefaultPointer>, any>(
|
||||
annotate<DefaultPointer>(Symbol.for('R'),
|
||||
Symbol.for('ar')),
|
||||
[annotate<DefaultPointer>(Symbol.for('f'),
|
||||
Symbol.for('af'))]),
|
||||
back: Record<symbol, any>(Symbol.for('R'), [Symbol.for('f')])
|
||||
},
|
||||
annotation7: {
|
||||
forward: annotate<Pointer>([], Symbol.for('a'), Symbol.for('b'), Symbol.for('c')),
|
||||
forward: annotate<DefaultPointer>([], Symbol.for('a'), Symbol.for('b'), Symbol.for('c')),
|
||||
back: []
|
||||
},
|
||||
list1: {
|
||||
|
@ -214,7 +225,11 @@ describe('common test suite', () => {
|
|||
|
||||
type Variety = 'normal' | 'nondeterministic' | 'decode';
|
||||
|
||||
function runTestCase(variety: Variety, tName: string, binaryForm: Bytes, annotatedTextForm: Value<Pointer>) {
|
||||
function runTestCase(variety: Variety,
|
||||
tName: string,
|
||||
binaryForm: Bytes,
|
||||
annotatedTextForm: Value<DefaultPointer>)
|
||||
{
|
||||
describe(tName, () => {
|
||||
const textForm = strip(annotatedTextForm);
|
||||
const {forward, back} = (function () {
|
||||
|
@ -241,10 +256,11 @@ describe('common test suite', () => {
|
|||
});
|
||||
}
|
||||
|
||||
const tests = peel(TestCases._.cases(peel(samples) as TestCases)) as Dictionary<Value<Pointer>, Pointer>;
|
||||
tests.forEach((t0: Value<Pointer>, tName0: Value<Pointer>) => {
|
||||
const tests = (peel(TestCases._.cases(peel(samples) as TestCases)) as
|
||||
Dictionary<Value<DefaultPointer>, DefaultPointer>);
|
||||
tests.forEach((t0: Value<DefaultPointer>, tName0: Value<DefaultPointer>) => {
|
||||
const tName = Symbol.keyFor(strip(tName0) as symbol)!;
|
||||
const t = peel(t0) as Record<symbol, any, Pointer>;
|
||||
const t = peel(t0) as Record<symbol, any, DefaultPointer>;
|
||||
switch (t.label) {
|
||||
case Symbol.for('Test'):
|
||||
runTestCase('normal', tName, strip(t[0]) as Bytes, t[1]);
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import { Bytes, Decoder, encode, Reader } from '../src/index';
|
||||
import { Bytes, decodeDefaultPointer, Decoder, encode, encodeDefaultPointer, readDefaultPointer, Reader } from '../src/index';
|
||||
import './test-utils';
|
||||
import { decodePointer, encodePointer, readPointer } from './test-utils';
|
||||
|
||||
import * as fs from 'fs';
|
||||
|
||||
|
@ -9,25 +8,25 @@ 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, { decodePointer: readPointer, includeAnnotations: false }).next();
|
||||
const s1 = new Reader(samples_pr, { decodePointer: readDefaultPointer, includeAnnotations: false }).next();
|
||||
const s2 = new Decoder(samples_bin, { includeAnnotations: false }).withPointerDecoder(
|
||||
decodePointer,
|
||||
decodeDefaultPointer,
|
||||
d => d.next());
|
||||
expect(s1).is(s2);
|
||||
});
|
||||
|
||||
it('should read equal to decoded binary with annotations', () => {
|
||||
const s1 = new Reader(samples_pr, { decodePointer: readPointer, includeAnnotations: true }).next();
|
||||
const s1 = new Reader(samples_pr, { decodePointer: readDefaultPointer, includeAnnotations: true }).next();
|
||||
const s2 = new Decoder(samples_bin, { includeAnnotations: true }).withPointerDecoder(
|
||||
decodePointer,
|
||||
decodeDefaultPointer,
|
||||
d => d.next());
|
||||
expect(s1).is(s2);
|
||||
});
|
||||
|
||||
it('should read and encode back to binary with annotations', () => {
|
||||
const s = new Reader(samples_pr, { decodePointer: readPointer, includeAnnotations: true }).next();
|
||||
const s = new Reader(samples_pr, { decodePointer: readDefaultPointer, includeAnnotations: true }).next();
|
||||
const bs = Bytes.toIO(encode(s, {
|
||||
encodePointer,
|
||||
encodePointer: encodeDefaultPointer,
|
||||
includeAnnotations: true,
|
||||
canonical: true,
|
||||
}));
|
||||
|
|
|
@ -34,31 +34,3 @@ expect.extend({
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
export class Pointer {
|
||||
v: Value<Pointer>;
|
||||
|
||||
constructor(v: Value<Pointer>) {
|
||||
this.v = v;
|
||||
}
|
||||
|
||||
equals(other: any, is: (a: any, b: any) => boolean) {
|
||||
return Object.is(other.constructor, this.constructor) && is(this.v, other.v);
|
||||
}
|
||||
|
||||
asPreservesText(): string {
|
||||
return '#!' + this.v.asPreservesText();
|
||||
}
|
||||
}
|
||||
|
||||
export function readPointer(v: Value<Pointer>): Pointer {
|
||||
return new Pointer(strip(v));
|
||||
}
|
||||
|
||||
export function decodePointer(d: TypedDecoder<Pointer>): Pointer {
|
||||
return readPointer(d.next());
|
||||
}
|
||||
|
||||
export function encodePointer(e: Encoder<Pointer>, w: Pointer): void {
|
||||
e.push(w.v);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue