preserves/implementations/javascript/src/values.ts

60 lines
1.6 KiB
TypeScript

// Preserves Values.
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 = object;
export type Value<T extends object = DefaultPointer> =
| Atom
| Compound<T>
| T
| Annotated<T>;
export type Atom =
| boolean
| SingleFloat
| DoubleFloat
| number
| string
| Bytes
| symbol;
export type Compound<T extends object = DefaultPointer> =
| (Array<Value<T>> | [Value<T>]) & { label: Value<T> }
// ^ expanded from definition of Record<> in record.ts,
// because if we use Record<Value<T>, Tuple<Value<T>>, T>,
// TypeScript currently complains about circular use of Value<T>,
// and if we use Record<any, any, T>, it accepts it but collapses
// Value<T> to any.
| Array<Value<T>>
| Set<T>
| Dictionary<Value<T>, T>;
declare global {
interface Object { asPreservesText(): string; }
}
Object.defineProperty(Object.prototype, 'asPreservesText', {
enumerable: false,
writable: true,
value: function(): string { return '#!' + JSON.stringify(this); }
});
Boolean.prototype.asPreservesText = function (): string {
return this ? '#t' : '#f';
};
Number.prototype.asPreservesText = function (): string {
return '' + this;
};
String.prototype.asPreservesText = function (): string {
return JSON.stringify(this);
};
Symbol.prototype.asPreservesText = function (): string {
// TODO: escaping
return this.description ?? '||';
};