From 2d7c0442e0524426a075d23c6eecff2dad53cc98 Mon Sep 17 00:00:00 2001 From: Marcus Date: Wed, 12 May 2021 00:15:53 -0400 Subject: [PATCH] static functions are being called. closes #8 --- Instance.js | 15 +++++++++++++-- Module.js | 5 +++-- System.js | 28 +++++++++++++++++++++++++--- grammar.ne | 7 ++++--- test/interface.v | 32 ++++++++++++++++++++++++++++++++ test/main.v | 4 +++- tokens.js | 1 + 7 files changed, 81 insertions(+), 11 deletions(-) create mode 100644 test/interface.v diff --git a/Instance.js b/Instance.js index 0243a08..8b2d6a5 100644 --- a/Instance.js +++ b/Instance.js @@ -11,7 +11,7 @@ export default class Instance extends Serializable { // reconstruct context when we need it... createContext() { - const ctx = {}; + let ctx = {}; for(const name in this.links) { ctx[name] = this.links[name]; } @@ -19,6 +19,13 @@ export default class Instance extends Serializable { ctx[name] = this.module.imports[name]; this.locals.push(name); } + ctx = { + ...ctx, + ...this.system.staticInstances + } + 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; @@ -46,10 +53,14 @@ export default class Instance extends Serializable { }); } + hasPublicFunction(name) { + return (name in this.module.functions); + } + invokeInternal(name, ...args) { // console.log('invoking', name); const content = this.module.functions[name]; - if(!content) throw new TypeError(content + ' is not a function!'); + if(!content) throw new TypeError(name + ' is not a function!'); return evalInContext(content, this.context, this.locals); } diff --git a/Module.js b/Module.js index 7d3e42e..c66ac9f 100644 --- a/Module.js +++ b/Module.js @@ -29,9 +29,10 @@ export default class Module { } singleton = false; keepalive = false; + 'static' = null; - async directive({value}) { - this[value] = true; + async directive({directive, value}) { + this[directive] = value ?? true; } async link({required, array, name}) { diff --git a/System.js b/System.js index e5fb3f8..0815f54 100644 --- a/System.js +++ b/System.js @@ -11,16 +11,37 @@ export default class System extends Serializable { instances = []; modules = null; namespace = null; + staticInstances = {}; constructor(modules, location = '.running') { super(); this.modules = modules; this.createNamespace(); const bootModules = this.deriveBootModules(); + this.createStaticInstances(); - log('instantiating modules...'); - for(const name of bootModules) + log('instantiating boot modules...'); + for(const name of bootModules) { + log(' ' + name); this.newInstance(name); + } + } + + createStaticInstances() { + log('deriving static modules...'); + const staticModules = this.modules.filter((module) => { + return !!module.static; + }).map((module) => { + log(' ' + module.name.full); + return module; + }); + + log('instantiating static modules...'); + for(const module of staticModules) { + log(' ' + module.static + ': ' + module.name.full); + this.staticInstances[module.static] = + this.newInstance(module.name.full, {}); + } } deriveBootModules() { @@ -59,7 +80,8 @@ export default class System extends Serializable { newInstance(name, args = {}) { const instance = this.createInstance(name, args); const link = instance.link; - instance.invokeInternal('restore'); + if(instance.hasPublicFunction('restore')) + instance.invokeInternal('restore'); return link; } } \ No newline at end of file diff --git a/grammar.ne b/grammar.ne index be43851..f7cd334 100644 --- a/grammar.ne +++ b/grammar.ne @@ -13,11 +13,12 @@ STATEMENT -> _ LINK_DECLARATION EOL {% ([,stuff]) => { return stuff } %} FUNCTION_DECLARATION -> _ IDENTIFIER _ PARAMETERS:? _ JS_BLOCK 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 __ OPEN_PARAMETERS EOL {% ([,directive,,parameters]) => { return { type: 'directive', value: directive, parameters }} %} - | DIRECTIVE EOL {% ([directive,,]) => { return { type: 'directive', value: directive }} %} +DIRECTIVE_STATEMENT -> DIRECTIVE __ IDENTIFIER EOL {% ([directive,,identifier]) => { return { type: 'directive', directive, value: identifier }} %} + | DIRECTIVE EOL {% ([directive]) => { return { type: 'directive', directive }} %} DIRECTIVE -> %SINGLETON {% () => 'singleton' %} | %KEEPALIVE {% () => 'keepalive' %} + | %STATIC {% () => 'static' %} LINK_DECLARATION -> LINK __ IDENTIFIER {% ([,,id]) => { return { type: 'link', array: false, required: false, name: id }} %} | LINK_ARR __ IDENTIFIER {% ([,,id]) => { return { type: 'link', array: true, required: false, name: id }} %} @@ -32,7 +33,7 @@ NAMESPACE -> IDENTIFIER OPEN_PARAMETERS -> _ IDENTIFIER _ ADDITIONAL_PARAMETERS:? _ {% ([,identifier,,more,]) => more ? [identifier, ...more] : [identifier] %} PARAMETERS -> _ %LPAREN _ IDENTIFIER _ ADDITIONAL_PARAMETERS:? _ %RPAREN _ {% ([,,,identifier,,more,,,]) => more ? [identifier, ...more] : [identifier] %} -ADDITIONAL_PARAMETERS -> "," _ IDENTIFIER _ ADDITIONAL_PARAMETERS:? {% ([,,identifier,,more]) => more ? [identifier, ...more] : [identifier] %} +ADDITIONAL_PARAMETERS -> %COMMA _ IDENTIFIER _ ADDITIONAL_PARAMETERS:? {% ([,,identifier,,more]) => more ? [identifier, ...more] : [identifier] %} EOL -> _ %SEMICOLON:? STRING -> %STRING {% ([d]) => d.value.substring(1, d.value.length - 1) %} diff --git a/test/interface.v b/test/interface.v new file mode 100644 index 0000000..9419f15 --- /dev/null +++ b/test/interface.v @@ -0,0 +1,32 @@ +namespace vogue +static Interface; + +import 'terminal-kit' as terminalKit; + +choice(message, choices, type) { + console.log('im being called!'); + // const {terminal} = terminalKit; + // type ??= 'string'; + + // return new Promise(res => { + + // terminal.saveCursor(); + // // terminal(message.split(/\x1b\[39m/g).join(', ')); + // // const loc = await new Promise (res => terminal.getCursorLocation((err, x, y) => res([x, y]))); + // for(const part of message.split(/\x1b\[39m/g)) { + // terminal.cyan(part); + // } + // terminal.cyan('\n'); + + // terminal.singleColumnMenu(choices, (error, response) => { + // terminal.restoreCursor(); + // terminal.cyan(`${message} `); + // terminal(response.selectedText + '\n').eraseDisplayBelow(); + // if(type === 'string') { + // res(response.selectedText); + // } else { + // res(response.selectedIndex); + // } + // }); + // }); +} \ No newline at end of file diff --git a/test/main.v b/test/main.v index 88c8e92..a1aa903 100644 --- a/test/main.v +++ b/test/main.v @@ -3,7 +3,9 @@ singleton; link currentSave; -restore { +async restore { terminalkit.terminal.cyan('~Welcome to Vogue~\n'); this.currentSave ??= create('world', {}); + // console.log(Interface); + const choice = await Interface.choice('select a thing', ['a', 'b', 'c']); } \ No newline at end of file diff --git a/tokens.js b/tokens.js index 8c29e00..d4d7dc8 100644 --- a/tokens.js +++ b/tokens.js @@ -10,6 +10,7 @@ export default { IMPORT: 'import', ASYNC: 'async', AS: 'as', + COMMA: ',', STRING: /'(?:\\['\\]|[^\n'\\])*'/, LSQBRACKET: '[', RSQBRACKET: ']',