UNPKG

diffusion

Version:

Diffusion JavaScript client

101 lines (85 loc) 2.17 kB
/*eslint valid-jsdoc: "off"*/ /** * Maintain recursive parsing context on a stack. */ function Context() { var ROOT = { length : -1, type : 'root', read : 0 }; var stack = []; var tail = ROOT; /** * @returns {Object} the type of the current context */ this.type = function() { return tail.type; }; /** * @returns {Number} how many tokens have been read in this context */ this.read = function() { return tail.read; }; /** * @returns {Number} how many tokens are expected by this current context */ this.expected = function() { return tail.length; }; /** * Add a new context */ this.push = function(type, length) { length = length === undefined ? -1 : length; tail = { length : length, type : type, read : 0 }; stack.push(tail); }; /** * Pop the current context * * @returns the previous tail on the context stack */ this.pop = function() { var prev = stack.pop(); if (stack.length) { tail = stack[stack.length - 1]; } else { tail = ROOT; } return prev; }; /** * Progress through the current context's expected value count */ this.next = function() { if (this.hasRemaining()) { tail.read++; } else { throw new Error('Exceeded expected collection limit'); } }; /** * Ends this current context. */ this.break = function() { if (this.acceptsBreakMarker()) { tail.length = 0; tail.read = 0; } }; /** * @returns {Number} the expected number of remaining values from the current context. */ this.hasRemaining = function() { return tail.length === -1 ? true : tail.length > tail.read; }; /** * @returns {Boolean} whether the current context accepts break marker tokens */ this.acceptsBreakMarker = function() { return tail !== ROOT && tail.length === -1; }; } module.exports = Context;