Make undeclared pointer type `any` instead of `never`, and take advantage of new explicit pointer wrappers
This commit is contained in:
parent
70ce961dd2
commit
58d2bf6f3a
|
@ -3,8 +3,8 @@ import * as M from "./meta";
|
||||||
import { CompilerOptions, ModuleContext } from "./compiler/context";
|
import { CompilerOptions, ModuleContext } from "./compiler/context";
|
||||||
import { Formatter, block, seq } from "./compiler/block";
|
import { Formatter, block, seq } from "./compiler/block";
|
||||||
import { typeForDefinition } from "./compiler/gentype";
|
import { typeForDefinition } from "./compiler/gentype";
|
||||||
import { converterForDefinition, converterForSimple } from "./compiler/genconverter";
|
import { converterForDefinition } from "./compiler/genconverter";
|
||||||
import { EMPTY_TYPE, renderType } from "./compiler/type";
|
import { renderType, Type } from "./compiler/type";
|
||||||
import { genConstructor } from "./compiler/genctor";
|
import { genConstructor } from "./compiler/genctor";
|
||||||
import { unconverterForDefinition } from "./compiler/genunconverter";
|
import { unconverterForDefinition } from "./compiler/genunconverter";
|
||||||
import { sourceCodeFor } from "./compiler/value";
|
import { sourceCodeFor } from "./compiler/value";
|
||||||
|
@ -15,22 +15,11 @@ export function compile(env: M.Environment, schema: M.Schema, options: CompilerO
|
||||||
const pointerName = schema.pointer;
|
const pointerName = schema.pointer;
|
||||||
mod.defineType(seq(`export type _ptr = `,
|
mod.defineType(seq(`export type _ptr = `,
|
||||||
renderType(pointerName._variant === 'false'
|
renderType(pointerName._variant === 'false'
|
||||||
? EMPTY_TYPE
|
? Type.ref('any')
|
||||||
: typeForDefinition(mod, M.Definition.Alternative(M.Alternative.Pattern(M.Pattern.SimplePattern(M.SimplePattern.Ref(pointerName.value)))))),
|
: typeForDefinition(mod, M.Definition.Alternative(M.Alternative.Pattern(M.Pattern.SimplePattern(M.SimplePattern.Ref(pointerName.value)))))),
|
||||||
`;`));
|
`;`));
|
||||||
mod.defineType(`export type _val = _.Value<_ptr>;`);
|
mod.defineType(`export type _val = _.Value<_ptr>;`);
|
||||||
|
|
||||||
mod.defineFunction(ctx =>
|
|
||||||
seq(`export const _toPtr = `,
|
|
||||||
(pointerName._variant === 'false'
|
|
||||||
? '() => { throw new _.DecodeError("Pointers forbidden"); }'
|
|
||||||
: seq(`(v: _val) => `, ctx.block(() => [
|
|
||||||
seq(`let result: undefined | _ptr`),
|
|
||||||
... converterForSimple(
|
|
||||||
ctx, M.SimplePattern.Ref(pointerName.value), 'v', 'result'),
|
|
||||||
seq(`return result`)]))),
|
|
||||||
`;`));
|
|
||||||
|
|
||||||
for (const [name, def] of schema.definitions) {
|
for (const [name, def] of schema.definitions) {
|
||||||
const t = typeForDefinition(mod, def);
|
const t = typeForDefinition(mod, def);
|
||||||
const nameStr = stringify(name);
|
const nameStr = stringify(name);
|
||||||
|
|
|
@ -22,7 +22,7 @@ export class ModuleContext {
|
||||||
readonly schema: M.Schema;
|
readonly schema: M.Schema;
|
||||||
readonly options: CompilerOptions;
|
readonly options: CompilerOptions;
|
||||||
|
|
||||||
readonly literals = new Dictionary<never, string>();
|
readonly literals = new Dictionary<M._ptr, string>();
|
||||||
readonly typedefs: Item[] = [];
|
readonly typedefs: Item[] = [];
|
||||||
readonly functiondefs: Item[] = [];
|
readonly functiondefs: Item[] = [];
|
||||||
readonly imports = new KeyedSet<[string, string]>();
|
readonly imports = new KeyedSet<[string, string]>();
|
||||||
|
|
|
@ -206,7 +206,7 @@ export function converterForSimple(
|
||||||
return [`${dest} = ${modId}.to${p.value.name.description!}(${src})`];
|
return [`${dest} = ${modId}.to${p.value.name.description!}(${src})`];
|
||||||
});
|
});
|
||||||
case 'pointer':
|
case 'pointer':
|
||||||
return [`${dest} = _toPtr(${src})`];
|
return [`${dest} = _.isPointer<_ptr>(${src}) ? ${src}.embeddedValue : void 0`];
|
||||||
default:
|
default:
|
||||||
((_p: never) => {})(p);
|
((_p: never) => {})(p);
|
||||||
throw new Error("Unreachable");
|
throw new Error("Unreachable");
|
||||||
|
|
|
@ -35,7 +35,6 @@ export namespace Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ANY_TYPE: AtomicType = Type.ref('_val');
|
export const ANY_TYPE: AtomicType = Type.ref('_val');
|
||||||
export const EMPTY_TYPE: AtomicType = Type.ref('never');
|
|
||||||
|
|
||||||
export function variantInitFor(variantName: string | undefined) : Item[] {
|
export function variantInitFor(variantName: string | undefined) : Item[] {
|
||||||
return variantName === void 0 ? [] : [variantFor(variantName)];
|
return variantName === void 0 ? [] : [variantFor(variantName)];
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { Annotated, Bytes, Set, Dictionary, Fold, fold, Record, Tuple, Value, stringify } from "@preserves/core";
|
import { Annotated, Bytes, Set, Dictionary, Fold, fold, Record, Tuple, Value, stringify } from "@preserves/core";
|
||||||
import { brackets, Item, parens, seq } from "./block";
|
import { brackets, Item, parens, seq } from "./block";
|
||||||
|
import * as M from '../meta';
|
||||||
|
|
||||||
export function sourceCodeFor(v: Value<never>): Item {
|
export function sourceCodeFor(v: Value<M._ptr>): Item {
|
||||||
return fold(v, {
|
return fold(v, {
|
||||||
boolean(b: boolean): Item { return b.toString(); },
|
boolean(b: boolean): Item { return b.toString(); },
|
||||||
single(f: number): Item { return f.toString(); },
|
single(f: number): Item { return f.toString(); },
|
||||||
|
@ -13,25 +14,25 @@ export function sourceCodeFor(v: Value<never>): Item {
|
||||||
},
|
},
|
||||||
symbol(s: symbol): Item { return `Symbol.for(${JSON.stringify(s.description!)})`; },
|
symbol(s: symbol): Item { return `Symbol.for(${JSON.stringify(s.description!)})`; },
|
||||||
|
|
||||||
record(r: Record<Value<never>, Tuple<Value<never>>, never>, k: Fold<never, Item>): Item {
|
record(r: Record<Value<M._ptr>, Tuple<Value<M._ptr>>, M._ptr>, k: Fold<M._ptr, Item>): Item {
|
||||||
return seq(`_.Record<_val, _.Tuple<_val>, _ptr>`, parens(k(r.label), brackets(... r.map(k))));
|
return seq(`_.Record<_val, _.Tuple<_val>, _ptr>`, parens(k(r.label), brackets(... r.map(k))));
|
||||||
},
|
},
|
||||||
array(a: Array<Value<never>>, k: Fold<never, Item>): Item {
|
array(a: Array<Value<M._ptr>>, k: Fold<M._ptr, Item>): Item {
|
||||||
return brackets(... a.map(k));
|
return brackets(... a.map(k));
|
||||||
},
|
},
|
||||||
set(s: Set<never>, k: Fold<never, Item>): Item {
|
set(s: Set<M._ptr>, k: Fold<M._ptr, Item>): Item {
|
||||||
return seq('new _.Set<_val>', parens(brackets(... Array.from(s).map(k))));
|
return seq('new _.Set<_val>', parens(brackets(... Array.from(s).map(k))));
|
||||||
},
|
},
|
||||||
dictionary(d: Dictionary<never>, k: Fold<never, Item>): Item {
|
dictionary(d: Dictionary<M._ptr>, k: Fold<M._ptr, Item>): Item {
|
||||||
return seq('new _.Dictionary<_ptr>', parens(brackets(... Array.from(d).map(([kk,vv]) =>
|
return seq('new _.Dictionary<_ptr>', parens(brackets(... Array.from(d).map(([kk,vv]) =>
|
||||||
brackets(k(kk), k(vv))))));
|
brackets(k(kk), k(vv))))));
|
||||||
},
|
},
|
||||||
|
|
||||||
annotated(a: Annotated<never>, k: Fold<never, Item>): Item {
|
annotated(a: Annotated<M._ptr>, k: Fold<M._ptr, Item>): Item {
|
||||||
return seq('_.annotate<_ptr>', parens(k(a.item), ... a.annotations.map(k)));
|
return seq('_.annotate<_ptr>', parens(k(a.item), ... a.annotations.map(k)));
|
||||||
},
|
},
|
||||||
|
|
||||||
pointer(t: never, _k: Fold<never, Item>): Item {
|
pointer(t: M._ptr, _k: Fold<M._ptr, Item>): Item {
|
||||||
throw new Error(`Cannot emit source code for construction of pointer ${stringify(t)}`);
|
throw new Error(`Cannot emit source code for construction of pointer ${stringify(t)}`);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const $tuple$STAR$ = Symbol.for("tuple*");
|
||||||
export const $version = Symbol.for("version");
|
export const $version = Symbol.for("version");
|
||||||
export const __lit6 = false;
|
export const __lit6 = false;
|
||||||
|
|
||||||
export type _ptr = never;
|
export type _ptr = any;
|
||||||
|
|
||||||
export type _val = _.Value<_ptr>;
|
export type _val = _.Value<_ptr>;
|
||||||
|
|
||||||
|
@ -115,8 +115,6 @@ export type Ref = {"module": ModulePath, "name": symbol};
|
||||||
export type ModulePath = Array<symbol>;
|
export type ModulePath = Array<symbol>;
|
||||||
|
|
||||||
|
|
||||||
export const _toPtr = () => { throw new _.DecodeError("Pointers forbidden"); };
|
|
||||||
|
|
||||||
export function Bundle(modules: Modules): Bundle {return {"modules": modules};}
|
export function Bundle(modules: Modules): Bundle {return {"modules": modules};}
|
||||||
|
|
||||||
export function Modules(value: _.KeyedDictionary<ModulePath, Schema, _ptr>): Modules {return value;}
|
export function Modules(value: _.KeyedDictionary<ModulePath, Schema, _ptr>): Modules {return value;}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Value, is, Position } from '@preserves/core';
|
import { is, Position } from '@preserves/core';
|
||||||
import * as M from './gen/schema';
|
import * as M from './gen/schema';
|
||||||
import { SchemaSyntaxError } from './error';
|
import { SchemaSyntaxError } from './error';
|
||||||
import type { AtomicType } from './compiler/type';
|
import type { AtomicType } from './compiler/type';
|
||||||
|
@ -8,7 +8,7 @@ export * from './gen/schema';
|
||||||
|
|
||||||
export type Builtin = { type: AtomicType, pattern: M.Alternative };
|
export type Builtin = { type: AtomicType, pattern: M.Alternative };
|
||||||
|
|
||||||
export type Input = Value<never>;
|
export type Input = M._val;
|
||||||
|
|
||||||
export function isValidToken(s: string): boolean {
|
export function isValidToken(s: string): boolean {
|
||||||
return /^[a-zA-Z][a-zA-Z_0-9]*$/.test(s);
|
return /^[a-zA-Z][a-zA-Z_0-9]*$/.test(s);
|
||||||
|
|
|
@ -49,7 +49,7 @@ export type SchemaReaderOptions = {
|
||||||
};
|
};
|
||||||
|
|
||||||
function _readSchema(source: string, options?: ReaderOptions<never>): Array<Input> {
|
function _readSchema(source: string, options?: ReaderOptions<never>): Array<Input> {
|
||||||
return new Reader<never>(source, {
|
return new Reader<any>(source, {
|
||||||
... options ?? {},
|
... options ?? {},
|
||||||
includeAnnotations: true
|
includeAnnotations: true
|
||||||
}).readToEnd();
|
}).readToEnd();
|
||||||
|
@ -223,9 +223,9 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
|
||||||
? M.SimplePattern.lit(Symbol.for(str.slice(1)))
|
? M.SimplePattern.lit(Symbol.for(str.slice(1)))
|
||||||
: M.SimplePattern.Ref(parseRef(str, pos)));
|
: M.SimplePattern.Ref(parseRef(str, pos)));
|
||||||
}
|
}
|
||||||
} else if (Record.isRecord<Input, Tuple<Input>, never>(item)) {
|
} else if (Record.isRecord<Input, Tuple<Input>, M._ptr>(item)) {
|
||||||
const label = item.label;
|
const label = item.label;
|
||||||
if (Record.isRecord<Input, [], never>(label)) {
|
if (Record.isRecord<Input, [], M._ptr>(label)) {
|
||||||
if (label.length !== 0) complain();
|
if (label.length !== 0) complain();
|
||||||
switch (label.label) {
|
switch (label.label) {
|
||||||
case M.$lit:
|
case M.$lit:
|
||||||
|
@ -290,9 +290,9 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Record.isRecord<Input, Tuple<Input>, never>(item)) {
|
if (Record.isRecord<Input, Tuple<Input>, M._ptr>(item)) {
|
||||||
const label = item.label;
|
const label = item.label;
|
||||||
if (Record.isRecord<Input, [], never>(label)) {
|
if (Record.isRecord<Input, [], M._ptr>(label)) {
|
||||||
if (label.length !== 0) complain();
|
if (label.length !== 0) complain();
|
||||||
switch (label.label) {
|
switch (label.label) {
|
||||||
case M.$rec:
|
case M.$rec:
|
||||||
|
@ -312,7 +312,7 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
|
||||||
}
|
}
|
||||||
} else if (Array.isArray(item)) {
|
} else if (Array.isArray(item)) {
|
||||||
return parseArrayLike(item);
|
return parseArrayLike(item);
|
||||||
} else if (Dictionary.isDictionary<never, Input>(item)) {
|
} else if (Dictionary.isDictionary<M._ptr, Input>(item)) {
|
||||||
if (item.size === 2 && item.has(M.DOTDOTDOT)) {
|
if (item.size === 2 && item.has(M.DOTDOTDOT)) {
|
||||||
const v = item.clone();
|
const v = item.clone();
|
||||||
v.delete(M.DOTDOTDOT);
|
v.delete(M.DOTDOTDOT);
|
||||||
|
|
Loading…
Reference in New Issue