lots of shit, okay?
parent
a9a6837c29
commit
b3342f0928
109
Instance.js
109
Instance.js
|
|
@ -1,109 +0,0 @@
|
||||||
|
|
||||||
import Serializable from './Serializable.js';
|
|
||||||
import minify from './minify.js';
|
|
||||||
import debug from 'debug';
|
|
||||||
import _ from 'lodash';
|
|
||||||
const log = debug('vogue:instance');
|
|
||||||
|
|
||||||
|
|
||||||
export default class Instance extends Serializable {
|
|
||||||
module = null;
|
|
||||||
links = {}
|
|
||||||
system = null;
|
|
||||||
context = null;
|
|
||||||
locals = [];
|
|
||||||
internalFunctions = {};
|
|
||||||
|
|
||||||
// reconstruct context when we need it...
|
|
||||||
createContext() {
|
|
||||||
let ctx = {};
|
|
||||||
for(const name in this.links) {
|
|
||||||
ctx[name] = this.links[name];
|
|
||||||
}
|
|
||||||
for(const name in this.module.imports) {
|
|
||||||
ctx[name] = this.module.imports[name];
|
|
||||||
this.locals.push(name);
|
|
||||||
}
|
|
||||||
ctx = {
|
|
||||||
...ctx,
|
|
||||||
...this.system.staticInstances,
|
|
||||||
...this.internalFunctions
|
|
||||||
}
|
|
||||||
for(const identifier in this.system.staticInstances) {
|
|
||||||
this.locals.push(identifier);
|
|
||||||
}
|
|
||||||
ctx.create = this.system.newInstance.bind(this.system);
|
|
||||||
this.locals.push('create');
|
|
||||||
this.context = ctx;
|
|
||||||
};
|
|
||||||
|
|
||||||
ready = false;
|
|
||||||
|
|
||||||
constructor(module, location, parameters, system) {
|
|
||||||
super();
|
|
||||||
this.module = module;
|
|
||||||
this.location = location;
|
|
||||||
this.system = system;
|
|
||||||
for(const name of this.module.links.optional.arrays) this.links[name] = [];
|
|
||||||
for(const name of this.module.links.optional.single) this.links[name] = null;
|
|
||||||
|
|
||||||
for(const fnName in this.module.functions) {
|
|
||||||
this.internalFunctions[fnName] =
|
|
||||||
this.invokeInternal.bind(this, fnName);
|
|
||||||
}
|
|
||||||
this.createContext();
|
|
||||||
|
|
||||||
this._link = new Proxy(this, {
|
|
||||||
get(target, prop, receiver) {
|
|
||||||
if(prop === 'restore') return undefined;
|
|
||||||
if(prop in target.module.functions) {
|
|
||||||
return target.invokeInternal.bind(target, prop);
|
|
||||||
}
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
hasPublicFunction(name) {
|
|
||||||
return (name in this.module.functions);
|
|
||||||
}
|
|
||||||
|
|
||||||
invokeInternal(name, ...args) {
|
|
||||||
log('invoking', this.module.name.full + '.' + name, 'with args', args);
|
|
||||||
const content = this.module.functions[name].code;
|
|
||||||
const passingArguments = _.zipObject(this.module.functions[name].parameters, args);
|
|
||||||
if(!content) throw new TypeError(name + ' is not a function!');
|
|
||||||
return evalInContext(content, this.context, this.locals, passingArguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
get link () {
|
|
||||||
return this._link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function evalInContext(js, context, locals, passingArguments) {
|
|
||||||
//# Return the results of the in-line anonymous function we .call with the passed context
|
|
||||||
// log('='.repeat(80) + 'OG Block');
|
|
||||||
// log(js);
|
|
||||||
// log('='.repeat(80) + 'Arguments');
|
|
||||||
// log(passingArguments);
|
|
||||||
const that = this;
|
|
||||||
return function() {
|
|
||||||
const preminJs =
|
|
||||||
`'use strict';
|
|
||||||
(() => {
|
|
||||||
${locals.map((k) => `const ${k} = this.${k};`).join('\n\t')}
|
|
||||||
${Object.keys(passingArguments).map(name => `let ${name} = passingArguments.${name};`).join('\n\t')}
|
|
||||||
${js}
|
|
||||||
})();`;
|
|
||||||
// log('='.repeat(80) + 'preminjs');
|
|
||||||
// log(preminJs);
|
|
||||||
const newJs = minify(preminJs);
|
|
||||||
// log('='.repeat(80) + 'minjs');
|
|
||||||
// log(newJs);
|
|
||||||
// newJs should inject into result...
|
|
||||||
let result;
|
|
||||||
eval(newJs);
|
|
||||||
return result;
|
|
||||||
}.call(context);
|
|
||||||
}
|
|
||||||
|
|
@ -11,15 +11,22 @@
|
||||||
"c": "nearleyc",
|
"c": "nearleyc",
|
||||||
"test": "node run.js test",
|
"test": "node run.js test",
|
||||||
"debug": "cross-env DEBUG=vogue:* yarn test",
|
"debug": "cross-env DEBUG=vogue:* yarn test",
|
||||||
"postinstall": "cd test && yarn"
|
"postinstall": "cd test && yarn",
|
||||||
|
"tsc": "tsc"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/debug": "^4.1.5",
|
||||||
|
"@types/lodash": "^4.14.169",
|
||||||
|
"@types/nearley": "^2.11.1",
|
||||||
|
"@types/node": "^15.3.0",
|
||||||
|
"@types/uglify-js": "^3.13.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"debug": "^4.3.1",
|
"debug": "^4.3.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"moo": "^0.5.1",
|
"moo": "^0.5.1",
|
||||||
"nearley": "^2.20.1",
|
"nearley": "^2.20.1",
|
||||||
"nedb": "^1.8.0",
|
"nedb": "^1.8.0",
|
||||||
|
"typescript": "^4.2.4",
|
||||||
"uglify-js": "^3.13.5",
|
"uglify-js": "^3.13.5",
|
||||||
"yarn": "^1.22.10"
|
"yarn": "^1.22.10"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,109 @@
|
||||||
|
|
||||||
|
import Serializable from './Serializable.js';
|
||||||
|
import minify from './minify.js';
|
||||||
|
import debug from 'debug';
|
||||||
|
import _ from 'lodash';
|
||||||
|
const log = debug('vogue:instance');
|
||||||
|
import vm from 'vm';
|
||||||
|
/**
|
||||||
|
* @typedef {import('./System.js').default} System
|
||||||
|
* @typedef {import('./Module.js').default} Module
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
export default class Instance extends Serializable {
|
||||||
|
/** @type {Module} */
|
||||||
|
module = null;
|
||||||
|
links = {}
|
||||||
|
system = null;
|
||||||
|
context = null;
|
||||||
|
locals = [];
|
||||||
|
internalFunctions = {};
|
||||||
|
/** @type {Proxy<Instance>} */
|
||||||
|
_link = null;
|
||||||
|
|
||||||
|
createContext() {
|
||||||
|
const initialContext = {};
|
||||||
|
|
||||||
|
// system globals!
|
||||||
|
// TODO turn this into its own vogue module! system.create/instance.create
|
||||||
|
// TODO request context from system...
|
||||||
|
initialContext.create = this.system.create.bind(this.system);
|
||||||
|
for(const name of this.system.staticInstances)
|
||||||
|
initialContext[name] = this.system.staticInstances[name];
|
||||||
|
|
||||||
|
// local links!
|
||||||
|
// optional arrays
|
||||||
|
// TODO maybe make these property accessors to allow for some automation
|
||||||
|
for(const name of this.module.links.optional.arrays)
|
||||||
|
initialContext[name] = [];
|
||||||
|
for(const name of this.module.links.optional.single)
|
||||||
|
initialContext[name] = null;
|
||||||
|
|
||||||
|
// local functions time!
|
||||||
|
// for(const name of this.module.functions)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// let ctx = vm.createContext({
|
||||||
|
// create: this.system.newInstance.bind(this.system),
|
||||||
|
// ...this.system.staticInstances,
|
||||||
|
// ...this.internalFunctions
|
||||||
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
// for(const name in this.module.imports) {
|
||||||
|
// ctx[name] = this.module.imports[name];
|
||||||
|
// this.locals.push(name);
|
||||||
|
// }
|
||||||
|
// ctx = {
|
||||||
|
// ...ctx,
|
||||||
|
|
||||||
|
// }
|
||||||
|
// for(const identifier in this.system.staticInstances) {
|
||||||
|
// this.locals.push(identifier);
|
||||||
|
// }
|
||||||
|
// // ctx.create =
|
||||||
|
// this.locals.push('create');
|
||||||
|
this.context = ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {Module} module
|
||||||
|
* @param {string} location
|
||||||
|
* @param {Object<string, any>} parameters
|
||||||
|
* @param {System} system
|
||||||
|
*/
|
||||||
|
constructor(module, location, parameters, system) {
|
||||||
|
super();
|
||||||
|
this.module = module;
|
||||||
|
this.location = location;
|
||||||
|
this.system = system;
|
||||||
|
|
||||||
|
this.createContext();
|
||||||
|
|
||||||
|
this._link = new Proxy(this, {
|
||||||
|
get(target, prop, receiver) {
|
||||||
|
if(prop === 'restore') return undefined;
|
||||||
|
if(prop in target.module.functions) {
|
||||||
|
// TODO return the fn
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
hasPublicFunction(name) {
|
||||||
|
return (name in this.module.functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
invokeInternal(name, ...args) {
|
||||||
|
log('invoking', this.module.name.full + '.' + name, 'with args', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
get link () {
|
||||||
|
return this._link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||||
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||||
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||||
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||||
|
function step(op) {
|
||||||
|
if (f) throw new TypeError("Generator is already executing.");
|
||||||
|
while (_) try {
|
||||||
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||||
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||||
|
switch (op[0]) {
|
||||||
|
case 0: case 1: t = op; break;
|
||||||
|
case 4: _.label++; return { value: op[1], done: false };
|
||||||
|
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||||
|
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||||
|
default:
|
||||||
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||||
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||||
|
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||||
|
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||||
|
if (t[2]) _.ops.pop();
|
||||||
|
_.trys.pop(); continue;
|
||||||
|
}
|
||||||
|
op = body.call(thisArg, _);
|
||||||
|
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||||
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
import { createAst } from './createAst';
|
||||||
|
import path from 'path';
|
||||||
|
import debug from 'debug';
|
||||||
|
import { createRequire } from 'module';
|
||||||
|
var log = debug('vogue:module');
|
||||||
|
var Module = /** @class */ (function () {
|
||||||
|
function Module() {
|
||||||
|
this.links = {
|
||||||
|
required: {
|
||||||
|
single: [],
|
||||||
|
arrays: []
|
||||||
|
},
|
||||||
|
optional: {
|
||||||
|
single: [],
|
||||||
|
arrays: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.globals = [];
|
||||||
|
this.functions = [];
|
||||||
|
this.identifiers = {};
|
||||||
|
this.name = {
|
||||||
|
space: '',
|
||||||
|
last: '',
|
||||||
|
full: ''
|
||||||
|
};
|
||||||
|
this.imports = {};
|
||||||
|
this.variables = {
|
||||||
|
cold: [],
|
||||||
|
warm: []
|
||||||
|
};
|
||||||
|
this.directives = {
|
||||||
|
'singleton': false,
|
||||||
|
'keepalive': false,
|
||||||
|
'static': ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Module.prototype.directive = function (_a) {
|
||||||
|
var directive = _a.directive, value = _a.value;
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
return __generator(this, function (_b) {
|
||||||
|
this.directives[directive] = value;
|
||||||
|
return [2 /*return*/];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Module.prototype.link = function (_a) {
|
||||||
|
var required = _a.required, array = _a.array, name = _a.name;
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
return __generator(this, function (_b) {
|
||||||
|
this.links[required ? 'required' : 'optional'][array ? 'arrays' : 'single']
|
||||||
|
.push(name);
|
||||||
|
return [2 /*return*/];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Module.prototype.namespace = function (_a) {
|
||||||
|
var namespace = _a.namespace;
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
return __generator(this, function (_b) {
|
||||||
|
this.name.space = namespace;
|
||||||
|
this.name.full = this.name.space + '.' + this.name.last;
|
||||||
|
return [2 /*return*/];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Module.prototype["function"] = function (_a) {
|
||||||
|
var name = _a.name, block = _a.block, parameters = _a.parameters;
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
return __generator(this, function (_b) {
|
||||||
|
this.functions[name] = {
|
||||||
|
code: block,
|
||||||
|
parameters: parameters
|
||||||
|
};
|
||||||
|
return [2 /*return*/];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Module.prototype["import"] = function (_a) {
|
||||||
|
var importName = _a.importName, name = _a.name;
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
var nodePath, __require__, imported;
|
||||||
|
return __generator(this, function (_b) {
|
||||||
|
nodePath = path.resolve(this.rootDir, 'node_module');
|
||||||
|
log('#'.repeat(80));
|
||||||
|
log(nodePath);
|
||||||
|
__require__ = createRequire(nodePath);
|
||||||
|
imported = __require__(importName);
|
||||||
|
if ('default' in imported)
|
||||||
|
this.imports[name] = imported["default"];
|
||||||
|
else
|
||||||
|
this.imports[name] = imported;
|
||||||
|
return [2 /*return*/];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Module.prototype.variable = function (_a) {
|
||||||
|
var persist = _a.persist, name = _a.name;
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
return __generator(this, function (_b) {
|
||||||
|
this.variables[persist ? 'cold' : 'warm'].push(name);
|
||||||
|
return [2 /*return*/];
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Module.create = function (location, rootDir) {
|
||||||
|
return __awaiter(this, void 0, void 0, function () {
|
||||||
|
var module, ast, name, _i, ast_1, item;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
module = new Module();
|
||||||
|
ast = createAst(location);
|
||||||
|
name = path.parse(location).name;
|
||||||
|
module.name.last = name;
|
||||||
|
module.name.full = name;
|
||||||
|
module.rootDir = rootDir;
|
||||||
|
_i = 0, ast_1 = ast;
|
||||||
|
_a.label = 1;
|
||||||
|
case 1:
|
||||||
|
if (!(_i < ast_1.length)) return [3 /*break*/, 4];
|
||||||
|
item = ast_1[_i];
|
||||||
|
if ('name' in item) {
|
||||||
|
if (item.name in module.identifiers)
|
||||||
|
throw new Error('Identifier ' + item.name + ' already declared!');
|
||||||
|
else
|
||||||
|
module.identifiers[item.name] = item.type;
|
||||||
|
}
|
||||||
|
if (!(item.type in module)) return [3 /*break*/, 3];
|
||||||
|
return [4 /*yield*/, module[item.type](item)];
|
||||||
|
case 2:
|
||||||
|
_a.sent();
|
||||||
|
_a.label = 3;
|
||||||
|
case 3:
|
||||||
|
_i++;
|
||||||
|
return [3 /*break*/, 1];
|
||||||
|
case 4:
|
||||||
|
log('='.repeat(80));
|
||||||
|
log(location);
|
||||||
|
log(module);
|
||||||
|
return [2 /*return*/, module];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
return Module;
|
||||||
|
}());
|
||||||
|
export default Module;
|
||||||
|
|
@ -1,23 +1,25 @@
|
||||||
import createAst from './createAst.js'
|
import { createAst, DirectiveRule, DirectiveValue, FunctionRule, ImportRule, LinkRule, NamespaceRule, VariableRule } from './createAst'
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
import { createRequire } from 'module';
|
import { createRequire } from 'module';
|
||||||
import { pathToFileURL } from 'url';
|
import { pathToFileURL } from 'url';
|
||||||
const log = debug('vogue:module');
|
const log = debug('vogue:module');
|
||||||
|
|
||||||
export default class Module {
|
type Link = {
|
||||||
links = {
|
name: string,
|
||||||
required: {
|
array: boolean,
|
||||||
single: [],
|
required: boolean
|
||||||
arrays: []
|
|
||||||
},
|
|
||||||
optional: {
|
|
||||||
single: [],
|
|
||||||
arrays: []
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
export default class Module {
|
||||||
|
links: Link[] = [];
|
||||||
globals = [];
|
globals = [];
|
||||||
functions = [];
|
functions: {
|
||||||
|
[name: string]: {
|
||||||
|
code: string,
|
||||||
|
parameters: string[]
|
||||||
|
}
|
||||||
|
} = {};
|
||||||
identifiers = {};
|
identifiers = {};
|
||||||
name = {
|
name = {
|
||||||
space: '',
|
space: '',
|
||||||
|
|
@ -28,35 +30,42 @@ export default class Module {
|
||||||
variables = {
|
variables = {
|
||||||
cold: [],
|
cold: [],
|
||||||
warm: []
|
warm: []
|
||||||
}
|
};
|
||||||
singleton = false;
|
directives: {
|
||||||
keepalive = false;
|
[key: string]: DirectiveValue
|
||||||
'static' = null;
|
} = {
|
||||||
|
'singleton': false,
|
||||||
|
'keepalive': false,
|
||||||
|
'static': ''
|
||||||
|
};
|
||||||
|
rootDir: string = '';
|
||||||
|
|
||||||
async directive({directive, value}) {
|
|
||||||
this[directive] = value ?? true;
|
async directive({directive, value}: DirectiveRule) {
|
||||||
|
this.directives[directive] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
async link({required, array, name}) {
|
async link({required, array, name}: LinkRule) {
|
||||||
this.links
|
this.links.push({
|
||||||
[required ? 'required' : 'optional']
|
name,
|
||||||
[array ? 'arrays' : 'single']
|
required,
|
||||||
.push(name);
|
array
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async namespace({namespace}) {
|
async namespace({namespace}: NamespaceRule) {
|
||||||
this.name.space = namespace;
|
this.name.space = namespace;
|
||||||
this.name.full = this.name.space + '.' + this.name.last;
|
this.name.full = this.name.space + '.' + this.name.last;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function({name, block, parameters}) {
|
async function({name, block, parameters}: FunctionRule) {
|
||||||
this.functions[name] = {
|
this.functions[name] = {
|
||||||
code: block,
|
code: block,
|
||||||
parameters
|
parameters
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async import({importName, name}) {
|
async import({importName, name}: ImportRule) {
|
||||||
const nodePath = path.resolve(this.rootDir, 'node_module');
|
const nodePath = path.resolve(this.rootDir, 'node_module');
|
||||||
log('#'.repeat(80));
|
log('#'.repeat(80));
|
||||||
log(nodePath);
|
log(nodePath);
|
||||||
|
|
@ -66,11 +75,11 @@ export default class Module {
|
||||||
else this.imports[name] = imported;
|
else this.imports[name] = imported;
|
||||||
}
|
}
|
||||||
|
|
||||||
async variable({persist, name}) {
|
async variable({persist, name}: VariableRule) {
|
||||||
this.variables[persist ? 'cold' : 'warm'].push(name);
|
this.variables[persist ? 'cold' : 'warm'].push(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static async create(location, rootDir) {
|
static async create(location: string, rootDir: string) {
|
||||||
const module = new Module();
|
const module = new Module();
|
||||||
const ast = createAst(location);
|
const ast = createAst(location);
|
||||||
const name = path.parse(location).name;
|
const name = path.parse(location).name;
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
var __extends = (this && this.__extends) || (function () {
|
||||||
|
var extendStatics = function (d, b) {
|
||||||
|
extendStatics = Object.setPrototypeOf ||
|
||||||
|
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||||
|
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||||
|
return extendStatics(d, b);
|
||||||
|
};
|
||||||
|
return function (d, b) {
|
||||||
|
if (typeof b !== "function" && b !== null)
|
||||||
|
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||||
|
extendStatics(d, b);
|
||||||
|
function __() { this.constructor = d; }
|
||||||
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
import Instance from './Instance';
|
||||||
|
import Serializable from './Serializable';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import Module from './Module';
|
||||||
|
import debug from 'debug';
|
||||||
|
var log = debug('vogue:system');
|
||||||
|
var get = _.get, set = _.set;
|
||||||
|
var System = /** @class */ (function (_super) {
|
||||||
|
__extends(System, _super);
|
||||||
|
function System(modules, rootDir) {
|
||||||
|
var _this = _super.call(this) || this;
|
||||||
|
_this.instances = [];
|
||||||
|
_this.namespace = {};
|
||||||
|
_this.staticInstances = {};
|
||||||
|
_this.modules = modules;
|
||||||
|
_this.createNamespace();
|
||||||
|
var bootModules = _this.deriveBootModules();
|
||||||
|
_this.createStaticInstances();
|
||||||
|
_this.rootDir = rootDir;
|
||||||
|
log('instantiating boot modules...');
|
||||||
|
for (var _i = 0, bootModules_1 = bootModules; _i < bootModules_1.length; _i++) {
|
||||||
|
var name_1 = bootModules_1[_i];
|
||||||
|
log(' ' + name_1);
|
||||||
|
_this.newInstance(name_1);
|
||||||
|
}
|
||||||
|
return _this;
|
||||||
|
}
|
||||||
|
System.prototype.createStaticInstances = function () {
|
||||||
|
log('deriving static modules...');
|
||||||
|
var staticModules = this.modules.filter(function (module) {
|
||||||
|
return !!module.static;
|
||||||
|
}).map(function (module) {
|
||||||
|
log(' ' + module.name.full);
|
||||||
|
return module;
|
||||||
|
});
|
||||||
|
log('instantiating static modules...');
|
||||||
|
for (var _i = 0, staticModules_1 = staticModules; _i < staticModules_1.length; _i++) {
|
||||||
|
var module_1 = staticModules_1[_i];
|
||||||
|
log(' ' + module_1.static + ': ' + module_1.name.full);
|
||||||
|
this.staticInstances[module_1.static] =
|
||||||
|
this.newInstance(module_1.name.full, {});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
System.prototype.deriveBootModules = function () {
|
||||||
|
log('deriving boot modules...');
|
||||||
|
var bootModules = this.modules.filter(function (module) {
|
||||||
|
return module.singleton;
|
||||||
|
}).map(function (module) {
|
||||||
|
return module.name.full;
|
||||||
|
});
|
||||||
|
for (var _i = 0, bootModules_2 = bootModules; _i < bootModules_2.length; _i++) {
|
||||||
|
var name_2 = bootModules_2[_i];
|
||||||
|
log(' ' + name_2);
|
||||||
|
}
|
||||||
|
return bootModules;
|
||||||
|
};
|
||||||
|
System.prototype.createNamespace = function () {
|
||||||
|
log('creating namespace map...');
|
||||||
|
this.namespace = this.modules.reduce(function (acc, val) {
|
||||||
|
if (get(acc, val.name.full) instanceof Module)
|
||||||
|
throw new Error('Duplicate module "' + val.name.full + '"');
|
||||||
|
set(acc, val.name.full, val);
|
||||||
|
log(' ' + val.name.full);
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
System.prototype.getModule = function (name) {
|
||||||
|
return get(this.namespace, name);
|
||||||
|
};
|
||||||
|
System.prototype.createInstance = function (name, args) {
|
||||||
|
if (args === void 0) { args = {}; }
|
||||||
|
return new Instance(this.getModule(name), null, args, this);
|
||||||
|
};
|
||||||
|
System.prototype.newInstance = function (name, args) {
|
||||||
|
if (args === void 0) { args = {}; }
|
||||||
|
var instance = this.createInstance(name, args);
|
||||||
|
var link = instance.link;
|
||||||
|
if (instance.hasPublicFunction('restore'))
|
||||||
|
instance.invokeInternal('restore');
|
||||||
|
return link;
|
||||||
|
};
|
||||||
|
return System;
|
||||||
|
}(Serializable));
|
||||||
|
export default System;
|
||||||
|
|
@ -1,19 +1,28 @@
|
||||||
import Instance from './Instance.js';
|
import Instance from './Instance';
|
||||||
import Serializable from './Serializable.js';
|
import Serializable from './Serializable';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Module from './Module.js';
|
import Module from './Module';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
const log = debug('vogue:system')
|
const log = debug('vogue:system')
|
||||||
|
|
||||||
const {get, set} = _;
|
const {get, set} = _;
|
||||||
|
|
||||||
export default class System extends Serializable {
|
type ModuleNamespaceMap = {
|
||||||
instances = [];
|
[key: string]: ModuleNamespaceMap | Module
|
||||||
modules = null;
|
};
|
||||||
namespace = null;
|
|
||||||
staticInstances = {};
|
|
||||||
|
|
||||||
constructor(modules, rootDir) {
|
type ModuleName = string;
|
||||||
|
|
||||||
|
class System extends Serializable {
|
||||||
|
instances: Instance[] = [];
|
||||||
|
modules: Module[];
|
||||||
|
namespace: ModuleNamespaceMap = {};
|
||||||
|
staticInstances: {
|
||||||
|
[key: string]: Instance
|
||||||
|
} = {};
|
||||||
|
rootDir: string;
|
||||||
|
|
||||||
|
constructor(modules: Module[], rootDir: string) {
|
||||||
super();
|
super();
|
||||||
this.modules = modules;
|
this.modules = modules;
|
||||||
this.createNamespace();
|
this.createNamespace();
|
||||||
|
|
@ -70,15 +79,15 @@ export default class System extends Serializable {
|
||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
getModule(name) {
|
getModule(name: ModuleName) {
|
||||||
return get(this.namespace, name);
|
return get(this.namespace, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
createInstance(name, args = {}) {
|
createInstance(name: ModuleName, args = {}) {
|
||||||
return new Instance(this.getModule(name), null, args, this);
|
return new Instance(this.getModule(name), null, args, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
newInstance(name, args = {}) {
|
newInstance(name: ModuleName, args = {}) {
|
||||||
const instance = this.createInstance(name, args);
|
const instance = this.createInstance(name, args);
|
||||||
const link = instance.link;
|
const link = instance.link;
|
||||||
if(instance.hasPublicFunction('restore'))
|
if(instance.hasPublicFunction('restore'))
|
||||||
|
|
@ -86,3 +95,5 @@ export default class System extends Serializable {
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default System;
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
import nearley from 'nearley';
|
||||||
|
// TODO none of these shits have typings, but its OKAY
|
||||||
|
// @ts-ignore
|
||||||
|
import compile from 'nearley/lib/compile.js';
|
||||||
|
// @ts-ignore
|
||||||
|
import generate from 'nearley/lib/generate.js';
|
||||||
|
// @ts-ignore
|
||||||
|
import nearleyGrammar from 'nearley/lib/nearley-language-bootstrapped.js';
|
||||||
|
// @ts-ignore
|
||||||
|
import moo from 'moo';
|
||||||
|
import tokens from './tokens';
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
|
import debug from 'debug';
|
||||||
|
import { resolve, dirname } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
var log = debug('vogue:ast');
|
||||||
|
var grammarFile = resolve(fileURLToPath(dirname(import.meta.url)), 'grammar.ne');
|
||||||
|
log('grammarFile:', grammarFile);
|
||||||
|
function createParser() {
|
||||||
|
// Parse the grammar source into an AST
|
||||||
|
var grammarParser = new nearley.Parser(nearleyGrammar);
|
||||||
|
grammarParser.feed(readFileSync(grammarFile).toString());
|
||||||
|
var grammarAst = grammarParser.results[0]; // TODO check for errors
|
||||||
|
// Compile the AST into a set of rules
|
||||||
|
var grammarInfoObject = compile(grammarAst, {});
|
||||||
|
// Generate JavaScript code from the rules
|
||||||
|
var grammarJs = generate(grammarInfoObject, "grammar");
|
||||||
|
var lexer = moo.compile(tokens);
|
||||||
|
// lexer.__proto__.formatError = function(token, message) {
|
||||||
|
// if (token == null) {
|
||||||
|
// // An undefined token indicates EOF
|
||||||
|
// var text = this.buffer.slice(this.index)
|
||||||
|
// var token = {
|
||||||
|
// text: text,
|
||||||
|
// offset: this.index,
|
||||||
|
// lineBreaks: text.indexOf('\n') === -1 ? 0 : 1,
|
||||||
|
// line: this.line,
|
||||||
|
// col: this.col,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// var start = Math.max(0, token.offset - token.col + 1)
|
||||||
|
// var eol = token.lineBreaks ? token.text.indexOf('\n') : token.text.length
|
||||||
|
// var firstLine = this.buffer.substring(start, token.offset + eol)
|
||||||
|
// message += " at line " + token.line + " col " + token.col + ":\n\n"
|
||||||
|
// message += " " + firstLine + "\n"
|
||||||
|
// message += " " + Array(token.col).join(" ") + "^"
|
||||||
|
// return message
|
||||||
|
// }
|
||||||
|
// Pretend this is a CommonJS environment to catch exports from the grammar.
|
||||||
|
var module = { exports: {} };
|
||||||
|
eval(grammarJs);
|
||||||
|
var grammar = module.exports;
|
||||||
|
// THESE IS COMPLICATED SHITS, IDK MAN WHAT ARE TYPINGS
|
||||||
|
// @ts-ignore
|
||||||
|
return new nearley.Parser(nearley.Grammar.fromCompiled(grammar));
|
||||||
|
}
|
||||||
|
export function createAst(location) {
|
||||||
|
var parser = createParser();
|
||||||
|
var contents = readFileSync(location).toString();
|
||||||
|
// parser.reportError = function(token) {
|
||||||
|
// return JSON.stringify(token, null, 2);
|
||||||
|
// var message = this.lexer.formatError(token, 'invalid syntax') + '\n';
|
||||||
|
// message += 'Unexpected ' + (token.type ? token.type + ' token: ' : '');
|
||||||
|
// message +=
|
||||||
|
// JSON.stringify(token.value !== undefined ? token.value : token) + '\n';
|
||||||
|
// return message;
|
||||||
|
// };
|
||||||
|
parser.feed(contents);
|
||||||
|
parser.finish();
|
||||||
|
var ast = parser.results[0];
|
||||||
|
log('='.repeat(80));
|
||||||
|
log(location);
|
||||||
|
log(ast);
|
||||||
|
return ast || [];
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,20 @@
|
||||||
import nearley from 'nearley';
|
import nearley from 'nearley';
|
||||||
|
// TODO none of these shits have typings, but its OKAY
|
||||||
|
// @ts-ignore
|
||||||
import compile from 'nearley/lib/compile.js';
|
import compile from 'nearley/lib/compile.js';
|
||||||
|
// @ts-ignore
|
||||||
import generate from 'nearley/lib/generate.js';
|
import generate from 'nearley/lib/generate.js';
|
||||||
|
// @ts-ignore
|
||||||
import nearleyGrammar from 'nearley/lib/nearley-language-bootstrapped.js';
|
import nearleyGrammar from 'nearley/lib/nearley-language-bootstrapped.js';
|
||||||
|
// @ts-ignore
|
||||||
import moo from 'moo';
|
import moo from 'moo';
|
||||||
import tokens from './tokens.js';
|
|
||||||
|
import tokens from './tokens';
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import debug from 'debug';
|
import debug from 'debug';
|
||||||
import { resolve, dirname } from 'path';
|
import { resolve, dirname } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import minify from './minify.js';
|
import minify from './minify';
|
||||||
|
|
||||||
const log = debug('vogue:ast');
|
const log = debug('vogue:ast');
|
||||||
const grammarFile = resolve(fileURLToPath(dirname(import.meta.url)), 'grammar.ne');
|
const grammarFile = resolve(fileURLToPath(dirname(import.meta.url)), 'grammar.ne');
|
||||||
|
|
@ -53,10 +59,61 @@ function createParser() {
|
||||||
eval(grammarJs);
|
eval(grammarJs);
|
||||||
|
|
||||||
const grammar = module.exports;
|
const grammar = module.exports;
|
||||||
|
// THESE IS COMPLICATED SHITS, IDK MAN WHAT ARE TYPINGS
|
||||||
|
// @ts-ignore
|
||||||
return new nearley.Parser(nearley.Grammar.fromCompiled(grammar))
|
return new nearley.Parser(nearley.Grammar.fromCompiled(grammar))
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function createAst(location) {
|
|
||||||
|
export type FunctionRule = {
|
||||||
|
type: 'function',
|
||||||
|
name: string
|
||||||
|
block: string,
|
||||||
|
parameters: string[]
|
||||||
|
};
|
||||||
|
|
||||||
|
export type VariableRule = {
|
||||||
|
type: 'variable',
|
||||||
|
persist: boolean,
|
||||||
|
name: string
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NamespaceRule = {
|
||||||
|
type: 'namesapce',
|
||||||
|
namespace: string
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ImportRule = {
|
||||||
|
type: 'import',
|
||||||
|
name: string,
|
||||||
|
importName: string
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LinkRule = {
|
||||||
|
type: 'link',
|
||||||
|
array: boolean,
|
||||||
|
required: boolean,
|
||||||
|
name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DirectiveValue = string | boolean;
|
||||||
|
|
||||||
|
export type DirectiveRule = {
|
||||||
|
type: 'directive',
|
||||||
|
directive: 'static' | 'singleton' | 'keepalive',
|
||||||
|
value: DirectiveValue
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Rule = FunctionRule
|
||||||
|
| VariableRule
|
||||||
|
| ImportRule
|
||||||
|
| DirectiveRule
|
||||||
|
| LinkRule
|
||||||
|
| NamespaceRule;
|
||||||
|
|
||||||
|
export type AST = Rule[];
|
||||||
|
|
||||||
|
export function createAst(location: string): AST {
|
||||||
const parser = createParser();
|
const parser = createParser();
|
||||||
const contents = readFileSync(location).toString();
|
const contents = readFileSync(location).toString();
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ FUNCTION_DECLARATION -> _ IDENTIFIER _ PARAMETERS:? _ JS_BLOCK EOL {% ([,name,,p
|
||||||
| _ %ASYNC __ IDENTIFIER _ PARAMETERS:? _ JS_BLOCK_ASYNC EOL {% ([,,,name,,params,,block]) => { return { type: 'function', name: name, block, parameters: params } } %}
|
| _ %ASYNC __ IDENTIFIER _ PARAMETERS:? _ JS_BLOCK_ASYNC EOL {% ([,,,name,,params,,block]) => { return { type: 'function', name: name, block, parameters: params } } %}
|
||||||
|
|
||||||
DIRECTIVE_STATEMENT -> DIRECTIVE __ IDENTIFIER EOL {% ([directive,,identifier]) => { return { type: 'directive', directive, value: identifier }} %}
|
DIRECTIVE_STATEMENT -> DIRECTIVE __ IDENTIFIER EOL {% ([directive,,identifier]) => { return { type: 'directive', directive, value: identifier }} %}
|
||||||
| DIRECTIVE EOL {% ([directive]) => { return { type: 'directive', directive }} %}
|
| DIRECTIVE EOL {% ([directive]) => { return { type: 'directive', directive, value: true }} %}
|
||||||
|
|
||||||
DIRECTIVE -> %SINGLETON {% () => 'singleton' %}
|
DIRECTIVE -> %SINGLETON {% () => 'singleton' %}
|
||||||
| %KEEPALIVE {% () => 'keepalive' %}
|
| %KEEPALIVE {% () => 'keepalive' %}
|
||||||
|
|
@ -42,10 +42,10 @@ EOL -> _ %SEMICOLON:?
|
||||||
STRING -> %STRING {% ([d]) => d.value.substring(1, d.value.length - 1) %}
|
STRING -> %STRING {% ([d]) => d.value.substring(1, d.value.length - 1) %}
|
||||||
SEMICOLON -> %SEMICOLON
|
SEMICOLON -> %SEMICOLON
|
||||||
IDENTIFIER -> %IDENTIFIER {% ([id]) => id.value %}
|
IDENTIFIER -> %IDENTIFIER {% ([id]) => id.value %}
|
||||||
JS_BLOCK -> %JS_BLOCK {% ([block]) => minify(`result = (() => {${block.value.substring(2, block.value.length - 2)}})();`) %}
|
JS_BLOCK -> %JS_BLOCK {% ([block]) => (`(() => {${block.value.substring(2, block.value.length - 2)}});`) %}
|
||||||
| %JS_BLOCK2 {% ([block]) => minify(`result = (() => {${block.value.substring(1, block.value.length - 1)}})();`) %}
|
| %JS_BLOCK2 {% ([block]) => (`(() => {${block.value.substring(1, block.value.length - 1)}});`) %}
|
||||||
JS_BLOCK_ASYNC -> %JS_BLOCK {% ([block]) => minify(`result = (async () => {${block.value.substring(2, block.value.length - 2)}})();`) %}
|
JS_BLOCK_ASYNC -> %JS_BLOCK {% ([block]) => (`(async () => {${block.value.substring(2, block.value.length - 2)}});`) %}
|
||||||
| %JS_BLOCK2 {% ([block]) => minify(`result = (async () => {${block.value.substring(1, block.value.length - 1)}})();`) %}
|
| %JS_BLOCK2 {% ([block]) => (`(async () => {${block.value.substring(1, block.value.length - 1)}});`) %}
|
||||||
SPREAD_OPERATOR -> %SPREAD_OPERATOR
|
SPREAD_OPERATOR -> %SPREAD_OPERATOR
|
||||||
_ -> null | %SPACE {% () => undefined %}
|
_ -> null | %SPACE {% () => undefined %}
|
||||||
__ -> %SPACE {% () => undefined %}
|
__ -> %SPACE {% () => undefined %}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import uglify from 'uglify-js';
|
||||||
|
export default (function (code) {
|
||||||
|
return uglify.minify(code, {
|
||||||
|
compress: {
|
||||||
|
dead_code: true,
|
||||||
|
global_defs: {
|
||||||
|
DEBUG: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sourceMap: {
|
||||||
|
content: 'inline'
|
||||||
|
}
|
||||||
|
}).code;
|
||||||
|
});
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import uglify from 'uglify-js';
|
import uglify from 'uglify-js';
|
||||||
|
|
||||||
export default (code) => {
|
export default (code: string): string => {
|
||||||
return uglify.minify(code, {
|
return uglify.minify(code, {
|
||||||
compress: {
|
compress: {
|
||||||
dead_code: true,
|
dead_code: true,
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
||||||
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
||||||
|
return new (P || (P = Promise))(function (resolve, reject) {
|
||||||
|
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
||||||
|
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
||||||
|
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
||||||
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
||||||
|
});
|
||||||
|
};
|
||||||
|
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||||
|
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
||||||
|
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
||||||
|
function verb(n) { return function (v) { return step([n, v]); }; }
|
||||||
|
function step(op) {
|
||||||
|
if (f) throw new TypeError("Generator is already executing.");
|
||||||
|
while (_) try {
|
||||||
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
||||||
|
if (y = 0, t) op = [op[0] & 2, t.value];
|
||||||
|
switch (op[0]) {
|
||||||
|
case 0: case 1: t = op; break;
|
||||||
|
case 4: _.label++; return { value: op[1], done: false };
|
||||||
|
case 5: _.label++; y = op[1]; op = [0]; continue;
|
||||||
|
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
||||||
|
default:
|
||||||
|
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
||||||
|
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
||||||
|
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
||||||
|
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
||||||
|
if (t[2]) _.ops.pop();
|
||||||
|
_.trys.pop(); continue;
|
||||||
|
}
|
||||||
|
op = body.call(thisArg, _);
|
||||||
|
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
||||||
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var __spreadArray = (this && this.__spreadArray) || function (to, from) {
|
||||||
|
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
|
||||||
|
to[j] = from[i];
|
||||||
|
return to;
|
||||||
|
};
|
||||||
|
import debug from 'debug';
|
||||||
|
var log = debug('vogue:cli');
|
||||||
|
var systemLocation = resolve(process.argv[2]);
|
||||||
|
import { parse, resolve, dirname } from 'path';
|
||||||
|
import { readdirSync, lstatSync } from 'fs';
|
||||||
|
import _ from 'lodash';
|
||||||
|
import Module from './Module';
|
||||||
|
import System from './System';
|
||||||
|
import './extensions.js';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
var get = _.get, set = _.set;
|
||||||
|
var standardLibrary = resolve(fileURLToPath(dirname(import.meta.url)), 'lib');
|
||||||
|
(function () { return __awaiter(void 0, void 0, void 0, function () {
|
||||||
|
var ignoreDeps, files, fullpaths, modules, sys;
|
||||||
|
return __generator(this, function (_a) {
|
||||||
|
switch (_a.label) {
|
||||||
|
case 0:
|
||||||
|
ignoreDeps = function (path) { return parse(path).name !== 'node_modules'; };
|
||||||
|
files = __spreadArray(__spreadArray([], walkdirSync(systemLocation, ignoreDeps)), walkdirSync(standardLibrary, ignoreDeps));
|
||||||
|
fullpaths = files
|
||||||
|
.filter(function (v) { return lstatSync(v).isFile(); })
|
||||||
|
.filter(function (v) { return parse(v).ext === '.v'; });
|
||||||
|
log('included modules');
|
||||||
|
log(files);
|
||||||
|
log('parsing modules...');
|
||||||
|
return [4 /*yield*/, Promise.all(fullpaths.map(function (loc) { return Module.create(loc, systemLocation); }))];
|
||||||
|
case 1:
|
||||||
|
modules = _a.sent();
|
||||||
|
sys = new System(modules, systemLocation);
|
||||||
|
return [2 /*return*/];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}); })();
|
||||||
|
function walkdirSync(root, filter) {
|
||||||
|
if (filter === void 0) { filter = function () { return true; }; }
|
||||||
|
log('reading', root, '...');
|
||||||
|
var paths = readdirSync(root).map(function (v) { return resolve(root, v); });
|
||||||
|
var _a = sift(paths.filter(filter), function (v) { return lstatSync(v).isFile(); }), files = _a[0], dirs = _a[1];
|
||||||
|
log("files: " + files.length + " | dirs: " + dirs.length);
|
||||||
|
var rfiles = dirs.map(function (v) { return walkdirSync(v, filter); }).reduce(function (a, v) { return __spreadArray(__spreadArray([], a), v); }, []);
|
||||||
|
return __spreadArray(__spreadArray([], files), rfiles);
|
||||||
|
}
|
||||||
|
function sift(a, fn) {
|
||||||
|
var left = [], right = [];
|
||||||
|
for (var i = 0; i < a.length; i++) {
|
||||||
|
var v = a[i];
|
||||||
|
var lr = !!fn(v, i, a);
|
||||||
|
if (lr)
|
||||||
|
left = __spreadArray(__spreadArray([], left), [v]);
|
||||||
|
else
|
||||||
|
right = __spreadArray(__spreadArray([], right), [v]);
|
||||||
|
}
|
||||||
|
return [left, right];
|
||||||
|
}
|
||||||
|
|
@ -7,19 +7,19 @@ import { parse, resolve, dirname } from 'path';
|
||||||
import { readdirSync, lstatSync } from 'fs';
|
import { readdirSync, lstatSync } from 'fs';
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import Module from './Module.js';
|
import Module from './Module';
|
||||||
import System from './System.js';
|
import System from './System';
|
||||||
import './extensions.js';
|
import './extensions.js';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
// globals inside grammar context
|
// globals inside grammar context
|
||||||
import minify from './minify.js';
|
import minify from './minify';
|
||||||
|
|
||||||
const { get, set } = _;
|
const { get, set } = _;
|
||||||
const standardLibrary = resolve(fileURLToPath(dirname(import.meta.url)), 'lib');
|
const standardLibrary = resolve(fileURLToPath(dirname(import.meta.url)), 'lib');
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
// TODO simplify this line gaddam
|
// TODO simplify this line gaddam
|
||||||
const ignoreDeps = (path) => parse(path).name !== 'node_modules';
|
const ignoreDeps = (path: string) => parse(path).name !== 'node_modules';
|
||||||
|
|
||||||
const files = [
|
const files = [
|
||||||
...walkdirSync(systemLocation, ignoreDeps),
|
...walkdirSync(systemLocation, ignoreDeps),
|
||||||
|
|
@ -37,10 +37,10 @@ const standardLibrary = resolve(fileURLToPath(dirname(import.meta.url)), 'lib');
|
||||||
const sys = new System(modules, systemLocation);
|
const sys = new System(modules, systemLocation);
|
||||||
})()
|
})()
|
||||||
|
|
||||||
function walkdirSync(root, filter = () => true) {
|
function walkdirSync(root: string, filter: ((path: string) => boolean) = () => true): string[] {
|
||||||
log('reading', root, '...');
|
log('reading', root, '...');
|
||||||
const paths = readdirSync(root).map(v => resolve(root, v));
|
const paths = readdirSync(root).map(v => resolve(root, v));
|
||||||
const [ files, dirs ] = sift(paths.filter(filter), (v) => lstatSync(v).isFile());
|
const [ files, dirs ] = sift(paths.filter(filter), (v: string) => lstatSync(v).isFile());
|
||||||
log(`files: ${files.length} | dirs: ${dirs.length}`);
|
log(`files: ${files.length} | dirs: ${dirs.length}`);
|
||||||
const rfiles = dirs.map(v => walkdirSync(v, filter)).reduce((a, v) => [...a, ...v], []);
|
const rfiles = dirs.map(v => walkdirSync(v, filter)).reduce((a, v) => [...a, ...v], []);
|
||||||
|
|
||||||
|
|
@ -50,15 +50,8 @@ function walkdirSync(root, filter = () => true) {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
function sift<T>(a: T[], fn: (v: T, i: number, a: T[]) => boolean): [T[], T[]] {
|
||||||
*
|
let left: T[] = [], right: T[] = [];
|
||||||
* @param {T[]} a
|
|
||||||
* @param {(v: T, i: number, a: T[]) => string} fn
|
|
||||||
*
|
|
||||||
* @returns {Object<string, T[]>}
|
|
||||||
*/
|
|
||||||
function sift(a, fn) {
|
|
||||||
let left = [], right = [];
|
|
||||||
for(let i = 0; i < a.length; i ++) {
|
for(let i = 0; i < a.length; i ++) {
|
||||||
const v = a[i]
|
const v = a[i]
|
||||||
const lr = !!fn(v, i, a);
|
const lr = !!fn(v, i, a);
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
export default {
|
||||||
|
LINK: 'link',
|
||||||
|
NAMESPACE: 'namespace',
|
||||||
|
REQUIRED: 'required',
|
||||||
|
SINGLETON: 'singleton',
|
||||||
|
KEEPALIVE: 'keepalive',
|
||||||
|
STATIC: 'static',
|
||||||
|
MEMBER: 'member',
|
||||||
|
RUNTIME: 'runtime',
|
||||||
|
IMPORT: 'import',
|
||||||
|
ASYNC: 'async',
|
||||||
|
AS: 'as',
|
||||||
|
FROM: 'from',
|
||||||
|
COMMA: ',',
|
||||||
|
STRING: /'(?:\\['\\]|[^\n'\\])*'/,
|
||||||
|
LSQBRACKET: '[',
|
||||||
|
RSQBRACKET: ']',
|
||||||
|
LPAREN: '(',
|
||||||
|
RPAREN: ')',
|
||||||
|
SPREAD_OPERATOR: '...',
|
||||||
|
DOTOP: '.',
|
||||||
|
JS_BLOCK: /\[\[[^]*?\n\]\]$/,
|
||||||
|
JS_BLOCK2: /{[^]*?\n}$/,
|
||||||
|
IDENTIFIER: /[a-zA-Z][a-zA-Z0-9]*/,
|
||||||
|
SPACE: { match: /\s+/, lineBreaks: true },
|
||||||
|
SEMICOLON: ';'
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
restore {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
namespace places;
|
|
||||||
|
|
||||||
required link world;
|
|
||||||
link[] roads;
|
|
||||||
|
|
||||||
member nitrogen;
|
|
||||||
|
|
||||||
restore {
|
|
||||||
this.nitrogen ??= Math.floor(Math.random() * 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
namespace places
|
|
||||||
26
test/world.v
26
test/world.v
|
|
@ -1,28 +1,16 @@
|
||||||
link[] places;
|
link[] pawns;
|
||||||
link place;
|
|
||||||
link character;
|
|
||||||
|
|
||||||
import random from 'random-world';
|
member map;
|
||||||
|
member size;
|
||||||
|
|
||||||
restore {
|
restore {
|
||||||
if(this.places.empty)
|
for(let i = 0; i < 3; i ++) {
|
||||||
this.createPlaces();
|
|
||||||
|
|
||||||
this.character ??= create('')
|
}
|
||||||
|
|
||||||
|
this.size ??= 64;
|
||||||
}
|
}
|
||||||
|
|
||||||
async render() {
|
async render() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createPlaces() {
|
|
||||||
for(let i = 0; i < 10; i ++) {
|
|
||||||
const name = random.city();
|
|
||||||
const valid = !!name.match(/^[A-Za-z ]*$/);
|
|
||||||
if(!valid) {
|
|
||||||
i --;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
console.log(name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"strict": true,
|
||||||
|
"allowSyntheticDefaultImports": true
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"src/**/*.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
30
yarn.lock
30
yarn.lock
|
|
@ -2,6 +2,28 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@types/debug@^4.1.5":
|
||||||
|
version "4.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.5.tgz#b14efa8852b7768d898906613c23f688713e02cd"
|
||||||
|
|
||||||
|
"@types/lodash@^4.14.169":
|
||||||
|
version "4.14.169"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.169.tgz#83c217688f07a4d9ef8f28a3ebd1d318f6ff4cbb"
|
||||||
|
|
||||||
|
"@types/nearley@^2.11.1":
|
||||||
|
version "2.11.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/nearley/-/nearley-2.11.1.tgz#6ac3f57c00ca28071a1774ec72d2e45750f21420"
|
||||||
|
|
||||||
|
"@types/node@^15.3.0":
|
||||||
|
version "15.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/node/-/node-15.3.0.tgz#d6fed7d6bc6854306da3dea1af9f874b00783e26"
|
||||||
|
|
||||||
|
"@types/uglify-js@^3.13.0":
|
||||||
|
version "3.13.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.13.0.tgz#1cad8df1fb0b143c5aba08de5712ea9d1ff71124"
|
||||||
|
dependencies:
|
||||||
|
source-map "^0.6.1"
|
||||||
|
|
||||||
async@0.2.10:
|
async@0.2.10:
|
||||||
version "0.2.10"
|
version "0.2.10"
|
||||||
resolved "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
|
resolved "https://registry.npmjs.org/async/-/async-0.2.10.tgz"
|
||||||
|
|
@ -130,6 +152,14 @@ shebang-regex@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
|
resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz"
|
||||||
|
|
||||||
|
source-map@^0.6.1:
|
||||||
|
version "0.6.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||||
|
|
||||||
|
typescript@^4.2.4:
|
||||||
|
version "4.2.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961"
|
||||||
|
|
||||||
uglify-js@^3.13.5:
|
uglify-js@^3.13.5:
|
||||||
version "3.13.5"
|
version "3.13.5"
|
||||||
resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.5.tgz"
|
resolved "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.5.tgz"
|
||||||
|
|
|
||||||
Reference in New Issue