preserves/implementations/javascript/packages/schema/src/meta.ts

81 lines
3.0 KiB
TypeScript

import { Dictionary, KeyedDictionary, Record, Value, preserves } from '@preserves/core';
export type Input = Value<never>;
export function isValidToken(s: string, allowLeadingUnderscore = false): boolean {
if (allowLeadingUnderscore) {
return /^[a-zA-Z_][a-zA-Z_0-9]*$/.test(s);
} else {
return /^[a-zA-Z][a-zA-Z_0-9]*$/.test(s);
}
}
export const ANDSYM = Symbol.for('&');
export const DOT = Symbol.for('.');
export const DOTDOTDOT = Symbol.for('...');
export const EQUALS = Symbol.for('=');
export const ORSYM = Symbol.for('/');
export const ___Boolean = Symbol.for('Boolean');
export const ___ByteString = Symbol.for('ByteString');
export const ___Double = Symbol.for('Double');
export const ___Float = Symbol.for('Float');
export const ___SignedInteger = Symbol.for('SignedInteger');
export const ___String = Symbol.for('String');
export const ___Symbol = Symbol.for('Symbol');
export const ___and = Symbol.for('and');
export const ___atom = Symbol.for('atom');
export const ___dict = Symbol.for('dict');
export const ___dictof = Symbol.for('dictof');
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');
export const ___setof = Symbol.for('setof');
export const ___tuple = Symbol.for('tuple');
export const ___tuple_STAR_ = Symbol.for('tuple*');
export const ___version = Symbol.for('version');
export type Environment = Array<Schema>;
export const Schema = Record.makeConstructor<{
version: number,
definitions: KeyedDictionary<symbol, Pattern, never>,
}>()(Symbol.for('schema'), ['version', 'definitions']);
export type Schema = ReturnType<typeof Schema>;
export type AtomKind =
| typeof ___Boolean
| typeof ___Float
| typeof ___Double
| typeof ___SignedInteger
| typeof ___String
| typeof ___ByteString
| typeof ___Symbol;
export type Pattern =
| Record<typeof ___atom, [AtomKind], never>
| Record<typeof ___lit, [Input], never>
| Record<typeof ___ref, [symbol], never>
| Record<typeof ___or, [Array<Pattern>], never>
| Record<typeof ___and, [Array<Pattern>], never>
| Record<typeof ___pointer, [], never>
| Record<typeof ___rec, [Pattern, Pattern], never>
| Record<typeof ___tuple, [Array<NamedPattern>], never>
| Record<typeof ___tuple_STAR_, [Array<NamedPattern>, NamedPattern], never>
| Record<typeof ___setof, [Pattern], never>
| Record<typeof ___dictof, [Pattern, Pattern], never>
| Record<typeof ___dict, [Dictionary<Pattern, never>], never>;
export type NamedPattern = Record<typeof ___named, [symbol, Pattern], never> | Pattern;
export function lookup(env: Environment, name: symbol): Pattern {
for (const s of env) {
const p = Schema._.definitions(s).get(name);
if (p !== void 0) return p;
}
throw new Error(preserves`Schema: unbound name ${name}`);
}