StringSource.js 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. var StringSource = module.exports = function(string, description) {
  2. var self = {
  3. asString: function() {
  4. return string;
  5. },
  6. range: function(startIndex, endIndex) {
  7. return new StringSourceRange(string, description, startIndex, endIndex);
  8. }
  9. };
  10. return self;
  11. };
  12. var StringSourceRange = function(string, description, startIndex, endIndex) {
  13. this._string = string;
  14. this._description = description;
  15. this._startIndex = startIndex;
  16. this._endIndex = endIndex;
  17. };
  18. StringSourceRange.prototype.to = function(otherRange) {
  19. // TODO: Assert that tokens are the same across both iterators
  20. return new StringSourceRange(this._string, this._description, this._startIndex, otherRange._endIndex);
  21. };
  22. StringSourceRange.prototype.describe = function() {
  23. var position = this._position();
  24. var description = this._description ? this._description + "\n" : "";
  25. return description + "Line number: " + position.lineNumber + "\nCharacter number: " + position.characterNumber;
  26. };
  27. StringSourceRange.prototype.lineNumber = function() {
  28. return this._position().lineNumber;
  29. };
  30. StringSourceRange.prototype.characterNumber = function() {
  31. return this._position().characterNumber;
  32. };
  33. StringSourceRange.prototype._position = function() {
  34. var self = this;
  35. var index = 0;
  36. var nextNewLine = function() {
  37. return self._string.indexOf("\n", index);
  38. };
  39. var lineNumber = 1;
  40. while (nextNewLine() !== -1 && nextNewLine() < this._startIndex) {
  41. index = nextNewLine() + 1;
  42. lineNumber += 1;
  43. }
  44. var characterNumber = this._startIndex - index + 1;
  45. return {lineNumber: lineNumber, characterNumber: characterNumber};
  46. };