*** empty log message ***
[m17n/m17n-lib-cs.git] / MPlist.cs
1 using System;
2 using System.Collections;
3 using M17N.Core;
4
5 namespace M17N.Core
6 {
7   public class MPlist : IEnumerable
8   {
9     public MSymbol Key;
10     public object Val;
11     private MPlist next;
12
13     public MPlist ()
14       {
15         Key = MSymbol.nil;
16         Val = null;
17       }
18
19     private MPlist (MSymbol key, object val)
20       {
21         Key = key;
22         Val = val;
23       }
24
25     public bool IsEmpty { get { return next == null; } }
26     public MPlist Next { get { return next; } }
27
28     public int Count
29     {
30       get
31         {
32           int i = 0;
33
34           for (MPlist p = this; p.next != null; i++, p = p.next);
35           return i;
36         }
37     }
38
39     public MPlist Clone ()
40     {
41       MPlist plist = new MPlist (), pl = plist;
42
43       for (MPlist p = this; p.next != null; p = p.next)
44         pl = pl.Add (p.Key, p.Val);
45       return plist;
46     }
47
48     public override string ToString ()
49     {
50         string str = "";
51
52         for (MPlist p = this; ! p.IsEmpty; p = p.next)
53           {
54             str += (p == this ? "(" : " ") + p.Key + ":" + p.Val;
55           }
56         return str + ")";
57     }
58
59     public MPlist Find (MSymbol key)
60     {
61       MPlist p;
62
63       for (p = this; ! p.IsEmpty; p = p.next)
64         if (p.Key == key)
65           break;
66       return p;
67     }
68
69     public object Get (MSymbol key)
70     {
71       return Find (key).Val;
72     }
73
74     public MPlist Set (MSymbol key, object val)
75     {
76       if (IsEmpty)
77         Push (key, val);
78       else
79         Val = val;
80       return this;
81     }
82
83     public MPlist Put (MSymbol key, object val)
84     {
85       return Find (key).Set (key, val);
86     }
87
88     public MPlist Push (MSymbol key, object val)
89     {
90       MPlist p = new MPlist (Key, Val);
91
92       p.next = this.next;
93       Key = key;
94       Val = val;
95       next = p;
96       return this;
97     }
98
99     public object Pop ()
100     {
101       if (IsEmpty)
102         return null;
103
104       object val = Val;
105
106       Key = next.Key;
107       Val = next.Val;
108       next = next.next;
109       return val;
110     }
111
112     public MPlist Add (MSymbol key, object val)
113     {
114       MPlist p;
115
116       for (p = this; ! p.IsEmpty; p = p.next);
117       return p.Push (key, val);
118     }
119
120     // Implement IEnumerable interface.
121     //   foreach (MPlist p in plist) { ... }
122
123     public virtual IEnumerator GetEnumerator ()
124     {
125       return new Enumerator (this);
126     }
127
128     private class Enumerator : IEnumerator
129     {
130       private MPlist plist;
131       private MPlist current;
132
133       internal Enumerator (MPlist plist)
134         {
135           this.plist = plist;
136         }
137
138       public object Current
139       {
140         get {
141           if (current == null || current.IsEmpty)
142             throw new InvalidOperationException ();
143           return current;
144         }
145       }
146
147       public void Reset ()
148       {
149         current = null;
150       }
151
152       public bool MoveNext ()
153       {
154         if (current == null)
155           current = plist;
156         else
157           current = current.next;
158         return (! current.IsEmpty);
159       }
160     }
161   }
162 }