PageRenderTime 37ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/System.Xronos/Language/PersistentList.cs

https://bitbucket.org/stefanrusek/xronos
C# | 258 lines | 182 code | 53 blank | 23 comment | 13 complexity | 3f9d6c7e0f74e89b6ac5ad2c3226f38a MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) 2008 Stefan Rusek and Benjamin Pollack
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining a copy
  6. * of this software and associated documentation files (the "Software"), to deal
  7. * in the Software without restriction, including without limitation the rights
  8. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. * copies of the Software, and to permit persons to whom the Software is
  10. * furnished to do so, subject to the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included in
  13. * all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. * THE SOFTWARE.
  22. *
  23. * ***************************************************************************/
  24. using System;
  25. using System.Collections.Generic;
  26. using System.Linq;
  27. using System.Text;
  28. using System.Collections;
  29. namespace System.Xronos.Language
  30. {
  31. public class PersistentList : Sequence, IPersistentList, IReduce
  32. {
  33. object _first;
  34. PersistentList _rest;
  35. int _count;
  36. private PersistentList(IPersistentMap meta, object first, PersistentList rest)
  37. : base(meta)
  38. {
  39. _first = first;
  40. _rest = rest;
  41. if (rest != null)
  42. _count = rest.Count;
  43. _count++;
  44. }
  45. public static IPersistentList Create(IList list)
  46. {
  47. IPersistentCollection rt = Empty;
  48. for (int i = list.Count-1; i >= 0; i--)
  49. {
  50. rt = rt.cons(list[i]);
  51. }
  52. return (IPersistentList)rt;
  53. }
  54. public static IPersistentList Create(ISequence seq)
  55. {
  56. if (seq == null)
  57. return Empty;
  58. return (IPersistentList)Create(seq.rest()).cons(seq.first());
  59. }
  60. public static readonly IPersistentList Empty = new EmptyList();
  61. public override object first()
  62. {
  63. return _first;
  64. }
  65. public override ISequence rest()
  66. {
  67. return _rest;
  68. }
  69. public override ISequence cons(object first)
  70. {
  71. return new PersistentList(null, first, this);
  72. }
  73. public override XronosObject withMeta(IPersistentMap meta)
  74. {
  75. return new PersistentList(meta, _first, _rest);
  76. }
  77. #region IPersistentStack Members
  78. public object peek()
  79. {
  80. return first();
  81. }
  82. public IPersistentStack pop()
  83. {
  84. if (_rest != null)
  85. return (IPersistentList)((PersistentList)_rest).withMeta(meta());
  86. return null;
  87. }
  88. #endregion
  89. #region IPersistentCollection Members
  90. public int count()
  91. {
  92. return _count;
  93. }
  94. public ISequence seq()
  95. {
  96. if (_count == 0)
  97. return null;
  98. return this;
  99. }
  100. IPersistentCollection IPersistentCollection.cons(object o)
  101. {
  102. return new PersistentList(null, o, this);
  103. }
  104. public IPersistentCollection empty()
  105. {
  106. return Empty;
  107. }
  108. #endregion
  109. #region IReduce Members
  110. public object reduce(object f)
  111. {
  112. var ret = first();
  113. for (var seq = rest(); seq != null; seq = seq.rest())
  114. ret = FunctionHelper.Invoke<object>(f, ret, seq.first());
  115. return ret;
  116. }
  117. public object reduce(object f, object start)
  118. {
  119. var ret = start;
  120. for (ISequence seq = this; seq != null; seq = seq.rest())
  121. ret = FunctionHelper.Invoke<object>(f, ret, seq.first());
  122. return ret;
  123. }
  124. #endregion
  125. private class EmptyList : IPersistentList, IReduce, ICollection, ISequence
  126. {
  127. #region IPersistentStack Members
  128. public object peek()
  129. {
  130. return null;
  131. }
  132. public IPersistentStack pop()
  133. {
  134. return null;
  135. }
  136. #endregion
  137. #region IPersistentCollection Members
  138. public int count()
  139. {
  140. return 0;
  141. }
  142. public ISequence seq()
  143. {
  144. return null;
  145. }
  146. public IPersistentCollection cons(object o)
  147. {
  148. return new PersistentList(null, o, null);
  149. }
  150. public IPersistentCollection empty()
  151. {
  152. return this;
  153. }
  154. #endregion
  155. #region IReduce Members
  156. public object reduce(object f)
  157. {
  158. return FunctionHelper.Invoke<object>(f);
  159. }
  160. public object reduce(object f, object start)
  161. {
  162. return start;
  163. }
  164. #endregion
  165. #region ICollection Members
  166. public void CopyTo(Array array, int index)
  167. {
  168. return;
  169. }
  170. public int Count
  171. {
  172. get { return 0; }
  173. }
  174. public bool IsSynchronized
  175. {
  176. get { return false; }
  177. }
  178. public object SyncRoot
  179. {
  180. get { return this; }
  181. }
  182. #endregion
  183. #region IEnumerable Members
  184. public IEnumerator GetEnumerator()
  185. {
  186. return new object[0].GetEnumerator();
  187. }
  188. #endregion
  189. #region ISequence Members
  190. public object first()
  191. {
  192. return null;
  193. }
  194. public ISequence rest()
  195. {
  196. return null;
  197. }
  198. ISequence ISequence.cons(object first)
  199. {
  200. return (ISequence)this.cons(first);
  201. }
  202. #endregion
  203. }
  204. }
  205. }