diff --git a/spec/compiler/passes/compute-params.spec.js b/spec/compiler/passes/compute-params.spec.js
index ec1bdee..16292f4 100644
--- a/spec/compiler/passes/compute-params.spec.js
+++ b/spec/compiler/passes/compute-params.spec.js
@@ -1,9 +1,20 @@
describe("compiler pass |computeParams|", function() {
function pass(ast) {
- PEG.compiler.passes.computeVarNames(ast);
+ PEG.compiler.passes.computeVarIndices(ast);
PEG.compiler.passes.computeParams(ast);
}
+ var result0 = { resultIndex: 0, subindices: [] },
+ result0_0 = { resultIndex: 0, subindices: [0] },
+ result0_1 = { resultIndex: 0, subindices: [1] },
+ result0_1_0 = { resultIndex: 0, subindices: [1, 0] },
+ result0_1_1 = { resultIndex: 0, subindices: [1, 1] },
+ result0_1_2 = { resultIndex: 0, subindices: [1, 2] },
+ result0_2 = { resultIndex: 0, subindices: [2] },
+ result1_9 = { resultIndex: 1, subindices: [9] },
+ result1 = { resultIndex: 1, subindices: [] };
+ result2 = { resultIndex: 2, subindices: [] };
+
function ruleDetails(details) { return { rules: [details] }; }
function expressionDetails(details) {
@@ -17,7 +28,7 @@ describe("compiler pass |computeParams|", function() {
describe("basic cases", function() {
it("computes params for an action", function() {
expect(pass).toChangeAST('start = a:"a" { }', expressionDetails({
- params: { a: "result0" }
+ params: { a: result0 }
}));
});
@@ -25,7 +36,7 @@ describe("compiler pass |computeParams|", function() {
expect(pass).toChangeAST('start = a:"a" &{ }', expressionDetails({
elements: [
{},
- { params: { a: "result0" } }
+ { params: { a: result0 } }
]
}));
});
@@ -34,7 +45,7 @@ describe("compiler pass |computeParams|", function() {
expect(pass).toChangeAST('start = a:"a" !{ }', expressionDetails({
elements: [
{},
- { params: { a: "result0" } }
+ { params: { a: result0 } }
]
}));
});
@@ -44,7 +55,7 @@ describe("compiler pass |computeParams|", function() {
it("computes params for a named", function() {
expect(pass).toChangeAST(
'start "start" = a:"a" { }',
- innerExpressionDetails({ params: { a: "result0" } })
+ innerExpressionDetails({ params: { a: result0 } })
);
});
@@ -52,20 +63,20 @@ describe("compiler pass |computeParams|", function() {
expect(pass).toChangeAST(
'start = a:"a" { } / "b" / "c"',
expressionDetails({
- alternatives: [{ params: { a: "result0" } }, {}, {}]
+ alternatives: [{ params: { a: result0 } }, {}, {}]
})
);
expect(pass).toChangeAST(
'start = "a" / "b" / c:"c" { }',
expressionDetails({
- alternatives: [{}, {}, { params: { c: "result0" } }]
+ alternatives: [{}, {}, { params: { c: result0 } }]
})
);
});
it("computes params for an action", function() {
expect(pass).toChangeAST('start = (a:"a" { }) { }', innerExpressionDetails({
- params: { a: "result0" }
+ params: { a: result0 }
}));
});
@@ -73,50 +84,50 @@ describe("compiler pass |computeParams|", function() {
expect(pass).toChangeAST(
'start = (a:"a" { }) "b" "c"',
expressionDetails({
- elements: [{ params: { a: "result0" } }, {}, {}]
+ elements: [{ params: { a: result0 } }, {}, {}]
})
);
expect(pass).toChangeAST(
'start = "a" "b" (c:"c" { })',
expressionDetails({
- elements: [{}, {}, { params: { c: "result2" } }]
+ elements: [{}, {}, { params: { c: result2 } }]
})
);
});
it("computes params for a labeled", function() {
expect(pass).toChangeAST('start = a:(b:"b" { })', innerExpressionDetails({
- params: { b: "result0" }
+ params: { b: result0 }
}));
});
it("computes params for a simple and", function() {
expect(pass).toChangeAST('start = &(a:"a" { })', innerExpressionDetails({
- params: { a: "result0" }
+ params: { a: result0 }
}));
});
it("computes params for a simple not", function() {
expect(pass).toChangeAST('start = &(a:"a" { })', innerExpressionDetails({
- params: { a: "result0" }
+ params: { a: result0 }
}));
});
it("computes params for an optional", function() {
expect(pass).toChangeAST('start = (a:"a" { })?', innerExpressionDetails({
- params: { a: "result0" }
+ params: { a: result0 }
}));
});
it("computes params for a zero or more", function() {
expect(pass).toChangeAST('start = (a:"a" { })*', innerExpressionDetails({
- params: { a: "result1" }
+ params: { a: result1 }
}));
});
it("computes params for a one or more", function() {
expect(pass).toChangeAST('start = (a:"a" { })+', innerExpressionDetails({
- params: { a: "result1" }
+ params: { a: result1 }
}));
});
});
@@ -139,38 +150,26 @@ describe("compiler pass |computeParams|", function() {
expect(pass).toChangeAST(
'start = a:"a" b:"b" c:"c" { }',
expressionDetails({
- params: { a: "result0[0]", b: "result0[1]", c: "result0[2]" }
+ params: { a: result0_0, b: result0_1, c: result0_2 }
})
);
expect(pass).toChangeAST(
'start = a:"a" (b:"b" c:"c" d:"d") e:"e"{ }',
expressionDetails({
params: {
- a: "result0[0]",
- b: "result0[1][0]",
- c: "result0[1][1]",
- d: "result0[1][2]",
- e: "result0[2]"
+ a: result0_0,
+ b: result0_1_0,
+ c: result0_1_1,
+ d: result0_1_2,
+ e: result0_2
}
})
);
-
- /*
- * Regression tests for a bug where e.g. resultVar names like |result10|
- * were incorrectly treated as names derived from |result1|, leading to
- * incorrect substitution.
- */
- expect(pass).toChangeAST(
- 'start = ("a" "b" "c" "d" "e" "f" "g" "h" "i" j:"j" { })*',
- innerExpressionDetails({
- params: { j: "result1[9]" } // Buggy code put "result1[0]0" here.
- })
- );
});
it("creates a new scope for a labeled", function() {
expect(pass).toChangeAST('start = a:(b:"b") { }', expressionDetails({
- params: { a: "result0"}
+ params: { a: result0 }
}));
});
diff --git a/spec/compiler/passes/compute-var-indices.spec.js b/spec/compiler/passes/compute-var-indices.spec.js
new file mode 100644
index 0000000..d57bac0
--- /dev/null
+++ b/spec/compiler/passes/compute-var-indices.spec.js
@@ -0,0 +1,229 @@
+describe("compiler pass |computeVarIndices|", function() {
+ var pass = PEG.compiler.passes.computeVarIndices;
+
+ var leafDetails = { resultIndex: 0 },
+ choiceDetails = {
+ resultIndex: 0,
+ alternatives: [
+ { resultIndex: 0, posIndex: 0 },
+ { resultIndex: 0, posIndex: 0 },
+ { resultIndex: 0, posIndex: 0 }
+ ]
+ },
+ sequenceDetails = {
+ resultIndex: 0,
+ posIndex: 0,
+ elements: [
+ { resultIndex: 0, posIndex: 1 },
+ { resultIndex: 1, posIndex: 1 },
+ { resultIndex: 2, posIndex: 1 }
+ ]
+ };
+
+ function ruleDetails(details) { return { rules: [details] }; }
+
+ it("computes variable indices for a named", function() {
+ expect(pass).toChangeAST('start "start" = &"a"', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0],
+ expression: {
+ resultIndex: 0,
+ expression: { resultIndex: 0, posIndex: 0 }
+ }
+ }));
+ });
+
+ it("computes variable indices for a choice", function() {
+ expect(pass).toChangeAST('start = &"a" / &"b" / &"c"', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0],
+ expression: choiceDetails
+ }));
+ expect(pass).toChangeAST('start = &"a" / &"b"* / &"c"', ruleDetails({
+ resultIndices: [0, 1],
+ posIndices: [0],
+ expression: choiceDetails
+ }));
+ expect(pass).toChangeAST('start = &"a" / &(&"b") / &"c"', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0, 1],
+ expression: choiceDetails
+ }));
+ });
+
+ it("computes variable indices for an action", function() {
+ expect(pass).toChangeAST('start = &"a" { code }', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0, 1],
+ expression: {
+ resultIndex: 0,
+ posIndex: 0,
+ expression: { resultIndex: 0, posIndex: 1 }
+ }
+ }));
+ });
+
+ it("computes variable indices for a sequence", function() {
+ expect(pass).toChangeAST('start = ', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0],
+ expression: { resultIndex: 0, posIndex: 0 }
+ }));
+ expect(pass).toChangeAST('start = &"a" &"b" &"c"', ruleDetails({
+ resultIndices: [0, 1, 2],
+ posIndices: [0, 1],
+ expression: sequenceDetails
+ }));
+ expect(pass).toChangeAST('start = &"a" &"b" &"c"*', ruleDetails({
+ resultIndices: [0, 1, 2, 3],
+ posIndices: [0, 1],
+ expression: sequenceDetails
+ }));
+ expect(pass).toChangeAST('start = &"a" &"b"* &"c"', ruleDetails({
+ resultIndices: [0, 1, 2],
+ posIndices: [0, 1],
+ expression: sequenceDetails
+ }));
+ expect(pass).toChangeAST('start = &"a" &("b"*)* &"c"', ruleDetails({
+ resultIndices: [0, 1, 2, 3],
+ posIndices: [0, 1],
+ expression: sequenceDetails
+ }));
+ expect(pass).toChangeAST('start = &"a"* &"b" &"c"', ruleDetails({
+ resultIndices: [0, 1, 2],
+ posIndices: [0, 1],
+ expression: sequenceDetails
+ }));
+ expect(pass).toChangeAST('start = &("a"*)* &"b" &"c"', ruleDetails({
+ resultIndices: [0, 1, 2],
+ posIndices: [0, 1],
+ expression: sequenceDetails
+ }));
+ expect(pass).toChangeAST('start = &(("a"*)*)* &"b" &"c"', ruleDetails({
+ resultIndices: [0, 1, 2, 3],
+ posIndices: [0, 1],
+ expression: sequenceDetails
+ }));
+ expect(pass).toChangeAST('start = &"a" &(&"b") &"c"', ruleDetails({
+ resultIndices: [0, 1, 2],
+ posIndices: [0, 1, 2],
+ expression: sequenceDetails
+ }));
+ });
+
+ it("computes variable indices for a labeled", function() {
+ expect(pass).toChangeAST('start = label:&"a"', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0],
+ expression: {
+ resultIndex: 0,
+ expression: { resultIndex: 0, posIndex: 0 }
+ }
+ }));
+ });
+
+ it("computes variable indices for a simple and", function() {
+ expect(pass).toChangeAST('start = &(&"a")', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0, 1],
+ expression: {
+ resultIndex: 0,
+ posIndex: 0,
+ expression: { resultIndex: 0, posIndex: 1 }
+ }
+ }));
+ });
+
+ it("computes variable indices for a simple not", function() {
+ expect(pass).toChangeAST('start = !(&"a")', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0, 1],
+ expression: {
+ resultIndex: 0,
+ posIndex: 0,
+ expression: { resultIndex: 0, posIndex: 1 }
+ }
+ }));
+ });
+
+ it("computes variable indices for a semantic and", function() {
+ expect(pass).toChangeAST('start = &{ code }', ruleDetails({
+ resultIndices: [0],
+ posIndices: [],
+ expression: leafDetails
+ }));
+ });
+
+ it("computes variable indices for a semantic not", function() {
+ expect(pass).toChangeAST('start = !{ code }', ruleDetails({
+ resultIndices: [0],
+ posIndices: [],
+ expression: leafDetails
+ }));
+ });
+
+ it("computes variable indices for an optional", function() {
+ expect(pass).toChangeAST('start = (&"a")?', ruleDetails({
+ resultIndices: [0],
+ posIndices: [0],
+ expression: {
+ resultIndex: 0,
+ expression: { resultIndex: 0, posIndex: 0 }
+ }
+ }));
+ });
+
+ it("computes variable indices for a zero or more", function() {
+ expect(pass).toChangeAST('start = (&"a")*', ruleDetails({
+ resultIndices: [0, 1],
+ posIndices: [0],
+ expression: {
+ resultIndex: 0,
+ expression: { resultIndex: 1, posIndex: 0 }
+ }
+ }));
+ });
+
+ it("computes variable indices for a one or more", function() {
+ expect(pass).toChangeAST('start = (&"a")+', ruleDetails({
+ resultIndices: [0, 1],
+ posIndices: [0],
+ expression: {
+ resultIndex: 0,
+ expression: { resultIndex: 1, posIndex: 0 }
+ }
+ }));
+ });
+
+ it("computes variable indices for a rule reference", function() {
+ expect(pass).toChangeAST('start = a', ruleDetails({
+ resultIndices: [0],
+ posIndices: [],
+ expression: leafDetails
+ }));
+ });
+
+ it("computes variable indices for a literal", function() {
+ expect(pass).toChangeAST('start = "a"', ruleDetails({
+ resultIndices: [0],
+ posIndices: [],
+ expression: leafDetails
+ }));
+ });
+
+ it("computes variable indices for a class", function() {
+ expect(pass).toChangeAST('start = [a-z]', ruleDetails({
+ resultIndices: [0],
+ posIndices: [],
+ expression: leafDetails
+ }));
+ });
+
+ it("computes variable indices for an any", function() {
+ expect(pass).toChangeAST('start = .', ruleDetails({
+ resultIndices: [0],
+ posIndices: [],
+ expression: leafDetails
+ }));
+ });
+});
diff --git a/spec/compiler/passes/compute-var-names.spec.js b/spec/compiler/passes/compute-var-names.spec.js
deleted file mode 100644
index 8d32efe..0000000
--- a/spec/compiler/passes/compute-var-names.spec.js
+++ /dev/null
@@ -1,229 +0,0 @@
-describe("compiler pass |computeVarNames|", function() {
- var pass = PEG.compiler.passes.computeVarNames;
-
- var leafDetails = { resultVar: "result0" },
- choiceDetails = {
- resultVar: "result0",
- alternatives: [
- { resultVar: "result0", posVar: "pos0" },
- { resultVar: "result0", posVar: "pos0" },
- { resultVar: "result0", posVar: "pos0" }
- ]
- },
- sequenceDetails = {
- resultVar: "result0",
- posVar: "pos0",
- elements: [
- { resultVar: "result0", posVar: "pos1" },
- { resultVar: "result1", posVar: "pos1" },
- { resultVar: "result2", posVar: "pos1" }
- ]
- };
-
- function ruleDetails(details) { return { rules: [details] }; }
-
- it("computes variable names for a named", function() {
- expect(pass).toChangeAST('start "start" = &"a"', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0"],
- expression: {
- resultVar: "result0",
- expression: { resultVar: "result0", posVar: "pos0" }
- }
- }));
- });
-
- it("computes variable names for a choice", function() {
- expect(pass).toChangeAST('start = &"a" / &"b" / &"c"', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0"],
- expression: choiceDetails
- }));
- expect(pass).toChangeAST('start = &"a" / &"b"* / &"c"', ruleDetails({
- resultVars: ["result0", "result1"],
- posVars: ["pos0"],
- expression: choiceDetails
- }));
- expect(pass).toChangeAST('start = &"a" / &(&"b") / &"c"', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0", "pos1"],
- expression: choiceDetails
- }));
- });
-
- it("computes variable names for an action", function() {
- expect(pass).toChangeAST('start = &"a" { code }', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0", "pos1"],
- expression: {
- resultVar: "result0",
- posVar: "pos0",
- expression: { resultVar: "result0", posVar: "pos1" }
- }
- }));
- });
-
- it("computes variable names for a sequence", function() {
- expect(pass).toChangeAST('start = ', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0"],
- expression: { resultVar: "result0", posVar: "pos0" }
- }));
- expect(pass).toChangeAST('start = &"a" &"b" &"c"', ruleDetails({
- resultVars: ["result0", "result1", "result2"],
- posVars: ["pos0", "pos1"],
- expression: sequenceDetails
- }));
- expect(pass).toChangeAST('start = &"a" &"b" &"c"*', ruleDetails({
- resultVars: ["result0", "result1", "result2", "result3"],
- posVars: ["pos0", "pos1"],
- expression: sequenceDetails
- }));
- expect(pass).toChangeAST('start = &"a" &"b"* &"c"', ruleDetails({
- resultVars: ["result0", "result1", "result2"],
- posVars: ["pos0", "pos1"],
- expression: sequenceDetails
- }));
- expect(pass).toChangeAST('start = &"a" &("b"*)* &"c"', ruleDetails({
- resultVars: ["result0", "result1", "result2", "result3"],
- posVars: ["pos0", "pos1"],
- expression: sequenceDetails
- }));
- expect(pass).toChangeAST('start = &"a"* &"b" &"c"', ruleDetails({
- resultVars: ["result0", "result1", "result2"],
- posVars: ["pos0", "pos1"],
- expression: sequenceDetails
- }));
- expect(pass).toChangeAST('start = &("a"*)* &"b" &"c"', ruleDetails({
- resultVars: ["result0", "result1", "result2"],
- posVars: ["pos0", "pos1"],
- expression: sequenceDetails
- }));
- expect(pass).toChangeAST('start = &(("a"*)*)* &"b" &"c"', ruleDetails({
- resultVars: ["result0", "result1", "result2", "result3"],
- posVars: ["pos0", "pos1"],
- expression: sequenceDetails
- }));
- expect(pass).toChangeAST('start = &"a" &(&"b") &"c"', ruleDetails({
- resultVars: ["result0", "result1", "result2"],
- posVars: ["pos0", "pos1", "pos2"],
- expression: sequenceDetails
- }));
- });
-
- it("computes variable names for a labeled", function() {
- expect(pass).toChangeAST('start = label:&"a"', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0"],
- expression: {
- resultVar: "result0",
- expression: { resultVar: "result0", posVar: "pos0" }
- }
- }));
- });
-
- it("computes variable names for a simple and", function() {
- expect(pass).toChangeAST('start = &(&"a")', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0", "pos1"],
- expression: {
- resultVar: "result0",
- posVar: "pos0",
- expression: { resultVar: "result0", posVar: "pos1" }
- }
- }));
- });
-
- it("computes variable names for a simple not", function() {
- expect(pass).toChangeAST('start = !(&"a")', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0", "pos1"],
- expression: {
- resultVar: "result0",
- posVar: "pos0",
- expression: { resultVar: "result0", posVar: "pos1" }
- }
- }));
- });
-
- it("computes variable names for a semantic and", function() {
- expect(pass).toChangeAST('start = &{ code }', ruleDetails({
- resultVars: ["result0"],
- posVars: [],
- expression: leafDetails
- }));
- });
-
- it("computes variable names for a semantic not", function() {
- expect(pass).toChangeAST('start = !{ code }', ruleDetails({
- resultVars: ["result0"],
- posVars: [],
- expression: leafDetails
- }));
- });
-
- it("computes variable names for an optional", function() {
- expect(pass).toChangeAST('start = (&"a")?', ruleDetails({
- resultVars: ["result0"],
- posVars: ["pos0"],
- expression: {
- resultVar: "result0",
- expression: { resultVar: "result0", posVar: "pos0" }
- }
- }));
- });
-
- it("computes variable names for a zero or more", function() {
- expect(pass).toChangeAST('start = (&"a")*', ruleDetails({
- resultVars: ["result0", "result1"],
- posVars: ["pos0"],
- expression: {
- resultVar: "result0",
- expression: { resultVar: "result1", posVar: "pos0" }
- }
- }));
- });
-
- it("computes variable names for a one or more", function() {
- expect(pass).toChangeAST('start = (&"a")+', ruleDetails({
- resultVars: ["result0", "result1"],
- posVars: ["pos0"],
- expression: {
- resultVar: "result0",
- expression: { resultVar: "result1", posVar: "pos0" }
- }
- }));
- });
-
- it("computes variable names for a rule reference", function() {
- expect(pass).toChangeAST('start = a', ruleDetails({
- resultVars: ["result0"],
- posVars: [],
- expression: leafDetails
- }));
- });
-
- it("computes variable names for a literal", function() {
- expect(pass).toChangeAST('start = "a"', ruleDetails({
- resultVars: ["result0"],
- posVars: [],
- expression: leafDetails
- }));
- });
-
- it("computes variable names for a class", function() {
- expect(pass).toChangeAST('start = [a-z]', ruleDetails({
- resultVars: ["result0"],
- posVars: [],
- expression: leafDetails
- }));
- });
-
- it("computes variable names for an any", function() {
- expect(pass).toChangeAST('start = .', ruleDetails({
- resultVars: ["result0"],
- posVars: [],
- expression: leafDetails
- }));
- });
-});
diff --git a/spec/index.html b/spec/index.html
index caff802..36dc248 100644
--- a/spec/index.html
+++ b/spec/index.html
@@ -12,7 +12,7 @@
-
+