starting variables, reorganize module creation

sdl
Marcus 2021-05-08 23:06:31 -04:00
parent 2a0ffec1f6
commit 50b89ce8a5
7 changed files with 85 additions and 72 deletions

View File

@ -7,6 +7,7 @@ export default class Instance extends Serializable {
links = {} links = {}
system = null; system = null;
context = null; context = null;
locals = [];
// reconstruct context when we need it... // reconstruct context when we need it...
createContext() { createContext() {
@ -16,9 +17,11 @@ export default class Instance extends Serializable {
} }
for(const name in this.module.imports) { for(const name in this.module.imports) {
ctx[name] = this.module.imports[name]; ctx[name] = this.module.imports[name];
this.locals.push(name);
} }
// ctx.Instance = Instance; // ctx.Instance = Instance;
ctx.create = this.system.newInstance.bind(this.system); ctx.create = this.system.newInstance.bind(this.system);
this.locals.push('create');
this.context = ctx; this.context = ctx;
}; };
@ -28,6 +31,7 @@ export default class Instance extends Serializable {
this.location = location; this.location = location;
this.system = system; this.system = system;
for(const name of this.module.links.optional.arrays) this.links[name] = []; 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;
this.createContext(); this.createContext();
this._link = new Proxy(this, { this._link = new Proxy(this, {
@ -43,7 +47,7 @@ export default class Instance extends Serializable {
invokeInternal(name, ...args) { invokeInternal(name, ...args) {
const content = this.module.functions[name]; const content = this.module.functions[name];
evalInContext(content, this.context); evalInContext(content, this.context, this.locals);
} }
get link () { get link () {
@ -51,12 +55,12 @@ export default class Instance extends Serializable {
} }
} }
function evalInContext(js, context) { function evalInContext(js, context, locals) {
//# Return the results of the in-line anonymous function we .call with the passed context //# Return the results of the in-line anonymous function we .call with the passed context
const that = this; const that = this;
return function() { return function() {
const preminJs = ` const preminJs = `
${Object.entries(context).map(([k, v]) => ` ${locals.map((k) => `
const ${k} = this.${k}; const ${k} = this.${k};
`).join('\n')} `).join('\n')}
${js}`; ${js}`;

View File

@ -19,5 +19,9 @@ export default class Module {
last: '', last: '',
full: '' full: ''
}; };
imports = {} imports = {};
variables = {
cold: [],
warm: []
}
} }

View File

@ -2,12 +2,14 @@
PROGRAM -> _ STATEMENT:+ _ {% ([,stuff,]) => { return stuff } %} PROGRAM -> _ STATEMENT:+ _ {% ([,stuff,]) => { return stuff } %}
STATEMENT -> _ LINK_DECLARATION _ SEMICOLON {% ([,stuff]) => { return stuff } %} STATEMENT -> _ LINK_DECLARATION EOL {% ([,stuff]) => { return stuff } %}
| _ %RESTORE _ JS_BLOCK _ SEMICOLON {% ([,,,block]) => { return { type: 'restore', block: block } } %} | _ %RESTORE _ JS_BLOCK EOL {% ([,,,block]) => { return { type: 'restore', block: block } } %}
| _ IDENTIFIER _ JS_BLOCK _ SEMICOLON {% ([,name,,block]) => { return { type: 'function', name: name, block: block } } %} | _ IDENTIFIER _ JS_BLOCK EOL {% ([,name,,block]) => { return { type: 'function', name: name, block: block } } %}
| _ %NAMESPACE __ NAMESPACE _ SEMICOLON {% ([,,,namespace]) => { return { type: 'namespace', namespace: namespace[0] } } %} | _ %NAMESPACE __ NAMESPACE EOL {% ([,,,namespace]) => { return { type: 'namespace', namespace: namespace[0] } } %}
| _ DIRECTIVE _ SEMICOLON {% ([,directive]) => { return { type: 'directive', value: directive }} %} | _ DIRECTIVE EOL {% ([,directive]) => { return { type: 'directive', value: directive }} %}
| _ %IMPORT __ STRING __ %AS __ IDENTIFIER _ SEMICOLON {% ([,,,moduleName,,,,identifier]) => { return { type: 'import', name: identifier, importName: moduleName }} %} | _ %IMPORT __ STRING __ %AS __ IDENTIFIER EOL {% ([,,,moduleName,,,,identifier]) => { return { type: 'import', name: identifier, importName: moduleName }} %}
| _ %RUNTIME __ %MEMBER __ IDENTIFIER EOL {% ([,,,,,identifier]) => {return{ type: 'variable', persist: false, name: identifier }} %}
| _ %MEMBER __ IDENTIFIER EOL {% ([,,,identifier]) => {return{ type: 'variable', persist: true, name: identifier }} %}
DIRECTIVE -> _ %SINGLETON {% () => 'singleton' %} DIRECTIVE -> _ %SINGLETON {% () => 'singleton' %}
| _ %KEEPALIVE {% () => 'keepalive' %} | _ %KEEPALIVE {% () => 'keepalive' %}
@ -20,10 +22,9 @@ LINK_DECLARATION -> _ %LINK __ IDENTIFIER {% ([,,,id]) => { return { type: 'link
NAMESPACE -> IDENTIFIER NAMESPACE -> IDENTIFIER
| IDENTIFIER %DOTOP NAMESPACE {% ([a,,b]) => { return [`${a}.${b}`] } %} | IDENTIFIER %DOTOP NAMESPACE {% ([a,,b]) => { return [`${a}.${b}`] } %}
EOL -> SEMICOLON EOL -> _ %SEMICOLON:?
| "\n"
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(block.value.substring(2, block.value.length - 2)) %} JS_BLOCK -> %JS_BLOCK {% ([block]) => minify(block.value.substring(2, block.value.length - 2)) %}
| %JS_BLOCK2 {% ([block]) => minify(block.value.substring(2, block.value.length - 2)) %} | %JS_BLOCK2 {% ([block]) => minify(block.value.substring(2, block.value.length - 2)) %}

101
run.js
View File

@ -41,6 +41,9 @@ function createParser() {
REQUIRED: 'required', REQUIRED: 'required',
SINGLETON: 'singleton', SINGLETON: 'singleton',
KEEPALIVE: 'keepalive', KEEPALIVE: 'keepalive',
STATIC: 'static',
MEMBER: 'member',
RUNTIME: 'runtime',
IMPORT: 'import', IMPORT: 'import',
AS: 'as', AS: 'as',
STRING: /'(?:\\['\\]|[^\n'\\])*'/, STRING: /'(?:\\['\\]|[^\n'\\])*'/,
@ -85,11 +88,21 @@ function createParser() {
const systemLocation = resolve(process.argv[2]); const systemLocation = resolve(process.argv[2]);
const entry = process.argv[3]; const entry = process.argv[3];
const modules = {};
(async () => { (async () => {
// TODO simplify this line gaddam // TODO simplify this line gaddam
await Promise.all(readdirSync(systemLocation).map(v => resolve(systemLocation, v)).map(parseModule)); const modules =
(await Promise.all(
readdirSync(systemLocation)
.map(v => resolve(systemLocation, v))
.map(parseModule)
)).reduce((acc, val) => {
set(acc, val.name.full, val);
return acc;
}, {});
console.log(modules)
const sys = new System(modules); const sys = new System(modules);
})() })()
@ -97,6 +110,8 @@ async function parseModule(location) {
const parser = createParser(); const parser = createParser();
const contents = readFileSync(location).toString(); const contents = readFileSync(location).toString();
const name = parse(location).name; const name = parse(location).name;
const module = new Module();
// parser.reportError = function(token) { // parser.reportError = function(token) {
// return JSON.stringify(token, null, 2); // return JSON.stringify(token, null, 2);
// var message = this.lexer.formatError(token, 'invalid syntax') + '\n'; // var message = this.lexer.formatError(token, 'invalid syntax') + '\n';
@ -105,63 +120,45 @@ async function parseModule(location) {
// JSON.stringify(token.value !== undefined ? token.value : token) + '\n'; // JSON.stringify(token.value !== undefined ? token.value : token) + '\n';
// return message; // return message;
// }; // };
try {
parser.feed(contents); parser.feed(contents);
} catch (e) {
console.error(e.message);
process.exit(1);
}
parser.finish(); parser.finish();
const module = new Module();
const parsed = parser.results[0]; const parsed = parser.results[0];
module.name.last = name; module.name.last = name;
module.name.full = name; module.name.full = name;
try { try {
// move this whole loop ass bitch into module.
for (const item of parsed) { for (const item of parsed) {
switch (item.type) { if ('name' in item && item.name in module.identifiers)
case 'link': { throw new Error('Identifier ' + item.name + ' already declared!');
if (item.name in module.identifiers)
throw new Error('Identifier ' + item.name + ' already declared!'); module.identifiers[item.name] = item.type;
module.identifiers[item.name] = 'link';
module.links if (item.type === 'link') {
[item.required ? 'required' : 'optional'] module.links
[item.array ? 'arrays' : 'single'] [item.required ? 'required' : 'optional']
.push(item.name); [item.array ? 'arrays' : 'single']
break; .push(item.name);
}
case 'namespace': { } else if (item.type === 'namespace') {
module.name.space = item.namespace; module.name.space = item.namespace;
module.name.full = module.name.space + '.' + module.name.last; module.name.full = module.name.space + '.' + module.name.last;
break;
} } else if (item.type === 'restore') {
case 'restore': { module.functions.restore = item.block;
if (item.name in module.identifiers)
throw new Error('Identifier ' + item.name + ' already declared!'); } else if (item.type === 'function') {
module.identifiers['restore'] = 'function'; module.functions[item.name] = item.block;
module.functions['restore'] = item.block;
break; } else if (item.type === 'import') {
} const imported = await import(item.importName);
case 'function': { if('default' in imported) module.imports[item.name] = imported.default;
if (item.name in module.identifiers) else module.imports[item.name] = imported;
throw new Error('Identifier ' + item.name + ' already declared!');
module.identifiers[item.name] = 'function'; } else if (item.type === 'variable') {
module.functions[item.name] = item.block;
break;
}
case 'import': {
if (item.name in module.identifiers)
throw new Error('Identifier ' + item.name + ' already declared!');
const imported = await import(item.importName);
if('default' in imported) {
module.imports[item.name] = imported.default;
} else {
module.imports[item.name] = imported;
}
module.identifiers[item.name] = 'import';
break;
}
} }
} }
} catch (e) { } catch (e) {
@ -171,6 +168,6 @@ async function parseModule(location) {
} }
} }
set(modules, module.name.full, module); return module;
} }

View File

@ -1,8 +1,14 @@
namespace xyz.places.places; namespace places;
required link world; required link world;
link[] roads; link[] roads;
member fertility;
restore {
this.fertility ??= Math.floor(Math.random() * 100);
}
ping { ping {
console.log('Ping!', new Date().getTime()); console.log('Ping!', new Date().getTime());
} }

View File

@ -1,8 +1,11 @@
namespace xyz.places;
singleton; singleton;
import 'terminal-kit' as terminalkit; import 'terminal-kit' as terminalkit;
link currentSave;
restore { restore {
terminalkit.terminal.cyan('~Welcome to Vogue~\n'); terminalkit.terminal.cyan('~Welcome to Vogue~\n');
this.currentSave ??= create('xyz.places.world', {});
} }

View File

@ -1,20 +1,18 @@
namespace xyz.places;
link[] places; link[] places;
link place; link place;
link character; link character;
restore { restore {
if(places.empty) { if(this.places.empty) {
for(let i = 0; i < 3; i ++) { for(let i = 0; i < 3; i ++) {
const place = create('xyz.places.places.forest', { const place = create('xyz.places.places.forest', {
world: this world: this
}); });
places.push(place); this.places.push(place);
} }
} }
for(const place of places) { for(const place of this.places) {
place.ping(); place.ping();
} }
} }