diff --git a/packages/pegjs/lib/compiler/index.js b/packages/pegjs/lib/compiler/index.js index 4d44bd4..dd35d7d 100644 --- a/packages/pegjs/lib/compiler/index.js +++ b/packages/pegjs/lib/compiler/index.js @@ -67,8 +67,8 @@ const compiler = { trace: false } ); - // We want `session.vm.runInContext` to return the parser - if ( options.output === "parser" ) options.format = "bare"; + // We want `session.vm.evalModule` to return the parser + if ( options.output === "parser" ) options.format = "umd"; util.each( session.passes, stage => { @@ -83,7 +83,7 @@ const compiler = { switch ( options.output ) { case "parser": - return session.vm.runInContext( ast.code, options.context ); + return session.vm.evalModule( ast.code, options.context ); case "source": return ast.code; diff --git a/packages/pegjs/lib/compiler/session.js b/packages/pegjs/lib/compiler/session.js index e26bc63..30a92d6 100644 --- a/packages/pegjs/lib/compiler/session.js +++ b/packages/pegjs/lib/compiler/session.js @@ -7,6 +7,7 @@ const GrammarError = require( "../grammar-error" ); const opcodes = require( "./opcodes" ); const parser = require( "../parser" ); const util = require( "../util" ); +const vm = require( "../util/vm" ); function fatal( message, location ) { @@ -28,9 +29,7 @@ class Session { this.parser = config.parser || parser; this.passes = config.passes || {}; this.visitor = config.visitor || ast.visitor; - this.vm = config.vm || { - runInContext: util.runInContext - }; + this.vm = config.vm || vm; if ( typeof config.warn === "function" ) this.warn = config.warn; if ( typeof config.error === "function" ) this.error = config.error; diff --git a/packages/pegjs/lib/util/vm.js b/packages/pegjs/lib/util/vm.js index 4e9beaa..d21b62c 100644 --- a/packages/pegjs/lib/util/vm.js +++ b/packages/pegjs/lib/util/vm.js @@ -1,26 +1,25 @@ "use strict"; /** - * `eval` the given source, using properties found in `context` as top-level variables. + * `eval` the given source as a CommonJS module, using properties found in `context` as top-level variables. * * Based on `vm.runInContext` found in Node.js, this is a cross-env solution. */ -function runInContext( source, context ) { +function evalModule( source, context ) { const argumentKeys = Object.keys( context ); const argumentValues = argumentKeys.map( argument => context[ argument ] ); - const object = {}; - argumentKeys.push( "_peg$object", `_peg$object.result = ${ source };` ); - argumentValues.push( object ); + const sandbox = { exports: {} }; + argumentKeys.push( "module", "exports", source ); + argumentValues.push( sandbox, sandbox.exports ); Function( ...argumentKeys )( ...argumentValues ); - return object.result; - + return sandbox.exports; } // Exports -module.exports = { runInContext }; +module.exports = { evalModule }; diff --git a/packages/pegjs/typings/api.d.ts b/packages/pegjs/typings/api.d.ts index defcc37..cae3426 100644 --- a/packages/pegjs/typings/api.d.ts +++ b/packages/pegjs/typings/api.d.ts @@ -435,7 +435,7 @@ declare namespace peg { interface ISessionVM { - runInContext( code: string, context?: { [ name: string ]: any; } ): any; + evalModule( code: string, context?: { [ name: string ]: any; } ): any; } diff --git a/test/spec/api/plugin-api.spec.js b/test/spec/api/plugin-api.spec.js index 9873f12..de3e610 100644 --- a/test/spec/api/plugin-api.spec.js +++ b/test/spec/api/plugin-api.spec.js @@ -131,7 +131,7 @@ describe( "plugin API", function () { function pass( ast ) { - ast.code = "({ parse: function() { return 42; } })"; + ast.code = "exports.parse = function() { return 42; }"; }