Replace variable name computations by computations of indices
This commit replaces all variable name computations in |computeVarNames| and |computeParams| passes by computations of indices. The actual names are computed later in the |generateCode| pass. This change makes the code generator the only place that deals with the actual variable names, making them easier to change for example. The code generator code seems bit more complicated after the change, but this complexity will pay off (and mostly disappear) later.redux
parent
725927e05f
commit
2c8b323ade
@ -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
|
||||
}));
|
||||
});
|
||||
});
|
@ -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
|
||||
}));
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue