diff --git a/.jshintrc b/.jshintrc index 0fdd54e..dd732c7 100644 --- a/.jshintrc +++ b/.jshintrc @@ -10,8 +10,10 @@ "loopfunc": true, "newcap": false, "noarg": true, + "node": true, "noempty": true, "nonew": true, + "strict": true, "trailing": true, "validthis": true, "-W082": false diff --git a/Makefile b/Makefile index 8c270a9..29bbf97 100644 --- a/Makefile +++ b/Makefile @@ -79,6 +79,8 @@ browser: echo ' * Licensed under the MIT license.' >> $(BROWSER_FILE_DEV) echo ' */' >> $(BROWSER_FILE_DEV) echo 'var PEG = (function(undefined) {' >> $(BROWSER_FILE_DEV) + echo ' "use strict";' >> $(BROWSER_FILE_DEV) + echo '' >> $(BROWSER_FILE_DEV) echo ' var modules = {' >> $(BROWSER_FILE_DEV) echo ' define: function(name, factory) {' >> $(BROWSER_FILE_DEV) echo ' var dir = name.replace(/(^|\/)[^/]+$$/, "$$1"),' >> $(BROWSER_FILE_DEV) diff --git a/benchmark/benchmarks.js b/benchmark/benchmarks.js index 6410cfa..b389871 100644 --- a/benchmark/benchmarks.js +++ b/benchmark/benchmarks.js @@ -1,38 +1,50 @@ -benchmarks = [ - { - id: "json", - title: "JSON", - tests: [ - { file: "example1.json", title: "Example 1" }, - { file: "example2.json", title: "Example 2" }, - { file: "example3.json", title: "Example 3" }, - { file: "example4.json", title: "Example 4" }, - { file: "example5.json", title: "Example 5" } - ] - }, - { - id: "css", - title: "CSS", - tests: [ - { file: "blueprint/src/reset.css", title: "Blueprint - reset.css (source)" }, - { file: "blueprint/src/typography.css", title: "Blueprint - typography.css (source)" }, - { file: "blueprint/src/forms.css", title: "Blueprint - forms.css (source)" }, - { file: "blueprint/src/grid.css", title: "Blueprint - grid.css (source)" }, - { file: "blueprint/src/print.css", title: "Blueprint - print.css (source)" }, - // Contains syntax errors. - // { file: "blueprint/src/ie.css", title: "Blueprint - ie.css (source)" }, - { file: "blueprint/min/screen.css", title: "Blueprint - screen.css (minified)" }, - { file: "blueprint/min/print.css", title: "Blueprint - print.css (minified)" }, - // Contains syntax errors. - // { file: "blueprint/min/ie.css", title: "Blueprint - ie.css (minified)" }, - { file: "960.gs/src/reset.css", title: "960.gs - reset.css (source)" }, - { file: "960.gs/src/text.css", title: "960.gs - text.css (source)" }, - { file: "960.gs/src/960.css", title: "960.gs - 960.css (source)" }, - { file: "960.gs/src/960_24_col.css", title: "960.gs - 960_24_col.css (source)" }, - { file: "960.gs/min/reset.css", title: "960.gs - reset.css (minified)" }, - { file: "960.gs/min/text.css", title: "960.gs - text.css (minified)" }, - { file: "960.gs/min/960.css", title: "960.gs - 960.css (minified)" }, - { file: "960.gs/min/960_24_col.css", title: "960.gs - 960_24_col.css (minified)" } - ] +"use strict"; + +(function(root, factory) { + if (typeof module !== 'undefined' && module.exports) { + module.exports = factory(); + } else { + root.benchmarks = factory(); } -]; +}(this, function() { + + return [ + { + id: "json", + title: "JSON", + tests: [ + { file: "example1.json", title: "Example 1" }, + { file: "example2.json", title: "Example 2" }, + { file: "example3.json", title: "Example 3" }, + { file: "example4.json", title: "Example 4" }, + { file: "example5.json", title: "Example 5" } + ] + }, + { + id: "css", + title: "CSS", + tests: [ + { file: "blueprint/src/reset.css", title: "Blueprint - reset.css (source)" }, + { file: "blueprint/src/typography.css", title: "Blueprint - typography.css (source)" }, + { file: "blueprint/src/forms.css", title: "Blueprint - forms.css (source)" }, + { file: "blueprint/src/grid.css", title: "Blueprint - grid.css (source)" }, + { file: "blueprint/src/print.css", title: "Blueprint - print.css (source)" }, + // Contains syntax errors. + // { file: "blueprint/src/ie.css", title: "Blueprint - ie.css (source)" }, + { file: "blueprint/min/screen.css", title: "Blueprint - screen.css (minified)" }, + { file: "blueprint/min/print.css", title: "Blueprint - print.css (minified)" }, + // Contains syntax errors. + // { file: "blueprint/min/ie.css", title: "Blueprint - ie.css (minified)" }, + { file: "960.gs/src/reset.css", title: "960.gs - reset.css (source)" }, + { file: "960.gs/src/text.css", title: "960.gs - text.css (source)" }, + { file: "960.gs/src/960.css", title: "960.gs - 960.css (source)" }, + { file: "960.gs/src/960_24_col.css", title: "960.gs - 960_24_col.css (source)" }, + { file: "960.gs/min/reset.css", title: "960.gs - reset.css (minified)" }, + { file: "960.gs/min/text.css", title: "960.gs - text.css (minified)" }, + { file: "960.gs/min/960.css", title: "960.gs - 960.css (minified)" }, + { file: "960.gs/min/960_24_col.css", title: "960.gs - 960_24_col.css (minified)" } + ] + } + ]; + +})); diff --git a/benchmark/index.js b/benchmark/index.js index aded7a9..af88b54 100644 --- a/benchmark/index.js +++ b/benchmark/index.js @@ -1,4 +1,8 @@ +/* jshint node:false */ +/* global $, alert, benchmarks, document, Runner */ + $("#run").click(function() { + "use strict"; /* Results Table Manipulation */ @@ -130,5 +134,7 @@ $("#run").click(function() { }); $(document).ready(function() { + "use strict"; + $("#run").focus(); }); diff --git a/benchmark/run b/benchmark/run index 9c5afcb..c1f6025 100755 --- a/benchmark/run +++ b/benchmark/run @@ -1,15 +1,13 @@ #!/usr/bin/env node +"use strict"; + var util = require("util"); var fs = require("fs"); var PEG = require("../lib/peg"); -[ - "benchmarks.js", - "runner.js", -].forEach(function(file) { - eval(fs.readFileSync(__dirname + "/" + file, "utf8")); -}); +var benchmarks = require("./benchmarks.js"); +var Runner = require("./runner.js")(PEG); /* Results Table Manipulation */ diff --git a/benchmark/runner.js b/benchmark/runner.js index f8ad443..4c482f8 100644 --- a/benchmark/runner.js +++ b/benchmark/runner.js @@ -1,119 +1,131 @@ -Runner = { - run: function(benchmarks, runCount, options, callbacks) { +"use strict"; - /* Queue */ +(function(root, factory) { + if (typeof module !== 'undefined' && module.exports) { + module.exports = factory; + } else { + root.Runner = factory(root.PEG); + } +}(this, function(PEG) { + + return { + run: function(benchmarks, runCount, options, callbacks) { + + /* Queue */ - var Q = { - functions: [], + var Q = { + functions: [], - add: function(f) { - this.functions.push(f); - }, + add: function(f) { + this.functions.push(f); + }, - run: function() { - if (this.functions.length > 0) { - this.functions.shift()(); + run: function() { + if (this.functions.length > 0) { + this.functions.shift()(); - /* - * We can't use |arguments.callee| here because |this| would get - * messed-up in that case. - */ - setTimeout(function() { Q.run(); }, 0); + /* + * We can't use |arguments.callee| here because |this| would get + * messed-up in that case. + */ + setTimeout(function() { Q.run(); }, 0); + } } - } - }; + }; + + /* + * The benchmark itself is factored out into several functions (some of them + * generated), which are enqueued and run one by one using |setTimeout|. We + * do this for two reasons: + * + * 1. To avoid bowser mechanism for interrupting long-running scripts to + * kick-in (or at least to not kick-in that often). + * + * 2. To ensure progressive rendering of results in the browser (some + * browsers do not render at all when running JavaScript code). + * + * The enqueued functions share state, which is all stored in the properties + * of the |state| object. + */ + + var state = {}, i, j; + + function initialize() { + callbacks.start(); + + state.totalInputSize = 0; + state.totalParseTime = 0; + } - /* - * The benchmark itself is factored out into several functions (some of them - * generated), which are enqueued and run one by one using |setTimeout|. We - * do this for two reasons: - * - * 1. To avoid bowser mechanism for interrupting long-running scripts to - * kick-in (or at least to not kick-in that often). - * - * 2. To ensure progressive rendering of results in the browser (some - * browsers do not render at all when running JavaScript code). - * - * The enqueued functions share state, which is all stored in the properties - * of the |state| object. - */ - - var state = {}, i, j; - - function initialize() { - callbacks.start(); - - state.totalInputSize = 0; - state.totalParseTime = 0; - } + function benchmarkInitializer(i) { + return function() { + callbacks.benchmarkStart(benchmarks[i]); - function benchmarkInitializer(i) { - return function() { - callbacks.benchmarkStart(benchmarks[i]); - - state.parser = PEG.buildParser( - callbacks.readFile("../examples/" + benchmarks[i].id + ".pegjs"), - options - ); - state.benchmarkInputSize = 0; - state.benchmarkParseTime = 0; - }; - } + state.parser = PEG.buildParser( + callbacks.readFile("../examples/" + benchmarks[i].id + ".pegjs"), + options + ); + state.benchmarkInputSize = 0; + state.benchmarkParseTime = 0; + }; + } - function testRunner(i, j) { - return function() { - var benchmark = benchmarks[i], - test = benchmark.tests[j], - input, parseTime, averageParseTime, k, t; + function testRunner(i, j) { + return function() { + var benchmark = benchmarks[i], + test = benchmark.tests[j], + input, parseTime, averageParseTime, k, t; - callbacks.testStart(benchmark, test); + callbacks.testStart(benchmark, test); - input = callbacks.readFile(benchmark.id + "/" + test.file); + input = callbacks.readFile(benchmark.id + "/" + test.file); - parseTime = 0; - for (k = 0; k < runCount; k++) { - t = (new Date()).getTime(); - state.parser.parse(input); - parseTime += (new Date()).getTime() - t; - } - averageParseTime = parseTime / runCount; + parseTime = 0; + for (k = 0; k < runCount; k++) { + t = (new Date()).getTime(); + state.parser.parse(input); + parseTime += (new Date()).getTime() - t; + } + averageParseTime = parseTime / runCount; - callbacks.testFinish(benchmark, test, input.length, averageParseTime); + callbacks.testFinish(benchmark, test, input.length, averageParseTime); - state.benchmarkInputSize += input.length; - state.benchmarkParseTime += averageParseTime; - }; - } + state.benchmarkInputSize += input.length; + state.benchmarkParseTime += averageParseTime; + }; + } - function benchmarkFinalizer(i) { - return function() { - callbacks.benchmarkFinish( - benchmarks[i], - state.benchmarkInputSize, - state.benchmarkParseTime - ); - - state.totalInputSize += state.benchmarkInputSize; - state.totalParseTime += state.benchmarkParseTime; - }; - } + function benchmarkFinalizer(i) { + return function() { + callbacks.benchmarkFinish( + benchmarks[i], + state.benchmarkInputSize, + state.benchmarkParseTime + ); - function finalize() { - callbacks.finish(state.totalInputSize, state.totalParseTime); - } + state.totalInputSize += state.benchmarkInputSize; + state.totalParseTime += state.benchmarkParseTime; + }; + } + + function finalize() { + callbacks.finish(state.totalInputSize, state.totalParseTime); + } - /* Main */ + /* Main */ - Q.add(initialize); - for (i = 0; i < benchmarks.length; i++) { - Q.add(benchmarkInitializer(i)); - for (j = 0; j < benchmarks[i].tests.length; j++) { - Q.add(testRunner(i, j)); + Q.add(initialize); + for (i = 0; i < benchmarks.length; i++) { + Q.add(benchmarkInitializer(i)); + for (j = 0; j < benchmarks[i].tests.length; j++) { + Q.add(testRunner(i, j)); + } + Q.add(benchmarkFinalizer(i)); } - Q.add(benchmarkFinalizer(i)); + Q.add(finalize); + + Q.run(); } - Q.add(finalize); + }; - Q.run(); - } -}; +})); diff --git a/bin/pegjs b/bin/pegjs index b3d4b04..3eb8452 100755 --- a/bin/pegjs +++ b/bin/pegjs @@ -1,5 +1,7 @@ #!/usr/bin/env node +"use strict"; + var util = require("util"); var fs = require("fs"); var path = require("path"); diff --git a/lib/compiler.js b/lib/compiler.js index 253c81b..4ea66eb 100644 --- a/lib/compiler.js +++ b/lib/compiler.js @@ -1,3 +1,5 @@ +"use strict"; + var arrays = require("./utils/arrays"), objects = require("./utils/objects"); diff --git a/lib/compiler/asts.js b/lib/compiler/asts.js index cf51bcd..102e354 100644 --- a/lib/compiler/asts.js +++ b/lib/compiler/asts.js @@ -1,3 +1,5 @@ +"use strict"; + var arrays = require("../utils/arrays"), visitor = require("./visitor"); diff --git a/lib/compiler/javascript.js b/lib/compiler/javascript.js index a4ee07c..bc2ce95 100644 --- a/lib/compiler/javascript.js +++ b/lib/compiler/javascript.js @@ -1,3 +1,5 @@ +"use strict"; + function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } /* JavaScript code generation helpers. */ diff --git a/lib/compiler/opcodes.js b/lib/compiler/opcodes.js index 86ff811..5d88242 100644 --- a/lib/compiler/opcodes.js +++ b/lib/compiler/opcodes.js @@ -1,3 +1,5 @@ +"use strict"; + /* Bytecode instruction opcodes. */ var opcodes = { /* Stack Manipulation */ diff --git a/lib/compiler/passes/generate-bytecode.js b/lib/compiler/passes/generate-bytecode.js index dcdc8ad..eb41383 100644 --- a/lib/compiler/passes/generate-bytecode.js +++ b/lib/compiler/passes/generate-bytecode.js @@ -1,3 +1,5 @@ +"use strict"; + var arrays = require("../../utils/arrays"), objects = require("../../utils/objects"), asts = require("../asts"), diff --git a/lib/compiler/passes/generate-javascript.js b/lib/compiler/passes/generate-javascript.js index 1268774..0b41967 100644 --- a/lib/compiler/passes/generate-javascript.js +++ b/lib/compiler/passes/generate-javascript.js @@ -1,3 +1,5 @@ +"use strict"; + var arrays = require("../../utils/arrays"), asts = require("../asts"), op = require("../opcodes"), diff --git a/lib/compiler/passes/remove-proxy-rules.js b/lib/compiler/passes/remove-proxy-rules.js index 8ab922e..8d50548 100644 --- a/lib/compiler/passes/remove-proxy-rules.js +++ b/lib/compiler/passes/remove-proxy-rules.js @@ -1,3 +1,5 @@ +"use strict"; + var arrays = require("../../utils/arrays"), visitor = require("../visitor"); diff --git a/lib/compiler/passes/report-infinite-loops.js b/lib/compiler/passes/report-infinite-loops.js index 7809271..9f8f11c 100644 --- a/lib/compiler/passes/report-infinite-loops.js +++ b/lib/compiler/passes/report-infinite-loops.js @@ -1,3 +1,5 @@ +"use strict"; + var GrammarError = require("../../grammar-error"), asts = require("../asts"), visitor = require("../visitor"); diff --git a/lib/compiler/passes/report-left-recursion.js b/lib/compiler/passes/report-left-recursion.js index 0ec244d..6261947 100644 --- a/lib/compiler/passes/report-left-recursion.js +++ b/lib/compiler/passes/report-left-recursion.js @@ -1,3 +1,5 @@ +"use strict"; + var arrays = require("../../utils/arrays"), GrammarError = require("../../grammar-error"), asts = require("../asts"), diff --git a/lib/compiler/passes/report-missing-rules.js b/lib/compiler/passes/report-missing-rules.js index 67f0908..476d84e 100644 --- a/lib/compiler/passes/report-missing-rules.js +++ b/lib/compiler/passes/report-missing-rules.js @@ -1,3 +1,5 @@ +"use strict"; + var GrammarError = require("../../grammar-error"), asts = require("../asts"), visitor = require("../visitor"); diff --git a/lib/compiler/visitor.js b/lib/compiler/visitor.js index 3dcbad1..70e6f12 100644 --- a/lib/compiler/visitor.js +++ b/lib/compiler/visitor.js @@ -1,3 +1,5 @@ +"use strict"; + var objects = require("../utils/objects"), arrays = require("../utils/arrays"); diff --git a/lib/grammar-error.js b/lib/grammar-error.js index 753aedc..790f92d 100644 --- a/lib/grammar-error.js +++ b/lib/grammar-error.js @@ -1,3 +1,5 @@ +"use strict"; + var classes = require("./utils/classes"); /* Thrown when the grammar contains an error. */ diff --git a/lib/peg.js b/lib/peg.js index 6e7c509..d806284 100644 --- a/lib/peg.js +++ b/lib/peg.js @@ -1,3 +1,5 @@ +"use strict"; + var arrays = require("./utils/arrays"), objects = require("./utils/objects"); diff --git a/lib/utils/arrays.js b/lib/utils/arrays.js index e910f87..93a833c 100644 --- a/lib/utils/arrays.js +++ b/lib/utils/arrays.js @@ -1,3 +1,5 @@ +"use strict"; + /* Array utilities. */ var arrays = { range: function(start, stop) { diff --git a/lib/utils/classes.js b/lib/utils/classes.js index f73bf58..ec0798a 100644 --- a/lib/utils/classes.js +++ b/lib/utils/classes.js @@ -1,3 +1,5 @@ +"use strict"; + /* Class utilities */ var classes = { subclass: function(child, parent) { diff --git a/lib/utils/objects.js b/lib/utils/objects.js index 3345f09..09587c1 100644 --- a/lib/utils/objects.js +++ b/lib/utils/objects.js @@ -1,3 +1,5 @@ +"use strict"; + /* Object utilities. */ var objects = { keys: function(object) { diff --git a/spec/api/generated-parser-api.spec.js b/spec/api/generated-parser-api.spec.js index 71c930f..68a27e7 100644 --- a/spec/api/generated-parser-api.spec.js +++ b/spec/api/generated-parser-api.spec.js @@ -1,3 +1,7 @@ +/* global describe, expect, it, PEG, spyOn */ + +"use strict"; + describe("generated parser API", function() { describe("parse", function() { it("parses input", function() { diff --git a/spec/api/pegjs-api.spec.js b/spec/api/pegjs-api.spec.js index 6c8a2c7..95b59d5 100644 --- a/spec/api/pegjs-api.spec.js +++ b/spec/api/pegjs-api.spec.js @@ -1,3 +1,7 @@ +/* global describe, expect, it, PEG, spyOn */ + +"use strict"; + describe("PEG.js API", function() { describe("buildParser", function() { it("builds a parser", function() { diff --git a/spec/api/plugin-api.spec.js b/spec/api/plugin-api.spec.js index 25e7171..fa53455 100644 --- a/spec/api/plugin-api.spec.js +++ b/spec/api/plugin-api.spec.js @@ -1,3 +1,7 @@ +/* global beforeEach, describe, expect, it, jasmine, PEG */ + +"use strict"; + describe("plugin API", function() { beforeEach(function() { this.addMatchers({ diff --git a/spec/behavior/generated-parser-behavior.spec.js b/spec/behavior/generated-parser-behavior.spec.js index adcfbf0..566a6a4 100644 --- a/spec/behavior/generated-parser-behavior.spec.js +++ b/spec/behavior/generated-parser-behavior.spec.js @@ -1,3 +1,7 @@ +/* global beforeEach, describe, expect, it, jasmine, PEG */ + +"use strict"; + describe("generated parser behavior", function() { function varyOptimizationOptions(block) { function clone(object) { diff --git a/spec/helpers.js b/spec/helpers.js index e7ab8f7..ed18655 100644 --- a/spec/helpers.js +++ b/spec/helpers.js @@ -1,3 +1,7 @@ -if (typeof module !== "undefined") { - PEG = require("../lib/peg.js"); -} +"use strict"; + +(function(root) { + if (typeof module !== 'undefined') { + root.PEG = require("../lib/peg.js"); + } +}(this)); diff --git a/spec/unit/compiler/passes/generate-bytecode.spec.js b/spec/unit/compiler/passes/generate-bytecode.spec.js index 60d6584..710ed60 100644 --- a/spec/unit/compiler/passes/generate-bytecode.spec.js +++ b/spec/unit/compiler/passes/generate-bytecode.spec.js @@ -1,3 +1,7 @@ +/* global describe, expect, it, PEG */ + +"use strict"; + describe("compiler pass |generateBytecode|", function() { var pass = PEG.compiler.passes.generate.generateBytecode; diff --git a/spec/unit/compiler/passes/helpers.js b/spec/unit/compiler/passes/helpers.js index 74ef3a3..41f88ce 100644 --- a/spec/unit/compiler/passes/helpers.js +++ b/spec/unit/compiler/passes/helpers.js @@ -1,3 +1,7 @@ +/* global beforeEach, jasmine, PEG */ + +"use strict"; + beforeEach(function() { this.addMatchers({ toChangeAST: function(grammar) { diff --git a/spec/unit/compiler/passes/remove-proxy-rules.spec.js b/spec/unit/compiler/passes/remove-proxy-rules.spec.js index 862033d..998e0fb 100644 --- a/spec/unit/compiler/passes/remove-proxy-rules.spec.js +++ b/spec/unit/compiler/passes/remove-proxy-rules.spec.js @@ -1,3 +1,7 @@ +/* global describe, expect, it, PEG */ + +"use strict"; + describe("compiler pass |removeProxyRules|", function() { var pass = PEG.compiler.passes.transform.removeProxyRules; diff --git a/spec/unit/compiler/passes/report-infinite-loops.spec.js b/spec/unit/compiler/passes/report-infinite-loops.spec.js index db973fa..fa9b7af 100644 --- a/spec/unit/compiler/passes/report-infinite-loops.spec.js +++ b/spec/unit/compiler/passes/report-infinite-loops.spec.js @@ -1,3 +1,7 @@ +/* global describe, expect, it, PEG */ + +"use strict"; + describe("compiler pass |reportLeftRecursion|", function() { var pass = PEG.compiler.passes.check.reportInfiniteLoops; diff --git a/spec/unit/compiler/passes/report-left-recursion.spec.js b/spec/unit/compiler/passes/report-left-recursion.spec.js index 77b654c..ad25008 100644 --- a/spec/unit/compiler/passes/report-left-recursion.spec.js +++ b/spec/unit/compiler/passes/report-left-recursion.spec.js @@ -1,3 +1,7 @@ +/* global describe, expect, it, PEG */ + +"use strict"; + describe("compiler pass |reportLeftRecursion|", function() { var pass = PEG.compiler.passes.check.reportLeftRecursion; diff --git a/spec/unit/compiler/passes/report-missing-rules.spec.js b/spec/unit/compiler/passes/report-missing-rules.spec.js index e0b50db..6dbd64c 100644 --- a/spec/unit/compiler/passes/report-missing-rules.spec.js +++ b/spec/unit/compiler/passes/report-missing-rules.spec.js @@ -1,3 +1,7 @@ +/* global describe, expect, it, PEG */ + +"use strict"; + describe("compiler pass |reportMissingRules|", function() { var pass = PEG.compiler.passes.check.reportMissingRules; diff --git a/spec/unit/parser.spec.js b/spec/unit/parser.spec.js index e68189e..e1803a9 100644 --- a/spec/unit/parser.spec.js +++ b/spec/unit/parser.spec.js @@ -1,3 +1,7 @@ +/* global beforeEach, describe, expect, it, jasmine, PEG */ + +"use strict"; + describe("PEG.js grammar parser", function() { var literalAbcd = { type: "literal", value: "abcd", ignoreCase: false }, literalEfgh = { type: "literal", value: "efgh", ignoreCase: false },