sdl
Bronwen 2021-05-06 09:33:28 -04:00
parent 222ae17ccb
commit bac6e4cfb8
9 changed files with 144 additions and 19 deletions

View File

@ -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);
} }

View File

@ -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) {

View File

@ -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 }} %}

View File

@ -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
View File

@ -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);
} }

58
syntax.md 100644
View File

@ -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

View File

@ -1,5 +1,8 @@
namespace places; namespace xyz.places.places;
required link world; required link world;
link[] roads; link[] roads;
ping [[
]]

View File

@ -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();
}
]] ]]

View File

@ -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"