Skip to content

Commit

Permalink
scripting: Add proof of concept (freezy/vpweb#1).
Browse files Browse the repository at this point in the history
  • Loading branch information
freezy committed Aug 23, 2019
1 parent d1d60fa commit 798ad00
Show file tree
Hide file tree
Showing 7 changed files with 268 additions and 0 deletions.
2 changes: 2 additions & 0 deletions lib/scripting/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
estree.js
vbscript.js
51 changes: 51 additions & 0 deletions lib/scripting/estree.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* VPDB - Virtual Pinball Database
* Copyright (C) 2019 freezy <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { Program, VariableDeclaration, VariableDeclarator } from 'estree';

/**
* Returns the root node.
* @param data List of `GlobalStmt` nodes
*/
export function program(data: any): Program {
return {
type: 'Program',
sourceType: 'script',
body: data,
};
}

/**
* Returns a variable declaration.
* @param data Result of the `"Dim" __ VarName OtherVarsOpt:* NL` rule.
*/
export function varDecl(data: [string, null, string, string[]]): VariableDeclaration {
return {
type: 'VariableDeclaration',
kind: 'let',
declarations: [ data[2], ...data[3] ].map(variableDeclarator),
};
}

export function variableDeclarator(name: string): VariableDeclarator {
return {
type: 'VariableDeclarator',
id: { type: 'Identifier', name },
};
}
31 changes: 31 additions & 0 deletions lib/scripting/transpile.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* VPDB - Virtual Pinball Database
* Copyright (C) 2019 freezy <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { expect } from 'chai';
import { vbsToJs } from './transpile';

describe('The VBScript transpiler', () => {

it('should transpile a variable declaration', () => {

const vbs = `Dim test1, test2, test3\n`;
const js = vbsToJs(vbs);
expect(js).to.equal('let test1, test2, test3;\n');
});
});
35 changes: 35 additions & 0 deletions lib/scripting/transpile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* VPDB - Virtual Pinball Database
* Copyright (C) 2019 freezy <[email protected]>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { generate } from 'astring';
import { Grammar, Parser } from 'nearley';

const vbsGrammar = require('./vbscript.js');

/**
* A function that transpiles VBScript to JavaScript.
*/
export function vbsToJs(vbs: string): string {
const parser = new Parser(Grammar.fromCompiled(vbsGrammar));
parser.feed(vbs);
if (parser.results.length === 0) {
throw new Error('Parser returned no results.');
}
return generate(parser.results[0]);
}
68 changes: 68 additions & 0 deletions lib/scripting/vbscript.ne
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
@builtin "whitespace.ne"

@{%
const estree = require('./estree');
%}

Program -> NLOpt GlobalStmt:* {% data => estree.program(data[1]) %}

GlobalStmt -> OptionExplicit
| BlockStmt {% data => data[0] %}


OptionExplicit -> "Option" __ "Explicit" NL

BlockStmt -> VarDecl {% data => data[0] %}

VarDecl -> "Dim" __ VarName OtherVarsOpt:* NL {% estree.varDecl %}

VarName -> ExtendedID ("(" ArrayRankList ")"):? {% data => data[0] %}

OtherVarsOpt -> "," __ VarName {% data => data[2] %}

ExtendedID -> SafeKeywordID
| ID {% data => data[0] %}

SafeKeywordID -> "Default"
| "Erase"
| "Error"
| "Explicit"
| "Property"
| "Step"

ID -> Letter IDTail {% data => data[0] + data[1] %}
| "[" IDNameChar:* "]"

ArrayRankList -> IntLiteral "," ArrayRankList
| IntLiteral

NLOpt -> NL:*

NL -> NewLine NL
| NewLine

NewLine -> CR LF
| CR
| LF
| ":"

IntLiteral -> DecDigit:+
| HexLiteral
| OctLiteral

HexLiteral -> "&H" HexDigit:+ "&":?
OctLiteral -> "&" OctDigit:+ "&":?

DecDigit -> [0-9]
HexDigit -> [0-9A-Fa-f]
OctDigit -> [0-7]

IDNameChar -> [\x20-\x5A\x5C\x5E-\x7E\xA0]

Letter -> [a-zA-Z]

LF -> [\n]

CR -> [\r]

IDTail -> [a-zA-Z0-9_]:* {% data => data[0].join('') %}
75 changes: 75 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"scripts": {
"build": "rimraf dist && tsc && cp -r res/maps dist/res",
"build:watch": "tsc --watch",
"compile": "nearleyc lib/scripting/vbscript.ne -o lib/scripting/vbscript.js && tsc lib/scripting/estree",
"lint": "tslint lib/**/*.ts --format stylish",
"test": "nyc mocha"
},
Expand All @@ -35,19 +36,24 @@
"author": "freezy <[email protected]>",
"license": "GPL-2.0",
"dependencies": {
"astring": "^1.4.1",
"buffer": "5.4.0",
"es6-promise-pool": "^2.5.0",
"gltf-pipeline": "github:freezy/gltf-pipeline#hotfix/dedupe",
"gm": "^1.23.1",
"nearley": "^2.18.0",
"pngquant": "^3.0.0",
"sharp": "^0.23.0",
"three": "^0.107.0"
},
"devDependencies": {
"@types/astring": "^1.3.0",
"@types/chai": "4.2.0",
"@types/estree": "0.0.39",
"@types/gm": "1.18.4",
"@types/microtime": "2.1.0",
"@types/mocha": "5.2.7",
"@types/nearley": "2.11.0",
"@types/node": "12.7.2",
"@types/sharp": "0.22.2",
"@types/sinon": "7.0.13",
Expand Down

0 comments on commit 798ad00

Please sign in to comment.