Improve compiler driver
This commit is contained in:
parent
ba2c7e9978
commit
d932431d83
|
@ -13,7 +13,7 @@
|
|||
"types": "lib/index.d.ts",
|
||||
"author": "Tony Garnock-Jones <tonyg@leastfixedpoint.com>",
|
||||
"scripts": {
|
||||
"regenerate": "./bin/preserves-schema-ts.js ../../../../schema/schema.txt > src/schemaschema.ts",
|
||||
"regenerate": "rm -rf ./src/gen && ./bin/preserves-schema-ts.js --output ./src/gen ../../../../schema/schema.prs",
|
||||
"clean": "rm -rf lib dist",
|
||||
"prepare": "tsc && rollup -c",
|
||||
"rollupwatch": "rollup -c -w",
|
||||
|
@ -26,6 +26,10 @@
|
|||
"preserves-schema-ts": "./bin/preserves-schema-ts.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@preserves/core": "^0.8.0"
|
||||
"@preserves/core": "^0.8.0",
|
||||
"@types/glob": "^7.1.3",
|
||||
"@types/yargs": "^16.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"yargs": "^16.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import { Record, Dictionary, Value } from '@preserves/core';
|
||||
import { Pattern, Schema } from './meta';
|
||||
import * as M from './meta';
|
||||
import * as M from './gen/schema';
|
||||
|
||||
export const BASE: Schema = Record(M.$schema, [new Dictionary<Value, never>([
|
||||
export const BASE: M.Schema = Record(M.$schema, [new Dictionary<Value, never>([
|
||||
[M.$version, 1],
|
||||
[M.$definitions, new Dictionary<Pattern, never>([
|
||||
[M.$definitions, new Dictionary<M.Pattern, never>([
|
||||
[Symbol.for('any'), Record(M.$and, [[]])],
|
||||
[Symbol.for('bool'), Record(M.$atom, [M.$Boolean])],
|
||||
[Symbol.for('float'), Record(M.$atom, [M.$Float])],
|
||||
|
|
|
@ -1,12 +1,102 @@
|
|||
import { BASE, compile, readSchema } from '../index';
|
||||
import { compile, readSchema } from '../index';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { glob } from 'glob';
|
||||
import yargs from 'yargs/yargs';
|
||||
import * as M from '../meta';
|
||||
|
||||
export type CommandLineArguments = {
|
||||
input: string;
|
||||
base: string | undefined;
|
||||
output: string | undefined;
|
||||
core: string;
|
||||
};
|
||||
|
||||
export function computeBase(paths: string[]): string {
|
||||
if (paths.length === 0) {
|
||||
return '';
|
||||
} else if (paths.length === 1) {
|
||||
return path.dirname(paths[0]) + '/';
|
||||
} else {
|
||||
let i = 0;
|
||||
while (true) {
|
||||
let ch: string | null = null
|
||||
for (const p of paths) {
|
||||
if (i >= p.length) return p.slice(0, i);
|
||||
if (ch === null) ch = p[i];
|
||||
if (p[i] !== ch) return p.slice(0, i - 1);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type ToCompile = {
|
||||
inputFilePath: string,
|
||||
outputFilePath: string,
|
||||
schemaPath: M.ModulePath,
|
||||
schema: M.Schema,
|
||||
};
|
||||
|
||||
function changeExt(p: string, newext: string) {
|
||||
return p.slice(0, -path.extname(p).length) + newext;
|
||||
}
|
||||
|
||||
export function run(options: CommandLineArguments) {
|
||||
glob(options.input, (err, matches) => {
|
||||
if (err) throw err;
|
||||
|
||||
const base = options.base ?? computeBase(matches);
|
||||
const output = options.output ?? base;
|
||||
|
||||
const toCompile: Array<ToCompile> = matches.map(inputFilePath => {
|
||||
if (!inputFilePath.startsWith(base)) {
|
||||
throw new Error(`Input filename ${inputFilePath} falls outside base ${base}`);
|
||||
}
|
||||
const relPath = inputFilePath.slice(base.length);
|
||||
const outputFilePath = path.join(output, changeExt(relPath, '.ts'));
|
||||
const src = fs.readFileSync(inputFilePath, 'utf-8');
|
||||
const schema = readSchema(src);
|
||||
const schemaPath = relPath.split(path.delimiter).map(p => p.split('.')[0]).map(Symbol.for);
|
||||
return { inputFilePath, outputFilePath, schemaPath, schema };
|
||||
});
|
||||
|
||||
toCompile.forEach(c => {
|
||||
const env: M.Environment = toCompile.map(cc => ({
|
||||
schema: cc.schema,
|
||||
schemaModulePath: cc.schemaPath,
|
||||
typescriptModulePath: path.relative(c.outputFilePath, cc.outputFilePath) || null,
|
||||
}));
|
||||
fs.mkdirSync(path.dirname(c.outputFilePath), { recursive: true });
|
||||
fs.writeFileSync(c.outputFilePath, compile(env, c.schema, options.core), 'utf-8');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export function main(argv: Array<string>) {
|
||||
const [filename] = argv;
|
||||
const src = fs.readFileSync(filename, 'utf-8');
|
||||
const sch = readSchema(src);
|
||||
console.log(compile(
|
||||
[{ moduleName: 'BASE', modulePath: 'BASE', schema: BASE, inline: true }],
|
||||
sch,
|
||||
'@preserves/core'));
|
||||
const options: CommandLineArguments = yargs(argv)
|
||||
.command('$0 <input>',
|
||||
'Compile Preserves schema definitions to TypeScript',
|
||||
yargs => yargs
|
||||
.positional('input', {
|
||||
type: 'string',
|
||||
description: 'Input filename or glob',
|
||||
demandOption: true,
|
||||
})
|
||||
.option('output', {
|
||||
type: 'string',
|
||||
description: 'Output directory for sources (default: next to sources)',
|
||||
})
|
||||
.option('base', {
|
||||
type: 'string',
|
||||
description: 'Base directory for sources (default: common prefix)',
|
||||
})
|
||||
.option('core', {
|
||||
type: 'string',
|
||||
description: 'Import path for @preserves/core',
|
||||
default: '@preserves/core',
|
||||
}),
|
||||
argv => argv)
|
||||
.argv;
|
||||
run(options);
|
||||
}
|
||||
|
|
|
@ -1,50 +1,27 @@
|
|||
import { Pattern, NamedPattern, Schema, Input } from "./meta";
|
||||
import { Pattern, NamedPattern, Schema, Input, Environment, Ref, lookup } from "./meta";
|
||||
import * as M from './meta';
|
||||
import { Annotated, Bytes, Dictionary, Fold, fold, preserves, Record, Tuple, Value } from "@preserves/core";
|
||||
import { Annotated, Bytes, Dictionary, Fold, fold, KeyedSet, preserves, Record, Set, Tuple, Value } from "@preserves/core";
|
||||
import { Formatter, parens, seq, Item, opseq, block, commas, brackets, anglebrackets, braces } from "./block";
|
||||
|
||||
function fnblock(... items: Item[]): Item {
|
||||
return seq('((() => ', block(... items), ')())');
|
||||
}
|
||||
|
||||
export type CompileEnvEntry = {
|
||||
moduleName: string,
|
||||
modulePath: string,
|
||||
schema: Schema,
|
||||
inline: boolean,
|
||||
};
|
||||
|
||||
export function compile(env: Array<CompileEnvEntry>, schema: Schema, preservesModule = '@preserves/core'): string {
|
||||
export function compile(env: Environment, schema: Schema, preservesModule = '@preserves/core'): string {
|
||||
const literals = new Dictionary<string, never>();
|
||||
const types: Array<Item> = [];
|
||||
const functions: Array<Item> = [];
|
||||
const imports = new KeyedSet<[string, string]>();
|
||||
let temps: Array<string> = [];
|
||||
|
||||
function environmentWith<R>(name: symbol,
|
||||
kLocal: () => R,
|
||||
kOther: (e: CompileEnvEntry, p: Pattern) => R): R {
|
||||
if (Schema._.details(schema).get(M.$definitions).has(name)) {
|
||||
return kLocal();
|
||||
}
|
||||
for (const e of env) {
|
||||
const p = Schema._.details(e.schema).get(M.$definitions).get(name);
|
||||
if (p !== void 0) {
|
||||
return kOther(e, p);
|
||||
}
|
||||
}
|
||||
throw new Error(`Undefined reference: ${name.description!}`);
|
||||
}
|
||||
|
||||
function applyPredicate(name: symbol, v: string): Item {
|
||||
return environmentWith(name,
|
||||
() => `is${name.description!}(${v})`,
|
||||
(e, p) => {
|
||||
if (e.inline) {
|
||||
return walk(v, p);
|
||||
} else {
|
||||
return `${e.moduleName}.is${name.description!}(${v})`;
|
||||
}
|
||||
});
|
||||
function applyPredicate(name: Ref, v: string): Item {
|
||||
return lookup(name, env,
|
||||
(_p) => `is${Ref._.name(name).description!}(${v})`,
|
||||
(p) => walk(v, p),
|
||||
(mod, modPath, _p) => {
|
||||
imports.add([mod, modPath]);
|
||||
return `${mod}.is${Ref._.name(name).description!}(${v})`;
|
||||
});
|
||||
}
|
||||
|
||||
function gentemp(): string {
|
||||
|
@ -80,16 +57,13 @@ export function compile(env: Array<CompileEnvEntry>, schema: Schema, preservesMo
|
|||
case M.$lit:
|
||||
return `(typeof ${literal(p[0])})`;
|
||||
case M.$ref:
|
||||
return environmentWith(
|
||||
p[0],
|
||||
() => p[0].description!,
|
||||
(e, pp) => {
|
||||
if (e.inline) {
|
||||
return typeFor(pp);
|
||||
} else {
|
||||
return `${e.moduleName}.${p[0].description!}`;
|
||||
}
|
||||
});
|
||||
return lookup(p, env,
|
||||
(_p) => p[1].description!,
|
||||
(p) => typeFor(p),
|
||||
(mod, modPath,_p) => {
|
||||
imports.add([mod, modPath]);
|
||||
return `${mod}.${p[1].description!}`;
|
||||
});
|
||||
case M.$or:
|
||||
return opseq('never', ' | ', ... p[0].map(pp => typeFor(pp)));
|
||||
case M.$and:
|
||||
|
@ -148,7 +122,7 @@ export function compile(env: Array<CompileEnvEntry>, schema: Schema, preservesMo
|
|||
return `_.is(${v}, ${literal(p[0])})`;
|
||||
}
|
||||
case M.$ref:
|
||||
return applyPredicate(p[0], v);
|
||||
return applyPredicate(p, v);
|
||||
case M.$or:
|
||||
return opseq('false', ' || ', ... p[0].map(pp => walk(v, pp)));
|
||||
case M.$and:
|
||||
|
|
|
@ -21,6 +21,7 @@ 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 $thisModule = Symbol.for("thisModule");
|
||||
export const $tuple = Symbol.for("tuple");
|
||||
export const $tuple_STAR_ = Symbol.for("tuple*");
|
||||
export const $version = Symbol.for("version");
|
||||
|
@ -69,7 +70,7 @@ export type Pattern = (
|
|||
> |
|
||||
_.Record<(typeof $pointer), []> |
|
||||
_.Record<(typeof $lit), [_.Value]> |
|
||||
_.Record<(typeof $ref), [symbol]> |
|
||||
Ref |
|
||||
_.Record<(typeof $or), [Array<Pattern>]> |
|
||||
_.Record<(typeof $and), [Array<Pattern>]> |
|
||||
_.Record<(typeof $rec), [Pattern, Pattern]> |
|
||||
|
@ -82,6 +83,14 @@ export type Pattern = (
|
|||
|
||||
export type NamedPattern = (_.Record<(typeof $named), [symbol, Pattern]> | Pattern);
|
||||
|
||||
export const Ref = _.Record.makeConstructor<{"module": ModuleRef, "name": symbol}>()($ref, ["module","name"]);
|
||||
|
||||
export type Ref = _.Record<(typeof $ref), [ModuleRef, symbol]>;
|
||||
|
||||
export type ModuleRef = ((typeof $thisModule) | ModulePath);
|
||||
|
||||
export type ModulePath = Array<symbol>;
|
||||
|
||||
|
||||
export function isSchema(v: any): v is Schema {
|
||||
let _tmp0, _tmp1: any;
|
||||
|
@ -136,11 +145,7 @@ export function isPattern(v: any): v is Pattern {
|
|||
) ||
|
||||
(_.Record.isRecord(v) && v.label === $pointer && ((v.length === 0))) ||
|
||||
(_.Record.isRecord(v) && v.label === $lit && ((v.length === 1) && true)) ||
|
||||
(
|
||||
_.Record.isRecord(v) &&
|
||||
v.label === $ref &&
|
||||
((v.length === 1) && typeof v[0] === 'symbol')
|
||||
) ||
|
||||
isRef(v) ||
|
||||
(
|
||||
_.Record.isRecord(v) &&
|
||||
v.label === $or &&
|
||||
|
@ -243,4 +248,28 @@ export function asNamedPattern(v: any): NamedPattern {
|
|||
if (!isNamedPattern(v)) {throw new TypeError("NamedPattern");} else {return v;};
|
||||
}
|
||||
|
||||
export function isRef(v: any): v is Ref {
|
||||
return (
|
||||
_.Record.isRecord(v) &&
|
||||
v.label === $ref &&
|
||||
((v.length === 2) && isModuleRef(v[0]) && typeof v[1] === 'symbol')
|
||||
);
|
||||
}
|
||||
|
||||
export function asRef(v: any): Ref {if (!isRef(v)) {throw new TypeError("Ref");} else {return v;};}
|
||||
|
||||
export function isModuleRef(v: any): v is ModuleRef {return (v === $thisModule || isModulePath(v));}
|
||||
|
||||
export function asModuleRef(v: any): ModuleRef {if (!isModuleRef(v)) {throw new TypeError("ModuleRef");} else {return v;};}
|
||||
|
||||
export function isModulePath(v: any): v is ModulePath {
|
||||
return (
|
||||
_.Array.isArray(v) &&
|
||||
!_.Record.isRecord(v) &&
|
||||
(v.length >= 0) &&
|
||||
v.slice(0).every(v => (typeof v === 'symbol'))
|
||||
);
|
||||
}
|
||||
|
||||
export function asModulePath(v: any): ModulePath {if (!isModulePath(v)) {throw new TypeError("ModulePath");} else {return v;};}
|
||||
|
|
@ -18,7 +18,10 @@ export function validator(env: Environment, p: Pattern): (v: Value<any>) => bool
|
|||
case M.$lit:
|
||||
return is(v, p[0]);
|
||||
case M.$ref:
|
||||
return walk(lookup(env, p[0]), v);
|
||||
return lookup(p, env,
|
||||
(p) => walk(p, v),
|
||||
(p) => walk(p, v),
|
||||
(_mod, _modPath, p) => walk(p, v));
|
||||
case M.$or:
|
||||
for (const pp of p[0]) {
|
||||
if (walk(pp, v)) return true;
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
import { Value, preserves } from '@preserves/core';
|
||||
import { Value, preserves, is } from '@preserves/core';
|
||||
import { ModulePath, Ref, Schema, Pattern, $thisModule, $definitions } from './gen/schema';
|
||||
import { BASE } from './base';
|
||||
|
||||
export * from './gen/schema';
|
||||
|
||||
export type Input = Value<never>;
|
||||
|
||||
|
@ -16,15 +20,40 @@ export const DOTDOTDOT = Symbol.for('...');
|
|||
export const EQUALS = Symbol.for('=');
|
||||
export const ORSYM = Symbol.for('/');
|
||||
|
||||
export * from './schemaschema';
|
||||
import { Schema, Pattern, $definitions } from './schemaschema';
|
||||
export type SchemaEnvEntry = {
|
||||
schemaModulePath: ModulePath,
|
||||
typescriptModulePath: string | null, // null means it's $thisModule in disguise
|
||||
schema: Schema,
|
||||
};
|
||||
|
||||
export type Environment = Array<Schema>;
|
||||
export type Environment = Array<SchemaEnvEntry>;
|
||||
|
||||
export function lookup(env: Environment, name: symbol): Pattern {
|
||||
for (const s of env) {
|
||||
const p = Schema._.details(s).get($definitions).get(name);
|
||||
if (p !== void 0) return p;
|
||||
export function lookup<R>(name: Ref,
|
||||
env: Environment,
|
||||
kLocal: (p: Pattern) => R,
|
||||
kBase: (p: Pattern) => R,
|
||||
kOther: (mod: string, modPath: string, p: Pattern) => R): R
|
||||
{
|
||||
for (const e of env) {
|
||||
if (is(e.schemaModulePath, Ref._.module(name)) ||
|
||||
(e.typescriptModulePath === null && Ref._.module(name) === $thisModule))
|
||||
{
|
||||
const p = Schema._.details(e.schema).get($definitions).get(Ref._.name(name));
|
||||
if (p !== void 0) {
|
||||
if (e.typescriptModulePath === null) {
|
||||
return kLocal(p);
|
||||
} else {
|
||||
const modsym = '_i_' + e.schemaModulePath.map(s => s.description!).join('$');
|
||||
return kOther(modsym, e.typescriptModulePath, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error(preserves`Schema: unbound name ${name}`);
|
||||
|
||||
if (Ref._.module(name) === $thisModule) {
|
||||
const p = Schema._.details(BASE).get($definitions).get(Ref._.name(name));
|
||||
if (p !== void 0) return kBase(p);
|
||||
}
|
||||
|
||||
throw new Error(preserves`Undefined reference: ${name}`);
|
||||
}
|
||||
|
|
|
@ -115,7 +115,15 @@ function parseBase(name: symbol, body: Array<Input>): Pattern {
|
|||
const s = item.description;
|
||||
if (s === void 0) complain();
|
||||
if (s[0] === '=') return Record(M.$lit, [Symbol.for(s.slice(1))]);
|
||||
return Record(M.$ref, [item]);
|
||||
const pieces = s.split('.');
|
||||
if (pieces.length === 1) {
|
||||
return Record(M.$ref, [M.$thisModule, item]);
|
||||
} else {
|
||||
return Record(M.$ref, [
|
||||
pieces.slice(0, pieces.length - 1).map(Symbol.for),
|
||||
Symbol.for(pieces[pieces.length - 1])
|
||||
]);
|
||||
}
|
||||
} else if (Record.isRecord<Input, Tuple<Input>, never>(item)) {
|
||||
const label = item.label;
|
||||
if (Record.isRecord<Input, [], never>(label)) {
|
||||
|
|
|
@ -533,6 +533,14 @@
|
|||
dependencies:
|
||||
"@babel/types" "^7.3.0"
|
||||
|
||||
"@types/glob@^7.1.3":
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
|
||||
integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==
|
||||
dependencies:
|
||||
"@types/minimatch" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/graceful-fs@^4.1.2":
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15"
|
||||
|
@ -567,6 +575,11 @@
|
|||
jest-diff "^26.0.0"
|
||||
pretty-format "^26.0.0"
|
||||
|
||||
"@types/minimatch@*":
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
|
||||
integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==
|
||||
|
||||
"@types/node@*":
|
||||
version "14.14.33"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.33.tgz#9e4f8c64345522e4e8ce77b334a8aaa64e2b6c78"
|
||||
|
@ -609,6 +622,13 @@
|
|||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
"@types/yargs@^16.0.0":
|
||||
version "16.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.0.tgz#0e033b23452da5d61b6c44747612cb80ac528751"
|
||||
integrity sha512-2nN6AGeMwe8+O6nO9ytQfbMQOJy65oi1yK2y/9oReR08DaXSGtMsrLyCM1ooKqfICpCx4oITaR4LkOmdzz41Ww==
|
||||
dependencies:
|
||||
"@types/yargs-parser" "*"
|
||||
|
||||
abab@^2.0.3, abab@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a"
|
||||
|
@ -1046,6 +1066,15 @@ cliui@^6.0.0:
|
|||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^6.2.0"
|
||||
|
||||
cliui@^7.0.2:
|
||||
version "7.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f"
|
||||
integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==
|
||||
dependencies:
|
||||
string-width "^4.2.0"
|
||||
strip-ansi "^6.0.0"
|
||||
wrap-ansi "^7.0.0"
|
||||
|
||||
co@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
|
||||
|
@ -1587,7 +1616,7 @@ gensync@^1.0.0-beta.2:
|
|||
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
||||
|
||||
get-caller-file@^2.0.1:
|
||||
get-caller-file@^2.0.1, get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||
|
@ -1635,7 +1664,7 @@ glob-parent@~5.1.0:
|
|||
dependencies:
|
||||
is-glob "^4.0.1"
|
||||
|
||||
glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4:
|
||||
glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
|
@ -4017,6 +4046,15 @@ wrap-ansi@^6.2.0:
|
|||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrap-ansi@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
|
||||
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
|
||||
dependencies:
|
||||
ansi-styles "^4.0.0"
|
||||
string-width "^4.1.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
|
@ -4057,6 +4095,11 @@ y18n@^4.0.0:
|
|||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.1.tgz#8db2b83c31c5d75099bb890b23f3094891e247d4"
|
||||
integrity sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==
|
||||
|
||||
y18n@^5.0.5:
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.5.tgz#8769ec08d03b1ea2df2500acef561743bbb9ab18"
|
||||
integrity sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg==
|
||||
|
||||
yallist@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
|
||||
|
@ -4075,6 +4118,11 @@ yargs-parser@^18.1.2:
|
|||
camelcase "^5.0.0"
|
||||
decamelize "^1.2.0"
|
||||
|
||||
yargs-parser@^20.2.2:
|
||||
version "20.2.7"
|
||||
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
|
||||
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
|
||||
|
||||
yargs@^15.4.1:
|
||||
version "15.4.1"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
|
||||
|
@ -4092,6 +4140,19 @@ yargs@^15.4.1:
|
|||
y18n "^4.0.0"
|
||||
yargs-parser "^18.1.2"
|
||||
|
||||
yargs@^16.2.0:
|
||||
version "16.2.0"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
|
||||
integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==
|
||||
dependencies:
|
||||
cliui "^7.0.2"
|
||||
escalade "^3.1.1"
|
||||
get-caller-file "^2.0.5"
|
||||
require-directory "^2.1.1"
|
||||
string-width "^4.2.0"
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yn@3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
|
||||
|
|
|
@ -20,8 +20,8 @@ Pattern = <<or> [
|
|||
; =symbol, <<lit> any>, or plain non-symbol atom
|
||||
<lit @value any>
|
||||
|
||||
; symbol
|
||||
<ref @name symbol>
|
||||
; symbol, symbol.symbol, symbol.symbol.symbol, ...
|
||||
Ref
|
||||
|
||||
; Pattern / Pattern / ...
|
||||
; <<or> [Pattern Pattern ...]>
|
||||
|
@ -55,3 +55,7 @@ Pattern = <<or> [
|
|||
]>.
|
||||
|
||||
NamedPattern = <named @name symbol @pattern Pattern> / Pattern .
|
||||
|
||||
Ref = <ref @module ModuleRef @name symbol>.
|
||||
ModuleRef = =thisModule / ModulePath .
|
||||
ModulePath = [symbol ...].
|
Loading…
Reference in New Issue