/BrainfuckNancy/BrainfuckCore/Memory.cs

https://gitlab.com/wipiano/BrainfuckNancy · C# · 141 lines · 77 code · 14 blank · 50 comment · 4 complexity · ae3bf565e481086bc332765399245fed MD5 · raw file

  1. using System.Configuration;
  2. using BrainfuckCore.Exception;
  3. namespace BrainfuckCore
  4. {
  5. /// <summary>
  6. /// Brainfuck インタプリタが使用する仮想メモリ
  7. /// </summary>
  8. internal class Memory
  9. {
  10. /// <summary>
  11. /// メモリの最大サイズ
  12. /// </summary>
  13. private static readonly int MaxMemorySize = int.Parse(ConfigurationManager.AppSettings["MaxMemorySize"]);
  14. /// <summary>
  15. /// メモリのポインタ
  16. /// </summary>
  17. private int _pointer;
  18. /// <summary>
  19. /// メモリの実体
  20. /// </summary>
  21. private readonly byte[] _memory;
  22. /// <summary>
  23. /// メモリサイズ
  24. /// </summary>
  25. public int MemorySize => _memory.Length;
  26. /// <summary>
  27. /// 現在のポインタがさしている値
  28. /// </summary>
  29. public byte CurrentValue
  30. {
  31. get { return _memory[_pointer]; }
  32. set { _memory[_pointer] = value; }
  33. }
  34. /// <summary>
  35. /// コンストラクタ
  36. /// </summary>
  37. /// <param name="memorySize">メモリサイズ</param>
  38. public Memory(int memorySize)
  39. {
  40. try
  41. {
  42. ValidateMemorySize(memorySize);
  43. _pointer = 0;
  44. _memory = new byte[memorySize];
  45. }
  46. catch (InvalidMemorySizeException)
  47. {
  48. throw;
  49. }
  50. }
  51. /// <summary>
  52. /// メモリを初期化します
  53. /// </summary>
  54. public void Init()
  55. {
  56. _pointer = 0;
  57. _memory.Initialize();
  58. }
  59. /// <summary>
  60. /// ポインタを一つ進めます
  61. /// </summary>
  62. public void MoveNext()
  63. {
  64. MoveIndex(_pointer + 1);
  65. }
  66. /// <summary>
  67. /// ポインタを一つ戻します
  68. /// </summary>
  69. public void MovePrevious()
  70. {
  71. MoveIndex(_pointer - 1);
  72. }
  73. /// <summary>
  74. /// ポインタが指す値をインクリメントします
  75. /// </summary>
  76. public void Increment()
  77. {
  78. CurrentValue++;
  79. }
  80. /// <summary>
  81. /// ポインタがさす値をデクリメントします
  82. /// </summary>
  83. public void Decrement()
  84. {
  85. CurrentValue--;
  86. }
  87. /// <summary>
  88. /// ポインタを移動させます
  89. /// </summary>
  90. /// <param name="destination"></param>
  91. private void MoveIndex(int destination)
  92. {
  93. try
  94. {
  95. ValidateIndex(destination);
  96. _pointer = destination;
  97. }
  98. catch (OutOfMemoryException)
  99. {
  100. throw;
  101. }
  102. }
  103. #region Validator
  104. /// <summary>
  105. /// 指定したメモリサイズが有効かどうか
  106. /// </summary>
  107. /// <param name="memorySize"></param>
  108. /// <returns></returns>
  109. private void ValidateMemorySize(int memorySize)
  110. {
  111. if (memorySize <= 0 || memorySize > MaxMemorySize)
  112. {
  113. throw new InvalidMemorySizeException(memorySize);
  114. }
  115. }
  116. /// <summary>
  117. /// 指定したインデックスが有効かどうか検証します
  118. /// </summary>
  119. /// <param name="index"></param>
  120. private void ValidateIndex(int index)
  121. {
  122. if (index >= 0 && index < MemorySize) return;
  123. throw new OutOfMemoryException(this.MemorySize, index);
  124. }
  125. #endregion
  126. }
  127. }