diff --git a/README.md b/README.md index dbb7adc..a9c8d48 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,11 @@ object to `PEG.buildParser`. The following options are supported: `false`) * `allowedStartRules` — rules the parser will be allowed to start parsing from (default: the first rule in the grammar) + * `exportVar` — name of a global variable into which the parser object is + assigned to when no module loader is detected; valid only when `format` is + set to `"umd"` (default: `null`) + * `format` — format of the genreated parser (`"bare"` or `"umd"`); valid only + when `output` is set to `"source"` (default: `"bare"`) * `output` — if set to `"parser"`, the method will return generated parser object; if set to `"source"`, it will return parser source code as a string (default: `"parser"`) diff --git a/lib/compiler.js b/lib/compiler.js index d8cc233..d5a3225 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -49,7 +49,9 @@ var compiler = { cache: false, trace: false, optimize: "speed", - output: "parser" + output: "parser", + format: "bare", + exportVar: null }); for (stage in passes) { diff --git a/lib/compiler/passes/generate-js.js b/lib/compiler/passes/generate-js.js index d03a8ae..0d97cbe 100644 --- a/lib/compiler/passes/generate-js.js +++ b/lib/compiler/passes/generate-js.js @@ -1168,17 +1168,60 @@ function generateJS(ast, options) { ].join('\n'); } - var parts = []; + var generators = { + bare: function() { + var parts = []; - parts.push('(function() {'); - parts.push(indent2(generateIntro())); - parts.push(''); - parts.push(indent2(toplevelCode)); - parts.push(''); - parts.push(indent2('return ' + generateParserObject() + ';')); - parts.push('})()'); + parts.push('(function() {'); + parts.push(indent2(generateIntro())); + parts.push(''); + parts.push(indent2(toplevelCode)); + parts.push(''); + parts.push(indent2('return ' + generateParserObject() + ';')); + parts.push('})()'); - return parts.join('\n'); + return parts.join('\n'); + }, + + umd: function() { + var parts = []; + + parts.push([ + '(function(root, factory) {', + ' if (typeof define === "function" && define.amd) {', + ' define([], factory);', + ' } else if (typeof module === "object" && module.exports) {', + ' module.exports = factory();' + ].join('\n')); + + if (options.exportVar !== null) { + parts.push([ + ' } else {', + ' root.' + options.exportVar + ' = factory();' + ].join('\n')); + } + + parts.push([ + ' }', + '})(this, function() {' + ].join('\n')); + + parts.push(indent2(generateIntro())); + parts.push(''); + parts.push(indent2(toplevelCode)); + parts.push(''); + parts.push(indent2('return ' + generateParserObject() + ';')); + + parts.push([ + '});', + '' + ].join('\n')); + + return parts.join('\n'); + } + }; + + return generators[options.format](); } ast.code = generateWrapper(generateToplevel()); diff --git a/spec/api/pegjs-api.spec.js b/spec/api/pegjs-api.spec.js index f42d04e..8a0d11a 100644 --- a/spec/api/pegjs-api.spec.js +++ b/spec/api/pegjs-api.spec.js @@ -199,6 +199,12 @@ describe("PEG.js API", function() { }); }); + /* + * The |format| and |exportVars| options are not tested becasue there is no + * meaningful way to thest their effects without turning this into an + * integration test. + */ + /* The |plugins| option is tested in plugin API specs. */ it("accepts custom options", function() {