From 30cfa295530a17b53bd1f71202bc8effe976408a Mon Sep 17 00:00:00 2001 From: Futago-za Ryuu Date: Fri, 2 Feb 2018 06:42:03 +0000 Subject: [PATCH] Provide context to parser (#517) --- lib/compiler/index.js | 5 ++++- lib/compiler/session.js | 2 ++ lib/compiler/vm.js | 25 +++++++++++++++++++++++++ test/spec/api/plugin-api.spec.js | 6 +----- 4 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 lib/compiler/vm.js diff --git a/lib/compiler/index.js b/lib/compiler/index.js index bf6b5c9..c4569d1 100644 --- a/lib/compiler/index.js +++ b/lib/compiler/index.js @@ -13,6 +13,7 @@ const reportUndefinedRules = require( "./passes/report-undefined-rules" ); const inferenceMatchResult = require( "./passes/inference-match-result" ); const Session = require( "./session" ); const util = require( "../util" ); +const vm = require( "./vm" ); function processOptions( options, defaults ) { @@ -28,6 +29,7 @@ function processOptions( options, defaults ) { const compiler = { Session: Session, + vm: vm, // Compiler passes. // @@ -65,6 +67,7 @@ const compiler = { options = processOptions( options, { allowedStartRules: [ ast.rules[ 0 ].name ], cache: false, + context: {}, dependencies: {}, exportVar: null, format: "bare", @@ -86,7 +89,7 @@ const compiler = { switch ( options.output ) { case "parser": - return eval( ast.code ); + return session.vm.runInContext( ast.code, options.context ); case "source": return ast.code; diff --git a/lib/compiler/session.js b/lib/compiler/session.js index 222b355..9bb8bf2 100644 --- a/lib/compiler/session.js +++ b/lib/compiler/session.js @@ -6,6 +6,7 @@ const ast = require( "../ast" ); const GrammarError = require( "../grammar-error" ); const opcodes = require( "./opcodes" ); const parser = require( "../parser" ); +const vm = require( "./vm" ); function fatal( message, location ) { @@ -28,6 +29,7 @@ class Session { this.parser = options.parser || parser; this.passes = options.passes || []; this.visitor = options.visitor || ast.visitor; + this.vm = options.vm || vm; if ( typeof options.warn === "function" ) this.warn = options.warn; if ( typeof options.error === "function" ) this.error = options.error; diff --git a/lib/compiler/vm.js b/lib/compiler/vm.js new file mode 100644 index 0000000..e2b2536 --- /dev/null +++ b/lib/compiler/vm.js @@ -0,0 +1,25 @@ +"use strict"; + +const vm = { + + runInContext( code, context ) { + + const peg$context = typeof context !== "undefined" ? context : {}; + + /* eslint indent: 0 */ + return eval( ` + ${ + Object.keys( peg$context ) + .map( key => `var ${ key } = peg$context.${ key };` ) + .join( "" ) + } + var vm = null, code = null, context = null; + + ${ code } + ` ); + + }, + +}; + +module.exports = vm; diff --git a/test/spec/api/plugin-api.spec.js b/test/spec/api/plugin-api.spec.js index fb64885..fdc9427 100644 --- a/test/spec/api/plugin-api.spec.js +++ b/test/spec/api/plugin-api.spec.js @@ -102,10 +102,6 @@ describe( "plugin API", function () { config.parser = peg.generate( ` - { - const ast = require( process.cwd() + "/lib/ast" ); - } - start = .* { return new ast.Grammar( void 0, [{ type: "rule", @@ -118,7 +114,7 @@ describe( "plugin API", function () { }] ); } - ` ); + `, { context: { ast: peg.ast } } ); } };