PageRenderTime 53ms CodeModel.GetById 20ms app.highlight 10ms RepoModel.GetById 20ms 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 * ***************************************************************************/
 24using System;
 25using System.Collections.Generic;
 26using System.Linq;
 27using System.Text;
 28using System.Collections;
 29
 30namespace System.Xronos.Language
 31{
 32    public class PersistentList : Sequence, IPersistentList, IReduce
 33    {
 34        object _first;
 35        PersistentList _rest;
 36        int _count;
 37
 38        private PersistentList(IPersistentMap meta, object first, PersistentList rest)
 39            : base(meta)
 40        {
 41            _first = first;
 42            _rest = rest;
 43
 44            if (rest != null)
 45                _count = rest.Count;
 46
 47            _count++;
 48        }
 49
 50        public static IPersistentList Create(IList list)
 51        {
 52            IPersistentCollection rt = Empty;
 53            for (int i = list.Count-1; i >= 0; i--)
 54            {
 55                rt = rt.cons(list[i]);
 56            }
 57            return (IPersistentList)rt;
 58        }
 59
 60        public static IPersistentList Create(ISequence seq)
 61        {
 62            if (seq == null)
 63                return Empty;
 64            return (IPersistentList)Create(seq.rest()).cons(seq.first());
 65        }
 66
 67        public static readonly IPersistentList Empty = new EmptyList();
 68
 69        public override object first()
 70        {
 71            return _first;
 72        }
 73
 74        public override ISequence rest()
 75        {
 76            return _rest;
 77        }
 78
 79        public override ISequence cons(object first)
 80        {
 81            return new PersistentList(null, first, this);
 82        }
 83
 84        public override XronosObject withMeta(IPersistentMap meta)
 85        {
 86            return new PersistentList(meta, _first, _rest);
 87        }
 88
 89        #region IPersistentStack Members
 90
 91        public object peek()
 92        {
 93            return first();
 94        }
 95
 96        public IPersistentStack pop()
 97        {
 98            if (_rest != null)
 99                return (IPersistentList)((PersistentList)_rest).withMeta(meta());
100            return null;
101        }
102
103        #endregion
104
105        #region IPersistentCollection Members
106
107        public int count()
108        {
109            return _count;
110        }
111
112        public ISequence seq()
113        {
114            if (_count == 0)
115                return null;
116            return this;
117        }
118
119        IPersistentCollection IPersistentCollection.cons(object o)
120        {
121            return new PersistentList(null, o, this);
122        }
123
124        public IPersistentCollection empty()
125        {
126            return Empty;
127        }
128
129        #endregion
130
131        #region IReduce Members
132
133        public object reduce(object f)
134        {
135            var ret = first();
136            for (var seq = rest(); seq != null; seq = seq.rest())
137                ret = FunctionHelper.Invoke<object>(f, ret, seq.first());
138            return ret;
139        }
140
141        public object reduce(object f, object start)
142        {
143            var ret = start;
144            for (ISequence seq = this; seq != null; seq = seq.rest())
145                ret = FunctionHelper.Invoke<object>(f, ret, seq.first());
146            return ret;
147        }
148
149        #endregion
150
151        private class EmptyList : IPersistentList, IReduce, ICollection, ISequence
152        {
153            #region IPersistentStack Members
154
155            public object peek()
156            {
157                return null;
158            }
159
160            public IPersistentStack pop()
161            {
162                return null;
163            }
164
165            #endregion
166
167            #region IPersistentCollection Members
168
169            public int count()
170            {
171                return 0;
172            }
173
174            public ISequence seq()
175            {
176                return null;
177            }
178
179            public IPersistentCollection cons(object o)
180            {
181                return new PersistentList(null, o, null);
182            }
183
184            public IPersistentCollection empty()
185            {
186                return this;
187            }
188
189            #endregion
190
191            #region IReduce Members
192
193            public object reduce(object f)
194            {
195                return FunctionHelper.Invoke<object>(f);
196            }
197
198            public object reduce(object f, object start)
199            {
200                return start;
201            }
202
203            #endregion
204
205            #region ICollection Members
206
207            public void CopyTo(Array array, int index)
208            {
209                return;
210            }
211
212            public int Count
213            {
214                get { return 0; }
215            }
216
217            public bool IsSynchronized
218            {
219                get { return false; }
220            }
221
222            public object SyncRoot
223            {
224                get { return this; }
225            }
226
227            #endregion
228
229            #region IEnumerable Members
230
231            public IEnumerator GetEnumerator()
232            {
233                return new object[0].GetEnumerator();
234            }
235
236            #endregion
237
238            #region ISequence Members
239
240            public object first()
241            {
242                return null;
243            }
244
245            public ISequence rest()
246            {
247                return null;
248            }
249
250            ISequence ISequence.cons(object first)
251            {
252                return (ISequence)this.cons(first);
253            }
254
255            #endregion
256        }
257    }
258}