(stack,tt)
| 464 | } |
| 465 | |
| 466 | function d(stack,tt) { |
| 467 | // stack is a stack of Token objects. |
| 468 | // tt is an object; {type:tokens} |
| 469 | // type is a char, tokens is a list of token strings. |
| 470 | // The function returns (possibly truncated) stack. |
| 471 | // It will descend the stack, looking for a Token such that Token.token |
| 472 | // is a member of tokens. If it does not find that, it will normally (but |
| 473 | // see "E" below) return stack. If it does find a match, it will remove |
| 474 | // all the Tokens between the top and the matched Token. |
| 475 | // If type is "m", that is all it does. |
| 476 | // If type is "i", it will also remove the matched Token and the top Token. |
| 477 | // If type is "g", like "i", but add a fake "group" token at the top. |
| 478 | // If type is "r", it will remove the matched Token, but not the top Token. |
| 479 | // If type is "e", it will keep the matched Token but not the top Token. |
| 480 | // If type is "E", it behaves as for type "e", except if there is no match, |
| 481 | // in which case it will return an empty stack. |
| 482 | |
| 483 | for (var type in tt) { |
| 484 | var len = stack.length-1; |
| 485 | var tokens = tt[type]; |
| 486 | for (var i = len-1; -1 < i ; i--) { |
| 487 | if (is_member(stack[i].token,tokens)) { |
| 488 | var ss = stack.slice(0,i); |
| 489 | switch (type) { |
| 490 | case "m": return ss.concat(stack[i]).concat(stack[len]); |
| 491 | case "r": return ss.concat(stack[len]); |
| 492 | case "i": return ss; |
| 493 | case "g": return ss.concat(fakeToken("group")); |
| 494 | case "E": return ss.concat(stack[i]); |
| 495 | case "e": return ss.concat(stack[i]); |
| 496 | } |
| 497 | } |
| 498 | } |
| 499 | } |
| 500 | return (type == "E" ? [] : stack); |
| 501 | } |
| 502 | |
| 503 | ///////////////////////////////////////////////////////////////////////////// |
| 504 | // indenter |
no test coverage detected