This repository has been archived on 2023-11-14. You can view files and clone it, but cannot push or open issues/pull-requests.
vogue/run.js

150 lines
4.6 KiB
JavaScript
Raw Normal View History

2021-05-02 17:42:04 -04:00
#!/usr/bin/env node
import { resolve, parse } from 'path';
import { readFileSync, readdirSync, readFile, fstat, mkdirSync } from 'fs';
import nearley from 'nearley';
import compile from 'nearley/lib/compile.js';
import generate from 'nearley/lib/generate.js';
import nearleyGrammar from 'nearley/lib/nearley-language-bootstrapped.js';
import moo from 'moo';
const grammarFile = 'grammar.ne';
2021-05-06 09:33:28 -04:00
// import Serializable from './Serializable.js';
2021-05-02 17:42:04 -04:00
import Module from './Module.js';
import System from './System.js';
2021-05-06 09:33:28 -04:00
// import Instance from './Instance.js';
2021-05-02 17:42:04 -04:00
2021-05-06 09:33:28 -04:00
// globals inside grammar context
import minify from './minify.js';
2021-05-02 17:42:04 -04:00
2021-05-06 09:33:28 -04:00
Object.defineProperty(Array.prototype, 'empty', {
get() {
return this.length === 0;
}
});
2021-05-02 17:42:04 -04:00
function createParser() {
// Parse the grammar source into an AST
const grammarParser = new nearley.Parser(nearleyGrammar);
grammarParser.feed(readFileSync(grammarFile).toString());
const grammarAst = grammarParser.results[0]; // TODO check for errors
// Compile the AST into a set of rules
const grammarInfoObject = compile(grammarAst, {});
// Generate JavaScript code from the rules
const grammarJs = generate(grammarInfoObject, "grammar");
const lexer = moo.compile({
LINK: 'link',
RESTORE: 'restore',
NAMESPACE: 'namespace',
REQUIRED: 'required',
ARRAY: '[]',
OBJECT: '{}',
DOTOP: '.',
JS_BLOCK: /\[\[[^]*?\n\]\]$/,
IDENTIFIER: /[a-zA-Z][a-zA-Z0-9]*/,
SPACE: {match: /\s+/, lineBreaks: true},
SEMICOLON: ';'
});
2021-05-06 09:33:28 -04:00
// 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
// }
2021-05-02 17:42:04 -04:00
// Pretend this is a CommonJS environment to catch exports from the grammar.
const module = { exports: {} };
eval(grammarJs);
const grammar = module.exports;
return new nearley.Parser(nearley.Grammar.fromCompiled(grammar))
}
2021-05-06 09:33:28 -04:00
import _ from 'lodash';
const {get, set} = _;
2021-05-02 17:42:04 -04:00
const systemLocation = resolve(process.argv[2]);
const entry = process.argv[3];
const modules = {};
readdirSync(systemLocation).map(v => resolve(systemLocation, v)).map(parseModule);
const sys = new System(modules);
function parseModule(location) {
const parser = createParser();
const contents = readFileSync(location).toString();
const name = parse(location).name;
2021-05-06 09:33:28 -04:00
// 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);
} catch (e) {
console.error(e.message);
process.exit(1);
}
2021-05-02 17:42:04 -04:00
parser.finish();
const module = new Module();
const parsed = parser.results[0];
module.name.last = name;
module.name.full = name;
for(const item of parsed) {
switch(item.type) {
case 'link': {
if(item.name in module.identifiers)
throw new Error('Identifier ' + item.name + ' already declared!');
module.identifiers[item.name] = 'link';
module.links
[item.required ? 'required' : 'optional']
[item.array ? 'arrays' : 'single']
.push(item.name);
break;
}
case 'namespace': {
module.name.space = item.namespace;
module.name.full = module.name.space + '.' + module.name.last;
break;
}
case 'restore': {
if(item.name in module.identifiers)
throw new Error('Identifier ' + item.name + ' already declared!');
module.identifiers['restore'] = 'function';
module.functions['restore'] = item.block;
break;
}
2021-05-06 09:33:28 -04:00
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.
2021-05-02 17:42:04 -04:00
}
}
2021-05-06 09:33:28 -04:00
set(modules, module.name.full, module);
2021-05-02 17:42:04 -04:00
}