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 { Formatter, block, seq } from "./compiler/block";
|
||||
import { typeForDefinition } from "./compiler/gentype";
|
||||
import { converterForDefinition, converterForSimple } from "./compiler/genconverter";
|
||||
import { EMPTY_TYPE, renderType } from "./compiler/type";
|
||||
import { converterForDefinition } from "./compiler/genconverter";
|
||||
import { renderType, Type } from "./compiler/type";
|
||||
import { genConstructor } from "./compiler/genctor";
|
||||
import { unconverterForDefinition } from "./compiler/genunconverter";
|
||||
import { sourceCodeFor } from "./compiler/value";
|
||||
|
@ -15,22 +15,11 @@ export function compile(env: M.Environment, schema: M.Schema, options: CompilerO
|
|||
const pointerName = schema.pointer;
|
||||
mod.defineType(seq(`export type _ptr = `,
|
||||
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)))))),
|
||||
`;`));
|
||||
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) {
|
||||
const t = typeForDefinition(mod, def);
|
||||
const nameStr = stringify(name);
|
||||
|
|
|
@ -22,7 +22,7 @@ export class ModuleContext {
|
|||
readonly schema: M.Schema;
|
||||
readonly options: CompilerOptions;
|
||||
|
||||
readonly literals = new Dictionary<never, string>();
|
||||
readonly literals = new Dictionary<M._ptr, string>();
|
||||
readonly typedefs: Item[] = [];
|
||||
readonly functiondefs: Item[] = [];
|
||||
readonly imports = new KeyedSet<[string, string]>();
|
||||
|
|
|
@ -206,7 +206,7 @@ export function converterForSimple(
|
|||
return [`${dest} = ${modId}.to${p.value.name.description!}(${src})`];
|
||||
});
|
||||
case 'pointer':
|
||||
return [`${dest} = _toPtr(${src})`];
|
||||
return [`${dest} = _.isPointer<_ptr>(${src}) ? ${src}.embeddedValue : void 0`];
|
||||
default:
|
||||
((_p: never) => {})(p);
|
||||
throw new Error("Unreachable");
|
||||
|
|
|
@ -35,7 +35,6 @@ export namespace Type {
|
|||
}
|
||||
|
||||
export const ANY_TYPE: AtomicType = Type.ref('_val');
|
||||
export const EMPTY_TYPE: AtomicType = Type.ref('never');
|
||||
|
||||
export function variantInitFor(variantName: string | undefined) : Item[] {
|
||||
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 { 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, {
|
||||
boolean(b: boolean): Item { return b.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!)})`; },
|
||||
|
||||
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))));
|
||||
},
|
||||
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));
|
||||
},
|
||||
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))));
|
||||
},
|
||||
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]) =>
|
||||
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)));
|
||||
},
|
||||
|
||||
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)}`);
|
||||
},
|
||||
});
|
||||
|
|
|
@ -28,7 +28,7 @@ export const $tuple$STAR$ = Symbol.for("tuple*");
|
|||
export const $version = Symbol.for("version");
|
||||
export const __lit6 = false;
|
||||
|
||||
export type _ptr = never;
|
||||
export type _ptr = any;
|
||||
|
||||
export type _val = _.Value<_ptr>;
|
||||
|
||||
|
@ -115,8 +115,6 @@ export type Ref = {"module": ModulePath, "name": 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 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 { SchemaSyntaxError } from './error';
|
||||
import type { AtomicType } from './compiler/type';
|
||||
|
@ -8,7 +8,7 @@ export * from './gen/schema';
|
|||
|
||||
export type Builtin = { type: AtomicType, pattern: M.Alternative };
|
||||
|
||||
export type Input = Value<never>;
|
||||
export type Input = M._val;
|
||||
|
||||
export function isValidToken(s: string): boolean {
|
||||
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> {
|
||||
return new Reader<never>(source, {
|
||||
return new Reader<any>(source, {
|
||||
... options ?? {},
|
||||
includeAnnotations: true
|
||||
}).readToEnd();
|
||||
|
@ -223,9 +223,9 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
|
|||
? M.SimplePattern.lit(Symbol.for(str.slice(1)))
|
||||
: 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;
|
||||
if (Record.isRecord<Input, [], never>(label)) {
|
||||
if (Record.isRecord<Input, [], M._ptr>(label)) {
|
||||
if (label.length !== 0) complain();
|
||||
switch (label.label) {
|
||||
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;
|
||||
if (Record.isRecord<Input, [], never>(label)) {
|
||||
if (Record.isRecord<Input, [], M._ptr>(label)) {
|
||||
if (label.length !== 0) complain();
|
||||
switch (label.label) {
|
||||
case M.$rec:
|
||||
|
@ -312,7 +312,7 @@ function parsePattern(name: symbol, body0: Array<Input>): Pattern {
|
|||
}
|
||||
} else if (Array.isArray(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)) {
|
||||
const v = item.clone();
|
||||
v.delete(M.DOTDOTDOT);
|
||||
|
|
Loading…
Reference in New Issue