101 lines
3.1 KiB
TypeScript
101 lines
3.1 KiB
TypeScript
import { GenericEmbedded, is, Value } from '@preserves/core';
|
|
import * as M from './gen/schema';
|
|
import { isJsKeyword } from './compiler/jskw';
|
|
|
|
export * from './gen/schema';
|
|
|
|
export type Input = Value;
|
|
export type InputEmbedded = GenericEmbedded;
|
|
|
|
export function qidLast(s: string): string {
|
|
const m = s.match(/^(.*\.)?([^.]+)$/);
|
|
return m![2];
|
|
}
|
|
|
|
export function isValidToken(s: string): boolean {
|
|
return /^[a-zA-Z][a-zA-Z_0-9]*$/.test(s);
|
|
}
|
|
|
|
export function isValidQid(s: string): boolean {
|
|
return s.split('.').every(isValidToken);
|
|
}
|
|
|
|
export function isValidJsId(s: string): boolean {
|
|
return /^[$_a-zA-Z][$_a-zA-Z0-9]*$/.test(s) && !isJsKeyword(s);
|
|
}
|
|
|
|
export function jsId(v: string, kf?: () => string): string {
|
|
return jsToken(v.replace('$', '$$'), kf);
|
|
}
|
|
|
|
export function jsToken(s: string, kf?: () => string): string {
|
|
if (isValidJsId(s)) return s;
|
|
if (isValidJsId('$' + s)) return '$' + s;
|
|
if (kf !== void 0) return kf();
|
|
throw new Error(`Internal error: jsToken needs to be completed (${s})`);
|
|
}
|
|
|
|
export const ANDSYM = Symbol.for('&');
|
|
export const DOT = Symbol.for('.');
|
|
export const DOTDOTDOT = Symbol.for('...');
|
|
export const EQUALS = Symbol.for('=');
|
|
export const INCLUDE = Symbol.for('include');
|
|
export const ORSYM = Symbol.for('/');
|
|
|
|
export type SchemaEnvEntry = {
|
|
schemaModulePath: M.ModulePath,
|
|
typescriptModulePath: string,
|
|
typescriptModuleExpr: string | null,
|
|
schema: M.Schema | null, // null means it's an artificial one, not corresponding to an input
|
|
};
|
|
|
|
export type Environment = Array<SchemaEnvEntry>;
|
|
|
|
export function envLookup(env: Environment, soughtModule: M.ModulePath): SchemaEnvEntry | null {
|
|
for (const e of env) {
|
|
if (is(e.schemaModulePath, soughtModule)) {
|
|
return e;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
export function modsymFor(e: SchemaEnvEntry): string {
|
|
return '_i_' + e.schemaModulePath.map(s => s.description!).join('$');
|
|
}
|
|
|
|
export function formatModulePath(p: M.ModulePath): string {
|
|
return p.map(s => s.description!).join('.');
|
|
}
|
|
|
|
export function formatRef(r: M.Ref): string {
|
|
return [... r.module, r.name].map(s => s.description!).join('.');
|
|
}
|
|
|
|
export function unnamePattern(p: M.NamedPattern): M.Pattern {
|
|
return (p._variant === 'named') ? M.Pattern.SimplePattern(p.value.pattern) : p.value;
|
|
}
|
|
|
|
export function unnameSimplePattern(p: M.NamedSimplePattern): M.SimplePattern {
|
|
return (p._variant === 'named') ? p.value.pattern : p.value;
|
|
}
|
|
|
|
export function promoteNamedSimplePattern(p: M.NamedSimplePattern): M.NamedPattern {
|
|
return (p._variant === 'named') ? p : M.NamedPattern.anonymous(M.Pattern.SimplePattern(p.value));
|
|
}
|
|
|
|
export function nameFor(p: M.NamedSimplePattern | M.NamedPattern) : string | undefined {
|
|
return (p._variant === 'named') ? p.value.name.description! : void 0;
|
|
}
|
|
|
|
export function anonymousSimplePattern(p: M.SimplePattern): M.NamedPattern {
|
|
return M.NamedPattern.anonymous(M.Pattern.SimplePattern(p));
|
|
}
|
|
|
|
export function namelike(x: Input): string | undefined {
|
|
if (typeof x === 'string') return x;
|
|
if (typeof x === 'symbol') return x.description!;
|
|
if (typeof x === 'boolean') return x ? 'true' : 'false';
|
|
return void 0;
|
|
}
|