*** 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
27     public new string ToString ()
28     {
29       string str = "";
30
31       for (MPlist p = this; ! p.IsEmpty; p = p.next)
32         {
33           str += (p == this ? "(" : " ") + p.Key.ToString () + ":";
34           if (p.Val is MSymbol)
35             str += ((MSymbol) p.Val).ToString ();
36           else if (p.Val is MPlist)
37             str += ((MPlist) p.Val).ToString ();
38         }
39       return str + ")";
40     }
41
42     public MPlist find (MSymbol key)
43     {
44       MPlist p;
45
46       for (p = this; ! p.IsEmpty; p = p.next)
47         if (p.Key == key)
48           break;
49       return p;
50     }
51
52     public object get (MSymbol key)
53     {
54       return find (key).Val;
55     }
56
57     public MPlist put (MSymbol key, object val)
58     {
59       MPlist p = find (key);
60
61       if (p.IsEmpty)
62         return p.push (key, val);
63       p.Val = val;
64       return p;
65     }
66
67     public MPlist push (MSymbol key, object val)
68     {
69       MPlist p = new MPlist (Key, Val);
70
71       p.next = this.next;
72       Key = key;
73       Val = val;
74       next = p;
75       return this;
76     }
77
78     public object pop ()
79     {
80       if (IsEmpty)
81         return null;
82
83       object val = Val;
84
85       Key = next.Key;
86       Val = next.Val;
87       next = next.next;
88       return val;
89     }
90
91     public MPlist add (MSymbol key, object val)
92     {
93       MPlist p;
94
95       for (p = this; ! p.IsEmpty; p = p.next);
96       return p.push (key, val);
97     }
98
99     // Implement IEnumerable interface.
100
101     public virtual IEnumerator GetEnumerator ()
102     {
103       return new Enumerator (this);
104     }
105
106     private class Enumerator : IEnumerator
107     {
108       private MPlist plist;
109       private MPlist current;
110
111       internal Enumerator (MPlist plist)
112         {
113           this.plist = plist;
114         }
115
116       public object Current
117       {
118         get {
119           if (current == null || current.IsEmpty)
120             throw new InvalidOperationException ();
121           return current;
122         }
123       }
124
125       public void Reset ()
126       {
127         current = null;
128       }
129
130       public bool MoveNext ()
131       {
132         if (current == null)
133           current = plist;
134         else if (current.IsEmpty)
135           return false;
136         else
137           current = current.next;
138         return true;
139       }
140     }
141   }
142 }