using System; using System.Collections.Generic; namespace Sprache { /// /// Represents an input for parsing. /// public class Input : IInput { private readonly string _source; private readonly int _position; private readonly int _line; private readonly int _column; /// /// Gets the list of memos assigned to the instance. /// public IDictionary Memos { get; private set; } /// /// Initializes a new instance of the class. /// /// The source. public Input(string source) : this(source, 0) { } internal Input(string source, int position, int line = 1, int column = 1) { _source = source; _position = position; _line = line; _column = column; Memos = new Dictionary(); } /// /// Advances the input. /// /// A new that is advanced. /// The input is already at the end of the source. public IInput Advance() { if (AtEnd) throw new InvalidOperationException("The input is already at the end of the source."); return new Input(_source, _position + 1, Current == '\n' ? _line + 1 : _line, Current == '\n' ? 1 : _column + 1); } /// /// Gets the whole source. /// public string Source { get { return _source; } } /// /// Gets the current . /// public char Current { get { return _source[_position]; } } /// /// Gets a value indicating whether the end of the source is reached. /// public bool AtEnd { get { return _position == _source.Length; } } /// /// Gets the current positon. /// public int Position { get { return _position; } } /// /// Gets the current line number. /// public int Line { get { return _line; } } /// /// Gets the current column. /// public int Column { get { return _column; } } /// /// Returns a string that represents the current object. /// /// /// A string that represents the current object. /// public override string ToString() { return string.Format("Line {0}, Column {1}", _line, _column); } /// /// Serves as a hash function for a particular type. /// /// /// A hash code for the current . /// public override int GetHashCode() { unchecked { return ((_source != null ? _source.GetHashCode() : 0) * 397) ^ _position; } } /// /// Determines whether the specified is equal to the current . /// /// /// true if the specified is equal to the current ; otherwise, false. /// /// The object to compare with the current object. public override bool Equals(object obj) { return Equals(obj as IInput); } /// /// Indicates whether the current is equal to another object of the same type. /// /// /// true if the current object is equal to the parameter; otherwise, false. /// /// An object to compare with this object. public bool Equals(IInput other) { if (ReferenceEquals(null, other)) return false; if (ReferenceEquals(this, other)) return true; return string.Equals(_source, other.Source) && _position == other.Position; } /// /// Indicates whether the left is equal to the right . /// /// The left . /// The right . /// true if both objects are equal. public static bool operator ==(Input left, Input right) { return Equals(left, right); } /// /// Indicates whether the left is not equal to the right . /// /// The left . /// The right . /// true if the objects are not equal. public static bool operator !=(Input left, Input right) { return !Equals(left, right); } } }