Browse Source

More responsibility for computing |resultIndex| to node's parent

Before this commit, each node was responsible for computing the value of
its |resultIndex| property in the |computeVarIndices| pass. This was
possible because |resultIndex| was always equal to |index.result|,
meaning that nodes always wrote their match results to the top of the
stack.

This behavior would cause problems in the future where nodes will use
the stack also for storing positions. Parent nodes storing position on
the stack would have to copy their childs' match results from the top of
the stack to some position below where parent's match result would be
expected. There would be no way to tell the children to place their
match result somewhere else than the top of the stack and avoid copying.

This commit fixes the described problem by shifting the responsibility
for setting the value of node's |resultIndex| property to its parent.
This way it can direct its child to place its result wherever it wants
to.
redux
David Majda 9 years ago
parent
commit
890140d73b
  1. 42
      src/compiler/passes/compute-var-indices.js

42
src/compiler/passes/compute-var-indices.js

@ -16,23 +16,22 @@
* variables in generated code.)
*/
PEG.compiler.passes.computeVarIndices = function(ast) {
function computeLeaf(node, index) {
node.resultIndex = index.result;
return { result: 0, pos: 0 };
}
function computeLeaf(node, index) { return { result: 0, pos: 0 }; }
function computeFromExpression(delta) {
return function(node, index) {
var depth = compute(
node.expression,
{
result: index.result + delta.result,
pos: index.pos + delta.pos
}
);
var depth;
node.expression.resultIndex = index.result + delta.result;
depth = compute(
node.expression,
{
result: index.result + delta.result,
pos: index.pos + delta.pos
}
);
node.resultIndex = index.result;
if (delta.pos !== 0) {
node.posIndex = index.pos;
}
@ -48,15 +47,19 @@ PEG.compiler.passes.computeVarIndices = function(ast) {
grammar:
function(node, index) {
each(node.rules, function(node) {
node.resultIndex = index.result;
compute(node, index);
});
},
rule:
function(node, index) {
var depth = compute(node.expression, index);
var depth;
node.expression.resultIndex = node.resultIndex;
depth = compute(node.expression, index);
node.resultIndex = index.result;
node.resultIndices = range(depth.result + 1);
node.posIndices = range(depth.pos);
},
@ -66,11 +69,11 @@ PEG.compiler.passes.computeVarIndices = function(ast) {
choice:
function(node, index) {
var depths = map(node.alternatives, function(alternative) {
alternative.resultIndex = node.resultIndex;
return compute(alternative, index);
});
node.resultIndex = index.result;
return {
result: Math.max.apply(null, pluck(depths, "result")),
pos: Math.max.apply(null, pluck(depths, "pos"))
@ -82,14 +85,15 @@ PEG.compiler.passes.computeVarIndices = function(ast) {
sequence:
function(node, index) {
var depths = map(node.elements, function(element, i) {
element.resultIndex = index.result + i;
return compute(
element,
{ result: index.result + i, pos: index.pos + 1 }
);
});
node.resultIndex = index.result;
node.posIndex = index.pos;
node.posIndex = index.pos;
return {
result:

Loading…
Cancel
Save