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);
}
}
}