Bootstrap following JsDictionary support in schema

This commit is contained in:
Tony Garnock-Jones 2024-03-27 16:35:47 +01:00
parent 00c0de40ea
commit 3093b89f0d
8 changed files with 27 additions and 23 deletions

View File

@ -1,11 +1,11 @@
import { stringify } from '@preserves/core';
import { JsDictionary, stringify } from '@preserves/core';
import * as M from './meta';
export function checkSchema(schema: M.Schema): (
{ ok: true, schema: M.Schema } | { ok: false, problems: Array<string> })
{
const checker = new Checker();
schema.definitions.forEach(checker.checkDefinition.bind(checker));
JsDictionary.forEach(schema.definitions, checker.checkDefinition.bind(checker));
if (checker.problems.length > 0) {
return { ok: false, problems: checker.problems };
} else {

View File

@ -1,4 +1,4 @@
import { encode, stringify } from "@preserves/core";
import { encode, JsDictionary, stringify } from "@preserves/core";
import * as M from "./meta";
import { CompilerOptions, ModuleContext } from "./compiler/context";
import { Formatter, block, seq, braces } from "./compiler/block";
@ -29,7 +29,7 @@ export function compile(
mod.defineType(seq(`export type _embedded = `, mod.embeddedType, `;`));
}
for (const [name, def] of schema.definitions) {
for (const [name, def] of JsDictionary.entries(schema.definitions)) {
const t = typeForDefinition(mod.resolver(), def);
const nameStr = stringify(name);
const resultTypeItem = seq(nameStr, mod.genericArgsFor(t));
@ -49,7 +49,7 @@ export function compile(
}
}
for (const [name0, def] of schema.definitions) {
for (const [name0, def] of JsDictionary.entries(schema.definitions)) {
const t = typeForDefinition(mod.resolver(), def);
const name = name0 as symbol;
const nameStr = name0.description!;

View File

@ -1,4 +1,4 @@
import { KeyedSet, FlexSet, Position, stringify, DictionaryMap } from "@preserves/core";
import { KeyedSet, FlexSet, Position, stringify, DictionaryMap, JsDictionary } from "@preserves/core";
import { refPosition } from "../reader";
import * as M from "../meta";
import { anglebrackets, block, braces, commas, formatItems, Item, keyvalue, seq } from "./block";
@ -137,7 +137,7 @@ export class ModuleContext {
null,
null);
} else {
const p = e.schema.definitions.get(name.name);
const p = JsDictionary.get(e.schema.definitions, name.name);
if (p !== void 0) {
let t = () => typeForDefinition(this.resolver(soughtModule), p);
if (name.module.length) {

View File

@ -58,7 +58,9 @@ function unconverterFor(ctx: FunctionContext, p: M.Pattern, src: string): Item {
`)`)));
case 'dictof':
return seq(`_.Dictionary.from<_embedded>`, parens(seq(
`_.Array.from(${src}.entries()).map(([k, v]) => `,
`_.Array.from(`,
M.isSymbolPattern(p.key) ? `_.JsDictionary.entries(${src})` : `${src}.entries()`,
`).map(([k, v]) => `,
brackets(
unconverterFor(ctx, M.Pattern.SimplePattern(p.key), 'k'),
unconverterFor(ctx, M.Pattern.SimplePattern(p.value), 'v')),

View File

@ -79,7 +79,7 @@ export type EmbeddedTypeName = (
}
);
export type Definitions<_embedded extends _.Embeddable = _.GenericEmbedded> = _.EncodableDictionary<_embedded, symbol, Definition<_embedded>>;
export type Definitions<_embedded extends _.Embeddable = _.GenericEmbedded> = _.JsDictionary<Definition<_embedded>>;
export type Definition<_embedded extends _.Embeddable = _.GenericEmbedded> = (
(
@ -304,7 +304,7 @@ export namespace EmbeddedTypeName {
};
}
export function Definitions<_embedded extends _.Embeddable = _.GenericEmbedded>(value: _.EncodableDictionary<_embedded, symbol, Definition<_embedded>>): Definitions<_embedded> {return value;}
export function Definitions<_embedded extends _.Embeddable = _.GenericEmbedded>(value: _.JsDictionary<Definition<_embedded>>): Definitions<_embedded> {return value;}
Definitions.schema = function () {
return {
@ -1086,19 +1086,19 @@ export function asDefinitions<_embedded extends _.Embeddable = _.GenericEmbedded
}
export function toDefinitions<_embedded extends _.Embeddable = _.GenericEmbedded>(v: _.Value<_embedded>): undefined | Definitions<_embedded> {
let _tmp0: (_.EncodableDictionary<_embedded, symbol, Definition<_embedded>>) | undefined;
let _tmp0: (_.JsDictionary<Definition<_embedded>>) | undefined;
let result: undefined | Definitions<_embedded>;
_tmp0 = void 0;
if (_.Dictionary.isDictionary<_embedded>(v)) {
const _tmp1 = new _.DictionaryMap(v);
_tmp0 = new _.EncodableDictionary<_embedded, symbol, Definition<_embedded>>(k => k, fromDefinition<_embedded>);
_tmp0 = {};
for (const [_tmp2, _tmp3] of _tmp1) {
let _tmp4: (symbol) | undefined;
_tmp4 = typeof _tmp2 === 'symbol' ? _tmp2 : void 0;
if (_tmp4 !== void 0) {
let _tmp5: (Definition<_embedded>) | undefined;
_tmp5 = toDefinition(_tmp3);
if (_tmp5 !== void 0) {_tmp0.set(_tmp4, _tmp5); continue;};
if (_tmp5 !== void 0) {_tmp0[_tmp4.description!] = _tmp5; continue;};
};
_tmp0 = void 0;
break;
@ -1111,7 +1111,9 @@ export function toDefinitions<_embedded extends _.Embeddable = _.GenericEmbedded
Definitions.__from_preserve__ = toDefinitions;
export function fromDefinitions<_embedded extends _.Embeddable = _.GenericEmbedded>(_v: Definitions<_embedded>): _.Value<_embedded> {
return _.Dictionary.from<_embedded>(_.Array.from(_v.entries()).map(([k, v]) => [k, fromDefinition<_embedded>(v)]));
return _.Dictionary.from<_embedded>(
_.Array.from(_.JsDictionary.entries(_v)).map(([k, v]) => [k, fromDefinition<_embedded>(v)])
);
}
export function asDefinition<_embedded extends _.Embeddable = _.GenericEmbedded>(v: _.Value<_embedded>): Definition<_embedded> {

View File

@ -2,7 +2,6 @@ import { EncodableDictionary, KeyedDictionary, Dictionary, Value, is, Record, Fl
import { SchemaDefinition } from './reflection';
import * as M from './meta';
import * as H from './host';
import { isSymbolType } from './compiler/type';
export const UNIT: true = true;
@ -136,7 +135,7 @@ export class SchemaInterpreter<V extends Embeddable> {
): R {
const { resolved, schema } = this._findModule(modulePath);
return this._withModule(resolved, () => {
const definition = schema.definitions.get(name);
const definition = JsDictionary.get(schema.definitions, name);
if (definition === void 0) {
throw new Error(`No such preserves-schema definition: ${[... modulePath, name].map(s => s.description!).join('.')}`);
}
@ -579,7 +578,7 @@ export class SchemaInterpreter<V extends Embeddable> {
const schema = this.env.get(modulePath);
if (schema === void 0) return void 0;
const mod: { [key: string]: any } = {};
schema.definitions.forEach((_d, n) => {
JsDictionary.forEach(schema.definitions, (_d, n) => {
const definitionName = n.description!;
const definitionId = M.jsId(definitionName);
mod[`${definitionId}`] = this.definitionConstructor(modulePath, n);

View File

@ -1,4 +1,4 @@
import { Reader, Annotated, Dictionary, is, peel, preserves, Record, strip, Tuple, Position, position, stringify, isCompound, EncodableDictionary, annotate, annotations, isEmbedded, GenericEmbedded, genericEmbeddedTypeDecode, DictionaryMap, KeyedDictionary } from '@preserves/core';
import { Reader, Annotated, Dictionary, is, peel, preserves, Record, strip, Tuple, Position, position, stringify, isCompound, EncodableDictionary, annotate, annotations, isEmbedded, GenericEmbedded, genericEmbeddedTypeDecode, JsDictionary, KeyedDictionary } from '@preserves/core';
import { Input, Pattern, Schema, Definition, CompoundPattern, SimplePattern } from './meta';
import * as M from './meta';
import { SchemaSyntaxError } from './error';
@ -70,7 +70,7 @@ export function parseSchema(toplevelTokens: Array<Input>, options: SchemaReaderO
{
let version: M.Version | undefined = void 0;
let embeddedType: M.EmbeddedTypeName = M.EmbeddedTypeName.$false();
let definitions: M.Definitions = new EncodableDictionary(k => k, M.fromDefinition);
let definitions: M.Definitions = {};
function process(toplevelTokens: Array<Input>): void {
const toplevelClauses = splitBy(peel(toplevelTokens) as Array<Input>, M.DOT);
@ -82,10 +82,10 @@ export function parseSchema(toplevelTokens: Array<Input>, options: SchemaReaderO
if (!M.isValidToken(name.description!)) {
throw new SchemaSyntaxError(preserves`Invalid definition name: ${name}`, pos);
}
if (definitions.has(name)) {
if (JsDictionary.has(definitions, name)) {
throw new SchemaSyntaxError(preserves`Duplicate definition: ${clause}`, pos);
}
definitions.set(name, parseDefinition(name, pos, clause.slice(2)));
JsDictionary.set(definitions, 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.$embeddedType)) {

View File

@ -1,3 +1,4 @@
import { JsDictionary } from '@preserves/core';
import { readSchema, Meta } from '../src/index';
describe('reader schema', () => {
@ -14,12 +15,12 @@ describe('reader schema', () => {
'__preserve_on__',
'__preserve_text_on__',
]);
expect(s.definitions.size).toBe(0);
expect(JsDictionary.size(s.definitions)).toBe(0);
expect(s.embeddedType._variant).toBe('false');
});
it('understands patterns under embed', () => {
const s = readSchema('version 1 . X = #:0 .');
const def: Meta.Definition = s.definitions.get(Symbol.for('X'))!;
const def: Meta.Definition = JsDictionary.get(s.definitions, Symbol.for('X'))!;
if (def._variant !== 'Pattern') fail('bad definition 1');
if (def.value._variant !== 'SimplePattern') fail ('bad definition 2');
if (def.value.value._variant !== 'embedded') fail('bad definition 3');