diff --git a/README.md b/README.md index 6d15897..eea37ca 100644 --- a/README.md +++ b/README.md @@ -295,13 +295,13 @@ otherwise return `null`. #### & *expression* -Try to match the expression. If the match succeeds, just return an empty string -and do not advance the parser position, otherwise consider the match failed. +Try to match the expression. If the match succeeds, just return `undefined` and +do not advance the parser position, otherwise consider the match failed. #### ! *expression* -Try to match the expression. If the match does not succeed, just return an empty -string and do not advance the parser position, otherwise consider the match +Try to match the expression. If the match does not succeed, just return +`undefined` and do not advance the parser position, otherwise consider the match failed. #### & { *predicate* } @@ -310,7 +310,7 @@ The predicate is a piece of JavaScript code that is executed as if it was inside a function. It gets the match results of labeled expressions in preceding expression as its arguments. It should return some JavaScript value using the `return` statement. If the returned value evaluates to `true` in boolean -context, just return an empty string and do not advance the parser position; +context, just return `undefined` and do not advance the parser position; otherwise consider the match failed. The code inside the predicate can access all variables and functions defined in @@ -332,7 +332,7 @@ The predicate is a piece of JavaScript code that is executed as if it was inside a function. It gets the match results of labeled expressions in preceding expression as its arguments. It should return some JavaScript value using the `return` statement. If the returned value evaluates to `false` in boolean -context, just return an empty string and do not advance the parser position; +context, just return `undefined` and do not advance the parser position; otherwise consider the match failed. The code inside the predicate can access all variables and functions defined in diff --git a/lib/compiler/passes/generate-bytecode.js b/lib/compiler/passes/generate-bytecode.js index 9709f9e..9f13c7b 100644 --- a/lib/compiler/passes/generate-bytecode.js +++ b/lib/compiler/passes/generate-bytecode.js @@ -213,8 +213,8 @@ module.exports = function(ast, options) { } function buildSimplePredicate(expression, negative, context) { - var emptyStringIndex = addConst('""'), - failedIndex = addConst('peg$FAILED'); + var undefinedIndex = addConst('void 0'), + failedIndex = addConst('peg$FAILED'); return buildSequence( [op.PUSH_CURR_POS], @@ -230,7 +230,7 @@ module.exports = function(ast, options) { buildSequence( [op.POP], [negative ? op.POP : op.POP_CURR_POS], - [op.PUSH, emptyStringIndex] + [op.PUSH, undefinedIndex] ), buildSequence( [op.POP], @@ -242,9 +242,9 @@ module.exports = function(ast, options) { } function buildSemanticPredicate(code, negative, context) { - var functionIndex = addFunctionConst(utils.keys(context.env), code), - emptyStringIndex = addConst('""'), - failedIndex = addConst('peg$FAILED'); + var functionIndex = addFunctionConst(utils.keys(context.env), code), + undefinedIndex = addConst('void 0'), + failedIndex = addConst('peg$FAILED'); return buildSequence( [op.REPORT_CURR_POS], @@ -253,11 +253,11 @@ module.exports = function(ast, options) { [op.IF], buildSequence( [op.POP], - [op.PUSH, negative ? failedIndex : emptyStringIndex] + [op.PUSH, negative ? failedIndex : undefinedIndex] ), buildSequence( [op.POP], - [op.PUSH, negative ? emptyStringIndex : failedIndex] + [op.PUSH, negative ? undefinedIndex : failedIndex] ) ) ); diff --git a/lib/parser.js b/lib/parser.js index e10921e..65ee165 100644 --- a/lib/parser.js +++ b/lib/parser.js @@ -197,7 +197,7 @@ module.exports = (function() { expression: expression }; }, - peg$c18 = "", + peg$c18 = void 0, peg$c19 = function(name) { return { type: "rule_ref", diff --git a/spec/compiler/passes/generate-bytecode.spec.js b/spec/compiler/passes/generate-bytecode.spec.js index d9a1e4e..84ed6b6 100644 --- a/spec/compiler/passes/generate-bytecode.spec.js +++ b/spec/compiler/passes/generate-bytecode.spec.js @@ -272,7 +272,7 @@ describe("compiler pass |generateBytecode|", function() { it("defines correct constants", function() { expect(pass).toChangeAST(grammar, constsDetails([ - '""', + 'void 0', 'peg$FAILED', '"a"', '{ type: "literal", value: "a", description: "\\"a\\"" }' @@ -301,7 +301,7 @@ describe("compiler pass |generateBytecode|", function() { it("defines correct constants", function() { expect(pass).toChangeAST(grammar, constsDetails([ - '""', + 'void 0', 'peg$FAILED', '"a"', '{ type: "literal", value: "a", description: "\\"a\\"" }' @@ -328,7 +328,7 @@ describe("compiler pass |generateBytecode|", function() { it("defines correct constants", function() { expect(pass).toChangeAST( grammar, - constsDetails(['function() { code }', '""', 'peg$FAILED']) + constsDetails(['function() { code }', 'void 0', 'peg$FAILED']) ); }); }); @@ -380,7 +380,7 @@ describe("compiler pass |generateBytecode|", function() { '"c"', '{ type: "literal", value: "c", description: "\\"c\\"" }', 'function(a, b, c) { code }', - '""' + 'void 0' ])); }); }); @@ -405,7 +405,7 @@ describe("compiler pass |generateBytecode|", function() { it("defines correct constants", function() { expect(pass).toChangeAST( grammar, - constsDetails(['function() { code }', '""', 'peg$FAILED']) + constsDetails(['function() { code }', 'void 0', 'peg$FAILED']) ); }); }); @@ -457,7 +457,7 @@ describe("compiler pass |generateBytecode|", function() { '"c"', '{ type: "literal", value: "c", description: "\\"c\\"" }', 'function(a, b, c) { code }', - '""' + 'void 0' ])); }); }); diff --git a/spec/generated-parser.spec.js b/spec/generated-parser.spec.js index c0fcff1..8abbb73 100644 --- a/spec/generated-parser.spec.js +++ b/spec/generated-parser.spec.js @@ -397,14 +397,14 @@ describe("generated parser", function() { it("matches correctly", function() { var parser = PEG.buildParser('start = &"a" "a"', options); - expect(parser).toParse("a", ["", "a"]); + expect(parser).toParse("a", [undefined, "a"]); expect(parser).toFailToParse("b"); }); it("does not advance position on success", function() { var parser = PEG.buildParser('start = &"a" "a"', options); - expect(parser).toParse("a", ["", "a"]); + expect(parser).toParse("a", [undefined, "a"]); }); it("does not influence expected strings on failure", function() { @@ -418,7 +418,7 @@ describe("generated parser", function() { it("matches correctly", function() { var parser = PEG.buildParser('start = !"a" "b"', options); - expect(parser).toParse("b", ["", "b"]); + expect(parser).toParse("b", [undefined, "b"]); expect(parser).toFailToParse("a"); }); @@ -439,7 +439,7 @@ describe("generated parser", function() { it("causes successful match by returning |true|", function() { var parser = PEG.buildParser('start = &{ return true; }', options); - expect(parser).toParse("", ""); + expect(parser).toParse("", undefined); }); it("causes match failure by returning |false|", function() { @@ -454,7 +454,7 @@ describe("generated parser", function() { options ); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use the |text| function", function() { @@ -463,7 +463,7 @@ describe("generated parser", function() { options ); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use the |offset| function to get the current parse position", function() { @@ -472,7 +472,7 @@ describe("generated parser", function() { options ); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use the |line| and |column| functions to get the current line and column", function() { @@ -504,7 +504,7 @@ describe("generated parser", function() { 'start = "a" &{ return v === 42; }' ].join("\n"), options); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use functions defined in the initializer", function() { @@ -513,7 +513,7 @@ describe("generated parser", function() { 'start = "a" &{ return f() === 42; }' ].join("\n"), options); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use options passed to the parser", function() { @@ -530,7 +530,7 @@ describe("generated parser", function() { it("causes successful match by returning |false|", function() { var parser = PEG.buildParser('start = !{ return false; }', options); - expect(parser).toParse("", ""); + expect(parser).toParse("", undefined); }); it("causes match failure by returning |true|", function() { @@ -545,7 +545,7 @@ describe("generated parser", function() { options ); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use the |text| function", function() { @@ -554,7 +554,7 @@ describe("generated parser", function() { options ); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use the |offset| function to get the current parse position", function() { @@ -563,7 +563,7 @@ describe("generated parser", function() { options ); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use the |line| and |column| functions to get the current line and column", function() { @@ -595,7 +595,7 @@ describe("generated parser", function() { 'start = "a" !{ return v !== 42; }' ].join("\n"), options); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use functions defined in the initializer", function() { @@ -604,7 +604,7 @@ describe("generated parser", function() { 'start = "a" !{ return f() !== 42; }' ].join("\n"), options); - expect(parser).toParse("a", ["a", ""]); + expect(parser).toParse("a", ["a", undefined]); }); it("can use options passed to the parser", function() {