diff --git a/spec/compiler/passes/compute-var-indices.spec.js b/spec/compiler/passes/compute-var-indices.spec.js index 4e1348e..5c7bb3c 100644 --- a/spec/compiler/passes/compute-var-indices.spec.js +++ b/spec/compiler/passes/compute-var-indices.spec.js @@ -24,8 +24,8 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a named", function() { expect(pass).toChangeAST('start "start" = &"a"', ruleDetails({ - resultIndices: [0, 1], - expression: { + resultCount: 2, + expression: { resultIndex: 0, expression: { resultIndex: 0, posIndex: 1 } } @@ -34,23 +34,23 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a choice", function() { expect(pass).toChangeAST('start = &"a" / &"b" / &"c"', ruleDetails({ - resultIndices: [0, 1], - expression: choiceDetails + resultCount: 2, + expression: choiceDetails })); expect(pass).toChangeAST('start = &"a" / &"b"* / &"c"', ruleDetails({ - resultIndices: [0, 1, 2], - expression: choiceDetails + resultCount: 3, + expression: choiceDetails })); expect(pass).toChangeAST('start = &"a" / &(&"b") / &"c"', ruleDetails({ - resultIndices: [0, 1, 2], - expression: choiceDetails + resultCount: 3, + expression: choiceDetails })); }); it("computes variable indices for an action", function() { expect(pass).toChangeAST('start = &"a" { code }', ruleDetails({ - resultIndices: [0, 1, 2], - expression: { + resultCount: 3, + expression: { resultIndex: 0, posIndex: 1, expression: { resultIndex: 0, posIndex: 2 } @@ -60,47 +60,47 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a sequence", function() { expect(pass).toChangeAST('start = ', ruleDetails({ - resultIndices: [0, 1], - expression: { resultIndex: 0, posIndex: 1 } + resultCount: 2, + expression: { resultIndex: 0, posIndex: 1 } })); expect(pass).toChangeAST('start = &"a" &"b" &"c"', ruleDetails({ - resultIndices: [0, 1, 2, 3, 4, 5], - expression: sequenceDetails + resultCount: 6, + expression: sequenceDetails })); expect(pass).toChangeAST('start = &"a" &"b" &"c"*', ruleDetails({ - resultIndices: [0, 1, 2, 3, 4, 5, 6], - expression: sequenceDetails + resultCount: 7, + expression: sequenceDetails })); expect(pass).toChangeAST('start = &"a" &"b"* &"c"', ruleDetails({ - resultIndices: [0, 1, 2, 3, 4, 5], - expression: sequenceDetails + resultCount: 6, + expression: sequenceDetails })); expect(pass).toChangeAST('start = &"a" &("b"*)* &"c"', ruleDetails({ - resultIndices: [0, 1, 2, 3, 4, 5, 6], - expression: sequenceDetails + resultCount: 7, + expression: sequenceDetails })); expect(pass).toChangeAST('start = &"a"* &"b" &"c"', ruleDetails({ - resultIndices: [0, 1, 2, 3, 4, 5], - expression: sequenceDetails + resultCount: 6, + expression: sequenceDetails })); expect(pass).toChangeAST('start = &("a"*)* &"b" &"c"', ruleDetails({ - resultIndices: [0, 1, 2, 3, 4, 5], - expression: sequenceDetails + resultCount: 6, + expression: sequenceDetails })); expect(pass).toChangeAST('start = &(("a"*)*)* &"b" &"c"', ruleDetails({ - resultIndices: [0, 1, 2, 3, 4, 5, 6], - expression: sequenceDetails + resultCount: 7, + expression: sequenceDetails })); expect(pass).toChangeAST('start = &"a" &(&"b") &"c"', ruleDetails({ - resultIndices: [0, 1, 2, 3, 4, 5], - expression: sequenceDetails + resultCount: 6, + expression: sequenceDetails })); }); it("computes variable indices for a labeled", function() { expect(pass).toChangeAST('start = label:&"a"', ruleDetails({ - resultIndices: [0, 1], - expression: { + resultCount: 2, + expression: { resultIndex: 0, expression: { resultIndex: 0, posIndex: 1 } } @@ -109,8 +109,8 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a simple and", function() { expect(pass).toChangeAST('start = &(&"a")', ruleDetails({ - resultIndices: [0, 1, 2], - expression: { + resultCount: 3, + expression: { resultIndex: 0, posIndex: 1, expression: { resultIndex: 0, posIndex: 2 } @@ -120,8 +120,8 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a simple not", function() { expect(pass).toChangeAST('start = !(&"a")', ruleDetails({ - resultIndices: [0, 1, 2], - expression: { + resultCount: 3, + expression: { resultIndex: 0, posIndex: 1, expression: { resultIndex: 0, posIndex: 2 } @@ -131,22 +131,22 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a semantic and", function() { expect(pass).toChangeAST('start = &{ code }', ruleDetails({ - resultIndices: [0], - expression: leafDetails + resultCount: 1, + expression: leafDetails })); }); it("computes variable indices for a semantic not", function() { expect(pass).toChangeAST('start = !{ code }', ruleDetails({ - resultIndices: [0], - expression: leafDetails + resultCount: 1, + expression: leafDetails })); }); it("computes variable indices for an optional", function() { expect(pass).toChangeAST('start = (&"a")?', ruleDetails({ - resultIndices: [0, 1], - expression: { + resultCount: 2, + expression: { resultIndex: 0, expression: { resultIndex: 0, posIndex: 1 } } @@ -155,8 +155,8 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a zero or more", function() { expect(pass).toChangeAST('start = (&"a")*', ruleDetails({ - resultIndices: [0, 1, 2], - expression: { + resultCount: 3, + expression: { resultIndex: 0, expression: { resultIndex: 1, posIndex: 2 } } @@ -165,8 +165,8 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a one or more", function() { expect(pass).toChangeAST('start = (&"a")+', ruleDetails({ - resultIndices: [0, 1, 2], - expression: { + resultCount: 3, + expression: { resultIndex: 0, expression: { resultIndex: 1, posIndex: 2 } } @@ -175,29 +175,29 @@ describe("compiler pass |computeVarIndices|", function() { it("computes variable indices for a rule reference", function() { expect(pass).toChangeAST('start = a', ruleDetails({ - resultIndices: [0], - expression: leafDetails + resultCount: 1, + expression: leafDetails })); }); it("computes variable indices for a literal", function() { expect(pass).toChangeAST('start = "a"', ruleDetails({ - resultIndices: [0], - expression: leafDetails + resultCount: 1, + expression: leafDetails })); }); it("computes variable indices for a class", function() { expect(pass).toChangeAST('start = [a-z]', ruleDetails({ - resultIndices: [0], - expression: leafDetails + resultCount: 1, + expression: leafDetails })); }); it("computes variable indices for an any", function() { expect(pass).toChangeAST('start = .', ruleDetails({ - resultIndices: [0], - expression: leafDetails + resultCount: 1, + expression: leafDetails })); }); }); diff --git a/src/compiler/passes/compute-var-indices.js b/src/compiler/passes/compute-var-indices.js index a27d73e..6c715a5 100644 --- a/src/compiler/passes/compute-var-indices.js +++ b/src/compiler/passes/compute-var-indices.js @@ -10,9 +10,10 @@ * * Some nodes will have a |posIndex| property. It will contain an index of * the variable that will store a parse position in generated code. * - * * All "rule" nodes will contain |resultIndices| property. It will contain a - * list of values of |resultIndex| and |posIndex| properties used in rule's - * subnodes. (This is useful to declare variables in generated code.) + * * All "rule" nodes will contain |resultCount| property. It will contain a + * count of distinct values of |resultIndex| and |posIndex| properties used + * in rule's subnodes. (This is useful to declare variables in generated + * code.) */ PEG.compiler.passes.computeVarIndices = function(ast) { function computeLeaf(node, index) { return 0; } @@ -55,7 +56,7 @@ PEG.compiler.passes.computeVarIndices = function(ast) { depth = compute(node.expression, index); - node.resultIndices = range(depth + 1); + node.resultCount = depth + 1; }, named: computeFromExpression({ result: 0, pos: 0 }), diff --git a/src/compiler/passes/generate-code.js b/src/compiler/passes/generate-code.js index 770ee1b..6fc267b 100644 --- a/src/compiler/passes/generate-code.js +++ b/src/compiler/passes/generate-code.js @@ -558,8 +558,8 @@ PEG.compiler.passes.generateCode = function(ast, options) { ' }', ' ', ' #end', - ' #if node.resultIndices.length > 0', - ' var #{map(node.resultIndices, resultVar).join(", ")};', + ' #if node.resultCount > 0', + ' var #{map(range(node.resultCount), resultVar).join(", ")};', ' #end', ' ', ' #block emit(node.expression)', @@ -741,6 +741,7 @@ PEG.compiler.passes.generateCode = function(ast, options) { function fill(name, vars) { vars.string = quote; + vars.range = range; vars.map = map; vars.pluck = pluck; vars.keys = keys;