UNPKG

ractive

Version:

Next-generation DOM manipulation

77 lines (60 loc) 2.32 kB
import types from 'config/types'; import getTypeof from 'parse/Parser/expressions/typeof'; var getLogicalOr, makeInfixSequenceMatcher; makeInfixSequenceMatcher = function ( symbol, fallthrough ) { return function ( parser ) { var start, left, right; left = fallthrough( parser ); if ( !left ) { return null; } // Loop to handle left-recursion in a case like `a * b * c` and produce // left association, i.e. `(a * b) * c`. The matcher can't call itself // to parse `left` because that would be infinite regress. while ( true ) { start = parser.pos; parser.allowWhitespace(); if ( !parser.matchString( symbol ) ) { parser.pos = start; return left; } // special case - in operator must not be followed by [a-zA-Z_$0-9] if ( symbol === 'in' && /[a-zA-Z_$0-9]/.test( parser.remaining().charAt( 0 ) ) ) { parser.pos = start; return left; } parser.allowWhitespace(); // right operand must also consist of only higher-precedence operators right = fallthrough( parser ); if ( !right ) { parser.pos = start; return left; } left = { t: types.INFIX_OPERATOR, s: symbol, o: [ left, right ] }; // Loop back around. If we don't see another occurrence of the symbol, // we'll return left. } }; }; // create all infix sequence matchers, and return getLogicalOr (function() { var i, len, matcher, infixOperators, fallthrough; // All the infix operators on order of precedence (source: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Operator_Precedence) // Each sequence matcher will initially fall through to its higher precedence // neighbour, and only attempt to match if one of the higher precedence operators // (or, ultimately, a literal, reference, or bracketed expression) already matched infixOperators = '* / % + - << >> >>> < <= > >= in instanceof == != === !== & ^ | && ||'.split( ' ' ); // A typeof operator is higher precedence than multiplication fallthrough = getTypeof; for ( i = 0, len = infixOperators.length; i < len; i += 1 ) { matcher = makeInfixSequenceMatcher( infixOperators[i], fallthrough ); fallthrough = matcher; } // Logical OR is the fallthrough for the conditional matcher getLogicalOr = fallthrough; }()); export default getLogicalOr;