sdfghjk
parent
222ae17ccb
commit
bac6e4cfb8
|
|
@ -15,7 +15,6 @@ export default class Instance extends Serializable {
|
||||||
}
|
}
|
||||||
// ctx.Instance = Instance;
|
// ctx.Instance = Instance;
|
||||||
ctx.create = this.system.newInstance.bind(this.system);
|
ctx.create = this.system.newInstance.bind(this.system);
|
||||||
console.log('context reconstructed', ctx);
|
|
||||||
return ctx;
|
return ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -28,7 +27,6 @@ export default class Instance extends Serializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeInternal(name, ...args) {
|
invokeInternal(name, ...args) {
|
||||||
console.trace();
|
|
||||||
const content = this.module.functions[name];
|
const content = this.module.functions[name];
|
||||||
evalInContext(content, this.context);
|
evalInContext(content, this.context);
|
||||||
}
|
}
|
||||||
|
|
@ -44,7 +42,6 @@ function evalInContext(js, context) {
|
||||||
`).join('\n')}
|
`).join('\n')}
|
||||||
${js}`;
|
${js}`;
|
||||||
const newJs = minify(preminJs);
|
const newJs = minify(preminJs);
|
||||||
console.log(`${'='.repeat(80)}\n${newJs}\n${'='.repeat(80)}`)
|
|
||||||
return eval(newJs);
|
return eval(newJs);
|
||||||
}.call(context);
|
}.call(context);
|
||||||
}
|
}
|
||||||
11
System.js
11
System.js
|
|
@ -1,5 +1,8 @@
|
||||||
import Instance from './Instance.js';
|
import Instance from './Instance.js';
|
||||||
import Serializable from './Serializable.js';
|
import Serializable from './Serializable.js';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
const {get, set} = _;
|
||||||
|
|
||||||
export default class System extends Serializable {
|
export default class System extends Serializable {
|
||||||
instances = [];
|
instances = [];
|
||||||
|
|
@ -11,11 +14,15 @@ export default class System extends Serializable {
|
||||||
try {
|
try {
|
||||||
mkdirSync(location);
|
mkdirSync(location);
|
||||||
} catch {}
|
} catch {}
|
||||||
this.newInstance('world');
|
this.newInstance('xyz.places.world');
|
||||||
|
}
|
||||||
|
|
||||||
|
getModule(name) {
|
||||||
|
return get(this.modules, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
createInstance(name, args = {}) {
|
createInstance(name, args = {}) {
|
||||||
return new Instance(this.modules[name], null, args, this);
|
return new Instance(this.getModule(name), null, args, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
linkInstance(instance) {
|
linkInstance(instance) {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
PROGRAM -> _ STATEMENT:+ _ {% ([,stuff,]) => { return stuff } %}
|
PROGRAM -> _ STATEMENT:+ _ {% ([,stuff,]) => { return stuff } %}
|
||||||
STATEMENT -> _ LINK_DECLARATION _ %SEMICOLON:? {% ([,stuff]) => { return stuff } %}
|
STATEMENT -> _ LINK_DECLARATION _ %SEMICOLON:? {% ([,stuff]) => { return stuff } %}
|
||||||
| _ %RESTORE _ JS_BLOCK _ %SEMICOLON:? {% ([,,,block]) => { return { type: 'restore', block: block } } %}
|
| _ %RESTORE _ JS_BLOCK _ %SEMICOLON:? {% ([,,,block]) => { return { type: 'restore', block: block } } %}
|
||||||
|
| _ IDENTIFIER _ JS_BLOCK _ %SEMICOLON:? {% ([,name,,block]) => { return { type: 'function', name: name, block: block } } %}
|
||||||
| _ %NAMESPACE __ NAMESPACE _ %SEMICOLON:? {% ([,,,namespace]) => { return { type: 'namespace', namespace: namespace[0] } } %}
|
| _ %NAMESPACE __ NAMESPACE _ %SEMICOLON:? {% ([,,,namespace]) => { return { type: 'namespace', namespace: namespace[0] } } %}
|
||||||
LINK_DECLARATION -> _ %LINK __ IDENTIFIER {% ([,,,id]) => {return{ type: 'link', array: false, required: false, name: id }} %}
|
LINK_DECLARATION -> _ %LINK __ IDENTIFIER {% ([,,,id]) => {return{ type: 'link', array: false, required: false, name: id }} %}
|
||||||
| _ %LINK _ %ARRAY __ IDENTIFIER {% ([,,,,,id]) => {return{ type: 'link', array: true, required: false, name: id }} %}
|
| _ %LINK _ %ARRAY __ IDENTIFIER {% ([,,,,,id]) => {return{ type: 'link', array: true, required: false, name: id }} %}
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,14 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": {
|
"bin": {
|
||||||
"run": "run.js"
|
"vogue": "run.js"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"c": "nearleyc"
|
"c": "nearleyc",
|
||||||
|
"test": "vogue test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"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",
|
||||||
|
|
|
||||||
60
run.js
60
run.js
|
|
@ -8,16 +8,19 @@ import generate from 'nearley/lib/generate.js';
|
||||||
import nearleyGrammar from 'nearley/lib/nearley-language-bootstrapped.js';
|
import nearleyGrammar from 'nearley/lib/nearley-language-bootstrapped.js';
|
||||||
import moo from 'moo';
|
import moo from 'moo';
|
||||||
const grammarFile = 'grammar.ne';
|
const grammarFile = 'grammar.ne';
|
||||||
import Serializable from './Serializable.js';
|
// import Serializable from './Serializable.js';
|
||||||
import Module from './Module.js';
|
import Module from './Module.js';
|
||||||
import System from './System.js';
|
import System from './System.js';
|
||||||
import Instance from './Instance.js';
|
// import Instance from './Instance.js';
|
||||||
|
|
||||||
|
// globals inside grammar context
|
||||||
import minify from './minify.js';
|
import minify from './minify.js';
|
||||||
|
|
||||||
Array.prototype.empty = function empty() {
|
Object.defineProperty(Array.prototype, 'empty', {
|
||||||
|
get() {
|
||||||
return this.length === 0;
|
return this.length === 0;
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
function createParser() {
|
function createParser() {
|
||||||
// Parse the grammar source into an AST
|
// Parse the grammar source into an AST
|
||||||
|
|
@ -44,6 +47,28 @@ function createParser() {
|
||||||
SEMICOLON: ';'
|
SEMICOLON: ';'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// 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.
|
// Pretend this is a CommonJS environment to catch exports from the grammar.
|
||||||
const module = { exports: {} };
|
const module = { exports: {} };
|
||||||
eval(grammarJs);
|
eval(grammarJs);
|
||||||
|
|
@ -52,6 +77,9 @@ function createParser() {
|
||||||
return new nearley.Parser(nearley.Grammar.fromCompiled(grammar))
|
return new nearley.Parser(nearley.Grammar.fromCompiled(grammar))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
import _ from 'lodash';
|
||||||
|
const {get, set} = _;
|
||||||
|
|
||||||
const systemLocation = resolve(process.argv[2]);
|
const systemLocation = resolve(process.argv[2]);
|
||||||
const entry = process.argv[3];
|
const entry = process.argv[3];
|
||||||
const modules = {};
|
const modules = {};
|
||||||
|
|
@ -62,7 +90,20 @@ 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;
|
||||||
|
// 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;
|
||||||
|
// };
|
||||||
|
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 module = new Module();
|
||||||
const parsed = parser.results[0];
|
const parsed = parser.results[0];
|
||||||
|
|
@ -93,9 +134,16 @@ function parseModule(location) {
|
||||||
module.functions['restore'] = item.block;
|
module.functions['restore'] = item.block;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'function': {
|
||||||
|
if(item.name in module.identifiers)
|
||||||
|
throw new Error('Identifier ' + item.name + ' already declared!');
|
||||||
|
module.identifiers[item.name] = 'function';
|
||||||
|
module.functions[item.name] = item.block;
|
||||||
|
} //WE JUST ADDED THE FUNCION TO THE MODULE TEMPLATE.
|
||||||
|
// TODO ADD IT TO THE INSTANCE LEVEL, THEN CONTEXT, THEN LiNK PROXY.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
modules[module.name.full] = module;
|
set(modules, module.name.full, module);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,58 @@
|
||||||
|
# Vogue programming language & framework
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [Basic System Structure](#Basic-System-Structure)
|
||||||
|
- [Directives](#directives)
|
||||||
|
- [keepalive directive](#keepalive-directive)
|
||||||
|
- [singleton directive](#singleton-directive)
|
||||||
|
- [functions](#functions)
|
||||||
|
- [restore](#restore)
|
||||||
|
- [Links](#links)
|
||||||
|
|
||||||
|
|
||||||
|
## Basic System Structure
|
||||||
|
|
||||||
|
A Vogue system is a database of interlinked instances and their persistent data. Two things are required to start: A group (usually a directory) of vogue modules that a system knows, and a database to load from or create (usually in the form of a single file).
|
||||||
|
|
||||||
|
At the initial creation of a Vogue system, if there is no database to load from, any template module with the [singleton directive](#singleton-directive) will have an instance created of itself, without any predefined parameters.
|
||||||
|
|
||||||
|
When a database is loaded, all instances who's template module has the [keepalive directive](#keepalive-directive) will be [restored](#restore).
|
||||||
|
|
||||||
|
## Keepalive Directive
|
||||||
|
|
||||||
|
The keepalive directive is used to describe that a module should always remain in memory. This directive applies only to instances. This means that if no instances exist of a particular template module with the keepalive directive, then no instances will be restored.
|
||||||
|
|
||||||
|
```vogue
|
||||||
|
keepalive;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Singleton Directive
|
||||||
|
|
||||||
|
The singleton directive is used to describe a template module which should always have an instance of itself in memory. If one does not exist, it will be created. A system will never be running in a state where a template module which has a singleton directive does not have a corresponding instance.
|
||||||
|
|
||||||
|
The singleton directive implies the keepalive directive.
|
||||||
|
|
||||||
|
```vogue
|
||||||
|
singleton;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
functions can be referred to in other functions with or without the `this.` prefix. Use the prefix to disambiguate if local variables exist with the same identifier.
|
||||||
|
|
||||||
|
```vogue
|
||||||
|
functionName (param1, param2) [[
|
||||||
|
// javacsript code
|
||||||
|
]]
|
||||||
|
|
||||||
|
functionName [[
|
||||||
|
// javascript code
|
||||||
|
]]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Restore
|
||||||
|
|
||||||
|
Restore is a special function that is invoked when an instance is created or awoken.
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
namespace places;
|
namespace xyz.places.places;
|
||||||
|
|
||||||
required link world;
|
required link world;
|
||||||
link[] roads;
|
link[] roads;
|
||||||
|
|
||||||
|
ping [[
|
||||||
|
|
||||||
|
]]
|
||||||
10
test/world.v
10
test/world.v
|
|
@ -1,16 +1,20 @@
|
||||||
|
namespace xyz.places;
|
||||||
|
|
||||||
link[] places;
|
link[] places;
|
||||||
link place;
|
link place;
|
||||||
link character;
|
link character;
|
||||||
|
|
||||||
restore [[
|
restore [[
|
||||||
if(places.empty()) {
|
if(places.empty) {
|
||||||
for(let i = 0; i < 3; i ++) {
|
for(let i = 0; i < 3; i ++) {
|
||||||
const place = create('places.forest', {
|
const place = create('xyz.places.places.forest', {
|
||||||
world: this
|
world: this
|
||||||
});
|
});
|
||||||
places.push(place);
|
places.push(place);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(places);
|
|
||||||
|
for(const place of places) {
|
||||||
|
place.ping();
|
||||||
|
}
|
||||||
]]
|
]]
|
||||||
|
|
@ -43,6 +43,11 @@ localforage@^1.3.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
lie "3.1.1"
|
lie "3.1.1"
|
||||||
|
|
||||||
|
lodash@^4.17.21:
|
||||||
|
version "4.17.21"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||||
|
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||||
|
|
||||||
minimist@^1.2.5:
|
minimist@^1.2.5:
|
||||||
version "1.2.5"
|
version "1.2.5"
|
||||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||||
|
|
|
||||||
Reference in New Issue