diff --git a/Module.js b/Module.js index e1fbd2a..7d3e42e 100644 --- a/Module.js +++ b/Module.js @@ -1,4 +1,7 @@ - +import createAst from './createAst.js' +import path from 'path'; +import debug from 'debug'; +const log = debug('vogue:module'); export default class Module { links = { @@ -24,65 +27,65 @@ export default class Module { cold: [], warm: [] } + singleton = false; + keepalive = false; - async link() { - + async directive({value}) { + this[value] = true; + } + + async link({required, array, name}) { + this.links + [required ? 'required' : 'optional'] + [array ? 'arrays' : 'single'] + .push(name); + } + + async namespace({namespace}) { + this.name.space = namespace; + this.name.full = this.name.space + '.' + this.name.last; + } + + async function({name, block}) { + this.functions[name] = block; + } + + async import({importName, name}) { + const imported = await import(importName); + if('default' in imported) this.imports[name] = imported.default; + else this.imports[name] = imported; + } + + async variable({persist, name}) { + this.variables[persist ? 'cold' : 'warm'].push(name); } static async create(location) { const module = new Module(); const ast = createAst(location); - const name = parse(location).name; + const name = path.parse(location).name; module.name.last = name; module.name.full = name; - log.ast('='.repeat(80)); - log.ast(location); - log.ast(ast); - - try { - - // move module whole loop ass bitch into module. - for (const item of ast) { - if ('name' in item && item.name in module.identifiers) + // move module whole loop ass bitch into module. + for (const item of ast) { + if ('name' in item) { + if(item.name in module.identifiers) throw new Error('Identifier ' + item.name + ' already declared!'); - - module.identifiers[item.name] = item.type; - - if(item.type in module) { - await module[item.type](item); - } - - if (item.type === 'link') { - module.links - [item.required ? 'required' : 'optional'] - [item.array ? 'arrays' : 'single'] - .push(item.name); - - } else if (item.type === 'namespace') { - module.name.space = item.namespace; - module.name.full = module.name.space + '.' + module.name.last; - - } else if (item.type === 'restore') { - module.functions.restore = item.block; - - } else if (item.type === 'function') { - module.functions[item.name] = item.block; - - } else if (item.type === 'import') { - const imported = await import(item.importName); - if('default' in imported) module.imports[item.name] = imported.default; - else module.imports[item.name] = imported; - - } else if (item.type === 'variable') { - module.variables[item.persist ? 'cold' : 'warm'].push(item.name); - } + else module.identifiers[item.name] = item.type; + } + + if(item.type in module) { + await module[item.type](item); } - } catch (e) { - console.error(e); } + log('='.repeat(80)); + log(location); + log(module); + + return module; } } diff --git a/System.js b/System.js index 4b87da9..e5fb3f8 100644 --- a/System.js +++ b/System.js @@ -1,24 +1,55 @@ import Instance from './Instance.js'; import Serializable from './Serializable.js'; import _ from 'lodash'; +import Module from './Module.js'; +import debug from 'debug'; +const log = debug('vogue:system') const {get, set} = _; export default class System extends Serializable { instances = []; modules = null; + namespace = null; constructor(modules, location = '.running') { super(); this.modules = modules; - try { - mkdirSync(location); - } catch {} - this.newInstance('main'); + this.createNamespace(); + const bootModules = this.deriveBootModules(); + + log('instantiating modules...'); + for(const name of bootModules) + this.newInstance(name); + } + + deriveBootModules() { + log('deriving boot modules...'); + const bootModules = this.modules.filter((module) => { + return module.singleton; + }).map((module) => { + return module.name.full; + }); + + for(const name of bootModules) + log(' ' + name); + + return bootModules; + } + + createNamespace() { + log('creating namespace map...'); + this.namespace = this.modules.reduce((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; + }, {}); } getModule(name) { - return get(this.modules, name); + return get(this.namespace, name); } createInstance(name, args = {}) { diff --git a/createAst.js b/createAst.js index 8958bbe..a1ebcf4 100644 --- a/createAst.js +++ b/createAst.js @@ -5,6 +5,8 @@ import nearleyGrammar from 'nearley/lib/nearley-language-bootstrapped.js'; import moo from 'moo'; import tokens from './tokens.js'; import { readFileSync } from 'fs'; +import debug from 'debug'; +const log = debug('vogue:ast'); import minify from './minify.js'; const grammarFile = 'grammar.ne'; @@ -54,7 +56,6 @@ export default function createAst(location) { const parser = createParser(); const contents = readFileSync(location).toString(); - // parser.reportError = function(token) { // return JSON.stringify(token, null, 2); // var message = this.lexer.formatError(token, 'invalid syntax') + '\n'; @@ -64,8 +65,14 @@ export default function createAst(location) { // return message; // }; - parser.feed(contents); parser.finish(); - return parser.results[0]; + + const ast = parser.results[0]; + + log('='.repeat(80)); + log(location); + log(ast); + + return ast; } \ No newline at end of file diff --git a/debug.js b/debug.js deleted file mode 100644 index 8124015..0000000 --- a/debug.js +++ /dev/null @@ -1,7 +0,0 @@ - -import d from 'debug'; - -export const ast = d('vogue:ast'); -export const modules = d('vogue:modules'); -export const system = d('vogue:system'); -export const debug = d('vogue:debug'); \ No newline at end of file diff --git a/extensions.js b/extensions.js new file mode 100644 index 0000000..e0bb37d --- /dev/null +++ b/extensions.js @@ -0,0 +1,6 @@ + +Object.defineProperty(Array.prototype, 'empty', { + get() { + return this.length === 0; + } +}); diff --git a/package.json b/package.json index 7a55ca2..b1e6dd0 100644 --- a/package.json +++ b/package.json @@ -9,15 +9,18 @@ }, "scripts": { "c": "nearleyc", - "test": "node run.js test" + "test": "node run.js test", + "debug": "cross-env DEBUG=vogue:* node run.js test" }, "dependencies": { + "cross-env": "^7.0.3", "debug": "^4.3.1", "lodash": "^4.17.21", "moo": "^0.5.1", "nearley": "^2.20.1", "nedb": "^1.8.0", "terminal-kit": "^2.1.0", - "uglify-js": "^3.13.5" + "uglify-js": "^3.13.5", + "yarn": "^1.22.10" } } diff --git a/run.js b/run.js index 81f43c6..1576841 100755 --- a/run.js +++ b/run.js @@ -1,39 +1,39 @@ #!/usr/bin/env node -import { resolve, parse } from 'path'; +import { resolve } from 'path'; import { readdirSync } from 'fs'; import _ from 'lodash'; -const { get, set } = _; import Module from './Module.js'; import System from './System.js'; -import * as log from './debug.js'; -import createAst from './createAst.js'; - +import debug from 'debug'; +import './extensions.js'; // globals inside grammar context import minify from './minify.js'; -Object.defineProperty(Array.prototype, 'empty', { - get() { - return this.length === 0; - } -}); - - +const { get, set } = _; +const log = debug('vogue:cli'); const systemLocation = resolve(process.argv[2]); -const entry = process.argv[3]; (async () => { // TODO simplify this line gaddam - const modules = - (await Promise.all( - readdirSync(systemLocation) - .map(v => resolve(systemLocation, v)) - .map(loc => new Module(loc)) - )).reduce((acc, val) => { - set(acc, val.name.full, val); - return acc; - }, {}); + log('reading', systemLocation, '...'); + const files = readdirSync(systemLocation); + const fullpaths = files.map(v => resolve(systemLocation, v)); + for(const path of fullpaths) log(path); + log('parsing modules...'); + const modules = await Promise.all(fullpaths.map(loc => Module.create(loc))); + + // const modules = + // (await Promise.all( + // readdirSync(systemLocation) + // .map(v => resolve(systemLocation, v)) + // .map(v => { log(v); return v; }) + // .map(loc => Module.create(loc)) + // )).reduce((acc, val) => { + // set(acc, val.name.full, val); + // return acc; + // }, {}); const sys = new System(modules); })() diff --git a/yarn.lock b/yarn.lock index 5ddc2a9..cfdb2b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -39,7 +39,13 @@ cross-env@^6.0.3: dependencies: cross-spawn "^7.0.0" -cross-spawn@^7.0.0: +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.0, cross-spawn@^7.0.1: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" dependencies: @@ -247,3 +253,7 @@ which@^2.0.1: resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" dependencies: isexe "^2.0.0" + +yarn@^1.22.10: + version "1.22.10" + resolved "https://registry.yarnpkg.com/yarn/-/yarn-1.22.10.tgz#c99daa06257c80f8fa2c3f1490724e394c26b18c"