Do not store result variable indices, just the counts

redux
David Majda 12 years ago
parent 42d4fc6dd4
commit 2f3dd951e9

@ -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
}));
});
});

@ -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 }),

@ -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;

Loading…
Cancel
Save