text: // 
  //  [The "BSD license"]
  //   Copyright (c) 2012 Terence Parr
  //   Copyright (c) 2012 Sam Harwell
  //   Copyright (c) 2014 Eric Vergnaud
  //   All rights reserved.
  // 
  //   Redistribution and use in source and binary forms, with or without
  //   modification, are permitted provided that the following conditions
  //   are met:
  // 
  //   1. Redistributions of source code must retain the above copyright
  //      notice, this list of conditions and the following disclaimer.
  //   2. Redistributions in binary form must reproduce the above copyright
  //      notice, this list of conditions and the following disclaimer in the
  //      documentation and/or other materials provided with the distribution.
  //   3. The name of the author may not be used to endorse or promote products
  //      derived from this software without specific prior written permission.
  // 
  //   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  //   IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  //   OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  //   IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  //   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  //   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  //   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  //   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  //   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  //   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  // 
  define(function(require, exports, module) {
  	var Token = require('./Token').Token;
  
  // Vacuum all input from a string and then treat it like a buffer.
  
  	function _loadString(stream) {
  		stream._index = 0;
  		stream.data = [];
  		for (var i = 0; i < stream.strdata.length; i++) {
  			stream.data.push(stream.strdata.charCodeAt(i));
  		}
  		stream._size = stream.data.length;
  	}
  
  	function InputStream(data) {
  		this.name = "<empty>";
  		this.strdata = data;
  		_loadString(this);
  		return this;
  	}
  
  	Object.defineProperty(InputStream.prototype, "index", {
  		get: function () {
  			return this._index;
  		}
  	});
  
  	Object.defineProperty(InputStream.prototype, "size", {
  		get: function () {
  			return this._size;
  		}
  	});
  
  // Reset the stream so that it's in the same state it was
  // when the object was created *except* the data array is not
  // touched.
  //
  	InputStream.prototype.reset = function () {
  		this._index = 0;
  	};
  
  	InputStream.prototype.consume = function () {
  		if (this._index >= this._size) {
  			// assert this.LA(1) == Token.EOF
  			throw ("cannot consume EOF");
  		}
  		this._index += 1;
  	};
  
  	InputStream.prototype.LA = function (offset) {
  		if (offset === 0) {
  			return 0; // undefined
  		}
  		if (offset < 0) {
  			offset += 1; // e.g., translate LA(-1) to use offset=0
  		}
  		var pos = this._index + offset - 1;
  		if (pos < 0 || pos >= this._size) { // invalid
  			return Token.EOF;
  		}
  		return this.data[pos];
  	};
  
  	InputStream.prototype.LT = function (offset) {
  		return this.LA(offset);
  	};
  
  // mark/release do nothing; we have entire buffer
  	InputStream.prototype.mark = function () {
  		return -1;
  	};
  
  	InputStream.prototype.release = function (marker) {
  	};
  
  // consume() ahead until p==_index; can't just set p=_index as we must
  // update line and column. If we seek backwards, just set p
  //
  	InputStream.prototype.seek = function (_index) {
  		if (_index <= this._index) {
  			this._index = _index; // just jump; don't update stream state (line,
  			// ...)
  			return;
  		}
  		// seek forward
  		this._index = Math.min(_index, this._size);
  	};
  
  	InputStream.prototype.getText = function (start, stop) {
  		if (stop >= this._size) {
  			stop = this._size - 1;
  		}
  		if (start >= this._size) {
  			return "";
  		} else {
  			return this.strdata.slice(start, stop + 1);
  		}
  	};
  
  	InputStream.prototype.toString = function () {
  		return this.strdata;
  	};
  
  	module.exports.InputStream = InputStream;
  });
  