falcor-path-syntax
Version:
Parser for Falcor Path Syntax
78 lines (60 loc) • 2.13 kB
JavaScript
var Tokenizer = require('./../tokenizer');
var TokenTypes = require('./../TokenTypes');
var E = require('./../exceptions');
/**
* The indexer is all the logic that happens in between
* the '[', opening bracket, and ']' closing bracket.
*/
module.exports = function range(tokenizer, openingToken, state, out) {
var token = tokenizer.peek();
var dotCount = 1;
var done = false;
var inclusive = true;
// Grab the last token off the stack. Must be an integer.
var idx = state.indexer.length - 1;
var from = Tokenizer.toNumber(state.indexer[idx]);
var to;
if (isNaN(from)) {
E.throwError(E.range.precedingNaN, tokenizer);
}
// Why is number checking so difficult in javascript.
while (!done && !token.done) {
switch (token.type) {
// dotSeparators at the top level have no meaning
case TokenTypes.dotSeparator:
if (dotCount === 3) {
E.throwError(E.unexpectedToken, tokenizer);
}
++dotCount;
if (dotCount === 3) {
inclusive = false;
}
break;
case TokenTypes.token:
// move the tokenizer forward and save to.
to = Tokenizer.toNumber(tokenizer.next().token);
// throw potential error.
if (isNaN(to)) {
E.throwError(E.range.suceedingNaN, tokenizer);
}
done = true;
break;
default:
done = true;
break;
}
// Keep cycling through the tokenizer. But ranges have to peek
// before they go to the next token since there is no 'terminating'
// character.
if (!done) {
tokenizer.next();
// go to the next token without consuming.
token = tokenizer.peek();
}
// break and remove state information.
else {
break;
}
}
state.indexer[idx] = {from: from, to: inclusive ? to : to - 1};
};